好久不分析,进来水个贴。。。
看到一个国外厂商发了报告,其中的样本为dll,是注册系统服务后运行的样本。于是尝试一番找到了调试的方法,记录和分享一下。
报告链接:https://blog.talosintelligence.com/tinyturla-next-generation/
由于dll文件无法独立运行,必须依赖宿主进程,因此需要使用 svchost.exe 承载这个样本dll。经过查看各位前辈的经验以及书籍资料。总结调试过程如下。
1. 创建系统服务
编写程序利用 Win32 API 创建系统服务,可以指定服务组名称,用 sc
创建服务似乎无法指定服务组名称。代码如下,注意编译为与调试样本相匹配的版本:
#include <windows.h>
#include <stdio.h>
int main()
{
SC_HANDLE schSCManager;
SC_HANDLE schService;
// Get a handle to the SCM database.
schSCManager = OpenSCManager(
NULL, // Local computer
NULL, // ServiceActive database
SC_MANAGER_CREATE_SERVICE); // full access rights
if (NULL == schSCManager)
{
printf("OpenSCManager failed (%d)\n", GetLastError());
return 1;
}
// Create the service
schService = CreateService(
schSCManager, // SCM database
TEXT("test"), // name of service
TEXT("My Sample Service"), // service name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_SHARE_PROCESS,// service type: share service
SERVICE_DEMAND_START, // start type
SERVICE_ERROR_NORMAL, // error control type
TEXT("C:\\Windows\\System32\\svchost.exe -k MyServiceGroup"), // path to service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL // no password
);
if (schService == NULL)
{
printf("Create Service failed %d\n", GetLastError());
CloseServiceHandle(schSCManager);
return 1;
}
else printf("Service installed sccuessfully\n");
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return 0;
}
本次调试的样本是64 位的,因此编译为 x64 版本。
用管理员权限运行程序,也可以用x64dbg调试查看运行是否成功。
2. 配置注册表
2.1 创建服务组 MyServiceGroup
在注册表目录 HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost
下,创建自己的服务组,单独存放要调试的服务。
右侧创建 多字符串值 ,名称修改为 “MyServiceGroup”,也可以修改为其他自定义的名称,注意区别于系统的服务组即可。
打开新创建的 多字符串值 键,窗口中填写服务名称,例如 test
。
2.2 设置服务参数
在注册表目录 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\test\
下,注意这个服务名称 test
是步骤一和步骤二的代码中指定的名称。
创建子项 Parameters
项,右侧新建一个 可扩充字符串值 类型的键,名称为 ServiceDll
,值为 DLL 文件路径:C:\test\out.dll
3. 修改函数入口点指令
找到样本的导出函数 ServiceMain
的入口点,修改汇编指令为 EB FE
,这个指令的意思是跳转到当前位置,这样就会陷入无限循环,这个时候附加进程后再还原指令,就能从开始位置调试服务了。
注意,不能改成 CC
,会导致后续启动服务时启动失败。
使用 PE 工具找到导出函数 ServiceMain
函数的入口点,在文件中的偏移。
修改后将样本文件存放到步骤3 指定的目录下,这里是 C:\test\out.dll
。
4. 启动服务
注意:先打开 procexp64.exe
,为查看新启动的 svchost.exe
进程的 PID 做准备。
用管理员权限启动 cmd,执行 sc
命令启动服务:
5. 用调试器附加 svchost
在 procexp64.exe
查看新创建的 svchost.exe
进程,鼠标指向该进程后,弹出的浮窗中会显示该进程加载的服务组名称,找到自己创建的 MyServiceGroup
对应的 svchost.exe
进程。
管理员权限打开 x64dbg,附加进程 704,找到 out.dll
的加载基址。
6. 修改入口点
根据内存地址和导出函数 ServiceMain
的 RVA ,计算出实际的 VA 是 7FEF303DD10
,跳转到该地址。
在该地址下断点,之后再将 EB FE
修改为正确的指令 48 83
即可。
即可开始正常调试样本了。
请求C2:
参考资料
《深入解析Windows操作系统第6版上册》第4章第2小节 服务
window服务调试(一):winodw服务运行原理
window服务调试(二):调试windows服务方法
使用Windbg&OllyDbg从头调试windows服务
[原创]记录自己调试windows服务的操作
简述:ServiceMain主函数的动态调试
样本(解压密码 52pojie):
267071df79927abd1e57f57106924dd8a68e1c4ed74e7b69403cdcdf6e6a453b.7z
(123.52 KB, 下载次数: 14)