恶意代码分析系列-几种常用技术(1) – 作者:雷石安全实验室

开发环境和工具

环境: Windows10x641909

开发工具和语言: 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文档


实现原理

  1. 通过 FindResource定位程序里的资源,通过资源类型和资源名称来定位

  2. 通过 SizeofResource获取资源的大小之后再通过 LoadResource把资源加载到程序内存中

  3. 最后使用 LockResource锁定加载到内存中的资源防止程序的其它操作影响这块内存,其中返回值就是资源在进程内存中的起始地址

DLL延迟加载

DLL延迟加载是在正式调用 DLL的时候,才会加载 DLL文件,这样在正式调用 DLL前,都是可以正常执行的,只需要在VS的开发环境设置链接器即可完成,

下面以测试程序为例:

1591930350_5ee2edeed5ab7.png!small

在VS的链接器中编辑 ucrtbased.dll,重新生成

1591930306_5ee2edc224918.png!small

再次查看发现这个 DLL已经不见了,延迟载入成功

1591930468_5ee2ee64cf383.png!small

如果通过编码来实现,它的字段是在PE文件NT头中的 DataDirectory—> IMAGE_DIRECTORY_ARRY,具体的编码这里就不演示了。

1591930325_5ee2edd5e58ff.png!small

启动方法

按照常规的步骤在将资源中的程序释放出来后会启动它,下面是常见的几种启动方式


函数 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黑客编程技术详解》、《黑客大曝光》

来源:freebuf.com 2020-06-15 15:27:31 by: 雷石安全实验室

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论