我正准备接受采访,并且由一位在那里工作的朋友给出了这部分代码,并且说我会问一些关于安全问题的问题。我不太了解这方面的事情,我希望能够学到一点所以我至少可以说一些我应该被问到的事情。
这是代码:
#include <stdio.h>
#include <string.h>
#include <limits.h>
int main(int argc, char *argv[]){
FILE *inputFile;
char filename[128];
char strings[USHRT_MAX][40];
unsigned short c = 0;
strcpy(filename, argv[1]);
inputFile = fopen (filename, "r");
if (inputFile == NULL) {
perror("Error: ");
return(-1);
}
while (fscanf(inputFile, "%s", strings[c++] ) != EOF);
fclose(inputFile);
return(0);
}
我知道它有一个漏洞可以溢出缓冲区,因为这是他告诉我的内容,但除此之外,我被卡住了。有人可以解释为什么这段代码易受攻击吗
答案 0 :(得分:4)
首先,我建议您阅读this book,它可以很好地解释漏洞利用的工作原理。它配备了Linux VM,您可以尝试利用代码。 (仅供参考,我不以任何方式与该书有任何关系,我只是觉得这很好。)
其次,我想在评论中回答philippe的问题:从main()
返回并不是程序执行时发生的最后一件事。例如,您可以从return
跳过main()
并看到许多有趣的事情发生:
Breakpoint 2, main (argc=1, argv=0x7fff5fbff320) at main.c:6
6 return 0;
(gdb) stepi
0x0000000100000f17 6 return 0;
(gdb)
0x0000000100000f1a 6 return 0;
(gdb)
0x0000000100000f1d 6 return 0;
(gdb)
0x0000000100000f20 6 return 0;
(gdb)
0x0000000100000f24 6 return 0;
(gdb)
Cannot access memory at address 0x0
0x0000000100000f25 in main (argc=1, argv=0x7fff5fbff310) at main.c:6
6 return 0;
(gdb)
Cannot access memory at address 0x0
0x0000000100000ee4 in start ()
(gdb)
Cannot access memory at address 0x0
0x0000000100000ee6 in start ()
(gdb)
0x0000000100000f26 in dyld_stub_exit ()
(gdb)
0x0000000100000f44 in dyld_stub_puts ()
(gdb)
0x0000000100000f49 in dyld_stub_puts ()
(gdb)
0x0000000100000f34 in dyld_stub_puts ()
(gdb)
0x0000000100000f3b in dyld_stub_puts ()
(gdb)
0x0000000100000f3d in dyld_stub_puts ()
(gdb)
0x00007fff83b396a0 in dyld_stub_binder ()
(gdb)
0x00007fff83b396a1 in dyld_stub_binder ()
(gdb)
0x00007fff83b396a4 in dyld_stub_binder ()
(gdb)
0x00007fff83b396ab in dyld_stub_binder ()
(gdb)
0x00007fff83b396af in dyld_stub_binder ()
(gdb)
0x00007fff83b396b4 in dyld_stub_binder ()
(gdb)
0x00007fff83b396b9 in dyld_stub_binder ()
(gdb)
0x00007fff83b396be in dyld_stub_binder ()
(gdb)
0x00007fff83b396c3 in dyld_stub_binder ()
(gdb)
0x00007fff83b396c8 in dyld_stub_binder ()
(gdb)
......等等。
答案 1 :(得分:0)
在玩缓冲区之前一定要进行绑定检查。
#define MAX_BUFFER_SIZE 128
int main(int argc, char *argv[]){
FILE *inputFile;
char filename[MAX_BUFFER_SIZE];
.
.
if(strlen(argv[1]) >= MAX_BUFFER_SIZE) // Bound check
{
/* Do something appropriate, such as throw an error. */
}
else {
strcpy(filename, argv[1]);
.
.
}
This可能对您的面试有所帮助。