技术博客 > 正文

漏洞分析 | LangChain代码注入漏洞(CVE-2023- 36281)

2024-03-11

漏洞概述
LangChain是一个 LLM 编程框架,通过可组合性使用LLM构建应用程序。LangChain 0.0.171版本存在代码注入漏洞,远程攻击者可以通过load_prompt函数的JSON文件来执行任意代码。该漏洞与subclasses或template有关。

受影响版本
0.0.171 =< LangChain < 0.0.312

漏洞分析
该漏洞的根本原因是服务端在接收用户输入或用户可控参数后,未作处理或未进行严格过滤,将用户的输入直接拼接到模板中进行渲染,造成模板注入攻击。该漏洞是利用python的jinja2框架,根据官方补丁发现漏洞函数jinja2_formatter(),在该函数中增加了一段安全告警,指出jinja2模板并不具备沙盒保护机制,可能导致任意Python代码的执行。

三度蝉联!网宿科技再获2019行业影响力品牌等双殊荣

该函数使用jinja2格式化模板,调用render方法并传入关键字参数对模板进行渲染,最后返回渲染后的字符串。下一步寻找该函数的调用位置:

三度蝉联!网宿科技再获2019行业影响力品牌等双殊荣

DEFAULT_FORMATTER_MAPPING字典表示了不同的格式化方式对应的格式化函数,jinja2对应的格式化函数是jinja2_formatter。接着找到在哪里用到了该字典:

三度蝉联!网宿科技再获2019行业影响力品牌等双殊荣

该format函数在PromptTemplate提示模板工具类中,将输入的关键字参数传递给prompt模板以格式化字符串,使用DEFAULT_FORMATTER_MAPPING中与template_format对应的格式化函数处理模板字符串。下一步找到PromptTemplate类的利用点,根据漏洞描述,攻击者通过load_prompt函数的JSON文件来执行任意代码。

三度蝉联!网宿科技再获2019行业影响力品牌等双殊荣

先来分析下load_prompt加载提示信息,try_load_from_hub 是尝试从给定的路径远程加载文件,但是因为我们是加载本地文件,所以接下会跳转到 _load_prompt_from_file:

三度蝉联!网宿科技再获2019行业影响力品牌等双殊荣

从文件中加载提示模板,根据文件的后缀名来确定文件类型,不同的文件类型使用不同的函数加载配置,最后将加载到的配置传递给load_prompt_from_config函数,下一步跳到load_prompt_from_config函数:

三度蝉联!网宿科技再获2019行业影响力品牌等双殊荣

load_prompt_from_config函数是从配置字典中加载提示,可能是包含各种数据或者文件,最后跳转到_load_prompt:

三度蝉联!网宿科技再获2019行业影响力品牌等双殊荣

从配置文件中加载具体的提示模板,并返回了一个PromptTemplate对象,与前面的PromptTemplate 类关联起来。其实漏洞利用的过程可以分为三步:

加载提示模板load_prompt
对加载的模板格式化format
使用jinja2格式化模板,对模板进行渲染
漏洞复现
Langchain可以加载一个json文件:

三度蝉联!网宿科技再获2019行业影响力品牌等双殊荣

'load_prompt’使用jinja2连接提示。由于在jinja2中是可以直接访问python的一些对象及其方法的,所以可以通过构造继承链来执行一些操作,写入一些恶意payload,加载json文件时触发模板注入attack_prompt.json。

三度蝉联!网宿科技再获2019行业影响力品牌等双殊荣

获取subprocess.popen在每个python环境中的不同索引。先通过class获取字典对象所属的类,再通过 base(bases[0])拿到基类,然后使用subclasses()获取子类列表,在子类列表中直接寻找可以利用的类。

三度蝉联!网宿科技再获2019行业影响力品牌等双殊荣

复现结果:

三度蝉联!网宿科技再获2019行业影响力品牌等双殊荣

修复方案
建议您更新当前系统或软件至最新版,完成漏洞的修复。

产品支持
网宿云 WAF 已第一时间支持对该漏洞利用攻击的防护,并持续挖掘分析其他变种攻击方式和各类组件漏洞,第一时间上线防护规则,缩短防护“空窗期”。

本文内容的版权持有者为网宿科技股份有限公司(“网宿科技”),未经许可,不得转载。