off-by-one
单字节缓冲区溢出
Maybe in:
- 使用循环语句向堆块中写入数据时,循环的次数设置错误
- 字符串操作不合适
off-by-one是可以基于各种缓冲区的,比如堆、栈、bss段等,在堆上比较常见
利用手法:
- 控制溢出字节:修改大小造成块结构之间出现重叠,从而泄漏其它块数据,或是覆盖其它块数据
- 溢出NULL字节:使得pre_inuse被清,这样前块会被认为是free块
- 这时可以用unlink方法
- prev_size域启用,可以伪造prev_size,从而造成块之间发生重叠,此方法的关键在于unlink的时候没有检查按照
prev_size
找到的块大小是否与prev_size
一致
- 新版本已经加入针对2.2的check,在2.28以及以前版本没有该check
ctfshow 142
修改free_got表
no pie
远程:ubuntu18.04
思路:
利用off-by-one控制堆块(改写堆块大小)
进而
劫持got表,got表是可写的!
根据题目,堆内存的读写依赖于堆块之间的指针链接
有edit() add() delete() show() 函数
通过off-by-one改写堆块大小,我们可以
- 根据我们想要的指针链接方式重新释放(改变了tcachebin的大小)、申请堆块
- 覆盖下一个堆块的内容
因为show()函数是根据堆块指针打印内容的
我们可以覆盖下一个堆块时修改存储指针的内存区域为free_got表地址,打印泄露出free()函数地址
- 可以计算出系统调用地址
sys_addr
- 改变了heapContent指针指向,指向了free_got表!!
而edit()函数也依赖于堆块指针
我们便可以修改free的got表!!
将sys_addr
写入free的got表 => 调用free = 调用sys_addr
接下来,
我们可以找个堆块,”free”掉指向heapContent的指针
这个”free”其实是sys
,heapContent指针指向字符串参数’/bin/sh\x00’
(只需写入heapContent的内容为’/bin/sh\x00’即可)
1 |
|
off-by-one
http://example.com/2025/03/27/off-by-one/