一、ASLR和DEP原理
1.ASLR原理:
ASLR是一种针对缓冲区溢出的安全保护技术,通过对堆、栈、共享库映射等线性区布局的随机化,通过增加攻击者预测目的地址的难度,防止攻击者直接定位攻击代码位置,达到阻止溢出攻击的目的。如今Linux、FreeBSD、Windows等主流操作系统都已采用了该技术。(虚拟地址)此技术需要操作系统和软件相配合。
PE头文件中会设置 IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE标示来说明其支持 ASLR。
ASLR(Address space layout randomization)windows系统中运行的同一个程序其模块加载的地址空间是随机的,也是防止恶意代码攻击的一种手段。(纯系统级别的实现)我们自己编写的程序或者链接库,可以通过设置一个链接选项,Project Property -> Configuration Properties -> Linker -> Advanced -> Randomized Base Address,在linux中使用此技术后,杀死某程序后重新开启,地址换。在windows中使用此技术后,杀死进程后重新开启,地址不换,重启才会改变
2.DEP技术介绍
数据执行保护(DEP)(Data Execution Prevention) 是一套软硬件技术,能够在内存上执行额外检查以帮助防止在系统上运行恶意代码。在 Microsoft Windows XP Service Pack 2及以上版本的Windows中,由硬件和软件一起强制实施 DEP。
支持 DEP 的 CPU 利用一种叫做“No eXecute 不执行”的技术识别标记出来的区域。如果发现当前执行的代码没有明确标记为可执行(例如程序执行后由病毒溢出到代码执行区的那部分代码),则禁止其执行,那么利用溢出攻击的病毒或网络攻击就无法利用溢出进行破坏了。如果 CPU 不支持 DEP,Windows 会以软件方式模拟出 DEP 的部分功能。
DEP(Data execution protect)数据执行保护,这个功能需要操作系统和硬件的共同支持才可以生效。DEP的原理就是在系统的内存页中设置了一个标志位,标示这个内存页的属性(可执行)。
在硬件上这个工作就交给了CPU来完成,intel CPU在内存页中设置了XD标志位,amd CPU在内存页中设置了NX标志位,都标志了内存页的执行权限。
在操作系统方面,windows xp sp2从开始支持DEP的功能,但是必须将操作系统运行在PAE(Physical address extension)模式下,即使用硬件的这个标志位。
1.WINXP SP2 默认 /NOEXECUTE = OPTIN;DEP只是对一些必须的windows程序和服务起效。
2.WIN2K3 SP1默认 /NOEXECUTE = OPTOUT;DEP对所有的windows程序和服务起效,除非是用户自己排除的程序。
3.绕过DEP的办法
直接利用程序中没有ASLR特性的模块,寻找能够利用的汇编指令,xchg、eax,、esp、retn、pop ebx、retn等等,找到这些特殊的指令,接下来就是构造一个适合这些指令使用的栈数据了,这个执行过程就利用原来模块的执行内存,我们的栈数据也仍然是作为数据使用,不会被DEP检测到。
比如WinExec、system已经在程序中被调用,我们只需要将调用处的地址拿过来,放到ret语句中,并配置好适当的参数。这种方式非常巧妙,都不需要写入一堆代码到内存中,但是前提是你需要使用的API原来程序中都有。
有了上面执行API的条件,我们就可以利用以下方法,改变进程或者内存页的DEP属性。
1、通过调用API赋予内存可执行的权限,包括VirtualAlloc HeapCreate等函数,可以改变内存页的执行属性。
2、通过调用API取消系统对本进程的DEP检测,SetProcessDEPPolicy,但是使用这个函数需要满足条件:
操作系统是vista sp1、winxp sp3、win2k8
操作系统DEP的模式设置为OPTIN OPTOUT,如果是AlwaysON就没有办法了
3、通过NT!NTSetInformationProcess函数关闭本进程的DEP检测,nt5.1都可以实现,vista版本也可以,但是vista sp1之后就不行了。
4、通过WriteProcessMemory把执行代码写入到可执行的内存页中
二、Window10下vs2019与DEVc++的不同
1.VS2019
新建项目打开vs2019,建立新的项目,建立一个main.cpp的源文件,main.cpp的内容如下图所示:
进行编译,运行结果如下:
进行反汇编
第一步在main函数入口加入断点:
在vs2019先运行程序,进入反汇编界面
进入func()函数的反汇编:
*func()函数对应的汇编代码为:*
*007F1975 call func(07F1037h)*
按键f11进入func()查看反汇编:
call指令跳转的目的地仍然是一个跳转到func函数入口的jmp语句,在这里func函数的入口地址为07F17D0h,接着单步调试以进入func函数
进入func函数之后,单步调试至func函数执行完毕,结果如下所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4aKpeq5i-1649239858121)(https://raw.githubusercontent.com/lmy12367/img/main/imgwps3677.tmp.jpg)]
执行完add esp,4指令实现栈平衡后,接着执行一系列pop指令后func函数执行结束,返回main函数,如下图所示
回到main函数,逐步进行结束程序:
2.DEV c++
新建项目
运行程序
在main()打上断点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QtcmcAnt-1649239858123)(https://raw.githubusercontent.com/lmy12367/img/main/imgwpsA90D.tmp.jpg)]
打开CPU窗口进入反汇编:
单步调式到func()函数的地方:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ctst8xU5-1649239858124)(https://raw.githubusercontent.com/lmy12367/img/main/imgwpsA90F.tmp.jpg)]
进入func()函数:
Func()函数运行完毕:
3.比较
通过比较相同代码在DEV C++和vs2019中编译运行自定义的func函数的调用的与地址的变化,可以发现不同的地方,在vs2019中地址发生变化可以有效阻断rop攻击。
三、Linux中的ALSR
1.查看ALSR的打开情况
输入指令cat /proc/sys/kernel/randomize_va_space
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LJi8Q19E-1649239858125)(https://raw.githubusercontent.com/lmy12367/img/main/imgwpsA921.tmp.jpg)]
结果为2说明ALSR已经打开,并且为完全的ALSR。
Linux中的ALSR对应的内核参数randomize_va_space有三个合法取值,其对应的效果如下:
0:不开启ASLR
1:运行栈和共享库以及部分堆的随机化
2:在1的基础上包括所有堆的随机化
注:ALSR不负责代码段和数据段和地址随机化,这项工作PIE负责,但是只有ASLR开启的情况下,PIE才会生效。
2.关闭ALSR
输入命令echo 0 > /proc/sys/kernel/randomize_va_space
*因为这个地方忘记了普通用户不能进行执行命令,换成root用户可以执行、忘记如何切换root用户改了很久,所以导致在终端造成这么乱的的截图,老师见谅*
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QZpqVUJq-1649239858125)(https://raw.githubusercontent.com/lmy12367/img/main/imgwpsA922.tmp.jpg)]
再次查看内核参数randomize_va_space的值
内核参数randomize_va_space的值为0,说明ALSR关闭成功
四、Linux系统中DEP的保护机制
1.Linux下的DEP的原理
Linux系统中的DEP通过NX来实现,NX即No-eXecute(不可执行)的意思,NX的基本原理是将数据所在内存页标识为不可执行,当程序溢出成功转入shellcode时,程序会尝试在数据页面上执行指令,此时CPU就会抛出异常,而不是去执行恶意指令。
gcc编译器默认开启了NX选项,如果需要关闭NX选项,可以给gcc编译器添加-z execstack参数
2.实践操作
Linux下编写一段c语言的代码:
对gcc进行反汇编,由于默认情况下数据执行保护和栈保护都是开启的,首先进行开启数据执行保护和栈保护的反汇编,输入命令gcc -S -o test.s test.c,得到test.s汇编代码
接着进行关闭数据执行保护和栈保护的反汇编,输入命令 gcc -fno-stack-protector -z execstack -S -o test1.s test.c,得到test1.s汇编代码,如下图所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T7EM0AFI-1649239858127)(https://raw.githubusercontent.com/lmy12367/img/main/imgwpsA928.tmp.jpg)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BvaXBEU3-1649239858127)(https://raw.githubusercontent.com/lmy12367/img/main/imgwpsA92A.tmp.jpg)]
经过对比可以发现,开启了数据执行保护和栈保护的程序对潜在的栈溢出风险做了处理,对应程序的执行结果也不同。
五、实验总结
[外链图片转存中…(img-T7EM0AFI-1649239858127)][外链图片转存中…(img-ldC3v9eN-1649239858127)][外链图片转存中…(img-BvaXBEU3-1649239858127)]
经过对比可以发现,开启了数据执行保护和栈保护的程序对潜在的栈溢出风险做了处理,对应程序的执行结果也不同。
五、实验总结
在此次实验中根据老师给的实验,体验一下ASLR和DEP的内容,加深了自己对于ASLR和DEP的操作,同时也通过此次实验自己温习了一些关于Linux的操作和关于vs2019关于查看反汇编代码的内容,认识到了在软件安全方面不仅要通过软件避免还需要结合一定的硬件功能。