ASLR

开始是一道CTF题加了UPX壳, 利用堆栈平衡脱壳,import rec进行IAT修复后,程序不能正常打开了. 后来才知道是开启了ASLR, 关闭后即可打开。 加壳会对PE文件的重定位表进行压缩,在OD直接dump出的程序是丢失重定位表的, 而程序又是开启了ASLR,那程序自然会访问到无效的地址而打不开

介绍

ASLR(地址空间布局随机化), 一种针对缓冲区溢出的安全保护技术. 从Windows Vsita(内核版本6.0)开始采用, 而Windows XP的内核版本是5.1, 所以我们在Windows XP下脱开启了ASLR 的壳是不会有这个问题的.

ASLR就是使我们的PE文件在每次载入内存时起始地址都会变得随机化, 增加恶意用户编写漏洞利用代码的难度(在之前我们知道只有dll文件在理想地址空间被占用了才会进行重定位)

对于ASLR功能我们系统(win10)是默认关闭的, 我们可以在设置的安全中心打开.image-20200511184233641

另外就是可执行文件的ASLR, 我们在我们的编译器上也可以选择是否引用该功能.image-20200511185012962

分析ASLR

以VS编译器写一个程序, 分别生成开启了随机基址与未开启的的版本来分析. (一共有三个地方不同)

(1)未开启ASLR的程序的文件头的Characteristics会多一个 IMAGE_FILE_RELOCS_STRIPPED 0X0001 的属性, 经过查看官方文档可以看得到属性解释, 所以我们开启ASLRd的程序不会有这个属性image-20200511200244008

​ 下面看程序对比:

image-20200511201513817

(2)开启了ASLR的程序的可选头的DllCharacteristics多了IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE

0X0040的属性. 同样查看官方文档. 即重定位时需要的属性.image-20200511201801401

程序对比:image-20200511202308748

(3)开启了ASLR的程序会多一个 .reloc 节(一般普通的exe文件是不需要该节的, 用于开启ASLR的程序进行重定位, 当然我们关闭了ASLR也可以把这个节删了)image-20200511202858464

关闭ASLR

由上面的分析知道有3处不同, 其中上面的(1)中是开启了ASLR的程序少了 IMAGE_FILE_RELOCS_STRIPPED 0X0001属性, 我们增加上这个属性即可关闭ASLR(即 0102 -> 0103 / 对应属性打上勾即可). 另外(2)中是多了DLL can move的属性,删除这个属性,同样可以关闭ASLR(即 8140 -> 8100 / 对应属性取消打勾即可 )

下面示例在010编译器中修改数值来关闭ASLR.image-20200511204613644

以上是关于ASLR的分析即关闭, 如果开启了ASLR, 我们在脱壳之前还是先关闭它最好,也方便调试时IDA与OD中地址的对应(如果只是想地址对应, 也可以在IDA中启动时把Manual load勾上, 手动输入加载的基地址即可), 既然关闭了ASLR, 那多出的.reloc节也就没用了, 下面手动删除该节区(虽然有很多工具可以直接实现, 还是手动熟悉下PE结构)

删除.reloc节区

首先每个节都对应一个节区头的, 那先从节区头开始. 使用010editor可以轻松在最后一节区头找到. 我们将其全部用0覆盖填充即可.(注: 不能直接删除了, 不然PE文件的很多属性会对应不上)image-20200511205903649

下面删除.reloc整个节区(一般这个节区都是新加的,所以在最后, 我们只要找到偏移地址直接删除到最后即可), 如图, 直接删除到最后即可. (这里的Size: 600h, 下面有用)image-20200511210742225

删除完后, 我们知道PE文件头的_IMAGE_FILE_HEADERNumberOfSections的值一定要严格的与实际节区对应, 所以去修改 _IMAGE_FILE_HEADERNumberOfSections使其减一.image-20200511210943674)image-20200511211434269

最后还有修改一个属性, 就是PE文件头 _IMAGE_OPTIONAL_HEADER

SizeOfImage, 修改为减去 .reloc节区后的大小 从上面我们知道.reloc大小是600h, 而该PE文件SectionAlignment(节在内存中的最小单位 (对齐单位) 一般为: 1000h)为1000h, 1000h > 600h. 以1000h对齐, 所以我们直接将SizeOfImage减去1000h即可.image-20200511211537176)image-20200511212159056

如果想增加一个节区, 也可以使用同样的方法

-------------本文结束感谢您的阅读-------------