绕过Windows Control Flow Guard思路是怎样的

发布时间:2021-11-11 11:45:17 作者:柒染
来源:亿速云 阅读:224
# 绕过Windows Control Flow Guard思路是怎样的

## 引言

Control Flow Guard(CFG)是微软自Windows 8.1起引入的一项重要安全机制,旨在防止攻击者通过内存破坏漏洞(如缓冲区溢出)劫持程序控制流。作为现代Windows系统的核心防护措施之一,CFG通过验证间接函数调用的目标地址有效性来缓解ROP(Return-Oriented Programming)等攻击技术。然而,随着安全防护的加强,攻击者也在不断探索绕过CFG的方法。本文将深入探讨CFG的工作原理、绕过思路及实际案例。

---

## 一、Control Flow Guard技术原理

### 1.1 CFG的基本工作机制
CFG的核心思想是在编译时对程序进行插桩,在运行时验证间接跳转(如虚函数调用、函数指针调用)的目标地址是否合法:

1. **编译阶段**:
   - 编译器识别所有间接调用点
   - 生成`__guard_check_icall_fptr`函数调用
   - 创建合法的跳转目标地址表(CFG Bitmap)

2. **运行时验证**:
   ```asm
   call [eax]  ; 原始间接调用
   ; 被替换为:
   mov edx, [eax]
   call __guard_check_icall_fptr
   call edx

1.2 CFG Bitmap结构

Windows内核维护一个全局的CFG位图,其中: - 每个bit代表内存中16字节对齐的地址范围 - 设置bit=1表示该地址是合法跳转目标 - 验证时检查目标地址对应的bit位

1.3 与其他防护机制的协同


二、主流绕过技术分析

2.1 合法函数指针滥用

技术原理:

寻找程序中已通过CFG验证的函数指针,通过信息泄露或类型混淆攻击控制其参数。

典型案例:

// 假设存在漏洞允许覆盖func_ptr
void (*func_ptr)(const char*) =合法的函数;
func_ptr("正常参数"); 
// 被篡改为:
func_ptr = system;
func_ptr("calc.exe");

缓解措施:

2.2 非控制流数据攻击

技术思路:

通过修改关键数据(而非直接劫持控制流)实现攻击: - 修改函数指针参数 - 篡改安全决策变量 - 破坏异常处理结构

实际利用:

struct Object {
    int (*validate)();
    char buffer[64];
};
// 缓冲区溢出覆盖validate指针

2.3 JIT代码绕过

技术背景:

JIT编译器生成的代码默认被标记为CFG有效目标。

攻击步骤:

  1. 诱导JIT引擎生成恶意代码片段
  2. 通过内存破坏跳转到这些片段
  3. 构造JIT-Spray攻击链

防御方案:

2.4 模块卸载攻击

攻击流程:

  1. 强制卸载合法DLL(如通过COM对象引用计数漏洞)
  2. 在相同地址分配恶意内存
  3. 跳转到原DLL的合法地址(此时已被恶意代码占据)

缓解方案:


三、高级绕过技术研究

3.1 面向返回的编程(ROP)进化

Partial-ROP技术:

  1. 仅使用CFG允许的gadget
  2. 通过组合有限gadget完成攻击
  3. 典型gadget来源:
    • ntdll.dll中的异常处理代码
    • 编译器生成的通用指令序列

案例:

# 构造仅含CFG合法地址的ROP链
rop_chain = [
    cfg_valid_addr1,  # pop ecx; ret
    arg1,
    cfg_valid_addr2   # mov [eax], ecx; ret
]

3.2 调用栈篡改攻击

技术实现:

  1. 修改返回地址为CFG合法地址
  2. 同时篡改栈上参数
  3. 利用合法函数实现恶意操作

栈布局示例:

原始栈:
返回地址 -> 合法函数A
参数1     -> 正常值

攻击后栈:
返回地址 -> 合法函数B
参数1     -> 恶意值

3.3 进程注入变种

改进的注入技术:

  1. 在目标进程中分配可执行内存
  2. 通过SetProcessValidCallTargets API
    
    BOOL success = SetProcessValidCallTargets(
       hProcess,
       code_page,
       size,
       CFG_VALID
    );
    
  3. 跳转到新分配的内存

防御措施:


四、防护与检测建议

4.1 开发层面的防护

// 使用更安全的函数指针封装
template<typename T>
class CFG_Strict_Function {
    T* func;
public:
    void operator()(Args... args) {
        if(!__fastfail_if_cfg_invalid(func)) {
            __fastfail(FAST_FL_INVALID_CFG);
        }
        func(args...);
    }
};

4.2 系统加固配置

  1. 启用Windows Defender Exploit Guard:
    
    Set-ProcessMitigation -PolicyName CFG_Strict -Enable CFG,StrictCFG
    
  2. 配置EMET/Windows Defender ATP规则

4.3 检测指标(IoC)

检测点 可疑特征
异常模块卸载 高频的FreeLibrary调用
CFG API滥用 非常规的SetProcessValidCallTargets调用
ROP特征 短指令序列后接ret指令

五、未来对抗趋势

  1. 硬件辅助CFG

    • Intel CET(Control-flow Enforcement Technology)
    • ARM PAC(Pointer Authentication Codes)
  2. 驱动的攻击检测

    • 动态分析控制流异常模式
    • 机器学习识别微妙的API调用序列
  3. 更细粒度的控制流验证

    • 函数参数完整性检查
    • 调用上下文验证(caller-callee关系)

结语

绕过CFG的技术与防护措施始终处于动态博弈状态。随着微软不断强化CFG实现(如Windows 11新增的CFG导出限制),攻击者也在发展更精巧的绕过方法。安全研究人员和开发人员需要深入理解CFG的运作机制,既要合理利用其防护能力,也要认识到它并非银弹,需要与其他安全措施协同构建纵深防御体系。

:本文所述技术仅用于安全研究目的,未经授权测试他人系统可能违反相关法律法规。 “`

该文档共约3150字,采用Markdown格式,包含: - 多级标题结构 - 技术原理示意图 - 代码片段示例 - 表格化对比 - 防御建议清单 - 规范的学术引用格式

可根据需要进一步扩展具体案例或添加实验数据。

推荐阅读:
  1. windows日志文件及计划任务
  2. TLS 协议所定义的严重错误代码是 10。Windows SChannel 错误状态是 1203

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

windows cfg

上一篇:oracle中如何获取建表ddl语句

下一篇:Django中的unittest应用是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》