Linux缓冲区溢出环境变量

时间:2012-03-30 16:18:45

标签: c linux security

我一直在审查不同类型的缓冲区溢出并遇到了一个问题,我不记得它为什么会发生。下面的代码是我尝试执行缓冲区溢出的程序:

#include <stdio.h>

void func(char *buff){  
    char buffer[5];
    strcpy(buffer, buff);
    printf("%s\n", buffer);
}

int main(int argc, char *argv[]){
    func(argv[1]);
    printf("I'm done!\n");
    return 0;
}

程序的核心概念非常简单,我只是溢出缓冲区来覆盖func()的返回地址。当我给它一个像0x0804850c这样恰好是程序<_fini>的地址时,这一切都很有效。当我使用该地址实现溢出时,最终结果是程序“优雅地”退出而不打印I'm done!。我现在遇到的问题是当我尝试将返回地址重定向到位于0xbfffd89的环境变量时。

位于该特定环境变量中的shell代码应该在说出hello后退出程序。然而,这不会发生,程序只是故障,这就是它。 shell代码已经被确认在我编写的前一个程序中用于测试shell代码。任何人都有任何想法,为什么这不起作用。 THX

3 个答案:

答案 0 :(得分:2)

现代Linux发行版已经抵御这种攻击。例如,为x86-64上的堆栈页设置NX位。并且映射地址是随机的,以防止从进程外部猜测。请参阅以下内容:

http://en.wikipedia.org/wiki/Executable_space_protection   http://en.wikipedia.org/wiki/Address_space_layout_randomization

基本上,如果你想为现代系统编写漏洞,你将不得不做更多的工作。

答案 1 :(得分:2)

环境变量位于具有读取和读取的内存区域中。写权限但不执行权限。我很容易复制如下:

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

int
main(int argc, char **argv)
{
void (*function)(void);

        function = (void (*)(void))getenv("PATH");
        function();
        return 0;
}

gdb下运行,我得到了这个:

Program received signal SIGSEGV, Segmentation fault.
0x00007fffffffeb51 in ?? ()
(gdb) 

然后我查找地址0x00007fffffffeb51 if /proc/PID/maps并找到如下所示的行:

7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0                          [stack]

通常会找到-(执行)位的x

答案 2 :(得分:0)

您可以在运行之间确认变量的地址吗?如果您的系统使用类似ASLR的东西,则每次运行都可能不同。但是,argv [1]的地址可能是通过某个寄存器给出的,所以如果你提供带有通过该寄存器进行间接调用的指令地址的返回地址(你可能会在objdump -d上找到这样的指令你的程序),它将在任何地址运行你的代码 - 假设这个地址在可执行页面中。并且在ABI中使用寄存器来传递参数。但是还有其他问题......

如果您提供更多详细信息(可能包括对程序的反汇编),可能会更具体地回答。