什么是Off_By_One

一种特殊的漏洞,单字节溢出,即只能溢出一个字节数据。

off-by-one 漏洞原理

off-by-one,漏洞的产生与边界验证不严和字符串操作有关,其中边界验证不严通常包括

  • 使用循环语句向堆块中写入数据时,循环的次数设置错误(这在 C 语言初学者中很常见)导致多写入了一个字节。
  • 字符串操作不合适

例如

char buf[10]
for(int i=0;i<=10;i++)
{
    buf[i]=getchar()
}
buff[i]=0

以上代码在一些c语言初学容易犯的错误,以为只输入了10字符(包括结束符),但实际却输入了11个字符,溢出了一个字符串结束标志符\00,这种也叫Off_By_unll。

或者

int main(void)
{
    char buffer[40]="";
    void *chunk1;
    chunk1=malloc(24);
    puts("Get Input");
    gets(buffer);
    if(strlen(buffer)==24)
    {
        strcpy(chunk1,buffer);
    }
    return 0;

}

由于strlen()函数识别\00截断,但返回的大小不包括\00,但在strcpy时会拷贝包括\00,所有实际拷贝了25个字符,导致Off_By_One。

利用方式

常见的利用方式:

  • 溢出修改全局chunk指针的低位,来实现堆chuank的操作空间转移(转移到提前布置的伪造区域)
  • 被溢出覆盖的数据二次重写后覆盖\00后如果有对数据的输入操作,可以实现数据泄露。
  • 溢出修改chunk的size位可实现chunk extend,或unlink

但在 libc-2.29 之后

  • 由于我们难以控制一个真实 chunk 的 size 字段,所以传统的 off-by-null 方法失效。但是,只需要满足被 unlink
    的 chunk 和下一个 chunk 相连,所以仍然可以伪造 fake_chunk。