Fickling安全工具因“内置模块”盲区导致检测绕过漏洞分析

本文详细分析了Fickling安全工具中的一个高危漏洞(CVE-2026-22612)。该漏洞源于工具在将Pickle字节码转换为AST时,未为来自"builtins"模块的导入生成相应的AST节点,导致安全扫描器无法识别利用内置模块的危险函数(如`__import__`)的攻击载荷,从而造成检测绕过。

漏洞概述

Fickling 是一个用于分析Python pickle文件安全性的工具。其工作流程为:Pickle字节码 -> 抽象语法树(AST) -> 安全分析。

漏洞详情

问题根源

在从字节码生成AST的阶段,Fickling的代码(fickling/fickling/fickle.py)会特意跳过对 __builtin____builtins__builtins 模块的导入节点生成:

1
2
3
if module in ("__builtin__", "__builtins__", "builtins"):
    # no need to emit an import for builtins!
    pass

然而,在安全分析规则(fickling/fickling/analysis.py)中,这些模块被明确标记为不安全:

1
2
3
4
5
UNSAFE_MODULES = {
    "__builtin__": "This module contains dangerous functions that can execute arbitrary code.",
    "__builtins__": "This module contains dangerous functions that can execute arbitrary code.",
    "builtins": "This module contains dangerous functions that can execute arbitrary code.",
}

由于没有为builtins生成导入节点,安全扫描器对此类导入“视而不见”,导致检测被绕过。

攻击载荷示例

攻击者可以构造一个恶意的pickle文件,利用builtins.__import__函数导入os模块并执行系统命令。由于分析器看不到builtins的导入,攻击链被解析为以下看似无害的AST表示:

1
2
3
4
5
6
7
_var0 = __import__('os')
_var1 = getattr(_var0, 'system')
_var2 = _var1('whoami')
_var3 = Exception()
_var4 = _var3
_var4.__setstate__({'rce_status': _var2})
result0 = _var4

攻击载荷还通过使用BUILD操作码更新对象内部状态,制造数据流依赖,欺骗了工具中检测“未使用变量”的启发式分析,最终导致恶意payload被错误地归类为 LIKELY_SAFE(可能安全)。

修复方案

确保在生成AST时,为来自builtins等内置模块的危险函数(如__import__)生成相应的导入节点,以便安全分析能够正确识别和标记。

受影响版本

  • Fickling <= 0.1.6

已修复版本

  • Fickling 0.1.7

参考信息

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计