第 1 章 总览:内网安全、EDR 与主机防御 ················ 1
1.1 复杂问题的简单起源 ······························1
1.2 EDR 与主机入侵检测与防御 ····················2
1.3 针对内网的攻击 ····································4
1.4 零信任的思想 ·······································7
1.5 纵深防御的设计 ····································8
1.6 防御的优先顺序 ····································9
模块执行防御篇
第 2 章 模块执行防御的设计思想 ··································· 13
2.1 执行与模块执行 ·································· 13
2.1.1 初始执行 ·································· 13
2.1.2 原生执行与解释执行 ··················· 14
2.1.3 模块执行的重要性 ······················ 15
2.2 模块的公开检验措施 ···························· 16
2.2.1 Windows 的可执行文件格式 ·········· 16
2.2.2 可执行模块的签名 ······················ 17
2.2.3 恶意代码的特征扫描 ··················· 22
2.3 模块的执行防御方案设计 ······················ 24
2.3.1 模块执行防御的功能设计 ············· 25
2.3.2 模块执行防御的技术选择 ············· 28
2.4 小结与练习 29
第 3 章 微过滤器驱动与模块执行防御 ······················· 31
3.1 微过滤器处理文件操作 ························· 31
3.1.1 理解微过滤器框架 ······················ 32
3.1.2 分页写入与非分页写入 ················ 33
3.1.3 请求前回调函数编写的基本模板 ···· 35
3.1.4 对生成文件操作的前回调函数的处理 ······································ 37
3.2 写文件操作处理的实现 ························· 39
3.2.1 前置条件检查和获取文件对象 ······· 39
3.2.2 判断文件是否为 PE 文件 ·············· 42
3.2.3 获取写缓冲内容 ························· 44
3.2.4 根据写缓冲内容决定处理方式 ······· 46
3.2.5 写操作的后处理 ························· 48
3.3 利用微过滤器捕获文件的改名操作 ·········· 51
3.3.1 在设置请求的前回调函数中发现文件改名 ································ 51
3.3.2 在文件改名的后回调函数中调用安全函数 ································ 54
3.3.3 文件改名的后回调安全函数的处理 · 56
3.3.4 关于文件的删除 ························· 57
3.4 小结与练习 58
第 4 章 防御方案的设计与集成 ································ 59
4.1 可疑库的设计 ····································· 59
4.1.1 可疑库的数据结构设计 ················ 59
4.1.2 可疑库的查找 ···························· 62
4.1.3 可疑路径的增加 ························· 64
4.1.4 可疑路径的删除和移动 ················ 66
4.2 可疑库的运用集成 ······························· 70
4.2.1 如何在微过滤器中获取路径 ·········· 70
4.2.2 在微过滤器中拦截可执行模块加载 · 72
4.2.3 最终演示效果 ···························· 75
4.3 小结与练习 78
第 5 章 方案漏洞分析与利用 ···················· 79
5.1 漏洞分析的基本原则 ···························· 79
5.1.1 尽量明确需求 ···························· 79
5.1.2 持续进行漏洞分析 ······················ 81
5.1.3 漏洞的分而治之 ························· 83
5.2 漏洞分析的基本方法 ···························· 85
5.2.1 设计漏洞分析的方法 ··················· 85
5.2.2 技术漏洞的分析方法 ··················· 88
5.2.3 实现漏洞的分析方法 ··················· 91
5.3 实现漏洞分析的具体过程 ······················ 92
5.3.1 实现漏洞分析的单位和起点 ·········· 92
5.3.2 代码风险标注 ···························· 93
5.3.3 函数风险标注 ···························· 95
5.3.4 风险点的关联展开 ······················ 98
5.4 漏洞利用与测试 ·································101
5.4.1 盘符与路径漏洞 ························102
5.4.2 内存映射读写漏洞 ·····················103
5.4.3 事务操作漏洞 ···························104
5.5 事务操作漏洞的利用 ···························106
5.5.1 本利用的编程原理 ·····················106
5.5.2 本利用的代码实现 ·····················107
5.5.3 实测效果和评估 ························110
5.6 小结与练习 ·······································112
第 6 章 漏洞修补:兼容事务的删除处理 ···················113
6.1 使用上下文记录文件是否被删除 ············113
6.1.1 事务操作与文件删除 ··················113
6.1.2 从生成操作中开始处理 ···············114
6.1.3 在微过滤器中使用流上下文 ·········116
6.1.4 设置操作中删除的处理 ···············119
6.2 利用事务上下文中的链表跟踪删除 ·········121
6.2.1 处理清理:删除的时机 ···············121
6.2.2 创建和获取事务上下文 ···············126
6.2.3 上下文及事务回调的注册 ············129
6.2.4 流上下文的结构和删除链表的实现 131
6.2.5 删除的最后处理 ························133
6.3 判断文件是否已删除 ···························134
6.3.1 利用获取对象 ID 判断文件是否已删除 ············134
6.3.2 利用文件 ID 判断文件是否已删除 ·137
6.3.3 如何构建文件 ID 串 ···················139
6.3.4 如何从文件过滤参数获得文件 ID ··140
6.3.5 获得卷全局标识符的方法 ············142
6.4 小结与练习 ·······································144
脚本执行防御篇
第 7 章 微过滤器实现的工具文件脚本防御 ··············· 146
7.1 为什么以及如何考虑脚本防御 ···············146
7.1.1 模块执行防御的不足 ··················146
7.1.2 脚本、解释器的分类和本质 ·········147
7.1.3 脚本防御的三条防线 ··················149
7.2 捕获文件脚本 ····································151
7.2.1 一个“恶意”脚本的示例 ············151
7.2.2 如何监控解释器读入脚本 ············152
7.2.3 过滤 cmd.exe 读入批处理文件 ······154
7.3 文件脚本防御的演示和实际策略 ············156
7.3.1 cmd.exe 脚本防御的演示效果 ·······156
7.3.2 powershell.exe 脚本防御的演示效果 ·······································157
7.3.3 工具文件脚本防御的实际策略 ······158
7.4 小结与练习 ·······································160
第 8 章 AMSI 实现的工具脚本防御 ························ 161
8.1 AMSI 介绍 161
8.1.1 AMSI 是什么 ····························161
8.1.2 AMSI 的应用 ····························163
8.1.3 AMSI 提供者介绍 ······················166
8.2 自定义 AMSI 提供者实现 ·····················168
8.2.1 新建自定义 AMSI 提供者工程 ······168
8.2.2 AMSI 提供者的注册和注销 ··········170
8.2.3 扫描信息提取和结果返回 ············172
8.3 AMSI 实现的工具脚本防御 ···················177
8.3.1 工具脚本防御的基本思想 ············177
8.3.2 对脚本进行信息提取的实现 ·········179
8.3.3 脚本签名检查逻辑的实现 ············182
8.3.4 自实现 AMSI 提供者功能的演示 ···187
8.4 小结与练习 ·······································189
第 9 章 AMSI 防御内容型脚本与低可测攻击 ············ 191
9.1 AMSI 实现的内容型脚本防御 ················191
9.1.1 内容型脚本的防御难点 ···············191
9.1.2 AMSI 提供者与混淆过的脚本 ·······192
9.1.3 用 ASMI 提供者截获明码脚本 ······194
9.2 对恶意内容型脚本的简单判定 ···············197
9.2.1 典型的恶意脚本的行为 ···············197
9.2.2 入侵指标(IOC)与简单黑白判定 ·198
9.2.3 简单判定拦截的演示效果 ············201
9.3 AMSI 对低可测攻击的防御 ···················201
9.3.1 低可测攻击的威胁 ·····················201
9.3.2 PowerShell 实现低可测攻击的模拟演示 ··································202
9.3.3 模拟攻击环境部署 ·····················207
9.3.4 模拟攻击被拦截的演示 ···············209
9.4 小结与练习 ·······································211
第 10 章 利用 ETW 监控系统事件 ·························· 213
10.1 ETW 的基本概念 ······························213
10.1.1 什么是 ETW ···························213
10.1.2 ETW 的主要概念 ·····················214
10.1.3 查看 ETW 相关组件 ·················215
10.2 编程读取 ETW 的日志 ·······················216
10.2.1 ETW 编程涉及的主要函数 ·········216
10.2.2 设计一个通用的 ETW 日志读取函数 ····································217
10.2.3 使用 ETW 日志函数读取函数 ·····218
10.3 ETW 日志读取源码解析 ·····················219
10.3.1 ETW 会话生成 ························219
10.3.2 ETW 给会话指定提供者 ············221
10.3.3 创建消费者 ····························222
10.3.4 启动日志处理和收尾工作 ··········223
10.4 尝试读取并解析 RPC 事件 ··················224
10.4.1 找到 RPC 事件相关的提供者 ······224
10.4.2 提供者的日志格式 ···················225
10.4.3 从 EventRecordCallback 中获取日志······································227
10.4.4 写代码解析日志 ······················228
10.5 小结与练习 ······································231
第 11 章 远程过程调用(RPC)的监控和防御 ·········· 232
11.1 什么是 RPC ·····································232
11.1.1 命令序列型的脚本 ···················232
11.1.2 RPC 与内网安全 ······················232
11.1.3 如何监控与拦截 RPC ················233
11.2 RPC 攻击的实际例子 ·························234
11.2.1 RPC 的攻击行为原理 ················234
11.2.2 PsExec 工具实现的 RPC 攻击 ······235
11.2.3 实际演示 PsExec 的使用 ············236
11.3 监控所有 RPC ··································238
11.3.1 过滤正确的 ETW 日志类型 ········238
11.3.2 显示解析之后的 RPC 日志信息 ···240
11.3.3 监控所有 RPC 调用的演示 ·········241
11.4 获取 RPC 调用者的 IP 地址 ·················242
11.4.1 从 SMB 相关日志获得调用者网络地址 ··································242
11.4.2 捕获和解析 SMB 日志的代码实现 245
11.4.3 从 SMB 日志数据中提取 IP 地址 ·246
11.5 监控 PsExec 调用的关键 RPC 接口 ········250
11.5.1 通过关联打印 RPC 日志信息 ······250
11.5.2 解决管道别名的问题 ················253
11.5.3 监控外部机器 RPC 调用的实例演示 ·····································254
11.6 利用 WFP 引擎进行 PRC 过滤 ··············256
11.6.1 利用 WFP 添加 PRC 接口过滤 ·····256
11.6.2 打开 WFP 引擎并指定要阻止的接口 ·····································259
11.6.3 过滤指定的 IP 地址 ··················260
11.7 小结与练习 ······································261
第 12 章 软件漏洞利用与文件行为防御 ··················· 263
12.1 软件漏洞的利用 ·······························263
12.1.1 模块、脚本执行防御的不足 ·······263
12.1.2 及时更新防御软硬件漏洞 ··········264
12.1.3 从执行流检查到行为防御 ··········265
12.2 主要的恶意行为 ·······························267
12.2.1 导致恶意行为的恶意目标 ··········267
12.2.2 文件和磁盘、注册表行为 ··········268
12.2.3 网络、跨进程和系统调用行为 ····270
12.3 利用微过滤器监控和拦截文件行为 ·······273
12.3.1 制定软件合理行为规则 ·············273
12.3.2 实现文件写打开监控和拦截 ·······274
12.3.3 实现可配置的规则库 ················278
12.4 小结与练习 ······································281
附录 A 开发工具准备、环境部署与 HelloWorld 示例 · 282
A.1 下载安装 Visual Studio 2022 ··················282
A.2 安装 Windows SDK ····························283
A.3 安装 Windows WDK ···························284
A.4 安装 VMware 及 Windows 11 虚拟机 ·······284
A.5 设置双机调试 ···································289
附录 B HelloWorld 示例 ······································ 293
B.1 创建一个驱动 ···································293
B.2 编写驱动代码 ···································294
B.3 编译并部署驱动 ································296
B.4 调试驱动 ··299
附录 C 随书源码说明 ·· 302
C.1 如何使用源码 ···································302
C.2 整体目录和编译方法 ··························302
C.3 章节示例到源码的索引 ·······················303