off- by-one(2.23)

off-by-one的漏洞形式是我们申请了一个大小为n的堆块,但是我们输入或者修改这个堆块的内容时由于代码漏洞可以输入n+1个字节。

常见的漏洞场景:for循环多接收了一个字符 /strcpy与strlen的行为不一致,strlen不计算入’\x00’,strcpy会把’\x00’一同复制 /判断字符串结束符为’\n’,而不是’\x00’

那么我们就可以利用这一字节来修改下一个堆块的size字段,进而完成一系列攻击,具体手法见下面例题。

还是用一道基础的菜单板子,这里自己出的题图方便就没有写上面所述的漏洞,输入字节是自己定义的,在写题的时候自己注意修改edit的字节数为n+1。

把菜单写好

image-20250807210035988

之后申请四个堆块,每个堆块都有各自的作用,见注释

image-20250807210118306

0号堆块的作用是利用off-by-one漏洞修改1号堆块的size,把1号堆块的size修改成1号堆块加上2号堆块的大小,使其达到吞并效果,3号堆块的作用是隔离topchunk,因为我们还要借助上面的堆块泄露libc。

接下来通过修改0号堆块来修改1号的size,修改的大小就是1号+2号的大小也就是0x70+0x70=0xe0,由于它之前的堆块没有被free,所以p位应该是1,修改为0xe1,注意这里用了0x19来实现off-by-one,然后将1号堆块delete,因为我们修改了1号的size,它的值现在是大于0x80的,所以会进入unsorted bin中,再申请一个大小为1号+2号堆块的堆块,注意我们申请时会加上pre size和size的0x10,再向下取整,所以我们申请一个0xd8的大小实际大小就是0xe0,将其从unsorted bin中申请回来,这样顺便可以泄露出4号堆块fd指针上残留的libc地址。

image-20250807212955981

接下来将2号堆块释放进fastbin中,然后修改4号堆块的内容,注意我们的4号堆块其实包含了2号堆块,但是4号堆块没有进入fastbin,所以我们可以通过修改4号堆块的内容来修改已经进入fastbin中的2号堆块的fd指针为malloc_hook-0x23,其实和double free的原理很接近。之后再连续申请两次把mallo_hook申请出来就可以了。

image-20250807215111836

注意之后正常写应该是用payload0,如果打不通可以多换几个one_gadget,但是如果都打不通的话,可以用payload1,用realloc函数来调整一下栈帧,realloc的位置在malloc_hook-0x8的位置,所以我们先填充到0x13-0x8也就是0xb,在realloc的位置填上one_gadget,在其后面的malloc_hook的位置填上realloc,这样在我们malloc申请堆块的时候,就会调用realloc,然后回到前面的realloc地址存放的one_gadget,就可以打通了。

image-20250807220126705