SIDOUmed/SQL-Server-Targeted-Malware-Campaign-Investigation
GitHub: SIDOUmed/SQL-Server-Targeted-Malware-Campaign-Investigation
一份针对 SQL Server 环境的内存取证分析报告,详细剖析了多阶段恶意软件攻击的完整感染链与高级逃避技术。
Stars: 1 | Forks: 0
# 取证分析报告:MemBase.mem
## 针对 SQL Server 的恶意软件活动调查
**分析日期:** 2025年7月
**目标系统:** Windows SQL Server 环境
**内存基础:** MemBase.mem
**状态:** 已确认的高级威胁活动
**级别:** 极难(非常非常困难)
## 执行摘要
通过对 `MemBase.mem` 的内存取证分析,我们发现了一起针对 Microsoft SQL Server 基础设施的复杂多阶段恶意软件攻击活动。该攻击采用了包括反射式 PE 加载、进程注入和 AES-256-CBC 加密在内的高级技术,以逃避检测并维持持久性。
**关键发现:**
- 两个反射式 PE 加载器(`sqlagent.exe`、`conhost.exe`)
- 针对 SQL Server 的进程注入链
- 高级沙箱逃避机制
- 带有基于环境变量派生密钥的自定义加密方案
- 通过进程句柄滥用进行的多次权限提升尝试
## 攻击链概述
```
┌─────────────────────────────────────────────────────────────┐
│ INFECTION CHAIN │
├─────────────────────────────────────────────────────────────┤
│ │
│ sqlagent.exe (PID 4940) │
│ │ │
│ ├─ Reflective PE Loader │
│ ├─ Loads encrypted payload │
│ ├─ Injects into sqlservr.exe (PID 3684) │
│ │ │
│ └─ Opens handles with PROCESS_ALL_ACCESS (0x1FFFFF) │
│ ├─ conhost.exe (PID 8616) │
│ └─ winlogon.exe (PID 576) ← SYSTEM privileges │
│ │
│ sqlservr.exe (PID 3684) — Compromised Service │
│ │ │
│ ├─ Receives injected payload │
│ ├─ Enumerates processes (CreateToolhelp32Snapshot) │
│ ├─ Searches for SQLSVC_TARGET environment variable │
│ ├─ Opens target process with full access │
│ ├─ Spawns high-priority worker threads │
│ └─ Performs sandbox evasion (4.8M iterations) │
│ │
│ conhost.exe (PID 8616) — Payload Executor │
│ │ │
│ ├─ Receives PROCESS_ARCHITECTURE as argument │
│ ├─ Calls sub_7FF7E1311660() decryption routine │
│ ├─ Derives AES key from SHA-256(environment var) │
│ ├─ Decrypts 238,608 bytes of payload │
│ └─ Executes decrypted PE binary │
│ │
└─────────────────────────────────────────────────────────────┘
```
## 详细进程分析
### 1. sqlagent.exe (PID 4940) — 阶段 1 加载器
**属性:**
- 进程 ID:4940
- 父进程:sqlservr.exe (PID 652)
- 内存基址:0x7FF6AB290000
- 类型:反射式 PE 加载器
**行为:**
主加载器 `sqlagent.exe` 实现了复杂的反射式 PE 加载机制:
```
v17 = VirtualAlloc(0, size, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
if (v17) {
sub_7FF6AB292440(v17, encrypted_data, size); // Decrypt payload
// Map PE sections with proper permissions
for (each section) {
VirtualProtect(section, size,
flags & (RX|RW|RWX) ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE,
&oldProtect);
}
// Hook API functions to prevent termination
VirtualProtect(ExitProcess, 14, PAGE_EXECUTE_READWRITE, &oldProtect);
*(_WORD *)ExitProcess = 0xb8fa; // mov r8, ExitThread
*(_QWORD *)(ExitProcess+2) = (QWORD)ExitThread;
VirtualProtect(ExitProcess, 14, oldProtect, &oldProtect);
}
```
**关键技术:**
- **两阶段分配:** RW 分配 → 代码复制 → 升级为 RWX(逃避即时 EDR 检测)
- **内联 Hook:** 修补 `ExitProcess`/`TerminateProcess` 以重定向到 `ExitThread`(防止进程终止)
- **动态 API 解析:** 使用 `GetProcAddress` 隐藏导入表以对抗静态分析
### 2. sqlservr.exe (PID 3684) — 被攻陷的服务
**注入的 Payload 行为:**
注入到 `sqlservr.exe`(合法的 Microsoft SQL Server)中的 Payload 执行以下操作:
#### 进程枚举
```
CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
while (Process32NextW(&pe)) {
if (matches(pe.szExeFile, GetEnvironmentVariable("SQLSVC_TARGET"))) {
th32ProcessID = pe.th32ProcessID;
break;
}
}
```
**目标环境变量:**
- `SQLSVC_TARGET` — 要攻陷的目标进程名
- `SQLSVC_PATH` — 要注入的可执行文件路径
- `PROCESSOR_ARCHITECTURE` — 加密密钥派生输入
#### 句柄获取与权限提升
```
v33 = OpenProcess(PROCESS_ALL_ACCESS, 0, th32ProcessID);
if (!v33) {
while (!v33) {
Sleep(100);
v33 = OpenProcess(PROCESS_ALL_ACCESS, 0, th32ProcessID);
}
}
```
**严重影响:** 获取对目标进程内存的无限制读写权限。
#### 沙箱逃避机制
```
for (v31 = 4896164; v31 > 0; v31--) {
NtQueryInformationToken(TokenHandle, TokenIntegrityLevel,
&buffer, 4096, &retLen);
// No-op loop: wastes 4,896,164 iterations
// Each iteration calls a Windows API
// Total time: ~30-50 seconds depending on system
}
```
**目的:**
- 逃避具有较短执行超时的自动化恶意软件沙箱
- 模拟合法工作以规避异常检测
- 延迟执行以绕过基于时间的特征码
#### 工作线程生成
```
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)StartAddress,
NULL, 0, NULL);
SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL); // Priority: 15
SetThreadAffinityMask(hThread, 1); // Lock to CPU Core 0
v50 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)StartAddress,
NULL, 0, NULL);
SetThreadPriority(v50, THREAD_PRIORITY_TIME_CRITICAL); // Priority: 15
SetThreadAffinityMask(v50, 2); // Lock to CPU Core 1
```
**分析:** 在专用核心上执行的高优先级 CPU 密集型工作表明存在资源消耗极大的操作(加密操作、数据编码或命令执行)。
### 3. conhost.exe (PID 8616) — 阶段 2 Payload 执行器
**属性:**
- 进程 ID:8616
- 父进程:winlogon.exe (PID 576) ← 通过进程句柄伪造
- 实际生成者:sqlservr.exe
- 角色:解密与执行引擎
**解密例程:**
```
int fastcall sub_7FF7E1311660(const CHAR *lpName) {
CHAR Buffer[272];
BYTE v17[32]; // SHA-256 hash output
EVP_MD_CTX *v4 = EVP_MD_CTX_new();
if (!GetEnvironmentVariableA(lpName, Buffer, sizeof(Buffer))) {
return 0;
}
EVP_MD_CTX_new();
EVP_sha256();
EVP_DigestInit_ex(v4, EVP_sha256(), NULL);
// Hash the environment variable value
size_t len = 0;
while (Buffer[len]) len++;
EVP_DigestUpdate(v4, Buffer, len);
EVP_DigestFinal_ex(v4, v17, NULL); // v17 = SHA256(PROCESSOR_ARCHITECTURE)
EVP_MD_CTX_free(v4);
// v17 now contains the 256-bit AES key
// Derived from: SHA-256(GetEnvironmentVariable("PROCESS_ARCHITECTURE"))
return v17; // Return key to AES decryption function
}
```
**密钥派生:**
- 输入:`PROCESSOR_ARCHITECTURE` 环境变量
- 过程:SHA-256 哈希
- 输出:用于 AES-256-CBC 解密的 256 位密钥
**可能值:**
- `x64` → 密钥:`5609f728403e197bb255ef50c62aeabb1f93b09f7b7c379903440b65cd4319cb`
- `Intel64` → 密钥:`47e7b753eb7ffb5c82107a70d65e144788d5e34a2f96e1a3bcbe01292f692553`
- `AMD64` → 密钥:`558b624e3a60d3e4a393272854dbbd35c6fea3f18ee692235dcbe31be8370700`
#### AES-256-CBC 解密
```
EVP_DecryptUpdate(ctx, plaintext_buffer, &outlen,
(const unsigned char *)0x7FF7E1327AD0, // Encrypted payload
238608); // Payload size
```
**加密 Payload 详情:**
- **位置:** 偏移量 0x7FF7E1327AD0
- **大小:** 238,608 字节
- **IV:** 偏移量 0x7FF7E1327AC0(16 字节)
- **算法:** AES-256-CBC
- **密钥:** SHA-256(PROCESSOR_ARCHITECTURE)
## 通过 Volatility 提取的环境数据
### 系统信息
```
PROCESSOR_IDENTIFIER: Intel64 Family 6 Model 79 Stepping 1, GenuineIntel
PROCESSOR_LEVEL: 6
PROCESSOR_REVISION: 4f01
NUMBER_OF_PROCESSORS: 4
```
### 进程层级结构 (pstree)
```
System
└── csrss.exe (412)
└── services.exe (652)
├── sqlservr.exe (3684) ← Compromised service
│ └── sqlagent.exe (4940) ← Injected loader
├── svchost.exe (3432, 3992)
└── winlogon.exe (576) ← Parent spoofing target
└── conhost.exe (8616) ← Payload executor
```
## 攻陷技术指标 (IOCs)
### 进程级 IOCs
| 指标 | 值 | 严重程度 | 上下文 |
|-----------|-------|----------|---------|
| 进程名 | sqlagent.exe | 严重 | 阶段 1 反射式加载器 |
| 进程 ID | 4940 | 严重 | 主要感染媒介 |
| 父进程 | sqlservr.exe (652) | 严重 | 合法服务滥用 |
| 子进程 | conhost.exe (8616) | 严重 | 阶段 2 执行器 |
| 句柄类型 | PROCESS_ALL_ACCESS | 严重 | 无限制进程访问 |
| 句柄访问权限 | 0x1FFFFF | 严重 | 最大权限 |
| 目标进程 | winlogon.exe (576), conhost.exe (8616) | 严重 | 父进程伪造 |
### 内存级 IOCs
| 指标 | 值 | 详情 |
|-----------|-------|---------|
| VirtualAlloc 模式 | RW → RWX 升级 | 两阶段分配逃避 |
| Hook 目标 | ExitProcess, TerminateProcess | 内联 API Hooking |
| 解密例程 | EVP_DecryptUpdate | 基于 OpenSSL 的 AES-256-CBC |
| 加密 Payload 偏移量 | 0x7FF7E1327AD0 | 238,608 字节密文 |
| IV 偏移量 | 0x7FF7E1327AC0 | 16 字节硬编码 IV |
| 密钥派生 | SHA-256(env_var) | 二进制文件中无明文密钥 |
### 环境变量 IOCs
```
SQLSVC_TARGET — Target process name
SQLSVC_PATH — Executable path for injection
PROCESSOR_ARCHITECTURE — Encryption key source
```
### API 调用特征 IOCs
```
CreateToolhelp32Snapshot + Process32NextW // Process enumeration
OpenProcess(0x1FFFFF) // Maximum access
VirtualAlloc + VirtualProtect pattern // Memory allocation evasion
EVP_DigestInit_ex + EVP_DigestUpdate // SHA-256 hash
EVP_DecryptUpdate with 238608-byte payload // AES decryption
NtQueryInformationToken loop (4896164 iter) // Sandbox evasion
```
## MITRE ATT&CK 映射
### 已识别技术
| 战术 | 技术 | ID | 证据 |
|--------|-----------|-----|----------|
| **执行** | 命令和脚本解释器 | T1059 | 通过环境变量执行 Batch/PowerShell |
| **持久化** | 引导或登录自动启动执行 | T1547 | 滥用 SQL Server 服务进行自动执行 |
| **防御逃避** | 混淆文件或信息 | T1027 | 加密 Payload,无明文字符串 |
| **防御逃避** | 解混淆/解码文件 | T1140 | 对内嵌 Payload 进行 AES-256-CBC 解密 |
| **防御逃避** | 虚拟化/沙箱逃避 | T1497 | 480 万次迭代的 NtQueryInformationToken 循环 |
| **防御逃避** | 修改系统镜像 | T1601 | API Hooking (ExitProcess/TerminateProcess) |
| **发现** | 进程发现 | T1057 | CreateToolhelp32Snapshot 枚举 |
| **权限提升** | 访问令牌操纵 | T1134 | 进程句柄滥用,父进程伪造 |
| **权限提升** | 进程注入 | T1055 | 将反射式 PE 加载到 sqlservr.exe |
### 攻击框架
```
Kill Chain Phase MITRE Technique Evidence
─────────────────────────────────────────────────────────────────────
Initial Access [External - Pre-compromise] Not observed in dump
Execution T1547 Boot or Logon Autostart sqlservr.exe injection
Persistence T1547 + T1055 Process Injection conhost.exe spawning
Privilege Escalation T1134 Access Token Manipulation PROCESS_ALL_ACCESS
Defense Evasion T1027 + T1140 Obfuscation AES-256-CBC
Discovery T1057 Process Discovery CreateToolhelp32Snapshot
```
## 加密分析
### AES-256-CBC 配置
```
Algorithm: AES-256-CBC (256-bit key, 128-bit blocks)
Key Source: SHA-256(GetEnvironmentVariable("PROCESSOR_ARCHITECTURE"))
IV Source: Hardcoded at offset 0x7FF7E1327AC0
Payload Size: 238,608 bytes
Payload Offset: 0x7FF7E1327AD0
```
### 密钥派生过程
```
┌─────────────────────────────────────────────────┐
│ GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")│
│ ↓ │
│ "x64" (or similar) │
│ ↓ │
│ EVP_DigestInit_ex() │
│ EVP_DigestUpdate() │
│ EVP_DigestFinal_ex() │
│ ↓ │
│ SHA-256 Hash Output (32 bytes) │
│ ↓ │
│ 256-bit AES Key (No plaintext in binary) │
│ ↓ │
│ AES-256-CBC Decryption Context │
│ ↓ │
│ Decrypted PE Payload (238,608 bytes) │
└─────────────────────────────────────────────────┘
```
### 为什么这种设计有效
1. **无明文密钥存储** — 密钥在运行时动态派生
2. **环境变量耦合** — 攻击者必须知道受害者的 PROCESSOR_ARCHITECTURE
3. **SHA-256 不可逆性** — 无法从加密 Payload 逆向工程出密钥
4. **硬编码 IV** — 简化部署;对于此用例,IV 并非安全关键
## 防御建议
### 立即行动(0-24 小时)
1. **隔离 SQL Server 系统**
- 断开网络连接
- 保留内存转储和磁盘镜像
- 防止横向移动
2. **终止恶意进程**
taskkill /PID 4940 /F # sqlagent.exe
taskkill /PID 8616 /F # conhost.exe
taskkill /PID 3684 /F # sqlservr.exe (如果安全)
3. **重置 SQL Server 凭据**
- 更改所有服务账户密码
- 审查服务账户权限
- 审计最近的 SQL Server 活动日志
4. **扫描持久化机制**
- 计划任务(带有 SQLSVC_TARGET, SQLSVC_PATH)
- 被 sqlservr.exe 修改的注册表 Run 键
- DLL 注入点
### 短期缓解措施(1-7 天)
1. **EDR/XDR 部署**
告警以下行为:
- sqlservr.exe 生成 conhost.exe
- OpenProcess(0x1FFFFF) 调用
- VirtualAlloc 后跟随 VirtualProtect RW→RWX
- NtQueryInformationToken 循环 >100 万次迭代
2. **网络分段**
- 将 SQL Server 与工作站隔离
- 要求 SQL Server 服务账户使用 MFA
- 监控来自 sqlservr.exe 的出站连接
3. **应用程序白名单**
- 在 AppLocker/WDAC 中禁用 sqlagent.exe
- 限制 sqlservr.exe 生成 conhost.exe
- 强制执行代码签名要求
### 长期强化(2-4 周)
1. **系统补丁**
- 应用最新的 Windows 更新
- 将 SQL Server 更新至最新 CU/SP
- 为所有第三方组件打补丁
2. **访问控制审查**
- 对服务账户实行最小权限原则
- 删除不必要的 SYSTEM 组成员身份
- 审计所有进程创建权限
3. **检测与响应**
- 部署针对反射式 PE 加载器的 YARA 规则
- 创建针对进程注入模式的 Sigma 规则
- 建立 SQL Server 攻陷的事件响应预案
## YARA 检测规则
```
rule SQL_Server_Malware_Loader {
meta:
description = "Detects sqlagent.exe reflective PE loader"
author = "Security Team"
date = "2025-07"
severity = "CRITICAL"
strings:
// VirtualAlloc + VirtualProtect pattern
$virtualalloc = { 48 89 C7 B9 00 30 00 00 B8 04 00 00 00 }
// Hook inline signature (patches ExitProcess)
$hook = { 66 C7 04 ?? FA B8 48 89 54 ?? 02 }
// AES-256-CBC EVP functions
$evp_init = "EVP_DigestInit_ex"
$evp_update = "EVP_DigestUpdate"
$evp_final = "EVP_DigestFinal_ex"
// Environment variable references
$env_target = "SQLSVC_TARGET"
$env_path = "SQLSVC_PATH"
$env_arch = "PROCESSOR_ARCHITECTURE"
condition:
uint16(0) == 0x5a4d and (
($virtualalloc) or
($hook) or
(all of ($evp*)) or
(all of ($env*))
)
}
```
## 搜索可疑模式:
cat search_patterns.sh
#!/bin/bash
cd /home/kali/Downloads/volatility3/vad-output/ || exit
echo "[*] Recherche des patterns suspects dans les fichiers .dmp..."
echo
for dump in *.dmp; do
count=$(strings "$dump" | grep -E -c "GetProcAddress|CreateThread|OpenProcess|EVP_|SQLSVC")
```
if [ "$count" -gt 5 ]; then
echo "[+] $dump : $count matches"
fi
```
done
# ./search_patterns.sh
[+] pid.3684.vad.0x7ff8f2ff0000-0x7ff8f3080fff-1.dmp : 7 matches
[+] pid.3684.vad.0x7ff8f2ff0000-0x7ff8f3080fff-2.dmp : 7 matches
[+] pid.3684.vad.0x7ff8f2ff0000-0x7ff8f3080fff.dmp : 7 matches
[+] pid.3684.vad.0x7ff8f5110000-0x7ff8f546efff-1.dmp : 11 matches
[+] pid.3684.vad.0x7ff8f5110000-0x7ff8f546efff-2.dmp : 11 matches
[+] pid.3684.vad.0x7ff8f5110000-0x7ff8f546efff.dmp : 11 matches
[+] pid.3684.vad.0x7ff8f6160000-0x7ff8f621bfff-1.dmp : 11 matches
[+] pid.3684.vad.0x7ff8f6160000-0x7ff8f621bfff-2.dmp : 11 matches
[+] pid.3684.vad.0x7ff8f6160000-0x7ff8f621bfff.dmp : 11 matches
[+] pid.3684ad.0x7ff8f78f0000-0x7ff8f7aeffff-1.dmp : 13 matches
[+] pid.3684.vad.0x7ff8f78f0000-0x7ff8f7aeffff-2.dmp : 13 matches
[+] pid.3684.vad.0x7ff8f78f0000-0x7ff8f7aeffff.dmp : 13 matches
[2] Dérivation de la clé SHA-256...
[*] x64 → 5609f728403e197bb255ef50c62aeabb1f93b09f7b7c379903440b65cd4319cb
[*] Intel64 → 47e7b753eb7ffb5c82107a70d65e144788d5e34a2f96e1a3bcbe01292f692553
[*] AMD64 → 558b624e3a60d3e4a393272854dbbd35c6fea3f18ee692235dcbe31be8370700
[*] X86 → ee914f0378c4a89fd5c2e8e715133ff6d2512725f76ff05fbd35fd6b470f2753
[*] x86 → 13d6a668eb0789a68e20ff5b93a5fd42981d81c14f9fb6a0756a9368b8e2037e
[+] Clé dérivée (x64): 5609f728403e197bb255ef50c62aeabb1f93b09f7b7c379903440b65cd4319cb
## 结论
`MemBase.mem` 的取证分析揭示了一场利用多种高级逃避技术的**复杂、有针对性的恶意软件攻击活动**。该攻击展示了:
- **极高的复杂程度** — 自定义加密、沙箱逃避、API Hooking
- **对 Windows 内部机制的深刻理解** — 反射式加载、权限提升
- **操作安全意识** — 无明文字符串、动态密钥派生
- **持久化机制** — SQL Server 滥用、环境变量耦合
**威胁评估:严重**
攻击者已经展示了以下能力:
1. 将代码注入合法服务
2. 提升至 SYSTEM 权限
3. 逃避检测机制
4. 部署加密 Payload
**建议状态:** 将其视为高级持续性威胁 (APT) 活动。在整个基础设施范围内进行全面的威胁搜寻。
## 附录
### A. 内存地址参考
- sqlagent.exe 基址:0x7FF6AB290000
- conhost.exe 基址:0x7FF7028D0000(约)
- 加密 Payload:0x7FF7E1327AD0
- IV 位置:0x7FF7E1327AC0
- VirtualAlloc 模式:0x3000 (MEM_COMMIT | MEM_RESERVE)
- Hook 目标:ExitProcess, TerminateProcess
### B. 命令行参数
```
conhost.exe PROCESS_ARCHITECTURE
```
### C. 使用的 Volatility 命令
```
python3 vol.py -f MemBase.mem windows.pslist
python3 vol.py -f MemBase.mem windows.pstree
python3 vol.py -f MemBase.mem windows.envars
python3 vol.py -f MemBase.mem windows.vadinfo --pid 3684 --dump
python3 vol.py -f MemBase.mem windows.dumpfiles --pid 4940
python3 vol.py -f MemBase.mem windows.handles --pid 4940
python3 vol.py -f MemBase.mem windows.malfind --pid 3684
```
**分发对象:** SOC、事件响应、威胁情报
以下截图说明了取证调查的每一个步骤,包括 Volatility 分析、内存检查、恶意软件行为、进程注入、加密分析以及调查期间识别出的攻陷指标。
## 插图


















































































标签:DAST, JARM, 内存分析, 威胁情报, 安全报告, 安全测试工具, 开发者工具, 恶意软件分析, 数字取证, 端点可见性, 自动化脚本