BROP - Blind Return Oriented Programming
Taarifa Msingi
Lengo la shambulio hili ni kuweza kutumia ROP kupitia kuzidi kwa ujazo wa buffer bila habari yoyote kuhusu binary inayoweza kudhuriwa. Shambulio hili linategemea hali ifuatayo:
Udhaifu wa stack na maarifa ya jinsi ya kuchochea hali hiyo.
Programu ya seva inayojirekebisha baada ya kushindwa.
Shambulio
1. Pata offset dhaifu kwa kutuma herufi moja zaidi hadi kosa la seva litambuliwe
2. Jaribu nguvu ya canary ili kuvuja hilo
3. Jaribu nguvu ya RBP na RIP zilizohifadhiwa kwenye stack ili kuzivuja
Unaweza kupata habari zaidi kuhusu mchakato huu hapa (BF Forked & Threaded Stack Canaries) na hapa (BF Addresses in the Stack).
4. Pata kifaa cha kusimamisha
Kifaa hiki kimsingi kuruhusu kuthibitisha kwamba kitu cha kuvutia kimeendeshwa na kifaa cha ROP kwa sababu utekelezaji haukushindwa. Kawaida, kifaa hiki kitakuwa kitu kinachosimamisha utekelezaji na kipo mwishoni mwa mnyororo wa ROP unapotafuta vifaa vya ROP kuthibitisha kifaa maalum cha ROP kilitekelezwa
5. Pata kifaa cha BROP
Mbinu hii hutumia kifaa cha ret2csu. Na hii ni kwa sababu ikiwa unafikia kifaa hiki katikati ya maagizo fulani unapata vifaa vya kudhibiti rsi
na rdi
:
Hivi ndivyo vifaa hivyo vitakavyokuwa:
pop rsi; pop r15; ret
pop rdi; ret
Gundua jinsi vifaa hivyo vinavyowezesha kudhibiti 2 hoja za kazi ya kupiga simu.
Pia, gundua kuwa kifaa cha ret2csu kina sahihi ya kipekee sana kwa sababu kitakuwa kikitoa 6 usajili kutoka kwenye stack. HIVYO kutuma mnyororo kama:
'A' * offset + canary + rbp + ADDR + 0xdead * 6 + STOP
Ikiwa STOP inatekelezwa, hii kimsingi inamaanisha anuani ambayo inapiga 6 usajili kutoka kwenye stack ilitumiwa. Au kwamba anuani iliyotumiwa pia ilikuwa anuani ya STOP.
Ili kuondoa chaguo hili la mwisho mnyororo mpya kama ifuatavyo unatekelezwa na haipaswi kutekeleza kifaa cha STOP kuthibitisha kwamba ile iliyotangulia ilipiga 6 usajili:
'A' * offset + canary + rbp + ADDR
Kwa kujua anuani ya kifaa cha ret2csu, ni rahisi kufikiria anuani za vifaa vya kudhibiti rsi
na rdi
.
6. Pata PLT
Jedwali la PLT linaweza kutafutwa kutoka 0x400000 au kutoka kwa anuani iliyovuja ya RIP kutoka kwenye stack (ikiwa PIE inatumika). Viingilio vya jedwali hilo vime tenganishwa na 16B (0x10B), na wakati kazi moja inaitwa seva haijashindwa hata ikiwa hoja haziko sahihi. Pia, kuangalia anuani ya kuingia katika PLT + 6B pia hakusababishi kushindwa kwani ni msimbo wa kwanza unaotekelezwa.
Hivyo basi, ni rahisi kupata jedwali la PLT kwa kuangalia tabia zifuatazo:
'A' * offset + canary + rbp + ADDR + STOP
-> hakuna kushindwa'A' * offset + canary + rbp + (ADDR + 0x6) + STOP
-> hakuna kushindwa'A' * offset + canary + rbp + (ADDR + 0x10) + STOP
-> hakuna kushindwa
7. Kupata strcmp
Kazi ya strcmp
inaweka usajili rdx
kwa urefu wa herufi zinazolinganishwa. Kumbuka kwamba rdx
ni hoja ya tatu na tunahitaji iwe kubwa kuliko 0 ili baadaye kutumia write
kuvuja programu.
Inawezekana kupata mahali pa strcmp
katika PLT kulingana na tabia yake kwa kutumia ukweli kwamba sasa tunaweza kudhibiti hoja 2 za kwanza za kazi:
strcmp(<anuani isiyosomwa>, <anuani isiyosomwa>) -> kushindwa
strcmp(<anuani isiyosomwa>, <anuani iliyosomwa>) -> kushindwa
strcmp(<anuani iliyosomwa>, <anuani isiyosomwa>) -> kushindwa
strcmp(<anuani iliyosomwa>, <anuani iliyosomwa>) -> hakuna kushindwa
Inawezekana kuthibitisha hili kwa kuita kila kuingia kwenye jedwali la PLT au kwa kutumia njia ya polepole ya PLT ambayo kimsingi inajumuisha kuita kuingia kwenye jedwali la PLT + 0xb (ambayo inaita dlresolve
) ikifuatiwa kwenye stack na namba ya kuingia mtu anayetaka kuchunguza (kuanzia sifuri) kusoma viingilio vyote vya PLT kutoka kwa la kwanza:
strcmp(<anuani isiyosomwa>, <anuani iliyosomwa>) -> kushindwa
b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0x300) + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP
-> Itashindwastrcmp(<anuani iliyosomwa>, <anuani isiyosomwa>) -> kushindwa
b'A' * offset + canary + rbp + (BROP + 0x9) + p64(0x300) + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP
strcmp(<anuani iliyosomwa>, <anuani iliyosomwa>) -> hakuna kushindwa
b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP
Kumbuka kwamba:
BROP + 0x7 inaelekeza kwa
pop RSI; pop R15; ret;
BROP + 0x9 inaelekeza kwa
pop RDI; ret;
PLT + 0xb inaelekeza kwa wito wa dl_resolve.
Baada ya kupata strcmp
inawezekana kuweka rdx
kwa thamani kubwa kuliko 0.
Kumbuka kwamba kawaida rdx
tayari itakuwa na thamani kubwa kuliko 0, hivyo hatua hii inaweza isiwe muhimu.
### 8. Kupata Write au sawa
Hatimaye, inahitajika kifaa kinachotoa data ili kutoa data ya binary. Na wakati huu ni inawezekana kudhibiti vigezo 2 na kuweka rdx
kuwa kubwa kuliko 0.
Kuna kazi 3 za kawaida ambazo zinaweza kutumiwa kwa hili:
puts(data)
dprintf(fd, data)
write(fd, data, len(data)
Walakini, karatasi ya awali inataja tu write
, kwa hivyo hebu tuzungumze kuhusu hilo:
Tatizo la sasa ni kwamba hatujui mahali ambapo kazi ya kuandika iko ndani ya PLT na hatujui namba ya fd ya kutuma data kwa soketi yetu.
Walakini, tunajua mahali ambapo jedwali la PLT liko na inawezekana kupata kuandika kulingana na tabia yake. Na tunaweza kuunda mawasiliano kadhaa na seva na kutumia FD kubwa tukitarajia kwamba inalingana na baadhi ya mawasiliano 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, basiputs
imepatikana'A' * offset + canary + rbp + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP
-> Ikiwa kuna data iliyochapishwa, basidprintf
imepatikana'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, basiwrite
imepatikana
Utekaji wa Kiotomatiki
Marejeo
Karatasi ya awali: https://www.scs.stanford.edu/brop/bittau-brop.pdf
Last updated