memcpy溢出边界漏洞利用? (粉碎堆栈)

时间:2011-03-08 17:35:02

标签: 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;
}

其中packet是从.txt文件读取的输入?

6 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

例如,如果该行以"nnnn\xff"开头,则会粉碎堆栈。

答案 2 :(得分:0)

绝对。你甚至不会检查输入缓冲区是否足够大。

答案 3 :(得分:0)

突然出现的主要问题是:

#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个字节,并且没有检查以验证复制的信息长度是< = _LENGTH。

当您知道进入的数据的长度(如果可能)或者检查以确保您没有将额外数据复制到addr char数组中时,您可能想要动态分配它:

if (hwaddr.len <= _LENGTH) {
    memcpy(...);
}

答案 4 :(得分:0)

让我们看看...... 您将数据包作为一个字符数组接收,其中第四个字符是数据包的大小。字符是8位,因此当用作无符号数字时,覆盖值0-255。您的缓冲区长度设置为128.这将溢出,您需要对_LENGTH进行某种检查。

答案 5 :(得分:0)

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

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

编辑我刚刚发现了OP的困惑。当您将长度编码为unsigned char时,意味着您使用ASCII来表示长度。也就是说,你不读这个字节,在它上面调用atoi(),并获得一个从0到9的单位数字。你只需使用八位,就像一个非常狭窄的int类型,其中每个位代表一个二进制数字。