想象一下以下易受攻击的代码

int getNumber(int* array, int index) {
    return array[index];
}

 int main(int argc, char** argv) {
    int myArray = malloc(10 * sizeof(int));
    myArray[0] = 1;
    myArray[1] = 5;
    printf("%d\n", getNumber(myArray, atoi(argv[1])));
}

显然,使用./hello 11运行程序将导致程序崩溃或在内存中转储某些内容。但是,是否有任何方法利用此程序运行任意代码(以程序的权限)?或者,从这种类型的攻击中实现代码执行的唯一方法是使用它获取内存转储,该内存转储可以反汇编到完整的代码库中?

最佳答案

undefined behavior
您可以对堆和编译器的实现方式进行一些一般性的猜测。在这个范围内,您可能会将影响的范围稍微限制为“它可能会有多糟”(通常是一次崩溃)。但是除了猜测…要有效地进行黑客攻击,你需要有一个反汇编程序来知道编译器为代码生成了什么指令…并且有很多关于系统的数据来与之匹配。
可能的漏洞是,如果您对程序有更广泛的了解,并且程序员不期望您可以修改您所要修改的某些变量,那么就在操作系统信任范围内。你给我们展示了一个很短的程序,不太可能有太多可利用的东西。但是,如果它是一个更大的程序,具有更多的功能,并且在某个地方声明了int privilegeLevel = 2;。。您可以在程序的进程边界内将privilegeLevel覆盖为1(让我们想象一下,这会给您提供比预期更多的功能,lower=better)。然后,您将利用对程序的某种程度的信任,这种信任是基于程序不存在此类错误的信念。
基本上:只有当你能在某个地方写下某样东西看到并作用于它的时候,你才能在内存中写下随机的垃圾。大多数现代系统将代码和数据段分开,并相互处理。因此,很难弄清楚argv的神奇数字是多少,这会让您将字节插入到另一个进程执行(作为指令)或操作(作为数据)的某个位置。
最简单的漏洞通常是“我们毁了你”。但是,系统越原始,就越有可能找到程序本身加载的偏移量,注意malloc放东西的位置的一致属性,并可能使用一些负数开始写入内核或代码。在更复杂的系统中,任意执行需要更多的漏洞,而不是孤立的这么小的漏洞。
在提供此类建议时,我遵循“信息是好的”政策。讲道德。

关于c - 利用缓冲区溢出读取操作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27141300/

10-12 16:02