DDexec / EverythingExec
Last updated
Last updated
Učite i vežbajte hakovanje AWS-a:HackTricks Obuka AWS Crveni Tim Stručnjak (ARTE) Učite i vežbajte hakovanje GCP-a: HackTricks Obuka GCP Crveni Tim Stručnjak (GRTE)
U Linuxu, da bi se pokrenuo program, mora postojati kao datoteka, mora biti dostupan na neki način kroz hijerarhiju fajl sistema (ovo je samo kako execve()
funkcioniše). Ova datoteka može biti smeštena na disku ili u memoriji (tmpfs, memfd) ali vam je potreban putanja do nje. Ovo je učinilo veoma lako kontrolisati šta se pokreće na Linux sistemu, olakšava otkrivanje pretnji i alata napadača ili sprečavanje njihovog pokušaja izvršavanja bilo čega svojstvenog (npr. ne dozvoljavajući neprivilegovanim korisnicima da postavljaju izvršne datoteke bilo gde).
Ali ova tehnika je tu da promeni sve to. Ako ne možete pokrenuti proces koji želite... onda preuzmete kontrolu nad već postojećim.
Ova tehnika vam omogućava da zaobiđete uobičajene tehnike zaštite poput samo za čitanje, noexec, bela lista imena fajlova, bela lista hešova...
Konačni skript zavisi od sledećih alata da bi radio, oni moraju biti dostupni u sistemu koji napadate (podrazumevano ćete ih pronaći svuda):
Ako možete proizvoljno izmeniti memoriju procesa, možete ga preuzeti. Ovo se može koristiti za preuzimanje već postojećeg procesa i zamenjivanje sa drugim programom. To možemo postići ili korišćenjem ptrace()
sistemskog poziva (što zahteva mogućnost izvršavanja sistemskih poziva ili prisustvo gdb-a na sistemu) ili, što je interesantnije, pisanjem u /proc/$pid/mem
.
Fajl /proc/$pid/mem
je jedan-na-jedan mapiranje celog adresnog prostora procesa (npr. od 0x0000000000000000
do 0x7ffffffffffff000
u x86-64). To znači da čitanje ili pisanje u ovaj fajl na offsetu x
isto je kao čitanje ili menjanje sadržaja na virtuelnoj adresi x
.
Sada, imamo četiri osnovna problema sa kojima se suočavamo:
Generalno, samo root i vlasnik programa fajla mogu ga izmeniti.
ASLR.
Ako pokušamo čitati ili pisati na adresu koja nije mapirana u adresnom prostoru programa, dobićemo I/O grešku.
Ovi problemi imaju rešenja koja, iako nisu savršena, su dobra:
Većina shell interpretatora dozvoljava kreiranje file deskriptora koji će biti nasleđeni od strane child procesa. Možemo kreirati fd koji pokazuje na mem
fajl šella sa dozvolama za pisanje... tako da će child procesi koji koriste taj fd moći da menjaju memoriju šella.
ASLR čak nije problem, možemo proveriti maps
fajl šella ili bilo koji drugi iz procfs-a kako bismo dobili informacije o adresnom prostoru procesa.
Dakle, moramo koristiti lseek()
preko fajla. Iz šella ovo ne može biti urađeno osim korišćenjem zloglasnog dd
.
Koraci su relativno jednostavni i ne zahtevaju nikakvu vrstu ekspertize da biste ih razumeli:
Parsirajte binarni fajl koji želimo da pokrenemo i loader kako biste saznali koje mapiranja im je potrebno. Zatim kreirajte "shell" kod koji će izvršiti, u najširem smislu, iste korake koje kernel obavlja prilikom svakog poziva execve()
:
Kreirajte navedena mapiranja.
Učitajte binarne fajlove u njih.
Postavite dozvole.
Na kraju inicijalizujte stek sa argumentima za program i postavite pomoćni vektor (potreban od strane loadera).
Skočite u loader i pustite ga da obavi ostalo (učitavanje potrebnih biblioteka za program).
Dobijte iz fajla syscall
adresu na koju će se proces vratiti nakon sistemskog poziva koji izvršava.
Prepisati to mesto, koje će biti izvršno, sa našim shell kodom (kroz mem
možemo menjati nepisive stranice).
Prosledite program koji želimo da pokrenemo na stdin procesa (biće read()
od strane navedenog "shell" koda).
U ovom trenutku je na loaderu da učita potrebne biblioteke za naš program i skoči u njega.
Pogledajte alat na https://github.com/arget13/DDexec
Postoje nekoliko alternativa za dd
, od kojih je jedna, tail
, trenutno podrazumevani program koji se koristi za lseek()
kroz mem
fajl (što je bila jedina svrha korišćenja dd
). Pomenute alternative su:
Postavljanjem promenljive SEEKER
možete promeniti korišćeni tražilac, npr.:
Ako pronađete još jednog važećeg tražioca koji nije implementiran u skriptu, i dalje ga možete koristiti postavljanjem promenljive SEEKER_ARGS
:
Blokiraj ovo, EDR-ovi.