黑客挑战 - 定位代码中的漏洞
Posted
技术标签:
【中文标题】黑客挑战 - 定位代码中的漏洞【英文标题】:Hacking Challenge - locating vulnerability in the code 【发布时间】:2016-06-10 19:45:31 【问题描述】:我的朋友最近完成了一项黑客挑战并将其发送给我(二进制和源代码)。我想在问他提示之前先在这里问一下,因为我想自己做:)
我一直在经历它,但我正在努力寻找漏洞。
#include <alloca.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static void usage(const char *argv0)
printf("Build your own string!\n");
printf("\n");
printf("Usage:\n");
printf(" %s length command...\n", argv0);
printf("\n");
printf("Each command consist of a single character followed by it's index.\n");
printf("\n");
printf("Example:\n");
printf(" %s 11 h0 e1 l2 l3 o4 w6 o7 r8 l9 d10\n", argv0);
exit(1);
int main(int argc, char **argv)
char *buffer;
unsigned short buffersize, i, index, length;
if (argc < 2) usage(argv[0]);
length = atoi(argv[1]);
if (length <= 0)
fprintf(stderr, "bad length\n");
return 1;
buffersize = length + 1;
buffer = alloca(buffersize);
memset(buffer, ' ', buffersize);
buffer[buffersize - 1] = 0;
for (i = 2; i < argc; i++)
if (strlen(argv[i]) < 2)
fprintf(stderr, "bad command \"%s\"\n", argv[i]);
return 1;
index = atoi(argv[i] + 1);
if (index >= length)
fprintf(stderr, "bad index in command \"%s\"\n", argv[i]);
return 1;
buffer[index] = argv[i][0];
printf("%s\n", buffer);
return 0;
我认为漏洞在于short int,以及alloca的使用。
输入./app 65535 65535
可能会导致段错误,但我实际上无法覆盖任何内容,因为缓冲区只会设置为最大值 65535,否则会循环。这让我觉得我不能覆盖 EIP 来注入 shellcode。
谁能帮我看看在哪里看?
谢谢!
【问题讨论】:
尝试在您的环境中为第一个参数输入定义为USHRT_MAX
的数字,
@MikeCAT 是的,我试过了,我可以得到一个段错误,但不能覆盖任何值,因为如果我将它设置为大于最大值,int 只会循环。
@JDoby,你将如何得到分段错误?
调试器应该有助于查看变量和返回地址的位置,buffer
中的值是什么。
因为buffersize
和length
是unsigned int
:将length
设置为65535 将导致buffersize
为0,因此不会在堆栈上为buffer
分配任何内容。但是,由于将index
与length
进行比较,因此可以使用buffer[index]
覆盖堆栈的前64Kb。
【参考方案1】:
实际上,漏洞在于您可以将字符存储在使用alloca
分配的缓冲区中的任何偏移量处,但测试是在length
而不是size
上完成的。传递 65535
和 a1
的参数会调用未定义的行为:size
作为值 0
,因为如果 unsigned short
有 16 位,则因为算术环绕。
您可以尝试传递 65535 的第一个参数和具有递增偏移量的后续参数,这将戳出超出 buffer
末尾的值,可能会覆盖 main
的返回地址并导致崩溃:
myprog 65535 a3 a7 a15 a19 a23 a27 a31 a35 a39 a43 a47 a51 a55 a59 a63 ...
根据实际的局部变量布局,所需的偏移量可能大于17
,但应小于80
。
【讨论】:
太棒了,我实际上尝试了这个,但没有输入足够的内容导致崩溃!我将如何输入“A”来用 x414141 覆盖 EIP,因为我似乎只能像你说的那样输入偏移量。 @JDoby:您将首先找到返回地址,例如 24,然后传递参数 A24 A25 A26 A27... 4 或 8 个,具体取决于架构。但是单次插入返回地址的更重要字节就足够了,而且会更优雅。以上是关于黑客挑战 - 定位代码中的漏洞的主要内容,如果未能解决你的问题,请参考以下文章
Linux 杀毒软件发现的漏洞可使得黑客获得 root 权限