我正在试图弄清楚这是否会以某种方式溢出:
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文件读取的输入?
答案 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
类型,其中每个位代表一个二进制数字。