《附录二:主要感染模块~WTR4132.tmp攻击载荷部分的逆向分析》 - By nEINEI 运行的dump的payload 就是之前提到分离出的PE文件: 在~wtr4132.tmp 被加载出运行到这里, 01656000 807C24 08 01 cmp byte ptr ss:[esp+0x8],0x1 01656005 0F85 D00B0000 jnz 01656BDB 0165600B 60 pushad 0165600C BE 00E05D01 mov esi,0x15DE000 01656011 8DBE 0030F4FF lea edi,dword ptr ds:[esi+0xFFF43000] 01656017 57 push edi 01656018 89E5 mov ebp,esp 0165601A 8D9C24 80C1FFFF lea ebx,dword ptr ss:[esp-0x3E80] 01656021 31C0 xor eax,eax 01656023 50 push eax 01656024 39DC cmp esp,ebx 01656026 ^ 75 FB jnz short 01656023 01656028 46 inc esi 01656029 46 inc esi 0165602A 53 push ebx 0165602B 68 8B441300 push 0x13448B 016560EC 8B4424 78 mov eax,dword ptr ss:[esp+0x78] 016560F0 66:C700 0004 mov word ptr ds:[eax],0x400 // 在栈中填充0x400 016560F5 83C0 02 add eax,0x2 016560F8 ^ E2 F6 loopd short 016560F0 // 运行到这里 01656369 /E9 0A070000 jmp 01656A78 0165636E |836C24 60 06 sub dword ptr ss:[esp+0x60],0x6 01656373 |E9 00070000 jmp 01656A78 01656378 |8B4C24 48 mov ecx,dword ptr ss:[esp+0x48] 0165637C |29C7 sub edi,eax 0165637E |8B7424 60 mov esi,dword ptr ss:[esp+0x60] // 修改这个条件分之 01656571 81FE FFFFFF00 cmp esi,0xFFFFFF 01656577 66:898D 98010000 mov word ptr ss:[ebp+0x198],cx 0165657E 77 16 ja short 01656596 01656580 3B5C24 4C cmp ebx,dword ptr ss:[esp+0x4C] 01656584 0F84 16050000 je 01656AA0 // 跳 0165658A 0FB603 movzx eax,byte ptr ds:[ebx] 0165658D C1E7 08 shl edi,0x8 01656590 C1E6 08 shl esi,0x8 // 寻址内存映像1521000 中开始为e8到指令,因为这些call 指令都是无效地址,通过动态的方式修复这些地址 01656AF2 47 inc edi 01656AF3 2C E8 sub al,0xE8 01656AF5 3C 01 cmp al,0x1 01656AF7 ^ 77 F7 ja short 01656AF0 01656AF9 803F 09 cmp byte ptr ds:[edi],0x9 01656AFC ^ 75 F2 jnz short 01656AF0 01656AFE 8B07 mov eax,dword ptr ds:[edi] 01656B00 8A5F 04 mov bl,byte ptr ds:[edi+0x4] // 修复方式: 01656AFE 8B07 mov eax,dword ptr ds:[edi] // 取出call 后面的偏移 01656B00 8A5F 04 mov bl,byte ptr ds:[edi+0x4] //取出call下一条指令的第一个字节opcode --》0152100A 51 push ecx ,也就是51 这个值 01656B03 66:C1E8 08 shr ax,0x8 01656B07 C1C0 10 rol eax,0x10 01656B0A 86C4 xchg ah,al 01656B0C 29F8 sub eax,edi // 偏移减去当前call指令的地址 01656B0E 80EB E8 sub bl,0xE8 01656B11 01F0 add eax,esi // esi = 当前MZ 映像的代码段地址,1521000,此时就是新的重定位地址 01656B15 83C7 05 add edi,0x5 01656B18 88D8 mov al,bl 01656B1A ^ E2 D9 loopd short 01656AF5 // 不断的找然后修复 // 例如开始的一个call 91ED1413 显然是非法地址 01521000 B8 0004B7CF mov eax,0xCFB70400 01521005 E8 09049B90 call 91ED1413 // 找到这里 0152100A 51 push ecx 0152100B 8365 F0 00 and dword ptr ss:[ebp-0x10],0x0 0152100F 56 push esi // 修改后, 01521000 B8 0004B7CF mov eax,0xCFB70400 01521005 E8 8A9B0400 call 0156AB94 // 调整为一个有效的地址 0152100A 51 push ecx 0152100B 8365 F0 00 and dword ptr ss:[ebp-0x10],0x0 0152100F 56 push esi 01521010 8B75 08 mov esi,dword ptr ss:[ebp+0x8] 但这个循环请注意,是一个没有退出条件的无条件循环,直到 01656AF0 > 8A07 mov al,byte ptr ds:[edi] ; edi //超出了映像的最大值,访问越界而退出。 // skip to here. forcing exit the big loop. 01656B1C 8DBE 00001300 lea edi,dword ptr ds:[esi+0x130000] 01656B22 8B07 mov eax,dword ptr ds:[edi] 01656B24 09C0 or eax,eax 01656B26 74 45 je short 01656B6D 01656B28 8B5F 04 mov ebx,dword ptr ds:[edi+0x4] 01656B2B 8D8430 98621300 lea eax,dword ptr ds:[eax+esi+0x136298] 01656B32 01F3 add ebx,esi 01656B34 50 push eax 01656B35 83C7 08 add edi,0x8 01656B38 FF96 EC631300 call dword ptr ds:[esi+0x1363EC] ; kernel32.LoadLibraryA // 这似乎说明当我们脱离了案例发生的时间分析,程序里面可能存在超过这段时间出判断不会引发到真正的执行流程,至此不能完全的分析获得。 通过静态分析可知, 基本信息: .rsrc 节里面含有非常丰富的内容: RCData: 201 - 加密数据 ,存储的是MrxCLs.sys 驱动,代码注入功能 202 - 加密数据 ,存储一个dll 文件,使用的step7中 203 - 加密数据,存储一个CAB 文件,包含非常类似202的内容,通过SQL执行来加载 205 - 不同的一段加密数据,很短,存储配置信息,主要是针对MrxCLs.sys 208 - 加密数据, 替换step7项目的一个dll 209 - 0x18字节长度的数据, 创建在“%windir\help\winmic.fts%” 210 - 加密数据, 一个PE文件,注入时会用到 221 - 加密数据,包含漏洞Ms08-067 222 - 加密数据,包含漏洞MS10-067 240 - 长度是0x104a,仅在头部95以内包含数据,存储的是.lnk文件,插入u时感染用的 241 - PE文件,明文存储的,这一点想不明白为什么时明文存储, WTR4141.tmp - 签名了Realtek 242 - 加密数据,存储 MrxNet.sys,boot型驱动,功能是隐藏lnk文件的,及代码注入,把stuxnet注入到其他进程(把oem7a.pnf 注入services.exe 和s7tgtopx.exe 和CCProjectMgr.exe, oem7m.png 注入explorer.exe) 250 - 加密数据,存储提权漏洞win32k.sys 这个dll导出函数很多, export 1 - 开始启动u 盘感染的例程,也是启动rpc 服务,在p2p的通信部分。 export2 - hooks api ,主要用在step 7 感染部分 export4 - 初始化export 18 , 从系统里面移除stuxnet export5 - 检查MrxCls.sys 是否安装 export6 - 返回一定数量的线程 export7 - 简单的跳到6,不清楚是否用来保留一些能力使用 export9 - 从感染的step 7项目中,执行新的stuxnet 版本 export10 - 类似9 export14 - 主要的一个wrapper ,在感染step7中用到的 export15 - 初始化入口函数 export16 - 负责安装例程 export17 - 替换 step 7 dll 感染PLC export18 - 从系统里面移除stuxnet,(恶意的step 7 dll , 驱动MrxCls.sys and MrxNet.sys , oem7A.PNF , mdmeric3.pnf , mdmcpq3.pnf(stuxnet 的配置文件) ) export19 - 移动设备感染例程 export22 - 包含所有的网络传播例程 export24 - 检查系统是否连接到internet , 执行dns 请求在2个domains (默认是 windowsupdate.com , msn.com) 和 更新配置数据及状态 export27 - 包含rpc部分代码 export28 - 包含c&c 服务 export29 - 同28 export31 - 和9很类似的 export32 类似export1,除了不检查事件信号在移动设备感染 // 很怪的一个段延迟返回代码,这个sleep总共要延迟60秒才返回给调用者模块handle. HMODULE __cdecl sub_10044D7E(LPCWSTR lpModuleName) { DWORD v1; // esi HMODULE result; // eax v1 = 0x3E8; do { Sleep(v1); result = GetModuleHandleW(lpModuleName); v1 += 1000; } while ( v1 <= 0xEA60 && !result ); return result; }