针对缓冲区保护技术(ASLR)的一次初探

0x01 前言

  • ASLR 是一种针对缓冲区溢出的安全保护技术,通过对堆、栈、共享库映射等线性区布局的随机化,通过增加攻击者预测目的地址的难度,防止攻击者直接定位攻击代码位置,达到阻止溢出攻击的目的的一种技术
  • 目前 ASLR 技术据我所知对3种情况进行了保护,分别是映像基址随机化、堆栈基址随机化和 PEB / TEB 随机化(有论文为参考)。下面来亲自测试一下,看看地址到底会不会变
    在这里插入图片描述
  • 实验环境:Windows 10 ,编译器:C-Free

0x02 映像基址随机化

  • 当可执行文件或动态链接库文件被映射到内存时,系统会对其虚拟地址进行随机化(重启系统后会更新地址),示例程序如下(做缓冲区溢出实验的,这里直接拿来用了)
    在这里插入图片描述
  • 这里准备测试7个数据:(1)msvcrt.dll 基地址及大小(2)msvcrt._cexit 的地址及偏移地址(3)msvcrt.singnal 的地址及偏移地址(3)msvcrt.strcpy 地址及偏移地址(4)msvcrt.atexit 地址及偏移地址(5)msvcrt._fileno 地址及偏移地址(6)msvcrt._setmode 地址及偏移地址。其中第一个是动态链接库,其他都是动态链接库里面的函数。
  • 测试 msvcrt.dll 的基地址及大小的方法,将编译好的程序放入OD保持程序为运行状态
    在这里插入图片描述
  • 打开 PCHunter 软件,找到刚刚加载的进程,右击在下方显示模块窗口
    在这里插入图片描述
  • 右击显示所有模块
    在这里插入图片描述
  • 可以看到 msvcrt.dll 模块的地址
    在这里插入图片描述
  • 测试动态链接库 msvcrt.dll 中的函数地址及偏移地址的方法,下面是刚刚加载进OD的文件,我们需要找到一个 msvcrt.dll 中存在的函数,这个程序在加载的时候刚好调用了一个(也可以自己编写)
    在这里插入图片描述
  • enter 进入这个函数,可以看到很多 msvcrt.dll 动态链接库里面的函数
    在这里插入图片描述
  • 想看某一个函数的内存中的地址,可以直接 enter 进入这个函数,比如 strcpy,0x775a6400 就是内存中的地址,以上就是测试 scvcrt.dll 动态链接库文件中函数地址的方法
    在这里插入图片描述
  • 之后我测试了10次
    在这里插入图片描述
  • 汇总一下,根据测试的结果可以发现,msvcrt.dll 动态链接库的基地址会变化,但是函数在动态链接库的偏移地址不会变化,基地址大小不变
msvcrt.dll 基地址大小
测试 10x761800000xBF000
测试 20x757C00000xBF000
测试 30x779F00000xBF000
测试 40x76FD00000xBF000
测试 50x754B00000xBF000
测试 60x76CF00000xBF000
测试 70x74FE00000xBF000
测试 80x758800000xBF000
测试 90x772400000xBF000
测试 100x775200000xBF000
_cexit偏移地址singnal偏移地址strcpy偏移地址
测试 10x761e5f30 0x65F300x761d6fe0 0x56FE00x76206400 0x86400
测试 20x75825f30 0x65F300x75816fe0 0x56FE00x75846400 0x86400
测试 30x77a55f30 0x65F300x77a46fe0 0x56FE00x77a76400 0x86400
测试 40x77035f30 0x65F300x77026fe0 0x56FE00x77056400 0x86400
测试 50x75515f30 0x65F300x75506fe0 0x56FE00x75536400 0x86400
测试 60x76d55f30 0x65F300x76d46fe0 0x56FE00x76d76400 0x86400
测试 70x75045f30 0x65F300x75036fe0 0x56FE00x75066400 0x86400
测试 80x758e5f30 0x65F300x758d6fe0 0x56FE00x75906400 0x86400
测试 90x772a5f30 0x65F300x77296fe0 0x56FE00x772c6400 0x86400
测试 100x77585f30 0x65F300x77576fe0 0x56FE00x775a6400 0x86400
atexit偏移地址_fileno偏移地址_setmode偏移地址
测试 10x761d6ca0 0x56CA00x761f3130 0x731300x761c9d70 0x49D70
测试 20x75816ca0 0x56CA00x75833130 0x731300x75809d70 0x49D70
测试 30x77a46ca0 0x56CA00x77a63130 0x731300x77a39d70 0x49D70
测试 40x77026ca0 0x56CA00x77043130 0x731300x77019d70 0x49D70
测试 50x75506ca0 0x56CA00x75523130 0x731300x754f9d70 0x49D70
测试 60x76d46ca0 0x56CA00x76d63130 0x731300x76d39d70 0x49D70
测试 70x75036ca0 0x56CA00x75053130 0x731300x75029d70 0x49D70
测试 80x758d6ca0 0x56CA00x758f3130 0x731300x758c9d70 0x49D70
测试 90x77296ca0 0x56CA00x772b3130 0x731300x77289d70 0x49D70
测试 100x77576ca0 0x56CA00x77593130 0x731300x77569d70 0x49D70

0x03 堆栈随机化

  • 程序启动时,系统会随机选择堆栈的基址,从而导致内存中各种变量地址发生改变(程序每次启动前)
  • 首先看一下如何开启程序的ASLR防护,这个貌似只有微软的编译器才有的功能,在VS编译器中新建一个项目(我的是 VS2017在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 将随机基址改为是即可,那么怎么看一个可执行文件是否受到 ASLR 保护呢,可以用 PEview 这个工具看文件头中是否有 IMAGE_FILE_RELOCS_STRIPPED 这个标志,有表示没有受到 ASLR 保护,没有则表示收到了 ASLR 的保护
  • 这个是没有的在这里插入图片描述
  • 这个是有的
    在这里插入图片描述
  • 下面测试一下受到了 ASLR 保护的程序堆栈地址到底会不会变化,OD载入,到达程序的真正入口 OEP
    在这里插入图片描述
  • 看一下此时堆栈地址
    在这里插入图片描述
  • 之后重复 10 次,对比一下,可以看出入口堆栈地址防护较好,变化很大,随机性非常强
程序入口时的堆栈地址(有 ASLR)程序入口时的堆栈地址(无 ASLR)
测试 10x00B7F76C0x243FF24
测试 20x0137F7500x243FF24
测试 30x00BDF7FC0x243FF24
测试 40x00DAF8C00x243FF24
测试 50x0077F7B00x243FF24
测试 60x0057FC880x243FF24
测试 70x009FF8340x243FF24
测试 80x012FF8480x243FF24
测试 90x008FFA340x243FF24
测试 100x0075FDD00x243FF24

0x04 PEB\TEB随机化

  • 进程环境块(PEB)和线程环境块(TEB)随机化,在程序每次启动时(这个和编译时有没有加上 ASLR 防护没有关系,好像是系统默认的,加不加都会随机)
  • 利用 Windbg 查看 PEB 和 TEB 的地址(Windbg32Windbg64
  • 选择 File -> Open Executable,选择要查看的文件
    在这里插入图片描述
    在这里插入图片描述
  • 在最下面的命令行中输入 !peb 和 !teb 即可查询
    在这里插入图片描述
  • 测试 5 次汇总一下,变化并不是很大
PEB地址TEB地址
测试 10x00000000002FD0000x00000000002FF000
测试 20x00000000003520000x0000000000354000
测试 30x000000000039A0000x000000000039C000
测试 40x000000000038A0000x000000000038C000
测试 50x00000000003020000x0000000000304000
  • 对于 ASLR 的全部测试到此结束
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值