idiotc4t's blog
  • 关于这个博客
  • 武器设计
    • 我也不知道能不能写
    • C2手稿
      • Heap加密
      • 数据打包DataPacker
      • 真·手稿
      • 实现UML图
    • 先占个位置
  • 武器化
    • COM组件相关的武器化开发技术
    • 攻击demo的bof改造
    • Go项目反射改造
    • VulnBins的利用 (vuln driver)
  • 红队研究
    • NtQueryInformationProcess逆向
    • NetUserAdd逆向
  • 应急响应
    • WannaMine4.0专杀的一些技巧
  • 防御逃避
    • ReflectiveDLLInjection变形应用
    • Execute-Assembly实现
    • ShadowMove复现与思考
    • 载入第二个Ntdll绕Hook
    • 编译时混淆字符串&函数调用
    • 基于线程结束的EventLog绕过
    • 动态获取系统调用(syscall)号
    • 基于内存补丁的AMSI绕过
    • 基于API Hook和DLL注入的AMSI绕过
    • 基于内存补丁ETW的绕过
    • 基于断链的DLL隐藏
    • 基于HEX字符串执行的AV绕过
    • CobaltStrike Argue命令实现
    • 简单的分离免杀
    • 伪装PPID规避检测
    • 伪装命令行规避检测
    • 通过重写ring3 API函数实现免杀
    • 动态调用无导入表编译
    • 基于Registry的虚拟机检测
    • 利用杀毒软件删除任意文件
    • 反转字符串绕杀软
    • 重新加载.text节拖钩
    • x64转换层&跨位数进程注入
  • 代码与进程注入
    • Divide and Conquer
    • Clipboard Data Deliver
    • .NET Reflective Injection
    • APC Thread Hijack
    • CreateRemoteThread
    • APC Injection
    • Mapping Injection
    • Bypass Session 0 Injection
    • WhiteFile Offset Table Generate Shellcode
    • Early Bird
    • Early Bird & CreateRemoteThread
    • TLS Code Execute
    • SEH Code Execute
    • APC & NtTestAlert Code Execute
    • NtCreateSection & NtMapViewOfSection Code Execute
    • Process Hollowing
    • SetContext Hijack Thread
    • DLL Hollowing
  • 权限提升
    • 基于注册表劫持BypassUAC
    • 基于dll劫持BypassUac
    • 通过com组件BypassUAC
    • 通过复制Token提权到SYSTEM
    • 通过code&dll注入提权到SYSTEM
    • 通过伪装PPID提权到SYSTEM
    • 通过系统服务提权到SYSTEM
  • 权限维持
    • 主机特征绑定木马
    • 寻找有价值的文件
    • 获取机器安装的软件
    • 通过API添加Windows用户
    • Detours InLine Hook
    • DLL劫持
    • RID劫持
    • 自启动服务
    • 编写简单远控
    • 注册表自启动项
由 GitBook 提供支持
在本页
  • 简介
  • 查杀思路
  • LINKS

这有帮助吗?

  1. 应急响应

WannaMine4.0专杀的一些技巧

上一页NetUserAdd逆向下一页ReflectiveDLLInjection变形应用

最后更新于4年前

这有帮助吗?

简介

今年我们这破地方的卫生系统又双叒叕爆发内网病毒了,这篇文章是记录病毒清理的一个思路,主要是对踩的一些坑的记录,本文仅对木马最后的执行体做查杀,这个病毒是基于WannaCry勒索的变种,仅将最后释放的执行体做了更改。

首先我们需要看一下这个病毒的分析,由于这种病毒已经有师傅做过详尽的分析,这里直接照搬师傅的流程图。

查杀思路

病毒首先注册污点注册表释放一个随机固定单词组合的一个服务dll,然后注册一个系统服务用svchost.exe带起这个恶意dll,这个注册表键值对里会写入服务名和dll路径和服务的描述信息,这里我们可以直接读取这个键值来获取服务名。(有一说一,有些专杀通过枚举单词组合来确定服务是真的蠢。)

字符串1列表:Windows、Microsoft、Network、Remote、Function、Secure、Application

字符串2列表:Update、Time、NetBIOS、RPC、Protocol、SSDP、UPnP

字符串3列表:Service、Host、Client、Event、Manager、Helper、System

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\NetworkPlatform\Location Awareness
	BOOL bRet = EnbalePrivileges(GetCurrentProcess(), SE_DEBUG_NAME);
	if(bRet){
		printf("[+]Enbale DebugPrivileges successful\n");
	}else	{
		printf("[-]Can not Enbale DebugPrivileges successful\n");
	}
	bRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\NetworkPlatform\\Location Awareness", 0, KEY_ALL_ACCESS, &hKey);
	if(!bRet){
		printf("[+]Open Key successful\n");
	}else	{
		printf("[-]Can not Open Key successful\n");
	}
	LONG lResult = RegQueryValueExA(hKey,"LastBackup" , NULL, &dwType,
           NULL, &dwSize);
    if (lResult == ERROR_SUCCESS)
       {        
           lResult = RegQueryValueExA(hKey, "LastBackup", NULL, &dwType,
                (LPBYTE)buffer, &dwSize);
            
    }
	if(!lResult){
		printf("[+]Query Key Value successful\n");
	}else	{
		printf("[-]Can not Query Key Value successful\n");
	}

根据多次调试,跑沙箱,发现这个病毒的流程并不固定,它可能会带起各种各样的进程,如果我们不结束这些进程就无法用常规的方法删除他们,当然也可以干掉启动项,然后重启删除他们,但这样会对业务产生影响,这里使用了结束进程树的方式,结束进程树可以干掉所有由父进程带起来的子进程以及子进程的子进程。

只要我们结束了最上级进程,那它下属的所有进程都会被结束(结束进程树),这样我们就有两种思路:

  1. 通过服务名定位服务进程实例(由于这个病毒是用服务带起来的所以,本文采用这种方法)。

方法2使用QueryServiceStatusEx函数来定位服务的实例进程,需要指定查询等级为SC_STATUS_PROCESS_INFO,这样这个函数会返回一个名为SERVICE_STATUS_PROCESS的结构体,这个结构体的dwProcessId成员就是改服务实例化的进程id。

typedef struct _SERVICE_STATUS_PROCESS {
  DWORD dwServiceType;
  DWORD dwCurrentState;
  DWORD dwControlsAccepted;
  DWORD dwWin32ExitCode;
  DWORD dwServiceSpecificExitCode;
  DWORD dwCheckPoint;
  DWORD dwWaitHint;
  DWORD dwProcessId;
  DWORD dwServiceFlags;
} SERVICE_STATUS_PROCESS, *LPSERVICE_STATUS_PROCESS;

现在我们就通过windows的services api定位,代码如下:

void KillProcessTree(DWORD dwProcessId) {

    PROCESSENTRY32 pe = { 0 };
    pe.dwSize = sizeof(PROCESSENTRY32);
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (Process32First(hSnap, &pe)) {
        do {
            if (pe.th32ParentProcessID == dwProcessId)
                KillProcessTree(pe.th32ProcessID);
        } while (Process32Next(hSnap, &pe));
    }


    HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
    if (hProc) {
        TerminateProcess(hProc, 1);
        CloseHandle(hProc);
    }
}
	
	bRet = QueryServiceStatusEx(
        hService,           
        SC_STATUS_PROCESS_INFO,   
        (LPBYTE)&ssStatus,           
        sizeof(SERVICE_STATUS_PROCESS),
        &outSize);

	if(bRet){
		printf("[+]Query ServiceStatus successful\n");
	}else	{
		printf("[-]Can not Query ServiceStatus successful\n");
	}
	if(ssStatus.dwProcessId!=0){
		KillProcessTree(ssStatus.dwProcessId);
	}

	bRet = DeleteService(hService);

最后就是简简单单的删文件删注册表删服务了。


	bRet = DeleteService(hService);
	if(bRet){
		printf("[+]Delete Service successful\n");
	}else	{
		printf("[-]Can not Delete Service successful\n");
	}

	printf("[*]Deleting malware file ......\n");
	char ServiceDllPath[MAX_PATH]={0};
	memcpy(ServiceDllPath,buffer,strlen(buffer));
	sprintf_s(buffer, "del %s /Q /F\n", ServiceDllPath);
    system(buffer);
	for (size_t i = 0; i < sizeof(strings) / MAX_PATH; i++)
    {
          sprintf_s(buffer, "del %s /Q /F\n", strings[i]);
          system(buffer);
    }
	printf("[+]Delete malware file successful!\n");
	RegCloseKey(hKey);
	CloseServiceHandle(hSCM);
	CloseServiceHandle(hService);

LINKS

定位其中一个进程查找可结束的最上级进程,之前的时候用过类似方法(这里是服务,所有windows服务都是由services进程带起的,所以查找到父进程是services.exe就代表这个进程是可结束的最上级进程)。

fuck-eventlog
WPeace
WannaMine升级到V4.0版本,警惕中招! - FreeBuf网络安全行业门户
Logo
[原创]WannaMine4.0病毒主程序分析-软件逆向-看雪论坛-安全社区|安全招聘|bbs.pediy.com[原创]WannaMine4.0病毒主程序分析-软件逆向-看雪论坛-安全社区|安全招聘|bbs.pediy.com
Logo
流程图