Skip to main content

反射式PE加载

CobaltStrike 的 Beacon,实际上是一个 DLL。Shellcode 形式的 Beacon,是补丁后的 DLL 文件。通过巧妙的补丁,Beacon 可以实现像 Shellcode 一般的位置独立。我们分别生成 DLL 与 RAW 格式的载荷,进行对比:

DLL 格式的 Beacon,符合典型的 PE 文件格式。

image.png

对于 Shellcode 格式的 Beacon,我们发现其实际上是个补丁后的 DLL 文件,因为其格式符合 PE 格式标准

image.png

我们甚至能解析出导出函数 ReflectiveLoader。

image.png

那么,补丁了哪些地方呢?我们仔细对比一下这 2 个文件的 DOS 头,我们会发现 Shellcode 格式的 Beacon(右边) 虽然大体上符合 PE 格式标准,但 DOS 头是补丁过的。

image.png

对于 PE 文件,因为 DOS 头并非代码区,所以并不该被解析成机器码执行。因此 DLL 文件的 DOS 头如果被强行解释成汇编指令,代码看起来没有什么实际意义。而右图的 DOS 头被补丁成了精心设计的代码,我们来解读一下:

4D 5A					pop r10				# PE Magic Bytes,同时与下面的指令共同平衡栈	
41 52					push r10			# 平衡栈 						
55 						push rbp			# 设置栈帧
48 89 E5 				mov rbp, rsp		
48 81 EC 20 00 00 00 	sub rsp,0x20		
48 8D 1D EA FF FF FF 	lea rbx, [rip-0x16]	# 前移0x16字节从而获得Shellcode地址
48 89 DF 				mov rdi,rbx			
48 81 C3 F4 5F 01 00 	add rbx, 0x15ff4	# 通过硬编码偏移调用ReflectiveLoader导出函数
FF D3 					call rbx
41 B8 F0 B5 A2 56 		mov r8d,0x56a2b5f0	# 调用 DllMain函数
68 04 00 00 00 			push 4
5A 						pop rdx
48 89 F9 				mov rcx, rdi
FF D0 					call rax

 

反射式加载



膨胀式加载