-4

使用的编译器:GCC 3.4.4 操作系统:Windows XP 32bit

使用较旧的 C/C++ 编译器(例如 gcc 3.4 或 Visual Studio 6),可以操纵堆栈帧以操纵缓冲区溢出的程序执行(例如,通过损坏的返回地址)。

试图证明这一点失败了,因为我需要复制的所有数据都包含一个零字节,在该字节处复制总是停止。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int checkauth(char *password)
{
    int authflag = 0;
    char passwordbuffer[10] = "aaaaaaa";


    strcpy(passwordbuffer, password);

    if(strcmp(passwordbuffer, "password")==0)
        authflag = 1;

    return authflag;
}

int main (int argc, char *argv[])
{
    int authflag = 0;
    char password[10] = "bbbbb";

    if (argc < 2)
    {
        printf("Password missing");
        exit(0);
    }

    authflag = checkauth(argv[1]);

    if(authflag > 0)
        printf(" password ok \r\n");
    else
        printf("wrong password, %s \r\n", argv[1]);

    return 0;
}

正如代码所示,我使用命令行参数来填充缓冲区。这总是在第一个空白处停止。我搜索了几个例子(书:Hacking – the art of exploit, stackoverflow…),但所有例子都使用不包含零字节的地址。这种情况下的问题取决于位于返回地址前面的内存中保存的堆栈指针(地址包括零字节),如果堆栈指针没有某个有效值,程序总是失败。

我想跳转的地址是 0x004013BA,而不是 0x004013b1。保存的堆栈指针的值为 0x0022ff78。这意味着我需要用 43 个字节的随机数以及堆栈指针和返回地址填充缓冲区。

如何解决这个问题?

谢谢

4

1 回答 1

0

简短的回答:这是不可能的

其背后的原因是 c-strings 是 Null-Terminated。strcpy如果读取 0x00,该函数将停止复制。该特性也用于一些缓冲区溢出保护功能,例如 ASCII-armor ASLR (RedHat Exec-Shield)。

这个链接可能也有帮助。

于 2014-12-09T15:23:09.383 回答