Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
memcpy溢出边界攻击?(砸碎书堆)_C_Stack_Overflow - Fatal编程技术网

memcpy溢出边界攻击?(砸碎书堆)

memcpy溢出边界攻击?(砸碎书堆),c,stack,overflow,C,Stack,Overflow,我试图弄清楚这是否会以某种方式溢出: void print_address(char *p) { arp_ hw; int i; hw.length = (size) *(p + _OFFSET1); //189 + 4 = 193 memcpy(hw.addr, packet + _OFFSET2, hw.length); return; } 如果数据包是从.txt文件读取的输入?是的,它可能会溢出;如果数据包中偏移量4处的值大于128,则会使hwaddr中的add

我试图弄清楚这是否会以某种方式溢出:

void print_address(char *p)
{
  arp_ hw;
  int i;

  hw.length = (size) *(p + _OFFSET1); //189 + 4 = 193
  memcpy(hw.addr, packet + _OFFSET2, hw.length);


  return;
}

如果数据包是从.txt文件读取的输入?

是的,它可能会溢出;如果数据包中偏移量4处的值大于128,则会使
hwaddr
中的
addr
字段溢出


例如,如果行以“
”nnnn\xff“
开头,这将彻底破坏堆栈。

绝对如此。您甚至从未检查过输入缓冲区是否足够大。

向我跳出来的主要内容是:

#define _LENGTH 128
...
typedef struct{
    char addr[_LENGTH];
...
随后:

hwaddr.len = (shsize_t) *(packet + _OFFSET1); //189 + 4 = 193
memcpy(hwaddr.addr, packet + _OFFSET2, hwaddr.len);
这似乎很危险。您只为addr分配了128个字节,还没有检查以验证复制的信息长度是否为让我们看看。。。
将数据包作为字符数组接收,其中第四个字符是数据包的大小。字符为8位,因此当用作无符号数字时,覆盖值为0-255。缓冲区长度设置为128。这将溢出,您需要对_长度进行某种检查。

hwaddr.len
是一个范围为0到255的无符号字符。因此,攻击者可以向您发送一个声明长度为255的数据包。由于
hwaddr.addr
被声明为128字节的缓冲区,因此攻击者可以提供127字节的有效负载。够了吗

通常的x86调用约定是推送返回地址、推送参数,然后跳转,此时被调用方将按照声明的顺序分配每个变量。因此,从
hwaddr
开始计算,
hwaddr.len
将比堆栈指针高128字节,
数据包
将比堆栈指针高129字节,返回地址将是
129+sizeof(char*)
,即使在64位系统上也最多137字节。因此,是的,攻击者可以覆盖您的返回地址,并提供118字节的外壳代码


编辑我刚刚发现了OP的困惑。将长度编码为
无符号字符
,这并不意味着使用ASCII表示长度。也就是说,您不读取这个字节,对它调用
atoi()
,然后得到一个从0到9的一位数。您只需使用八位,就像一个非常窄的
int
类型,其中每一位表示一个二进制数字

您应该将memcpy的大小限制为您分配的目的地的预定最大长度。您可能希望简单地拒绝任何带有警告消息的较长内容,因为它可能表示有攻击企图,或网络或源程序出现故障。我认为8位字符的范围为0-255。回答得很好。当你说“声明长度255”不是(shsize\u t)*(packet+\u OFFSET1)只有一个字节?所以可以设置0-9长度?我想你基本上误解了
无符号字符
类型的工作方式,但我不知道这是什么。0-9长度是什么“什么意思?单个字节的范围是0到9?你可以看到这不是2的幂,对吗?所以在偏移量4处,我应该使用\xff来表示255或11111111?它怎么可能大于128?偏移量4处的长度不是只有一个字节吗?那么长度是0-9?一个无符号字节可以是0到255。那么,偏移量为4的字符会产生255的长度的例子是什么呢?@digitalsubdivide:asveikau在其答案中显示的
\xff
字符(ASCII值255)。@digitalsubdive-逐步浏览代码,这是显而易见的。因为
memcpy
的第一个参数是一个固定大小的缓冲区。第三个参数根据用户输入确定。这是一个非常大的危险信号,是你永远不应该做的事情。
if (hwaddr.len <= _LENGTH) {
    memcpy(...);
}