注意到p神在paper发的一篇跟pgAdmin命令执行漏洞有关的文章,所以利用vulhub靶场环境复现一下
pgAdmin命令执行漏洞
简介
pgAdmin是一种开源的数据库管理工具,它用于管理和操作PostgreSQL数据库。PostgreSQL是一种功能强大的关系型数据库系统,而pgAdmin则是一个用于管理和维护这个数据库系统的图形用户界面(GUI)工具。
本文复现关于pgAdmin的两个命令执行漏洞,结合源码进行分析 源码链接
pgAdmin <= 6.16 未授权命令执行漏洞(CVE-2022-4223)
pgAdmin支持在后台设置psql、pg_dump、pg_restore等PostgreSQL数据库工具所在的基础路径,在保存设置前,用户可以执行validate_binary_path
这个API来检查路径是否合法。
这里用户传入的utility_path
拼接上可执行文件名后,直接拼接进subprocess.getoutput()
方法执行。这是一个非常简单的命令注入漏洞。而且这个API没有增加@login_required
修饰器,任意用户均可调用这个函数,导致了在/misc/validate_binary_path
路由下的未授权命令执行漏洞。
在本地搭建环境,访问5050端口是登录界面
然后我们抓包在accept头添加application/json
,成功获取token值
将获取到的session id
和csrf token
填写进去发包,并添加上执行命令
1 | POST /misc/validate_binary_path HTTP/1.1 |
payload将前面的双引号闭合后,用#
将后面代码注释掉
1 | subprocess.getoutput('"a\";id;#" --version'.format(full_path)) |
成功命令执行,返回包如下
pgAdmin <= 7.6 后台命令执行漏洞(CVE-2023-5002)
官方对于CVE-2022-4223漏洞,做了如下两个处理:
- 给
validate_binary_path
函数增加@login_required
装饰器,限制未授权的用户访问相关接口 - 使用
os.path.exists()
检查用户传入的路径是否有效
@login_required
装饰器是由Flask-Login这个第三方库提供的能力,并不存在绕过的问题,所以这个API后续就没法再无授权的情况下利用了。
对于使用os.path.exists()
检查用户传入的路径是否存在,我们可以有两个绕过方法:
- 使用
../
跳转到一个存在的目录,如:/path/to/exist/folder/a";id;/../
- 通过文件上传等功能创建一个文件名中包含Payload的文件
对于第一个方法来说(注意php和python环境都行)判断文件存在时,Windows会将路径normalize后再判断,Linux会逐级判断文件夹是否存在,因此具体执行结果也会不同
Windows下返回结果为True
而Linux下返回结果为False
所以在Windows环境下我们可以直接绕过os.path.exists()
继续注入命令,但Linux下则无法实现命令执行
搭建环境,使用帐号vulhub@example.com
和密码vulhub
登录pgAdmin
然后访问工具 => 存储管理器
,创建目录";id;#
这样在与/var/lib/pgadmin/storage/vulhub_example.com/
拼接后的绝对路径,用于漏洞利用
访问设置 => 配置 =>路径
界面,然后添加上刚刚拼接的绝对路径,点击验证
1 | /var/lib/pgadmin/storage/vulhub_example.com/";id;# |
成功命令执行