我试图在一个c程序上造成缓冲区溢出,但我无法找到漏洞并利用代码进行攻击。在
我试过上千个输入。 一般来说,我试过这些: 1) 我尝试了一个很明显的方法-给一个很长的字符串作为输入。 2) 我试图返回一个很大的字符串。 3) 我尝试将空字节和EOF作为输入,并附加字符串。它不允许我输入这些字符作为输入。 4) 我尝试过重写某个的东西,但是没有什么东西被覆盖(如果我成功地覆盖了某些东西,那么对我来说这是70%的方法)
所有这些我都尝试过Python。在
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int secretCode = 123;
#define STATUS_WINNER 'WIN!'
typedef struct _word_struct
{
char word[32 + 24];
char result[48 + 24];
int status;
} word_struct, *word_data;
int get_input(char *word, int len)
{
int wordSize = 0;
char *locWord = malloc(len+4);
if(!locWord)
return -2;
printf("Enter your guess: ");
fgets(locWord,len+4,stdin);
wordSize = strlen(locWord);
// strip newline character
if(locWord[wordSize-1] == '\n')
locWord[wordSize-1] = '\0';
if(strlen(locWord) > len)
{
free(locWord);
return -1;
}
strcpy(word,locWord);
free(locWord);
return 1;
}
void check_input(word_data w)
{
//todo: implement this
printf("Incorrect word!\n");
w->status = strlen(w->word);
}
int main(int argc, char* argv[])
{
//check with sizeof - off by one + strcpy (overwrite the next with 0)
//strcpy that will copy that additional symbol
//strncat that will start later because there is a 0 later
word_struct guess;
int i,offset,len,ret;
printf("Welcome to Alladin's magic cave!\n");
printf("Enter the secret word and get the treasure cave entrance code!\n");
ret = get_input(guess.word, sizeof(guess.word));
if(ret == -1)
{
printf("Exiting due to buffer overflow!\n");
return -1;
}
else if(ret == -2)
{
printf("Out of resources! Exiting...\n");
return -2;
}
check_input(&guess);
printf("STATUS: %d\n", guess.status);
printf("REAL:%d\n", STATUS_WINNER);
if(guess.status == STATUS_WINNER)
strcpy(guess.result,"CORRECT! YOU ENTERED: ");
else
strcpy(guess.result,"WRONG! YOUR WORD: ");
//we don't use unsafe str functions, we copy strings carefully one-by-one!
offset = strlen(guess.result);
len = strlen(guess.word);
for(i = 0; i < len; ++i)
guess.result[offset+i] = guess.word[i];
guess.result[offset+i] = '\0';
printf("%s\n",guess.result);
// give them the flag?
if(guess.status == STATUS_WINNER)
printf("It was cool, wasn't it ?! Go get your treasure, the code is %d\n", secretCode);
else
printf("Better luck next time!\n");
return 0;
}
对于输入56字节长的正好,我得到segfault。 对于大于56的输入,我从程序中得到缓冲区溢出“错误”。 对于非常大的输入(超过10^6字节[长得多或少])—程序有点卡住了。在
我希望能够覆盖任何内容,但我无法覆盖任何内容,可能直接跳转到打印代码的地址(0x804889d)
装配图如下:
^{pr2}$我在c9环境工作。在
{我也读过这个 帮不上忙。在
当您精确地输入复制到的
len
个字符时,就会发生缓冲区溢出猜猜看并且nul
结束符溢出超过结尾。在在
strcpy(guess.result,
“thing”然后重写nul
,然后for循环循环,直到内存耗尽,得到一个segfault。在成功利用漏洞将向
i
和offset
写入一个值,这样 a: 循环在没有命中错误内存地址的情况下终止 b:status
中的值与STATUS_WINNER
匹配要做到这一点,LEN必须被一个小于70的值痛击
感谢大家的帮助,你们给了我很好的主意,下面是我的解决方案:
此函数在循环中有:
偏移量等于字符串“错误!你的话:“就是19。 因此,如果用户输入56字节长的字符串(这是猜猜看),“len”将是75(输入+19的56),“offset+i”将在19和74之间(实际上是75,但循环将退出)。因此,当“偏移量+i”为72时,猜测。结果会启动超驰控制猜测状态(猜测。结果是72字节长,并且猜测状态在“偏移量+i”=75时,当i=56时,猜猜看[56]是的猜测。结果[0],即“W”(错误!你的…)。 从那里很容易。在
相关问题 更多 >
编程相关推荐