调试恶意dll注册的windows服务
本帖最后由 Payload_82 于 2024-4-30 19:09 编辑好久不分析,进来水个贴。。。
看到一个国外厂商发了报告,其中的样本为dll,是注册系统服务后运行的样本。于是尝试一番找到了调试的方法,记录和分享一下。
报告链接:https://blog.talosintelligence.com/tinyturla-next-generation/
由于dll文件无法独立运行,必须依赖宿主进程,因此需要使用 svchost.exe 承载这个样本dll。经过查看各位前辈的经验以及书籍资料。总结调试过程如下。
# 1. 创建系统服务
编写程序利用 Win32 API 创建系统服务,可以指定服务组名称,用 `sc` 创建服务似乎无法指定服务组名称。代码如下,注意编译为与调试样本相匹配的版本:
```cpp
#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小节 服务
(https://blog.51cto.com/u_15060540/3888919)
(https://blog.51cto.com/u_15060540/3888921)
[使用Windbg&OllyDbg从头调试windows服务](https://bbs.kanxue.com/thread-229643.htm)
[[原创]记录自己调试windows服务的操作](https://bbs.kanxue.com/thread-271099.htm)
[简述:ServiceMain主函数的动态调试](https://www.52pojie.cn/forum.php?mod=viewthread&tid=593454&page=1&extra=#pid15594667)
样本(解压密码 52pojie):
佩服技术大佬 值得学习学习哦 优秀,值得学习 大佬优秀 优秀,学习学习 学习学习,疯狂内卷 优秀的大佬,学习学习
页:
[1]