BROP - Blind Return Oriented Programming

Leer AWS-hacking vanaf nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun:

Basiese Inligting

Die doel van hierdie aanval is om 'n ROP te misbruik deur 'n buffer-oorvloei sonder enige inligting oor die kwesbare binêre lêer. Hierdie aanval is gebaseer op die volgende scenario:

  • 'n Stokkwesbaarheid en kennis oor hoe om dit te aktiveer.

  • 'n Bedienertoepassing wat herlaai na 'n ongeluk.

Aanval

1. Vind kwesbare offset deur een karakter meer te stuur totdat 'n fout van die bediener opgespoor word

2. Brute-force kanarie om dit te lek

3. Brute-force gestoorde RBP en RIP-adresse in die stok om dit te lek

Meer inligting oor hierdie prosesse kan hier gevind word hier (BF Forked & Threaded Stack Canaries) en hier (BF Addresses in the Stack).

4. Vind die stop-gadget

Hierdie gadget laat basies toe om te bevestig dat iets interessants uitgevoer is deur die ROP-gadget omdat die uitvoering nie afgeskakel het nie. Gewoonlik gaan hierdie gadget iets wees wat die uitvoering stop en dit is aan die einde van die ROP-ketting wanneer daar na ROP-gadgets gesoek word om 'n spesifieke ROP-gadget te bevestig wat uitgevoer is.

5. Vind BROP-gadget

Hierdie tegniek maak gebruik van die ret2csu gadget. En dit is omdat as jy hierdie gadget in die middel van sekere instruksies toegang kry, kry jy gadgets om rsi en rdi te beheer:

Hierdie sou die gadgets wees:

  • pop rsi; pop r15; ret

  • pop rdi; ret

Let daarop hoe dit met daardie gadgets moontlik is om 2 argumente van 'n funksie te beheer om aan te roep.

Let ook daarop dat die ret2csu-gadget 'n baie unieke handtekening het omdat dit 6 register van die stok gaan afhaal. Dus, deur 'n ketting soos die volgende te stuur:

'A' * offset + kanarie + rbp + ADDR + 0xdead * 6 + STOP

As die STOP uitgevoer word, beteken dit basies dat 'n adres wat 6 register afhaal van die stok gebruik is. Of dat die adres wat gebruik is ook 'n STOP-adres was.

Om hierdie laaste opsie te verwyder word 'n nuwe ketting soos die volgende uitgevoer en dit mag nie die STOP-gadget uitvoer om die vorige een te bevestig wat 6 register afgehaal het nie:

'A' * offset + kanarie + rbp + ADDR

Deur die adres van die ret2csu-gadget te ken, is dit moontlik om die adres van die gadgets om rsi en rdi te beheer, te bepaal.

6. Vind PLT

Die PLT-tabel kan gesoek word vanaf 0x400000 of vanaf die gelekke RIP-adres van die stok (as PIE gebruik word). Die inskrywings van die tabel is geskei deur 16B (0x10B), en wanneer 'n funksie aangeroep word, skakel die bediener nie af selfs al is die argumente nie korrek nie. Ook, deur die adres van 'n inskrywing in die PLT + 6B te kontroleer skakel dit ook nie af nie aangesien dit die eerste kode is wat uitgevoer word.

Daarom is dit moontlik om die PLT-tabel te vind deur die volgende gedrag te kontroleer:

  • 'A' * offset + kanarie + rbp + ADDR + STOP -> geen afslag

  • 'A' * offset + kanarie + rbp + (ADDR + 0x6) + STOP -> geen afslag

  • 'A' * offset + kanarie + rbp + (ADDR + 0x10) + STOP -> geen afslag

7. Vind strcmp

Die strcmp-funksie stel die register rdx in op die lengte van die string wat vergelyk word. Let daarop dat rdx die derde argument is en ons dit nodig het om groter as 0 te wees om later write te gebruik om die program te lek.

Dit is moontlik om die ligging van strcmp in die PLT te vind gebaseer op sy gedrag deur die feit te gebruik dat ons nou die 2 eerste argumente van funksies kan beheer:

  • strcmp(<nie lees adres>, <nie lees adres>) -> afslag

  • strcmp(<nie lees adres>, <lees adres>) -> afslag

  • strcmp(<lees adres>, <nie lees adres>) -> afslag

  • strcmp(<lees adres>, <lees adres>) -> geen afslag

Dit is moontlik om hiervoor te toets deur elke inskrywing van die PLT-tabel te roep of deur die PLT stadige pad te gebruik wat basies daarop neerkom om 'n inskrywing in die PLT-tabel + 0xb te roep (wat na dlresolve roep) gevolg in die stok deur die inskrywing nommer wat mens wil ondersoek (beginnende by nul) om al die PLT-inskrywings van die eerste een af te soek:

  • strcmp(<nie lees adres>, <lees adres>) -> afslag

  • b'A' * offset + kanarie + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0x300) + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP -> Sal afsluit

  • strcmp(<lees adres>, <nie lees adres>) -> afslag

  • b'A' * offset + kanarie + rbp + (BROP + 0x9) + p64(0x300) + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP

  • strcmp(<lees adres>, <lees adres>) -> geen afslag

  • b'A' * offset + kanarie + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP

Onthou dat:

  • BROP + 0x7 wys na pop RSI; pop R15; ret;

  • BROP + 0x9 wys na pop RDI; ret;

  • PLT + 0xb wys na 'n oproep na dl_resolve.

Nadat strcmp gevind is, is dit moontlik om rdx in te stel op 'n waarde groter as 0.

Let daarop dat gewoonlik rdx reeds 'n waarde groter as 0 sal hê, so hierdie stap mag nie nodig wees nie.

### 8. Vind Skryf of ekwivalent

Laastens is 'n gadget nodig wat data eksfiltreer om die binêre kode te eksfiltreer. En op hierdie oomblik is dit moontlik om 2 argumente te beheer en rdx groter as 0 in te stel.

Daar is 3 algemene funksies wat misbruik kan word vir hierdie doel:

  • puts(data)

  • dprintf(fd, data)

  • write(fd, data, len(data)

Die oorspronklike dokument noem egter net die write een, so laat ons daaroor praat:

Die huidige probleem is dat ons nie weet waar die write-funksie binne die PLT is nie en ons weet nie 'n fd-nommer om die data na ons sokket te stuur nie.

Nietemin weet ons waar die PLT-tabel is en dit is moontlik om write te vind op grond van sy gedrag. En ons kan verskeie verbindings met die bediener skep en 'n hoë FD gebruik in die hoop dat dit ooreenstem met een van ons verbindings.

Gedragskenmerke om daardie funksies te vind:

  • 'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0) + p64(0) + (PLT + 0xb) + p64(ENTRY) + STOP -> As daar data gedruk word, is puts gevind

  • 'A' * offset + canary + rbp + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP -> As daar data gedruk word, is dprintf gevind

  • '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 -> As daar data gedruk word, is write gevind

Outomatiese Uitbuiting

Verwysings

Leer AWS-hacking vanaf nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun:

Last updated