N1CTF Pwn&Re部分
拖了好久的wp,差点咕咕咕了⏰
sigin
这题我开始的思路错了,先去劫持tecache_struct泄露,之后打free_hook的时候也是改的tecache_struct,由于tecache_struct和我们申请的heap之间还有一个0x1010的堆,导致后面再去调整cur指针时疯狂循环dele大概0x2000多次🤦,本地通了,远程GG,所以后面换了种解法0.0
先分析程序逻辑,C++写的菜单题,使用了vector来存储我们的数据,我们可以拥有两个vector。
数据结构为:
1 | struct con{ |
当cur==end时vector会进行扩容的操作,先申请一个更大的堆,之后将数据copy过去,再将旧堆free。扩容大小依次为0x20,0x20,0x30,0x50,0x90,0x110,0x210,0x410,0x810,0x1010
(就堆的大小而言)
漏洞在于dele时只是将cur指针减小8,因此我们可以通过dele控制cur指针,配合add可任意地址写。
利用思路:
1.通过不断add使得扩容free的堆放入unsorted bin
2.dele控制cur指向unsortedbin->fd的地址,配合show泄露。
3.之后利用vecort扩容的规律0x20,0x20
,先将在tecache的0x20位置的第一个bin1->fd写如__free_hook-8,之后vector2先拿出bin1。这里写入str(0x68732f6e69622f)(即’/bin/sh’),之后add(2,str(libc.sym['system']))
,由于扩容从而在free_hook-8写入’/bin/sh’同时劫持free_hook为system。
exp:
1 | from pwn import * |
easywrite
这题学到新姿势了,ruan师傅几分钟打通tql。
程序逻辑很简单,给了我们libc地址,有一次往任意地址写入heap地址的机会,而且heap的内容可控,之后程序会申请0x30的堆存放留言,并在退出时free。
由于最后的这个0x30的堆malloc/free操作很可疑,最后应该就是要劫持free_hook,使得在free时触发。
没想到上题没用到tecache_struct,而这题用到了。libc中有个指针,指向tacache_struct,程序也是通过这个指针找到tecache_struct的位置的。
因此我们只要将这个指针指向内容可控的heap,就能伪造tecache_struct,并且在假struct中对应0x40大小bin的位置写入free_hook,那接下来的malloc(0x30)就会拿到free_hook,进而劫持free_hook:)
exp:
1 | from pwn import * |
Oflo
这题逆向很有意思🤳
先执行一下发现输出了linux版本并要求输入。
IDA打开发先main函数有花指令,先去花,之后配合动态调试发现程序在main_0有ptrace函数检查调试器,因此不能直接gdb,得attach上去调。
1 | #ps -aux | grep oflo 获得进程号 |
这样就可以了,动态调的过程中发现程序会将我们的输入的前5位和0x0400A6处的操作码xor,从而不断的修正该处的操作码(10次)
1 | .text:0000000000400A69 byte_400A69 db 3Bh, 79h, 0EAh, 91h, 2Eh, 0EDh, 0DDh ;是坏掉的 |
之后程序会call 0x400a69,如过修正的不对的话程序就报错了,而我们发现使用的只是我们输入的前5个如果是flag的话那就是n1ctf,结果把0x400a69修正位push rbp,显然是正确的。
进入该函数后就是核心的逻辑的,值得注意的是:
1 | 0x400a88 mov byte ptr [rbp - 0x20], 0x35 |
显然是用来运算的数据,那么和谁进行运算呢?
往下调发现:
1 | RAX 0x35 |
多循环几次就会发现是和’Linux version ‘各个字符的ord()+2进行xor,进而写出脚本:
1 | data=[0x35,0x2d,0x11,0x1a,0x49,0x7d,0x11,0x14,0x2b,0x3b,0x3e,0x3d,0x3c,0x5f] |
前面修正机器码的部分调了好久才明白🛌