mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
88 lines
4.7 KiB
Markdown
88 lines
4.7 KiB
Markdown
# DDexec / EverythingExec
|
|
|
|
{{#include ../../../banners/hacktricks-training.md}}
|
|
|
|
## Kontekst
|
|
|
|
U Linuxu, da bi se pokrenuo program, mora postojati kao datoteka, mora biti dostupna na neki način kroz hijerarhiju datotečnog sistema (to je jednostavno kako `execve()` funkcioniše). Ova datoteka može biti na disku ili u RAM-u (tmpfs, memfd), ali vam je potreban put do datoteke. To je olakšalo kontrolu onoga što se pokreće na Linux sistemu, olakšava otkrivanje pretnji i alata napadača ili sprečavanje da pokušaju da izvrše bilo šta svoje (_npr._ ne dozvoljavajući korisnicima bez privilegija da postavljaju izvršne datoteke bilo gde).
|
|
|
|
Ali ova tehnika je ovde da promeni sve to. Ako ne možete da pokrenete proces koji želite... **onda preuzimate već postojeći**.
|
|
|
|
Ova tehnika vam omogućava da **zaobiđete uobičajene zaštitne tehnike kao što su samo za čitanje, noexec, bela lista imena datoteka, bela lista hešova...**
|
|
|
|
## Zavisnosti
|
|
|
|
Konačni skript zavisi od sledećih alata da bi radio, oni moraju biti dostupni u sistemu koji napadate (po defaultu ćete ih pronaći svuda):
|
|
```
|
|
dd
|
|
bash | zsh | ash (busybox)
|
|
head
|
|
tail
|
|
cut
|
|
grep
|
|
od
|
|
readlink
|
|
wc
|
|
tr
|
|
base64
|
|
```
|
|
## Tehnika
|
|
|
|
Ako ste u mogućnosti da proizvoljno modifikujete memoriju procesa, onda ga možete preuzeti. Ovo se može koristiti za preuzimanje već postojećeg procesa i zamenu sa drugim programom. To možemo postići ili korišćenjem `ptrace()` sistemskog poziva (što zahteva da imate mogućnost izvršavanja sistemskih poziva ili da imate gdb dostupan na sistemu) ili, što je zanimljivije, pisanjem u `/proc/$pid/mem`.
|
|
|
|
Datoteka `/proc/$pid/mem` je jedan-na-jedan mapiranje celog adresnog prostora procesa (_npr._ od `0x0000000000000000` do `0x7ffffffffffff000` u x86-64). To znači da je čitanje ili pisanje u ovu datoteku na offsetu `x` isto kao čitanje ili modifikovanje sadržaja na virtuelnoj adresi `x`.
|
|
|
|
Sada imamo četiri osnovna problema sa kojima se suočavamo:
|
|
|
|
- Uopšte, samo root i vlasnik programa datoteke mogu da je modifikuju.
|
|
- ASLR.
|
|
- Ako pokušamo da čitamo ili pišemo 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 interpretera omogućava kreiranje deskriptora datoteka koji će zatim biti nasledni od strane podprocesa. Možemo kreirati fd koji pokazuje na `mem` datoteku shelle sa dozvolama za pisanje... tako da podprocesi koji koriste taj fd mogu modifikovati memoriju shelle.
|
|
- ASLR čak nije ni problem, možemo proveriti `maps` datoteku shelle ili bilo koju drugu iz procfs kako bismo dobili informacije o adresnom prostoru procesa.
|
|
- Tako da treba da `lseek()` preko datoteke. Iz shelle to ne može biti urađeno osim korišćenjem infamoznog `dd`.
|
|
|
|
### Detaljnije
|
|
|
|
Koraci su relativno laki i ne zahtevaju nikakvu vrstu stručnosti da bi ih razumeli:
|
|
|
|
- Parsirajte binarni fajl koji želimo da pokrenemo i loader da saznamo koje mape su im potrebne. Zatim kreirajte "shell" kod koji će, u širokom smislu, izvesti iste korake koje kernel preduzima pri svakom pozivu `execve()`:
|
|
- Kreirajte pomenute mape.
|
|
- Učitajte binarne fajlove u njih.
|
|
- Postavite dozvole.
|
|
- Na kraju, inicijalizujte stek sa argumentima za program i postavite pomoćni vektor (potreban loader-u).
|
|
- Skočite u loader i pustite ga da uradi ostalo (učita biblioteke potrebne programu).
|
|
- Dobijte iz `syscall` datoteke adresu na koju će se proces vratiti nakon sistemskog poziva koji izvršava.
|
|
- Prepišite to mesto, koje će biti izvršivo, našim shell kodom (kroz `mem` možemo modifikovati nepisive stranice).
|
|
- Prosledite program koji želimo da pokrenemo na stdin procesa (biće `read()` od strane pomenutog "shell" koda).
|
|
- U ovom trenutku, na loader-u je da učita potrebne biblioteke za naš program i skoči u njega.
|
|
|
|
**Pogledajte alat na** [**https://github.com/arget13/DDexec**](https://github.com/arget13/DDexec)
|
|
|
|
## EverythingExec
|
|
|
|
Postoji nekoliko alternativa za `dd`, od kojih je jedna, `tail`, trenutno podrazumevani program koji se koristi za `lseek()` kroz `mem` datoteku (što je bio jedini cilj korišćenja `dd`). Te alternative su:
|
|
```bash
|
|
tail
|
|
hexdump
|
|
cmp
|
|
xxd
|
|
```
|
|
Podešavanjem promenljive `SEEKER` možete promeniti korišćenog tražioca, _npr._:
|
|
```bash
|
|
SEEKER=cmp bash ddexec.sh ls -l <<< $(base64 -w0 /bin/ls)
|
|
```
|
|
Ako pronađete drugog validnog tražioca koji nije implementiran u skripti, još uvek ga možete koristiti postavljanjem promenljive `SEEKER_ARGS`:
|
|
```bash
|
|
SEEKER=xxd SEEKER_ARGS='-s $offset' zsh ddexec.sh ls -l <<< $(base64 -w0 /bin/ls)
|
|
```
|
|
Blokirajte ovo, EDR-ove.
|
|
|
|
## Reference
|
|
|
|
- [https://github.com/arget13/DDexec](https://github.com/arget13/DDexec)
|
|
|
|
{{#include ../../../banners/hacktricks-training.md}}
|