PWNTools

Basic usage

Connect to host

from pwn import *

r = remote("host", port)
r.send("Your exploit")
print(r.recvline())

r.interactive() # Interaktive Eingabe: Text von stdin wird direkt gesendet und alle Antworten vom Server angezeigt (auch bisherige)

Connect through SSH

from pwn import *

r = ssh("user", "ssh-host", port, password = "password").remote("service-host", port)

Run local binary

from pwn import *

r = process('./binary')

r.send('Your exploit') # Just like a remote connection

Run local binary in gdb

from pwn import *
context.terminal = ['x-terminal-emulator', '-e'] # Setze das Terminal, dass benutzt werden soll (Mit der `run command` option)

r = gdb.debug('./binary')

r.send('Your exploit') # Just like a remote connection

Binaries

Loading an ELF

from pwn import *

bin = ELF('./binary')
print(bin.symbols['foobar']) # Addresse des Symbols `foobar` im binary
print(bin.got['system']) # Addresse des got-Eintrags für `system`

Crafting assembly

from pwn import *
context.arch = 'amd64' # Instruction-set setzen

code = asm('mov rax, 10')
shellcode = asm(shellcraft.sh()) # Hiermit kann man den standard shellcode kompilieren

PWNTools ROP

PWNTools stellt ein Objekt zur Verfügung, das die benötigte Payload automatisch generieren kann. doc
Hierbei können Funktionen mit Aufrufparametern übergeben werden und PWNTools sucht automatisch die nötigen Gadgets heraus.

Funktionen aufrufen

In diesem Beispiel möchten wir die Funktion do_stuff(1, 2, 3) aufrufen:

rop = ROP(ELF("./binary"))

rop.do_stuff(1, 2, 3) # Aquivalent zu rop.call("do_stuff", (1, 2, 3))

r.send(bytes(rop)) # Send the exploit

Ist an der zu springenden Adresse kein Symbol (z.B. weil das Binary gestripped ist), kann man die Adresse auch an die call-Funktion übergeben:

rop = ROP(ELF("./binary"))

rop.call(0x40000, (1, 2, 3)) # do_stuff ist bei Adresse 0x40000

r.send(str(rop)) # Send the exploit