zl程序教程

您现在的位置是:首页 >  系统

当前栏目

恶意代码分析实战 隐蔽的恶意代码启动 lab12-1 12-2 12-3 12-4 进程注入、进程替换、hook procmon监控os api调用不行 数据分析还是要sysmon

2023-09-14 09:11:45 时间

一、常用的隐藏技术

  1. 启动器
  2. 进程注入
  3. 进程替换
  4. Hook注入
  5. Detours
  6. APC注入

二、Lab12-1  - 创建远程线程

(winxp有效,win7我没有运行成功,why?)

1.行为分析

执行之后的效果是每隔一段时间会弹窗。
在这里插入图片描述
查看process momitor。可以发现psapi.dll被createFileMapping进内存,可能是修改了CreateFileMapping.
在这里插入图片描述

我++,没有监控到createremotethread!procmon只能监控到dll加载。如下图:

只是到线程创建和退出、dll加载!但是是不是用该dll创建远程线程,它提供的信息就不充分了!

 

在process explorer里也可以看到类似的:

 

 

 使用火绒剑监控更好!

针对恶意代码分析实战 lab 12-1的创建远程线程注入方式,我监控了下:

火绒剑报出的关键日志如下:

11:34:38:656,	explorer.exe,	2744:2156,	0,	THRD_resume,	C:\Documents and Settings\Administrator\桌面\Chapter_12L\Lab12-01.exe,	target_pid:1984 target_tid:3068 ,	0x00000000 [操作成功完成。  ],	
11:34:38:734,	Lab12-01.exe,	1984:3068,	1984,	PROC_writevm,	C:\WINDOWS\explorer.exe,	target_pid:2744 base:0x01750000 bytes_written:0x00000104 datalen:0x00000104 data:'43 3A 5C 44 6F 63 75 6D 65 6E 74 73 20 61 6E 64 ' ,	0x00000000 [操作成功完成。  ],	
11:34:38:734,	Lab12-01.exe,	1984:3068,	1984,	THRD_remote,	C:\WINDOWS\explorer.exe,	target_pid:2744 target_tid:3064 access:0x001F03FF suspended:true start_vaddr:0x7C801D7B thread_param:0xB0B5FD64 ,	0x00000000 [操作成功完成。  ],	
11:34:38:734,	Lab12-01.exe,	1984:3068,	1984,	THRD_resume,	C:\WINDOWS\explorer.exe,	target_pid:2744 target_tid:3064 ,	0x00000000 [操作成功完成。  ],	

 看来的确是可以监控进程注入!比procmon和procexp都方便!

 

 

 

这几个都是进程注入的常用api监控!

 

2.Lab12-1.exe

反汇编看下:

 

可以看到是在做进程注入!都是典型的os api!

注入到explorer.exe里是

 

 

 

 其他都是边角细节了,如下:

 

主要流程分析
1.初始化:通过LoadLibrary和GetProcAddress来获得EnumProcessModules、GetModuleBaseNameA、EnumProcesses函数地址。并拼接得到Lab12-01.dll的绝对地址
2.通过上面EnumProcesses、EnumProcessModules和GetModuleBaseName寻找explorer.exe的pid
3.通过openProcess、VirtualAllocEx和WriteProcessMemory向explorer,exe写入Lab12-01.dll的地址
4.CreateRemoteThread指定explorer.exe调用LoadLibrary,参数为吸入的Lab12-01.dll地址
在这里插入图片描述
在这里插入图片描述

3.Lab12-01.dll

字符串里面找到前面弹窗里面的字符串"Press OK to reboot"和“Practical Malware Analysis %d”
在这里插入图片描述

DLLMain
通过CreateThread调用sub_10001030函数
在这里插入图片描述
sub_10001030函数每60秒调用一次StartAddress
在这里插入图片描述
StartAddress函数创建一个弹窗
在这里插入图片描述

反编译看起来更快:

 

 

 

 

 

4.用到的数据结构和函数

获得PID数组
使用方法
https://docs.microsoft.com/en-us/windows/win32/psapi/enumerating-all-processes
BOOL EnumProcesses(
  DWORD   *lpidProcess,//指向保存pid的数组
  DWORD   cb,//数组大小
  LPDWORD lpcbNeeded//指向返回pid的数量
);
获得现有PID的句柄
HANDLE OpenProcess(
  DWORD dwDesiredAccess,
  BOOL  bInheritHandle,
  DWORD dwProcessId
);
枚举进程模块信息
BOOL EnumProcessModules(
  HANDLE  hProcess,
  HMODULE *lphModule,
  DWORD   cb,
  LPDWORD lpcbNeeded
);
获得模块的名字
DWORD GetModuleBaseNameA(
  HANDLE  hProcess,
  HMODULE hModule,
  LPSTR   lpBaseName,
  DWORD   nSize
);
为某个进程申请空间(flAllocationType都有什么用呢)
LPVOID VirtualAllocEx(
  HANDLE hProcess,
  LPVOID lpAddress,
  SIZE_T dwSize,
  DWORD  flAllocationType,
  DWORD  flProtect
);
向某个进程的某个地址写入内容
BOOL WriteProcessMemory(
  HANDLE  hProcess,
  LPVOID  lpBaseAddress,
  LPCVOID lpBuffer,
  SIZE_T  nSize,
  SIZE_T  *lpNumberOfBytesWritten
);
在另一个进程启动一个线程
HANDLE CreateRemoteThread(
  HANDLE                 hProcess,
  LPSECURITY_ATTRIBUTES  lpThreadAttributes,
  SIZE_T                 dwStackSize,
  LPTHREAD_START_ROUTINE lpStartAddress,//线程地址
  LPVOID                 lpParameter,//参数
  DWORD                  dwCreationFlags,
  LPDWORD                lpThreadId
);
创建一个线程执行虚拟地址的函数
HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES   lpThreadAttributes,
  SIZE_T                  dwStackSize,
  LPTHREAD_START_ROUTINE  lpStartAddress,
  __drv_aliasesMem LPVOID lpParameter,
  DWORD                   dwCreationFlags,
  LPDWORD                 lpThreadId
);
 

5. 远程线程注入流程

1.EnumProcesses得到所有进程PID。遍历PID,EnumProcessModules和GetModuleBaseName得到进程文件名
2.OpenProcess打开目标进程
3.VirtualAllocEx在目标进程开辟一块空间用于写入hack.dll
4.WriteProcessMemory向目标进程写入hack.dll的绝对路径
5.CreateRemoteThread指定线程地址为LoadLibraryA,参数为前面开辟的地址

三、Lab12-2 - 进程替换、Lab12-3

1.行为分析

整体功能:进程替换svchost,做键盘记录器,替换的shellcode是xor加密的资源文件,因此解密的话需要使用xor。

 

 比较下dll加载:

正常的svchost:

 

恶意的:

 

 貌似都没有看到本质的差别,都是正常的dll。

 

没有对注册表进行修改
先关注进程线程操作,发现程序还启动了一个svchost.exe进程
在这里插入图片描述
接下来关注一下文件操作,有没有对svchost.exe进行修改或者注入。确实有一些操作但是不能确定
在这里插入图片描述
当前目录生成了practicalmalwareanalysis.log,保存了击键信息。猜测是击键记录器。
在这里插入图片描述

 

2.Lab12-02.exe

1.拼接字符串得到svchost.exe的系统目录
2.获取资源并解密
在这里插入图片描述
资源类型为UNICODE,名字为LOCALIZATION。大量的0x41,猜测是与0x41异或的。动态调试下断点保存资源。
在这里插入图片描述
在这里插入图片描述

使用winhex,进行解密:

 

然后就正常了:

 

 反编译下看看,可以看出是一个键盘记录器:

 

 

 

 

 

 

 


3.比较加载内存中的文件标志‘MZ’和‘PE’是否正确
4.以挂起的方式(CREATE_SUSPENDED)创建c:\WINDOWS\system32\svchost.exe。接下来应该要进程替换了。
5.新创建被挂起的进程EBX寄存器总是包含一个指向进程环境块(PEB)的数据结构,+8表示StackLimit
在这里插入图片描述
6.NtUnmapViewOfSection卸载原本进程的stack
在这里插入图片描述
7.循环将所有的节拷贝到目标进程中
8.设置CONTEXT->eax=addressOfEntryPoint
9.ResumeThread恢复进程运行,此时运行的svchost.exe实际为资源文件的PE
在这里插入图片描述

3.资源文件分析

字符串有一个文件名,还有一些键盘操作
在这里插入图片描述
设置挂钩0x0d为WH_KEYBOARD_LL
在这里插入图片描述
fn函数为保存击键信息并将消息传递
在这里插入图片描述

 

 

4.用到的一些函数和结构体

返回指向资源信息的块
HRSRC FindResourceA(
  HMODULE hModule,
  LPCSTR  lpName,//资源名字
  LPCSTR  lpType//资源类型
);
得到和资源联系的句柄
HGLOBAL LoadResource(
  HMODULE hModule,
  HRSRC   hResInfo
);
返回资源的第一个字节地址
LPVOID LockResource(
  HGLOBAL hResData
);
创建进程
BOOL CreateProcessA(
  LPCSTR                lpApplicationName,
  LPSTR                 lpCommandLine,
  LPSECURITY_ATTRIBUTES lpProcessAttributes,
  LPSECURITY_ATTRIBUTES lpThreadAttributes,
  BOOL                  bInheritHandles,
  DWORD                 dwCreationFlags,
  LPVOID                lpEnvironment,
  LPCSTR                lpCurrentDirectory,
  LPSTARTUPINFOA        lpStartupInfo,
  LPPROCESS_INFORMATION lpProcessInformation
);
创建进程的信息结构体
typedef struct _PROCESS_INFORMATION {
  HANDLE hProcess;//进程句柄
  HANDLE hThread;//线程句柄
  DWORD  dwProcessId;//PID
  DWORD  dwThreadId;//TID
} PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;
获得线程信息
BOOL GetThreadContext(
  HANDLE    hThread,
  LPCONTEXT lpContext//比较复杂的结构体包含当前线程的所有寄存器信息
);
读取进程数据
BOOL ReadProcessMemory(
  HANDLE  hProcess,//进程句柄
  LPCVOID lpBaseAddress,//要读的地址
  LPVOID  lpBuffer,//保存内容地址
  SIZE_T  nSize,//大小
  SIZE_T  *lpNumberOfBytesRead
);
写进程数据
BOOL WriteProcessMemory(
  HANDLE  hProcess,
  LPVOID  lpBaseAddress,
  LPCVOID lpBuffer,
  SIZE_T  nSize,
  SIZE_T  *lpNumberOfBytesWritten
);
unmaps进程一块内存
NTSYSAPI NTSTATUS ZwUnmapViewOfSection(
  HANDLE ProcessHandle,
  PVOID  BaseAddress
);
找到ClassName的窗体
HWND FindWindowA(
  LPCSTR lpClassName,
  LPCSTR lpWindowName//如果为0,表示搜索所有
);
HHOOK SetWindowsHookExA(
  int       idHook,
  HOOKPROC  lpfn,
  HINSTANCE hmod,
  DWORD     dwThreadId
);

5.进程替换流程

1.用挂起的方式执行进程
2.ZwUnmapViewOfSection释放指向的内存,解除内存映射
3.VirtualAlloc为恶意代码分配新的内存
4.循环将恶意代码的每个段写入受害者进程的内存空间
5.恢复受害者进程的环境,SetThreadContext函数
6.ResumeThread函数恢复执行。

 

lab12-3:

 

 

就是利用setwindowhook进行键盘记录!比12-2还简单,就是12-2解密出来的exe。

 

Lab12-4

1.行为分析

整体功能:winlogon里去createremotethread,进行注入,注入代码主要是从url去下载更新恶意文件。

开启了新进程
在这里插入图片描述

2.Lab12-04.exe

1.找到winlogon.exe的PID
在这里插入图片描述
2.提升进程权限
在这里插入图片描述

这个提权比较有意思,反汇编看下:

 

 


3.创建远程线程执行,sfc_os.dll的2号导出函数(负责Windows文件保护机制,2号为SfcTerminateWatcherThread函数禁用文件保护机制)
在这里插入图片描述
4.将wupdmgr.exe移动到%Temp%目录
在这里插入图片描述

注入后效果:

 

 我们导出该dll看下2号函数是什么鬼?

我++,啥也没有!

 看来是msdn的内部函数,而不开放。不行,必须IDA搞下:

 

 

 

 

 

 

不太容易看懂!我们看下原版:

The fourth argument is the address for the remote thread to begin execution. In this case, it points to the undocumented function sfc_os.SfcTerminateWatcherThread, which will disable Windows File Protection, allowing system files to be modified.

The remote thread was set to execute beginning at a function in sfc_os.dll, referenced by the ordinal "2" during the call to GetProcAddress.

pma12-04_sfcload

Viewing sfc_os.dll through Dependency Walker doesn't give a name for the ordinal, only an offset.

pma12-04_sfcdepwalk

However, viewing sfc_os.dll through IDA shows that the ordinal references the function SfcTerminateWatcherThread, which disables Windows File Protection.

pma12-04_sfcida==》GG,我的IDA没有!


5.释放资源到wupdmgr.exe
在这里插入图片描述
6.最后运行wupdmgr.exe
在这里插入图片描述
在这里插入图片描述

3.BIN101.bin

1.运行原版wupdmgrd.exe
2.下载http://www.practicalmalwareanalysis.com/updater.exe
3.运行updater.exe
在这里插入图片描述

总结

最近也分析了一个实际的病毒样本imnet蠕虫病毒。虽然是8年前的病毒了,但是也用到了很多病毒技术,而且加壳之后分析起来也挺麻烦的。