面对就好,去经历就好。 收藏本站
登陆 / 注册 搜索

阅读: 8K   回复: 3

[# 系统基础] ASLR/DEP绕过技术概览(学习)(转)

soarcloud 「龙战于野」 2016-7-15 21:36 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

http://cybersword.net/attack/exploit/558.html9 Z- {( ~- K. b3 G  r
+ Z8 G9 ]4 g& c( t2 S9 U; ]
1..覆盖返回地址为jmp esp,执行shellcode,当函数返回,返回地址被覆盖为jmpesp,导致执行shellcode
( ]% {. |1 |" G( G+ E1 K9 I: ]                      h$ _/ G' z% W; C$ i2 \
      1)对付方法:引入Dep(data ExecutionPrevention 数据执行保护),堆,栈上的内存页属性为不可执行,执行会出错。/ z6 `' t+ ^: V+ z* n% ^/ `/ \3 z2 K6 k
       2)Anti-Dep:绕过Dep技术ROP(return oriented programming),ROP由一系列的 Gadget组成。所谓ROP Gadget,就是一系列以retn结尾的指令。: E$ b3 i* a8 X" L
                           
% ~( Z4 ~' B8 i                1))为了使Gadget地址固定,无论什么时候指向的都是我们的命令,引入ASLR(address space layout randomization 地址空间格局随机化),ASLR,使得加载程    序时,不适用固定的加载基地址加载,该技术需要操作系统,和程序的双重支持,支持ASLR的程序会在pe头设置属性:
, V5 x* I6 T7 @- IIMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE标识表明其支持ASLR。  k1 \5 N' @1 m2 Q  f
       在VS中可选择:1 G: Y( @$ N: A. t% \
                   2))ASLR所影响的部分有
: J, h2 f4 M6 Q0 Y/ H# l/ W 6 L: \9 S: o4 t6 ^
                         1)))模块随即化:OD打开进程-〉查看-〉可执行模块,基地址在系统重启的时候会变化 
( n6 t0 s0 ]0 w1 V) e4 I- ^4 o                     2)))堆栈随即化,堆栈基地址会变化,进而导致内存中的变量会发生变化
" A2 \4 X1 O* R9 z% F8 E+ L' F                      3)))PEB/TEB随机化(不用固定的地址去获取PEB,TEB,用FS寄存器获取)7 L* q7 q( H1 U& h3 u- Z
                 3)) Anti-ASLR模块! J& t; i" a6 r/ [
                              1)))攻击未时启用的ASLR模块:虽然有映像随机化,但有可能有进程存在未启用ASLR,ROP技术要求从固定的地址获得Gadget,可使用OD的OLLYFindAddr插件查找进程 空间中未启用的ASLR模块
. c* ^1 c6 c- Z: X+ j( R                              2)))堆喷射技术(HeapSpray技术):虽然堆栈随机化,但HeapSpray技术将ShellCode布局到0x0C0C0C0C(或者其他指定的地址上,通常这个地址要比较大),并不会受堆栈随机化的影响。 其实,HeapSpray中使用ROP绕过DEP的时候,就使用了前面提到的“攻击未启用ASLR的模块”。只是,HeapSpray把ShellCode布局在堆上。; {5 v6 j) t7 A# }( y6 b
                             3)))覆盖部分返回地址:虽然模块加载基地址发生变化,但是各模块的入口点地址的低字节不变,只有高位变化
' G4 ~* b( B( W/ `- K' R4 g对于地址0×12345678,其中5678部分是固定的,如果存在缓冲区溢出,可以通过memcpy对后两个字节进行覆盖,可以将其设置为0×12340000 ~ 0x1234FFFF中的任意一个值。
$ o) a7 K' Q( Z8 h) d         如果通过strcpy进行覆盖,因为strcpy会复制末尾的结束符0×00,那么可以将0×12345678覆盖为0×12345600,或者0×12340001 ~ 0x123400FF。: p: i- x# T0 [
         部分返回地址覆盖,可以使得覆盖后的地址相对于基地址的距离是固定的,可以从基地址附近找可以利用的跳转指令。
5 q, W6 q3 p% {3 h" ~2 U& C, h; A         这种方法的通用性不是很强,因为覆盖返回地址时栈上的Cookie会被破坏。不过具体问题具体分析,为了绕过操作系统的安全保护机制需要考虑各种各样的情况。' A3 e& ]& v) O/ `8 m
                            4)))   java Applet Spray: java applet中动态申请的内存空间具有可执行属性,可在固定地址上分配滑板指令(如NOP)和shellcode,然后挑转到上面地址执行。和常规的HeapSpray不同,Applet申请空间的上限为100MB,而常规的HeapSpray可以达到1GB。
' B2 B! r/ _/ W                             5)))   just in Time Compliation(JIT)即时编译,也就是解释器(如python解释器),主要思想是将ActionSCRIPT代码进行大量xor操作,然后编译成字节码,并且多次更新到FLASH VM 这样它会建立很多带有恶意XOR操作的内存块
$ F7 j9 m- F/ e/ n+ O+ evary=(0×11223344^0×44332211^0×4433221);3 \  C6 ^5 j' B5 S3 \
正常情况下被解释器解释为:1 \, O5 Q9 a) y6 W" h) Q
如果非常规的跳转到中间某一个字节开始执行代码,结果就是另一番景象了:
& {# }0 K1 B, N  O4 ^% u% l         关于JIT的详细介绍,可以参考Pointer Inference and JIT Spraying以及Writing JIT-Spray shellcodefor fun and profit,文章末尾会给出链接。7 S6 j9 z0 ?, i; R2 d  z# E8 c
Pointer Inference and JIT Spraying" [5 N( q: z, t3 ~' y# k
Writing JIT-Spray shellcode for fun and profit (中文版); q  [5 X5 h1 E0 {6 r
                         6.))) Tombkeeper在CanSecWest2013上提出的基于SharedUserData的方法
$ g/ k0 d. e/ s5 f; x9 n8 e& m
& a6 L- J$ ]' V4 `! Z! ?: M                                     1))))  从Windows NT 4到Windows 8,SharedUserData的位置一直固定在地址0x7ffe0000上。从WRK源代码中nti386.h以及ntamd64.h可以看出:
# C- S  j9 J! ~2 N4 r7 B                                                     #define MM_SHARED_USER_DATA_VA 0x7FFE0000
" f! F, v. B) Z  P                                                       在x86 Windows上,通过Windbg,可以看到:. U$ r) |; J5 E0 M+ H6 a2 {/ t
                                                       0:001> dt _KUSER_SHARED_DATASystemCall 0x7ffe00009 M5 D# Y( H% I4 }3 r$ O/ @
                                                        ntdll!_KUSER_SHARED_DATA. ^/ Q" m. n$ J3 e/ p5 J* h
                                                       +0×300 SystemCall : 0x774364f0
$ g) A# v' j  O2 J7 i 0 O0 E2 ^8 M+ W3 u9 Z
0x7ffe0300总是指向KiFastSystemCall
% b% \. l. A, ~7 V" l' `& b* I/ K0:001> uf poi(0x7ffe0300)
) m# G! \' N3 ~- z1 \$ \ntdll!KiFastSystemCall:
6 `/ m4 Q0 G  Y774364f08bd4           mov     edx,esp; Z/ G2 g! ^6 P0 L
774364f2 0f34           sysenter+ W. ^# `; D. [7 z! r
774364f4 c3             ret! r/ ^0 x$ a9 _/ R

6 o+ F3 E. j0 Z5 _1 G; r8 n( {& A                                  2))))    反汇编NtUserLockWorkStation函数,发现其就是通过7ffe0300进入内核的:+ V3 A; U% y- T* T4 _: g2 ]7 Q
0:001> ufUSER32!NtUserLockWorkStation9 R. c0 Z+ E+ E% x
USER32!NtUserLockWorkStation:+ S* ~: p  I1 \2 S9 N9 |
75f70fadb8e6110000      mov     eax,11E6h' U$ H0 n5 W- P. `  [/ i$ ^
75f70fb2 ba0003fe7f      mov    edx,offset SharedUserData!SystemCallStub (7ffe0300)0 ]% X: H' H0 S9 i& n
75f70fb7 ff12           call   dword ptr [edx]
0 V! E, \( ^* ^, ?$ Z7 Y75f70fb9 c3             ret
  R8 Z/ n8 v$ R2 |9 R         其中11E6是NtUserLockWorkStation的服务号(ShadowSSDT中0x01E6的服务),通过Xuetr可以看到:
; Z8 o  u9 P0 }4 l7 T         这样,在触发漏洞前合理布局寄存器内容,用函数在系统服务(SSDT / Shadow SSDT)中服务号填充EAX寄存器,然后让EIP跳转到对应的地方去执行,就可以调用指定的函数了。但是也存在很大的局限性:仅仅工作于x86 Windows上;几乎无法调用有参数的函数。
  T! S1 W; J+ I  L2 b: `: U0 Q       5 S: N; s# I0 y% t0 Q! r3 t* k
7 `: U6 h9 ^2 C. J0 \( \
  64位Windows系统上0x7ffe0350总是指向函数ntdll!LdrHotPatchRoutine。# R1 E1 B& ]" K8 W) A
HotPatchBuffer结构体的定义如下:
" U7 X6 U1 z$ j' W- r9 v% x  pstruct HotPatchBuffer {
1 e  {6 c8 s/ v# ~& g( E% yULONG   NotSoSure01; //& 0×20000000  != 0
  |: E  e9 l/ V3 ?% sULONG   NotSoSure02;- Y! Y+ K4 y. b
USHORT  PatcherNameOffset;  // 结构体相对偏移地址2 L6 z% j# j, ^: T2 H1 [* X$ Z# J1 o
USHORT  PatcherNameLen;, N$ @) }8 T' ~0 R9 T6 B. K- R
USHORT  PatcheeNameOffset;
/ x' o) x% ]( u' D& m, DUSHORT  PatcheeNameLen;, E* G: g1 J  Y
USHORT  UnknownNameOffset;) n4 c! F% |+ J2 J5 d! x
USHORT  UnknownNameLen. D, B/ G8 f4 c
};
) E! [: s+ L! ?* SLdrHotPatchRoutine调用方式:: Y" }# u& r5 {, }0 G
void LdrHotPatchRoutine (struct *HotPatchBuffer);& l: d" c* R0 ]- }) I9 s, F
         在触发漏洞前合理布局寄存器内容,合理填充HotPatchBuffer 结构体的内容,然后调用LdrHotPatchRoutine。0 u% B. o$ b% _) J
         如果是网页挂马,可以指定从远程地址加载一个DLL文件;
% Y" ?- X  Q  J4 x. E3 ~         如果已经经过其他方法把DLL打包发送给受害者,执行本地加载DLL即可。; L' M+ W) I7 _# R. x+ ?5 b
         此方法通常需要HeapSpray协助布局内存数据;且需要文件共享服务器存放恶意DLL;只工作于64位系统上的32位应用程序;不适用于Windows 8(已经被修补)。
上一篇
下一篇


雾月 「出类拔萃」 2018-5-4 18:20 来自手机 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

为毛老子总也抢不到沙发?!!
初晓微芒 「出类拔萃」 2018-5-5 14:56 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

此贴构思巧妙,视角独到,手法新颖。字字斟酌,句句精美,情节曲折,而又始终不离中心思想,引人入胜,淡淡的言语中,显示人生之大道理,充分体现了您深厚的文化底韵与丰富的社会经验,真可谓讽刺之经典,骂人之绝学,这正是我辈苦学闷读追求的至高境界啊!
您需要登录后才可以回帖 登录 | 免费注册  

本版积分规则

关于本站|大事记|小黑屋|古黑论 网站统计

GMT+8, 2021-10-26 10:23 , Processed in 0.025309 second(s), 19 queries , Redis On.

© 2015-2021 GuHei.Net

Powered by Discuz! X3.4

快速回复 返回列表