奇安信Z-Team技术博客

技术源于分享,但不止于分享

0%

利用代码审计突破网络隔离

背景

​ 一次红队项目中,通过反序列化拿下入口点webshell,经过信息收集发现该机器在dmz区域,且c段内只有一台机器,猜测应该是防火墙做了连接限制,如果突破不了dmz区域,这个点就毫无作用。后续对webshell进行本机信息收集,发现了一个感兴趣的进程”b*agent.exe”,通过检索该进程配置文件定位到该agent服务端,经过测试连接,竟然能直接跨网段访问到it运维人员用于监控网络资产的设备主页,从设备的用途上可以分析出大概率这台设备的ACL很好,经过坚持不懈的努力成功登陆(不要问,问就是弱口令),通过监控面板看到了很多其他网段的关键主机和设备,如果能打下来这个监控设备的点,就能突破网络隔离,去探索新世界了!

​ 黑盒测过没发现能直接打死的漏洞,只能走上找寻源码的不归路。通过fofa、google搜了下,公网用的还不少,但打旁站或者供应商成本过于大,结合在供应商主页找到了设备的系统名称,拿着关键字最后在某盘找到了几套与目标版本比较近的安装包 :)

源码

​ 安装完之后,导出代码到IDEA,SpringMVC的,正常走一遍代码审计流程,web.xml下没有能直接RCE的,查看第三方jar包也没有能利用的,那就看看路由吧!

任意文件读取

path参数可控,response直接返回了FileInputStream

image-20210805131225117

image-20210805132220649

入口点如下:

image-20210804120050819

​ 路由 “/testDataBaseConn” 传入传参DataBaseConfigPojo类调用testDataBaseConn方法,DataBaseConfigPojo类中定义了getter/setter方法,用来获取ip、端口、配置项等。

image-20210804121402518

testDataBaseConn 方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//DataBaseConfigPojo实体类,获得整个url以及ip、端口的getter/setter等
private void testDataBaseConn(DataBaseConfigPojo dbConfPojo) throws Exception {
//初始化数据库连接
Connection t_conn = null;
Statement t_stmt = null;

try {
//t_url是数据库连接的格式,替换ip、端口、名称到t_url
//这里的t_url我们就可以控制他的连接ip、端口、配置项了
String t_url = dbConfPojo.getUrlTemplate().replace("{0}", dbConfPojo.getIp()).replace("{1}", dbConfPojo.getPort()).replace("{2}", dbConfPojo.getName());
Class.forName(dbConfPojo.getDriver());
S_LOGGER.info("Successfully download JDBC!");
//使用t_url的内容连接数据库,触发漏洞
t_conn = DriverManager.getConnection(t_url, dbConfPojo.getUser(), dbConfPojo.getPassword());
S_LOGGER.info("Successfully connect to DB!");
t_stmt = t_conn.createStatement();
t_stmt.executeQuery("Select count(*) from " + dbConfPojo.getTableName());
} catch (SQLException var8) {
S_LOGGER.error("testDataBaseConn", var8);
throw var8;
} finally {
t_stmt.close();
t_conn.close();
}

}

可以看到ip、host、配置项我们都可以控制,只要目标能够连接到恶意Mysql服务器就可以实现反序列化。

JDBC简介

JDBC(Java DataBase Connectivity)即Java数据库连接,是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。

一般格式:

1
jdbc://driver://host:port/database?配置name1=配置Value1&配置name2=配置Value2

漏洞原理

如果攻击者能够控制JDBC连接设置项,那么就可以通过设置其指向恶意MySQL服务器进行ObjectInputStream.readObject()的反序列化攻击从而RCE。

具体点说,就是通过JDBC连接MySQL服务端时,会有几个内置的SQL查询语句要执行,其中两个查询的结果集在MySQL客户端被处理时会调用ObjectInputStream.readObject()进行反序列化操作。如果攻击者搭建恶意MySQL服务器来控制这两个查询的结果集,并且攻击者可以控制JDBC连接设置项,那么就能触发MySQL JDBC客户端反序列化漏洞。

可被利用的两条查询语句:

  • SHOW SESSION STATUS
  • SHOW COLLATION

说通俗点,就是在目标可以连接到恶意MySQL服务器的前提下,host、post、配置项可控,就可以触发Mysql反序列化。

漏洞范围

mysql-connector-java < 5.1.49

mysql-connector-java-6.x

mysql-connector-java < 8.0.20

使用工具

​ 恶意Mysql服务器搭建:

漏洞复现

构造恶意Mysql服务器,以fnmsd的工具为例

1
git clone https://github.com.cnpmjs.org/fnmsd/MySQL_Fake_Server.git

修改 config.json

image-20210804134351391

启动服务

image-20210804134439332

发包,MySQL_Fake_Server通过user来选择payload,这里使用URLDNS来确定是否存在漏洞

image-20210804141942664

Dnslog有回显,现在就找个反序列化链直接打就可以了

image-20210804142021591

查看lib包,有一条CC10的链image-20210804173310667

重新配置config.json 。

image-20210804175451690

user参数修改成config.json中自定义的参数,目标出网,可利用CC10执行系统命令,直接上线cs一发入魂

image-20210804175624951

接着就可以去探索新世界了!

image-20210804175841322

总结

  1. 登陆设备

  2. 找到源码

  3. 代码审计发现Mysql反序列化

  4. 漏洞利用