连打两天,逆向花了不少时间,人都快调傻了
红明谷—双边协定1.0
分析
输出
这个程序对输入输出都是有动手脚的,首先输出数据是加密过的,看看加密函数
大概就是会在需要输出的信息前再加上一串东西,然后base64加密,也就是说将收到的数据base64揭秘之后,末尾才是你真正需要的,可以验证一下这一点:
输入
其次来看输入
可以很容易看出decrypt函数就是处理我们输入的一个关键函数了:
不难看出是个base64解密,也就是说我们在输入的时候,需要将数据base64编码之后再发过去
接下来就是输入数据的格式了,分析之后得:
1 | 0x1234567812345678 |
当输入成功后返回chunk2(ptr)的指针,也就是说需要将你的有效输入数据放在chunk2_data里面
exp
首先泄露地址,这一点并不难
虽说add这里可以申请的chunk大小有限,但是在输入时用到的那两个chunk的size可以开到很大,切割unsorted bin泄露地址就行
其次就是漏洞点:
倘若在add时输入content的时候使之返回ERROR,程序并不会结束,里面会free一次ptr,外面也会free一次,这样一来就构成了一个double free,正常写malloc_hook就行了
脚本的话老习惯了,懒得写函数,看着乱哈哈
不过这题的难点在分析,漏洞利用还是比较简单的,最后写完hook就可以直接interactive()了,因为menu输出数据时也是会申请chunk的
exp:
1 | from pwn import * |
虎符quiet
分析
虚拟机pwn,分析了几个函数之后如下:
很显然,由于mmap_addr可读可写可执行,这已经足够我们完成攻击了
exp
利用off_12038的get_c功能和off_12018的指针后移功能,逐个字节地向mmap_addr(0x100000000000)中写入shellcode,然后用off_12058的跳转功能跳转执行shellcode即可
exp:
1 | from pwn import * |
虎符apollo
这题说实话可惜了,最后时间太慌了,但凡比赛最后冷静分析个十几分钟当时也就出了
分析
也是虚拟机pwn,还能咋办,慢慢逆呗
首先第一步是要执行loc_eb8的,不然dword_14098为0啥也干不了
这里就是输入两个数a,b,在0x3到0x10之间
然后就是
chunk1=calloc(a*b,1);
chunk2=calloc(a*b,1)
这步过后,dword_14098置1,其他函数的功能就可以正常使用了
然后就是几个常规的add,delete和show功能:
add
delete
show
还有可以对chunk1数据做修改的两个函数:
接下来就是几个关键函数了
这四个函数的作用相类似,取一个看一下:
总结出两个关键点:
1)可以对chunk1和chunk2的数据做修改,数据在一定范围内可控
2)修改的位置可以溢出
exp
根据上面的分析,这样就很简单了:
a=4,b=6
sub_1990中如下分支执行两次(要满足相应的分支条件需要提前布置好相应的值):
这样就实现了dword_140a4=4
qword_14090 + dword_140A4 * dword_140A0 + dword_140A8=chunk2[24],溢出达成
(这里有关于下标的索引类似于二维数组)
然后就是继续多次执行sub_1990,dword_14080会累加并不断写入chunk2[24],也就是说可以溢出写下一个chunk的size,直到它变成一个你需要的值
我这里申请0x4f0的chunk,这样得到的chunk的size的数据就是0x501,溢出将其写到0x521为止,再将其free掉,就有了与下一个堆块之间的重叠
free下一个chunk进tcache,再切割上述的0x521大小的chunk,即可改写tcache指针
exp:
1 | from pwn import * |