几种恶意代码常用技术解析
开发环境和工具
环境:Windows10 x64 1909
开发工具和语言:VS2017
C/C++
以下内容都是debug版本
介绍
最近在分析恶意样本,对于各种恶意代码的行为特征和运行机制有了一些总结,抱着知己知彼才能百战百胜的态度,重新梳理一下分析时遇到的一些恶意代码的技术的手段,从一个病毒的释放、注入、隐藏和免杀等过程采用的思路和实现方法出发来进一步刨析这些代码的原理,在今后的分析中对于细节才能更加的得心应手,下面先介绍常见的和释放有关的手段。
单一实例运行
这个在分析的两个勒索病毒都有发现,起先会检查自己是否在运行,在开始的时候都使用了一个函数
WINAPI
CreateMutexA(
_In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性指针,可以为null
_In_ BOOL bInitialOwner, // 初始化互斥体对象的所有者
_In_opt_ LPCSTR lpName // 指向互斥体对象名称指针
);
需要注意的是,使用CreateMutex()
创建的互斥体对象名称不能与现有的事件、信号量、或者文件映射对象名称相同,否则互斥体对象会创建失败。
资源释放
很多的木马程序会使用资源释放的技术,这样可以让一些额外的DLL
、EXE
、文本和图片等文件作为资源插入到程序里面,等到程序正式运行的时候再把他们释放到本地上,这样编译出的只有一个exe文件,降低了被发现的风险。
- 关键
API
函数
// 发现资源
HRSRC
WINAPI FindResource(
_In_opt_ HMODULE hModule, // 模块名称
_In_ LPCWSTR lpName, // 指定资源名称
_In_ LPCWSTR lpType // 资源类型
);
// 获取资源大小
DWORD
WINAPI SizeofResource(
_In_opt_ HMODULE hModule,
_In_ HRSRC hResInfo
);
// 加载资源
HGLOBAL
WINAPI LoadResource(
_In_opt_ HMODULE hModule, // 模块名称
_In_ HRSRC hResInfo // 资源句柄
);
// 锁定资源字节
LPVOID
WINAPI LockResource(
_In_ HGLOBAL hResData
);
// 其它详细的函数信息可以参见MSDN文档
- 实现原理
- 通过
FindResource
定位程序里的资源,通过资源类型和资源名称来定位 - 通过
SizeofResource
获取资源的大小之后再通过LoadResource
把资源加载到程序内存中 - 最后使用
LockResource
锁定加载到内存中的资源防止程序的其它操作影响这块内存,其中返回值就是资源在进程内存中的起始地址
DLL延迟加载
DLL
延迟加载是在正式调用DLL
的时候,才会加载DLL
文件,这样在正式调用DLL
前,都是可以正常执行的,只需要在VS的开发环境设置链接器即可完成,
下面以测试程序为例:
在VS的链接器中编辑ucrtbased.dll
,重新生成
再次查看发现这个DLL
已经不见了,延迟载入成功
如果通过编码来实现,它的字段是在PE文件NT头中的DataDirectory
—>IMAGE_DIRECTORY_ARRY
,具体的编码这里就不演示了。
启动方法
按照常规的步骤在将资源中的程序释放出来后会启动它,下面是常见的几种启动方式
- 函数
WinExec
UINT
WINAPI
WinExec(
_In_ LPCSTR lpCmdLine, // 要执行的程序的命令行
_In_ UINT uCmdShow // 显示选项
);
- 函数
ShellExecute
HINSTANCE ShellExecuteW(
_In_opt_ HWND hwnd, // 父窗口句柄
_In_opt_ LPCWSTR lpOperation, // 要执行的操作:edit、explore、find、open等
_In_ LPCWSTR lpFile, // 指向shell名称空间对象
_In_opt_ LPCWSTR lpParameters,// 指向一个可执行文件
_In_opt_ LPCWSTR lpDirectory, // 指向默认操作的目录
_In_ INT nShowCmd); // 打开窗口如何显示 SW_HIDE
- 函数
CreateProcess
BOOL
WINAPI
CreateProcessW(
_In_opt_ LPCWSTR lpApplicationName, // 执行模块名可以为 NULL
_Inout_opt_ LPWSTR lpCommandLine, // 执行命令行可以为NULL
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, // 进程安全属性指针
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程安全属性指针
_In_ BOOL bInheritHandles,
_In_ DWORD dwCreationFlags, // 控制优先级和创建进程标志
_In_opt_ LPVOID lpEnvironment, // 指向新进程的环境块的指针
_In_opt_ LPCWSTR lpCurrentDirectory, // 指向进程当前目录的完整路径
_In_ LPSTARTUPINFOW lpStartupInfo, // STARTUPINFOW结构指针
_Out_ LPPROCESS_INFORMATION lpProcessInformation // PROCESS_INFORMATION结构的指针
);
使用这些API
主要就是对参数的理解,例如WinExec
和ShellExecute
函数设置位SW_HIDE
方式可以隐藏程序窗口,并且成功隐藏执行CMD
命令行的窗口。
总结
上面是罗列了几种常规的恶意代码常用手段,在分析的时候看到这些API
就应该有所警觉了,不过这是一些最基本的手段,在下一篇注入篇会继续探讨稍微有点难度的东西,总结常见的注入手段。
参考:《Windows黑客编程技术详解》、《黑客大曝光》