Tomcat漏洞详解

Tomcat可能是我们使用比较多的一个Java Web Server系统了,对于它的漏洞,个人觉得还是比较少的,但是它的弱口令问题真的让人心痛啊!来张图压压场子:

1

0x00 Tomcat 基本配置

    8005    Server Shutdown Port
    8080    HTTP/1.1 Connector Port
    8009    AJP/1.3 Connector Port

其次Tomcat 默认有许多重要的配置文件,下面我将对不同版本的这些文件做一个概述;

2

3

4

5

5

     

其他文件:

0x01 Tomcat 口令爆破

Tomcat6 conf/tomcat-user.xml

<?xml version='1.0' encoding='cp936'?>
<tomcat-users>
    <user username="admin" password="bloodzer0" roles="tomcat,role1,manager" />
</tomcat-users>

我们需要爆破tomcat manager,我们就需要知道爆破的请求时怎么样的,通过抓包发现

7

就是在头中加入了一个Authorization认证,爆破tomcat管理后台,Metasploit中集成了一个脚本: use auxiliary/scanner/http/tomcat_mgr_login,我们可以看一下这个脚本
msf auxiliary(tomcat_mgr_login) > edit
因为对ruby不是很熟悉,就不献丑了;验证是否成功是这里段代码

if result.success?
    credential_core = create_credential(credential_data)
    credential_data[:core] = credential_core
    create_credential_login(credential_data)
    print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential}" 
else
    invalidate_login(credential_data)
    vprint_error "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status}: #{result.proof})"

我这里写了2个脚本,一个脚本是生成tomcat-manager爆破的字典,另外一个是爆破脚本;会在文章最后贴出来!

tomcat7 conf/tomcat-user.xml

<?xml version='1.0' encoding='cp936'?>
<tomcat-users>
    <user username="admin" password="bloodzer0" roles="manager-gui,manager-script,manager-jmx,manager-status,admin-gui,admin-script" />
</tomcat-users>

注意9也有可能出现403,修改webapps\manager\META-INF\content.xml

<Context antiResourceLocking="false" privileged="true" >
  <!--
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
         allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
  -->
</Context
将中间注释了

这里我就用我自己写的脚本来进行爆破,会发现爆破不成功,于是找找问题,我们会发现通过 http://192.168.11.144:8080/ 这个网页点击过去登录时没有问题的,但是直接访问 http://192.168.11.144:8080/manager/html 登录就会一直不成功,是不是校验了Referer呢?我在脚本中加入Referer,发现还是爆破不成功,这是为什么呢?我们看一下Tomcat的日志
8

这下大家就明白为什么不能进行爆破了吧!那么它的验证在什么位置呢,我们根据日志报错信息去找到 conf/server.xml 文件中找到下图这一段,这就是限制错误次数的代码(大家一定不要尝试注释这段代码,因为注释以后,你会发现登录不上去了),关于这段代码大家可以看看官方文档:http://tomcat.apache.org/tomcat-7.0-doc/realm-howto.html  这个时候我们可以去看看Tomcat6中会发现 只是对Realm 中的子域进行了限制;所以针对Tomcat7.0以后的manager/html就不能进行爆破了。

9
当然也有一种情况是可以爆破的,如图:不过估计很少会有人这么配置吧,第一个参数控制错误次数,第二个参数控制锁定时间;(引发思考是不是可以用来加固Tomcat呢)
10
如果像上图这样配置,我们使用之前的爆破脚本(不用加Referer)
11
tomcat从版本7开始就有了上诉的这种验证,而且验证默认是开启的,所以7版本后的爆破大家就不要去想了,社工可以考虑;

这里放上我写的两个脚本:https://yunpan.cn/c66KAWcyj7aH3  访问密码 526a   脚本还有待完善,目前来说并发问题没有解决后期解决了或更新在github上。

0x02 Tomcat 部署WebShell
     在tomcat的管理页面  http://www.xxx.com:8080/manager/html
     有一个“war file to deploy”也就是war文件部署;上传一个包含木马的war文件点击start,这样就可以获取webshell了;相当的Deploy directory or WAR file located on server这种很少利用;
1213
题外话:构建war格式webshell
          使用myeclipse或eclipse中新建web项目,将shell放到web项目目录,导出为war格式即可;或者将新建项目中的index.jsp文件内容替换掉!

0x03 Tomcat 8009端口另用
     这一节出自以前某大牛在乌云写过一篇文章“Tomcat的8009端口AJP的利用”但是文章比较老了是13年写的,经过测试,我发现按照原文会有一些问题,所以这里重新对这篇文章进行梳理;

yum install httpd.x86_64 httpd-devel.x86_64 -y   #添加web环境

systemctl start httpd.service     #启动Web环境

firewall-cmd --permanent --add-service=http;firewall-cmd --reload  #允许外网访问测试主机80端口

yum install gcc.x86_64 gcc-c++.x86_64 -y  #编译环境(编译我们的mod_jk)

tar -zxvf tomcat-connectors-1.2.32-src.tar.gz   #下载链接:http://archive.apache.org/dist/tomcat/tomcat-connectors/ 选择对应的版本,其实在windows中也可以

cd tomcat-connectors-1.2.32-src/native/

./configure --with-apxs=/usr/bin/apxs  #在编译过程中,如果有什么问题,欢迎一起交流,我这里只是遇到了make的时候不成功;解决方案参考:http://blog.csdn.net/zxh87/article/details/8451599

vim apache-2.0/mod_jk.c  #在这里给大家说一下,快速跳到指定行是:767gg 或 767G(命令行模式下执行)

     767    s->remote_addr = r->connection->remote_ip;

     768    s->remote_port = apr_itoa(r->pool, r->connection->remote_addr->port);

         修改为

     767    s->remote_addr = r->connection->client_ip;

     768    s->remote_port = apr_itoa(r->pool, r->connection->client_addr->port);

     1036   STRNULL_FOR_NULL(r->connection->remote_ip),

         修改为

     1036   STRNULL_FOR_NULL(r->connection->client_ip),

make && make install   #执行安装

cd /etc/httpd/modules/ && ls -l   # 查看是否存在mod_jk.so,如果有就说嘛已经安装成功了

vim /etc/httpd/conf/httpd.conf    # 在配置文件最后添加如下代码,其实在新的httpd服务中,提供了一个很好的东西,就是在conf.d目录下编辑我们的东西,这样不会影响我们原来的东西,不害怕误删除,这里也推荐大家使用;

    LoadModule jk_module modules/mod_jk.so

    JkWorkersFile /etc/httpd/conf/jk_workers.properties

    JkLogFile /var/log/mod_jk.log

    JkLogLevel info

    JkMount /* ajp13

    JkMount /manager/ ajp13

    JkMount /manager/* ajp13

    JkMount /host-manager/ ajp13

    JkMount /host-manager/* ajp13

vim /etc/httpd/conf/jk_workers.properties  # 配置代码如下

    worker.list=ajp13

    worker.ajp13.type=ajp13

    worker.ajp13.host=192.168.11.144       # 这里是要目标主机的IP地址

    worker.ajp13.port=8009

    worker.ajp13.lbfactor=50

    worker.ajp13.cachesize=10

    worker.ajp13.cache_timeout=600

    worker.ajp13.socket_keepalive=1

    worker.ajp13.socket_timeout=300

重启服务,我们就可以成功了!systemctl restart httpd.service
这里说两个错误:
     访问测试机显示503:说明Tomcat 8009端口没有开放;
     其他5xx就说明:测试机的配置文件写的有问题;

效果图:
     正常访问Tomcat的8080端口:
 14
     正常访问Tomcat的8009端口:
15
     通过apache 的 mod_jk 模块利用ajp协议转发,访问我们的测试机的80端口:
16

     使用前文说到的爆破脚本(注意这里的tomcat是6.0,如果是7就不能爆破),爆破用户名密码,进入后台获取WebShell;

最后就是分析一下,这样到底是怎么实现的(利用wireshark抓包分析 ip.src == 192.168.11.128 and ip.dst == 192.168.11.144 and ajp13):
     这是直接访问时的整个数据包结构:(因为我这里是使用的虚拟机进行的实验,挥发性的RADDR是我的虚拟网卡的地址,如果有两天主机来进行测试的话,应该是Tomcat的IP地址),可以看到Code这里就是转发请求;
 17

     再看一下我们同ajp登录时的数据包:

18

     我们会发现其实跟正常的登录没有太大的区别;

     这里在贴上一张我们在部署WebShell的数据包图:
19
     第一条是请求数据包,接下来的几条都是数据包的内容;

0x04 总结
     Tomcat 是我们在选择Java Web服务器中比较多的一款,相对于其他的它的漏洞更少,经常都是出在弱口令上,但是只要管理员在设置密码时稍微注意一下,在使用现在的7、8、9等新版本,我们就可以一定程度上保护好我们的Tomcat服务器,当然万事无绝对,漏洞都是人在挖掘的!本文虽然分成了两篇,但是可以理解为就是Tomcat 在8080端口上的弱口令问题,其实关于后台的部署,那只是Tomcat的功能,不过被恶化了而已,欢迎交流!