ASLR/DEP绕过技术概览(学习)(转) |
http://cybersword.net/attack/exploit/558.html
1..覆盖返回地址为jmp esp,执行shellcode,当函数返回,返回地址被覆盖为jmpesp,导致执行shellcode 1)对付方法:引入Dep(data ExecutionPrevention 数据执行保护),堆,栈上的内存页属性为不可执行,执行会出错。 🥩☯🐅 2)Anti-Dep:绕过Dep技术ROP(return oriented programming),ROP由一系列的 Gadget组成。所谓ROP Gadget,就是一系列以retn结尾的指令。1))为了使Gadget地址固定,无论什么时候指向的都是我们的命令,引入ASLR(address space layout randomization 地址空间格局随机化),ASLR,使得加载程 序时,不适用固定的加载基地址加载,该技术需要操作系统,和程序的双重支持,支持ASLR的程序会在pe头设置属性: IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE标识表明其支持ASLR。 在VS中可选择: 👵👒🪗🤖👌 2))ASLR所影响的部分有 1)))模块随即化:OD打开进程-〉查看-〉可执行模块,基地址在系统重启的时候会变化 2)))堆栈随即化,堆栈基地址会变化,进而导致内存中的变量会发生变化 3)))PEB/TEB随机化(不用固定的地址去获取PEB,TEB,用FS寄存器获取)🧒👗🗑😘👄 3)) Anti-ASLR模块 1)))攻击未时启用的ASLR模块:虽然有映像随机化,但有可能有进程存在未启用ASLR,ROP技术要求从固定的地址获得Gadget,可使用OD的OLLYFindAddr插件查找进程 空间中未启用的ASLR模块 2)))堆喷射技术(HeapSpray技术):虽然堆栈随机化,但HeapSpray技术将ShellCode布局到0x0C0C0C0C(或者其他指定的地址上,通常这个地址要比较大),并不会受堆栈随机化的影响。 其实,HeapSpray中使用ROP绕过DEP的时候,就使用了前面提到的“攻击未启用ASLR的模块”。只是,HeapSpray把ShellCode布局在堆上。 3)))覆盖部分返回地址:虽然模块加载基地址发生变化,但是各模块的入口点地址的低字节不变,只有高位变化 对于地址0×12345678,其中5678部分是固定的,如果存在缓冲区溢出,可以通过memcpy对后两个字节进行覆盖,可以将其设置为0×12340000 ~ 0x1234FFFF中的任意一个值。 👍🎠🍭⁉🐢 如果通过strcpy进行覆盖,因为strcpy会复制末尾的结束符0×00,那么可以将0×12345678覆盖为0×12345600,或者0×12340001 ~ 0x123400FF。 部分返回地址覆盖,可以使得覆盖后的地址相对于基地址的距离是固定的,可以从基地址附近找可以利用的跳转指令。 这种方法的通用性不是很强,因为覆盖返回地址时栈上的Cookie会被破坏。不过具体问题具体分析,为了绕过操作系统的安全保护机制需要考虑各种各样的情况。 4))) java Applet Spray: java applet中动态申请的内存空间具有可执行属性,可在固定地址上分配滑板指令(如NOP)和shellcode,然后挑转到上面地址执行。和常规的HeapSpray不同,Applet申请空间的上限为100MB,而常规的HeapSpray可以达到1GB。 5))) just in Time Compliation(JIT)即时编译,也就是解释器(如python解释器),主要思想是将ActionSCRIPT代码进行大量xor操作,然后编译成字节码,并且多次更新到FLASH VM 这样它会建立很多带有恶意XOR操作的内存块🧑🎤👞📮🤪👎 vary=(0×11223344^0×44332211^0×4433221); 正常情况下被解释器解释为: 如果非常规的跳转到中间某一个字节开始执行代码,结果就是另一番景象了: 关于JIT的详细介绍,可以参考Pointer Inference and JIT Spraying以及Writing JIT-Spray shellcodefor fun and profit,文章末尾会给出链接。 Pointer Inference and JIT Spraying 🤝⛵🍌🈚🐮Writing JIT-Spray shellcode for fun and profit (中文版) 6.))) Tombkeeper在CanSecWest2013上提出的基于SharedUserData的方法 1)))) 从Windows NT 4到Windows 8,SharedUserData的位置一直固定在地址0x7ffe0000上。从WRK源代码中nti386.h以及ntamd64.h可以看出: #define MM_SHARED_USER_DATA_VA 0x7FFE0000👮♂️🧣🧪😭🖕 在x86 Windows上,通过Windbg,可以看到: 0:001> dt _KUSER_SHARED_DATASystemCall 0x7ffe0000 ntdll!_KUSER_SHARED_DATA +0×300 SystemCall : 0x774364f0 👠🛏🙂🧠 0x7ffe0300总是指向KiFastSystemCall 0:001> uf poi(0x7ffe0300) ntdll!KiFastSystemCall: 774364f08bd4 mov edx,esp 774364f2 0f34 sysenter🧑🚀🧣🪜😳🖐 774364f4 c3 ret 2)))) 反汇编NtUserLockWorkStation函数,发现其就是通过7ffe0300进入内核的: 0:001> ufUSER32!NtUserLockWorkStation USER32!NtUserLockWorkStation:🧑🚀👠🩺😉🦷 75f70fadb8e6110000 mov eax,11E6h 75f70fb2 ba0003fe7f mov edx,offset SharedUserData!SystemCallStub (7ffe0300) 75f70fb7 ff12 call dword ptr [edx] 75f70fb9 c3 ret 其中11E6是NtUserLockWorkStation的服务号(ShadowSSDT中0x01E6的服务),通过Xuetr可以看到: 👨🚒👒🧪😃👆 这样,在触发漏洞前合理布局寄存器内容,用函数在系统服务(SSDT / Shadow SSDT)中服务号填充EAX寄存器,然后让EIP跳转到对应的地方去执行,就可以调用指定的函数了。但是也存在很大的局限性:仅仅工作于x86 Windows上;几乎无法调用有参数的函数。 64位Windows系统上0x7ffe0350总是指向函数ntdll!LdrHotPatchRoutine。 HotPatchBuffer结构体的定义如下: 👮♂️👠💳👻🤞 struct HotPatchBuffer { ULONG NotSoSure01; //& 0×20000000 != 0 ULONG NotSoSure02; USHORT PatcherNameOffset; // 结构体相对偏移地址 USHORT PatcherNameLen; 💈🍇🉑🐡USHORT PatcheeNameOffset; USHORT PatcheeNameLen; USHORT UnknownNameOffset; USHORT UnknownNameLen };🧑🌾🛍🧯😈🦷 LdrHotPatchRoutine调用方式: void LdrHotPatchRoutine (struct *HotPatchBuffer); 在触发漏洞前合理布局寄存器内容,合理填充HotPatchBuffer 结构体的内容,然后调用LdrHotPatchRoutine。 如果是网页挂马,可以指定从远程地址加载一个DLL文件; 如果已经经过其他方法把DLL打包发送给受害者,执行本地加载DLL即可。 🤛🔥🔪♀🐮 此方法通常需要HeapSpray协助布局内存数据;且需要文件共享服务器存放恶意DLL;只工作于64位系统上的32位应用程序;不适用于Windows 8(已经被修补)。
帖子热度 1.1万 ℃
|
|
此贴构思巧妙,视角独到,手法新颖。字字斟酌,句句精美,情节曲折,而又始终不离中心思想,引人入胜,淡淡的言语中,显示人生之大道理,充分体现了您深厚的文化底韵与丰富的社会经验,真可谓讽刺之经典,骂人之绝学,这正是我辈苦学闷读追求的至高境界啊!
|