知道活着的痛苦处的人就能对人温柔,这和软弱是不一样的。 收藏本站
登陆 / 注册 搜索

阅读: 8.7K   回复: 3

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

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

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

http://cybersword.net/attack/exploit/558.html
' Y3 k: u. n* M
+ `) d. j2 b* ~# R) ~8 l( t1..覆盖返回地址为jmp esp,执行shellcode,当函数返回,返回地址被覆盖为jmpesp,导致执行shellcode
0 \5 e6 [0 }1 \6 ]                    1 [: w# V9 N- O, G& o. `: Y
      1)对付方法:引入Dep(data ExecutionPrevention 数据执行保护),堆,栈上的内存页属性为不可执行,执行会出错。
: x. M; Y, j( P' Q2 C, T4 j/ S3 \$ _       2)Anti-Dep:绕过Dep技术ROP(return oriented programming),ROP由一系列的 Gadget组成。所谓ROP Gadget,就是一系列以retn结尾的指令。
) ]- l. e) {3 K, f5 R1 w/ X8 o                           
* E8 O& J2 G6 C5 o. i! w# X                1))为了使Gadget地址固定,无论什么时候指向的都是我们的命令,引入ASLR(address space layout randomization 地址空间格局随机化),ASLR,使得加载程    序时,不适用固定的加载基地址加载,该技术需要操作系统,和程序的双重支持,支持ASLR的程序会在pe头设置属性:' Q. H( c' x- r* n8 y8 R( ~
IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE标识表明其支持ASLR。) s& R+ _: M. D. L: f$ l, ~) Z
       在VS中可选择:+ H' S. F6 ?: J- n. v# j3 u
                   2))ASLR所影响的部分有9 C6 s7 L3 X" \* ^8 v4 J
; e+ L# b/ u0 c( q/ Q& U1 `
                         1)))模块随即化:OD打开进程-〉查看-〉可执行模块,基地址在系统重启的时候会变化 3 y% l6 V* N( O5 j& V
                     2)))堆栈随即化,堆栈基地址会变化,进而导致内存中的变量会发生变化! U/ Z& N; t- G. e6 b1 G9 U' m  r
                      3)))PEB/TEB随机化(不用固定的地址去获取PEB,TEB,用FS寄存器获取)
$ ?9 u+ b1 d! d                 3)) Anti-ASLR模块
9 ?( G0 ]1 B! q7 F" ^, {3 h- i                              1)))攻击未时启用的ASLR模块:虽然有映像随机化,但有可能有进程存在未启用ASLR,ROP技术要求从固定的地址获得Gadget,可使用OD的OLLYFindAddr插件查找进程 空间中未启用的ASLR模块
8 Q- t9 l( T* _3 B; k                              2)))堆喷射技术(HeapSpray技术):虽然堆栈随机化,但HeapSpray技术将ShellCode布局到0x0C0C0C0C(或者其他指定的地址上,通常这个地址要比较大),并不会受堆栈随机化的影响。 其实,HeapSpray中使用ROP绕过DEP的时候,就使用了前面提到的“攻击未启用ASLR的模块”。只是,HeapSpray把ShellCode布局在堆上。
' B& R4 O) c& [8 k5 K; X                             3)))覆盖部分返回地址:虽然模块加载基地址发生变化,但是各模块的入口点地址的低字节不变,只有高位变化
( Q* k9 ]+ |0 d: L4 ]) b9 C* X对于地址0×12345678,其中5678部分是固定的,如果存在缓冲区溢出,可以通过memcpy对后两个字节进行覆盖,可以将其设置为0×12340000 ~ 0x1234FFFF中的任意一个值。
1 Q: u0 g( }: o' N" ~7 t" O$ S+ p         如果通过strcpy进行覆盖,因为strcpy会复制末尾的结束符0×00,那么可以将0×12345678覆盖为0×12345600,或者0×12340001 ~ 0x123400FF。
" ?2 V* N! o3 G+ s3 B/ H         部分返回地址覆盖,可以使得覆盖后的地址相对于基地址的距离是固定的,可以从基地址附近找可以利用的跳转指令。  _% U- Y9 W+ K9 k! ^9 r: z
         这种方法的通用性不是很强,因为覆盖返回地址时栈上的Cookie会被破坏。不过具体问题具体分析,为了绕过操作系统的安全保护机制需要考虑各种各样的情况。( U/ J# v) a: E, S  C% S& h
                            4)))   java Applet Spray: java applet中动态申请的内存空间具有可执行属性,可在固定地址上分配滑板指令(如NOP)和shellcode,然后挑转到上面地址执行。和常规的HeapSpray不同,Applet申请空间的上限为100MB,而常规的HeapSpray可以达到1GB。6 @5 _: X) N; ]; P' `' M5 P
                             5)))   just in Time Compliation(JIT)即时编译,也就是解释器(如python解释器),主要思想是将ActionSCRIPT代码进行大量xor操作,然后编译成字节码,并且多次更新到FLASH VM 这样它会建立很多带有恶意XOR操作的内存块/ n  l: v3 G$ Y# c! a0 @% X
vary=(0×11223344^0×44332211^0×4433221);7 o3 ]- n5 m0 k% m  \
正常情况下被解释器解释为:6 A8 ~# `( i; B" ?: J3 L
如果非常规的跳转到中间某一个字节开始执行代码,结果就是另一番景象了:
, x6 M4 B9 W% I" t$ C         关于JIT的详细介绍,可以参考Pointer Inference and JIT Spraying以及Writing JIT-Spray shellcodefor fun and profit,文章末尾会给出链接。+ B6 C2 R" U8 w1 c! S# t0 e) p% R
Pointer Inference and JIT Spraying+ _3 _4 \' f- A
Writing JIT-Spray shellcode for fun and profit (中文版)
- |# ]/ S. G0 h                         6.))) Tombkeeper在CanSecWest2013上提出的基于SharedUserData的方法$ ?' d' b( K* a9 w  N* m

( z" s, d/ G( ^( S5 c5 o4 _- G                                     1))))  从Windows NT 4到Windows 8,SharedUserData的位置一直固定在地址0x7ffe0000上。从WRK源代码中nti386.h以及ntamd64.h可以看出:
- m' ?- F1 c5 b; I) X4 c  \                                                     #define MM_SHARED_USER_DATA_VA 0x7FFE0000
, x# X" \& p' r6 M                                                       在x86 Windows上,通过Windbg,可以看到:
! v1 F6 Q3 v  K( X9 D7 M2 e                                                       0:001> dt _KUSER_SHARED_DATASystemCall 0x7ffe0000. \! P& o& q& z/ D! Y1 M  a
                                                        ntdll!_KUSER_SHARED_DATA
! E" o$ i% [7 Q" v; o% t$ v                                                       +0×300 SystemCall : 0x774364f0+ c* Y4 J3 \2 u8 _7 P
7 ?& h" B) w7 \! I, z
0x7ffe0300总是指向KiFastSystemCall* p" H0 V2 t( i" p; E5 D
0:001> uf poi(0x7ffe0300)/ l! u2 f5 G$ F/ [! [
ntdll!KiFastSystemCall:
4 T0 E) W7 K. ~) j; t774364f08bd4           mov     edx,esp
7 H3 ^4 T" J" o' f0 a774364f2 0f34           sysenter
  O+ D' [* |( y- [1 @1 H774364f4 c3             ret, z- [" \' u; G3 q. Q
& y4 @" T4 I7 c. L1 G5 }
                                  2))))    反汇编NtUserLockWorkStation函数,发现其就是通过7ffe0300进入内核的:
2 _$ o& e- z3 q7 G0:001> ufUSER32!NtUserLockWorkStation
1 \0 k3 R  m) H( q7 |: L( }: ~) _USER32!NtUserLockWorkStation:% p  K# Q* w5 ~3 J' ]1 a8 e
75f70fadb8e6110000      mov     eax,11E6h; v" J1 G& ?( @/ Y
75f70fb2 ba0003fe7f      mov    edx,offset SharedUserData!SystemCallStub (7ffe0300)
) F! Q9 t, t& L" ~* w' {' K' |75f70fb7 ff12           call   dword ptr [edx]
8 J* `) Z3 R9 {3 Y7 n6 z0 L$ z75f70fb9 c3             ret
+ v) b& J; |! Y8 v( C& ^         其中11E6是NtUserLockWorkStation的服务号(ShadowSSDT中0x01E6的服务),通过Xuetr可以看到:, H& v- w$ |. S5 t. n3 ^
         这样,在触发漏洞前合理布局寄存器内容,用函数在系统服务(SSDT / Shadow SSDT)中服务号填充EAX寄存器,然后让EIP跳转到对应的地方去执行,就可以调用指定的函数了。但是也存在很大的局限性:仅仅工作于x86 Windows上;几乎无法调用有参数的函数。' |7 |( s' ~$ T; L; f4 F8 R: a
      
  p: R1 U9 p" g) M! U0 ]6 D0 W 3 L& t- c  \  x$ R, H
  64位Windows系统上0x7ffe0350总是指向函数ntdll!LdrHotPatchRoutine。
6 r; t$ t7 j& R& vHotPatchBuffer结构体的定义如下:
, E1 Y  b$ c% q, x7 R  Rstruct HotPatchBuffer {+ [  @- h" D5 M) G0 h8 O
ULONG   NotSoSure01; //& 0×20000000  != 0
; h. Q3 X( ~6 c8 f0 WULONG   NotSoSure02;9 T( V+ d  L) \0 Z
USHORT  PatcherNameOffset;  // 结构体相对偏移地址$ ~6 }7 u/ ^9 Q8 F  H  i6 r
USHORT  PatcherNameLen;
4 s# J0 o1 z& f0 {6 ^; \USHORT  PatcheeNameOffset;' P; S' t# n/ A3 J
USHORT  PatcheeNameLen;
. [# n# z" C1 c2 A1 ~* ]" HUSHORT  UnknownNameOffset;
' I7 A1 H/ L& D) ?) NUSHORT  UnknownNameLen
/ _2 f, p! N* `5 V3 x};
0 n) V! I5 v; c8 {% qLdrHotPatchRoutine调用方式:0 C& ^* P) D# ~& U
void LdrHotPatchRoutine (struct *HotPatchBuffer);) f* W: h: S& }0 U0 C  R
         在触发漏洞前合理布局寄存器内容,合理填充HotPatchBuffer 结构体的内容,然后调用LdrHotPatchRoutine。  x! ?+ S1 U& s6 G% Y" H
         如果是网页挂马,可以指定从远程地址加载一个DLL文件;+ {/ G5 N3 \/ U) @3 j
         如果已经经过其他方法把DLL打包发送给受害者,执行本地加载DLL即可。) s6 U  L5 b: _* m  ~8 a% ^
         此方法通常需要HeapSpray协助布局内存数据;且需要文件共享服务器存放恶意DLL;只工作于64位系统上的32位应用程序;不适用于Windows 8(已经被修补)。
上一篇
下一篇

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

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

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

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

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

本版积分规则

快速回复 返回列表