Payloads

The "Magic Gadget"

Tell me more Tool

libc contains code to execve("/bin/sh") in several places. If you know the libc in use and its loaded base address (see ASLR), you can just jump there.

Reverse shells

Reverse Shell Generator

ROP techniques

Exercises

Tools:

Good to know:

  • call on x86-64 requires a 16-byte aligned stack. Not always an issue, but it can be. Pad your ROP chain.

Ret2CSU

Tell me more

TODO: Learn about this

Ret2ld-resolve

Tell me more Tell me not enough Tool

.got is populated by the linker (ld) on demand, when a .plt function is called for the first time.

Lookups are performed using some giant tables (JMPREL, SYMTAB, STRTAB), and string matching in these tables.

The top of .plt is a stub which calls dl-resolve, and takes an index into these tables as a parameter.

  1. Write a fake SYMTAB and STRTAB somewhere, containing an entry for "system"

  2. ROP into dl-resolve with a well-chosen table index (overflow the existing STRTAB into our fake buffer)

  3. dl-resolve will go find system and call it for us!

Danger Stack alignment is an issue, and system() relies on the stack being 16-byte aligned when it's called. If your chain doesn't work, try adding a ret; gadget to it for a different alignment.

Sigreturn Oriented Programming

Tell me more Tool

If you can push to the stack and execute syscall 15, you can control all the registers at once. Neat.

Syscall cobbling

Linux syscalls

If you've got ROP control, maybe you can emulate a system call?

x86

x86 Syscalls

Set $eax and find an int 0x80 instruction to lift off! Arguments are in $ebx, $ecx, $edx, $esi.

x86_64

x86_64 Syscalls

Making a system call is as easy as setting $rax and executing the syscall instruction. Arguments are in $rdi, $rsi, $rdx.

32-bit syscalls are also available, see Evasion for more info about that.

Lesser-known syscalls

If there's a blocklist, here are some less obvious tricks:

  • arch_prctl can be used for an arbitrary write (Tell me more)

  • brk can be used to find the address of the heap (Tell me more)

Register control

The ax registers which control syscall number also happen to be the return value registers in the SystemV calling convention. If you control a read() before your ROP chain, for example, it will return the number of bytes read. Send it 11 bytes and you've lined yourself up for execve()!

Alternatively, check out the Sigreturn syscall below to control all the registers!

Last updated