c语言 - 如何'hack'缓冲区溢出攻击


#include <stdio.h>
char user_name[20] = "                   ";
char password[20] = "                   ";
char users[][2][20] =
{ { "root", "98765" },
{ "me", "hello" },
{ "abc", "password" },
{ "", "" }
};
int check_name()
{
int i;
gets(user_name);
gets(password);
for(i=0; users[i][0][0] != 0; i++)
{
if(strcmp(user_name, users[i][0]) == 0 &&
strcmp(password,  users[i][1]) == 0)
return 1;
}
return 0;
}
void logon()
{
printf("Welcome! n");
exit(1);
}
void reject()
{
printf("Connection closed !n");
printf("Real username: n");
printf(users[0][0]);
printf("n");
printf("Real password: n");
printf(users[0][1]);
printf("n");
exit(0);
}
main()
{
if(check_name())
logon();
else
reject();
}

嘿,伙计们,我有点理解缓冲区溢出背后的理论,但我似乎无法在这里实现它。

注意,我添加了额外的printf来输出真实的用户名和密码,以查看我在内存中覆盖了多少。

我试着写一个随机字母x

首先我做了:用户名=20xs,密码=60xs,输出为:

Real user:                                                                                                                                                                                  
xxxxxxxxxxxxxxxxxxxxxxxxxxxx                    // 28 x's                                                                                                                                                              
Real pass:                                                                                                                                                                                  
xxxxxxxx                                        // 8 x's

所以我在密码中添加了12个xs,使其最大大小为20,所以密码=72个xs,输出为:

// with input user = 20 x's and pass = 72 x's
Real user:                                                                                                                                                                                  
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx        // 40                                                                                                                                               
Real pass:                                                                                                                                                                                  
xxxxxxxxxxxxxxxxxxxx                            // 20

最终,我认为将我的输入用户名更新为40x会起作用,但事实并非如此。输出与上一个相同(真实用户为40 x,真实密码为20 x(;破解";

我不知道此刻该怎么办。提前感谢!

您必须了解C中的字符串是由什么组成的。类似printf的东西将继续从字符串中打印字节,直到它达到NULL字符。以您的方式在程序中嵌入字符串(foo="barbaz"(会自动包含一个空字符。

当程序将字符串读取到固定长度的缓冲区时,会发生缓冲区溢出错误,但输入大于缓冲区时。例如,如果我有char username[8],但用户输入supercalifragilisticexpalidocious

显然,输入比缓冲区大,如果程序允许所有输入,它将继续覆盖内存中超出用户名的内容。

在这种情况下,一个足够聪明的黑客可以覆盖内存,使她能够访问程序的某些部分或她通常无法访问的数据。

因此,为了回答您的问题,由于您是如何使用代码编译部分中完全定义的字符串来构建程序的,因此不会出现缓冲区溢出错误。

尝试接受无限制的用户输入,然后将超出缓冲区所能接受的数据放入缓冲区,看看结果的内存块会发生什么。

最新更新