linux的地址随机化ASLR,linux溢出总结+windows aslr地址随机化绕过

实验一 Linux下缓冲区溢出

通过缓冲区溢出漏洞执行自己的代码

【实验代码】

836c7e4e1dd8767a01a145acc71e891c.png

【实验目的】

通过缓冲区溢出,使其执行not_called函数。

【实验原理及结果】

(1)编译程序(关闭掉栈保护):

0bb150448e6ba44df88afee318e04e8f.png

(2)gdb调试程序

查看vulnerable_function函数汇编代码

7438c0b2612db9b410d852e0dc0edb46.png

我们可以看到该函数开辟了一个0x6c大小的缓冲区

| argument |

| return address |

| old %ebp> | <= %ebp

| 0x6c bytes of |

| … |

| buffer> |

| argument |

| address of buffer> | <= %esp

因此构造的buffer如下所示:

| not_called>的地址 |

| BBBB |

| 0x41414141 … |

| … (0x6c bytes of ‘A’s) |

| … 0x41414141 |

查看not_called函数的地址

9b38a8d0f4184c1d4ac704b841cc6992.png

因此,如下所示:

我们构造的缓冲区结构如下:

“A”*0x6c + “BBBB” + “\x44\x84\x04\x08”

a63d7ce61f83ecf820a81917e0c32e08.png

缓冲区溢出漏洞改进版(1)

【实验代码】

实验代码同上

【实验目的】

第一次实验是通过缓冲区溢出执行自己的其他代码,这次主要是通过缓冲区溢出执行system函数,例如执行system(“/bin/sh”);

【实验原理及结果】

执行system函数,很明显要找到函数system以及字符串”/bin/sh”

(1) 找到system函数,函数地址如下所示:0x8048360

07ed848ab710ba3f77dd0df4bb3664e8.png

(2) 找到字符串/bin/sh

首先在main函数入口处设断点

0ce4cb2209043ee5e74b93c35ec79105.png

找到system的地址

f15aaf312f8015ce15e8ad3da0783a42.png

根据system找到字符串”/bin/sh”的地址

95ba5da043ff0049b3a2d339760deada.png

(3) 构造buffer

| 0x40197fb8 “/bin/sh” |

| 0x43434343 fake return address> |

| 0x8048360 address of system@plt> |

| 0x42424242 fake old %ebp> |

| 0x41414141 … |

| … (0x6c bytes of ‘A’s) |

| … 0x41414141 |

【运行结果】

a5e3400e52e5efaa91d79d9d52c8048b.png

缓冲区溢出漏洞(方法2)—利用pop-pop-return指令

【原理分析】

在这里我们使用pop-pop-return指令来执行代码

栈构造的格式如下:

| address of mov %eax, (%ecx)> |

| value to write> |

| address to write to> |

| address of pop %ecx; pop %eax; ret> |

【实验代码】

f1a9fe9ee9939e811eba99ed05de38ff.png

a5c67cb9b9370fbe57f23894b7483b63.png

【实验目的】

本次试验的目的是先去call add_bin函数然后call add_sh函数,最后call exec_string函数

当我们call add_bin函数时,栈的结构如下:

| argument> |

| return address> |

首先我们要先构造参数0xdeadbeef返回地址是pop;ret。这样的话,函数就会从栈中弹出oxdeadbeef然后返回到下一个地址中。

| 0xdeadbeef |

| address of pop; ret> |

| address of add_bin> |

Add_sh函数需要两个参数,我们使用指令pop;pop;ret

| 0x0badf00d |

| 0xcafebabe |

| address of pop; pop; ret> |

| address of add_sh> |

因此我们总体构造的栈的结构是:

| address of exec_string> |

| 0x0badf00d |

| 0xcafebabe |

| address of pop; pop; ret> |

| address of add_sh> |

| 0xdeadbeef |

| address of pop; ret> |

| address of add_bin> |

| 0x42424242 (fake saved %ebp) |

| 0x41414141 … |

| … (0x6c bytes of ‘A’s) |

| … 0x41414141 |

【实验步骤】

1.查看pop;ret pop;pop;ret 以及三个函数的地址

Pop;ret的地址0x80484b7

Pop;pop;ret的地址为0x80484b6

函数add_bin:0x8048428

函数add_sh的地址0x804846e

函数exec_string的地址为0x8048414

(2)构造shellcode

d800cc704a3e0084632cad0e58b14e7f.png

ccc7c59ea5e0542d090c395eb24d344c.png

实验二windows缓冲区溢出绕过ASLR

【原理】

加载程序不再使用固定的基址加载,从而干扰 shellcode 定位的一种保护机制

在 VS 2008 中启用里链接/dynmicbase 链接选项可以开启 ASLR 保护,如图为 vs 中 ASLR 的编 译选项:

b101d2ca7428b10459cfcd49cc01ee34.png

ASLR 保护措施:

1. 映像随机化:

在 PE 文件映射到内存中时,对其加载的虚拟地址进行随机化处理,这个地址在系统启动 时确定,系统重启后这个地址会变化。但是虽然模块的加载基址变化了,但是各模块的入口点地址的低两位是不变的,也就是说映像随机化只是对加载基址的前两个字节做了随机处理。两次开机重启之后 PE 文件映射到内存中位置是不同的。

160e4c8f6f11e67dee5c0cd58f47a5e2.png

2.堆栈随机化

每个线程的堆栈基址都做了随机化处理,使得程序每次运行变量的地址都不相同。在程序运行时随机的选择堆栈的基址,与映像基址随机化不同的是堆栈的基址不是在程序启动 时候确定的,而是在打开程序的时候确定的,也就是说在同一个程序任意两次运行时的堆栈 基址都是不同的,进而各变量在内存中的位置也是不确定的。这种处理只能防止精准攻击, 但是由于跳板指令的使用使得程序不需要精准跳转,只需要跳到一个大概的位置即可。 如图,第一次运行程序时堆栈的位置如图:

7862443881d532f4eae455e25c3853a2.png

两次运行该代码堆栈情况分别如下:

42d0b2749fc781090b545142a6fddbe6.png

49497b46f30db921676be3e319a86553.png

3.PEB 和 TEB 随机化

编写程序获取当前进程的 TEB 和 PEB,TEB 存放在 FS:0 和 FS:[0x18]处,PEB 放在 TEB

运行了几次,进程的 PEB,TEB 的地址没有什么变化,说明 ASLR 对 PEB(Process Environment Block,进程环境块)和 TEB(Thread Environment Block,线程环境块)的随机化并不好。

【攻击手段】

1.攻击未启用 ASLR 模块

在当前进程里面找到一个使用 ASLR 的模块,利用它里面的指令来做跳板,跳入到

shellcode 里面即可。

2.利用 Heap apray 技术定位内存地址

通过申请大量的内存,占领内存中的 0x0C0C0C0C 的位置,并在这些内存中放置 0x90 和

shellcode,最后控制程序转入 0x C0C0 C0C0 执行,在函数执行返回执行后就会转入我们申请 的内存空间中。

3.利用 Java applet heap spray 技术定位内存空间

4.用.NET 控件禁用 ASLR

5.利用部分覆盖进行定位内存地址 映像随机化只是对映像加载基址的强两个字节做随机化处理,我们可以选择覆盖这个地址的

最后一个字节;此外,ASLR 只是随机化了映像的加载基址,而没有对指令序列进行随机化,

也就是说指令的执行相对于基址的位置是相对不变的。

【利用部分覆盖进行定位内存地址】

3.1 实验环境

操作系统 Windows Vista SP0

DEP 状态 Option

编译器 Visual Studio 2008

优化选项 禁用优化选项

GS 选项 GS 关闭

DEP 选项 /NXCOMPAT.NO

Build 版本 Release 版本

3.2 实验代码

c87e1b045f031a1449ef35ff444f070d.png

实验思路和代码的简要解释:

(1)为了直观地反映绕过 ASLR 的过程,本次编译的程序不启用 GS

(2)编译程序禁用 DEP

(3)Test 函数中存在典型的溢出漏洞,通过复制超长字符串可以覆盖函数返回地址。

(4)复制结束后,test 函数返回 tt 字符数组的首地址

(5)我们找到跳板指令 call eax,用它地址的后两个字节覆盖返回地址的后两个字节

3.3 实验步骤

(1)先将 she llcode 设置为 2 62 个字节的 0x90,并将 memcpy 函数中的复制长度设置为

262,用 od 加载,找到 call eax 对应的地址的后两个字节

817af35bf6148d4aa004e3300aaf29fa.png

(2)构造 shellcode

构造之后的 shellcode 代码如下:

6803a0e565885d8fc19e424b93114fd4.png

3.4 运行之后实验结果:

faca3d8a8cd94f74891bc75d44653cda.png

【实验分析】

(1)main 函数,栈中的变化图下图所示:

ce30cd8de30065ef65ece25d03d0d85c.png

发现 call eax 的地址的后两位为 141C

(2)Call test 单步进入 test 函数:

4c2c0904856aa22632b184f43aead7f9.png

在 test 函数中,是一个典型的缓冲区溢出的代码,memcpy 将 26 2 字节的 shellcode 复制到 了栈中,由于栈开辟了 256 个字节的空间,这样的话,就会发生缓冲区溢出,多出来的 6 个字节就会淹没掉 ebp 以及返回地址的最后两个字节,这两个字节里面的内容如下。

e8760d5a9da26710497510ada6f1b3d8.png

很明显函数的返回地址就是 call eax 的地址。

dc25a3a93d6678ded0ab21568093ab42.png

所以在函数返回的时候代码会跳到 call eax 这条指令的地方,由于 eax 中存放的是 shellcode的首地址,这样我们就转到了 shellcode 里面并执行恶意代码,达到目的。

参考资料:

http://codearcana.com/posts/2013/05/28/introduction-to-return-oriented-programming-rop.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值