首页 > 解决方案 > 取消引用 C 中空指针的偏移量

问题描述

我正在阅读一本关于安全 C 编码的书,其中包含以下段落。

取消引用空指针通常会导致程序崩溃,但取消引用空指针的偏移量允许利用成功而不会导致程序崩溃。

假设在以下示例中 temp_num 、 tmp2 和 num_of_records 处于恶意用户的控制之下,攻击者可以通过为 num_of_records 提供较大的值来导致 malloc() 失败:

signal_info * start = malloc(num_of_records * sizeof(signal_info));
signal_info * point = (signal_info *)start;
point = start + temp_num - 1;
memcpy(point->sig_desc, tmp2, strlen(tmp2));
/* ... */

当 malloc() 失败时,它返回一个分配给 start 的空指针。当添加到 start 时, temp_num 的值按 signal_info 的大小进行缩放。结果指针值存储在 point 中。为了利用此漏洞,攻击者可以为 temp_num 提供一个值,该值导致指向最终将控制权转移到的可写地址。该地址处的内存被 tmp2 引用的字符串的内容覆盖,从而导致任意代码执行漏洞。

我的问题与这条线有关:

point = start + temp_num - 1;

start包含NULL. 作者说的是什么意思value of temp_num is scaled by the size of signal_info when added to start,为什么允许使用 NULL 指针进行加法?

标签: cpointersmalloc

解决方案


今天的许多系统不仅会在NULL指针被取消引用时崩溃,而且还会在允许的地址范围之外的任何指针上崩溃。因此,temp_num必须以总和指向这样一个范围的方式选择 的值。这必须考虑“比例”(乘以 的大小signal_info)。

一些随机假定的数字:

  • 的大小signal_info为 0x1000。
  • 攻击者目标的地址范围为0x55000000(含)到0x55008000(不含)。

现在让我们颠倒数学。

point = start + temp_num - 1;
// now based on bytes:
[0x55000000 .. 0x55008000[ = NULL + (temp_num - 1) * 0x1000;
[0x55000 .. 0x55008[ = temp_num - 1;
[0x55001 .. 0x55009[ = temp_num;

所以所需的值temp_num必须在 0x55001 到 0x55008 范围内。


推荐阅读