Urahara's Blog

NSFOCUS M01N RedTeam Member, Co-founder of FormSec, security researcher, bug hunter, Red Teamer, pentester. Opinions are my own.

TOMCAT安全测试概要

23 Feb 2018 » Pentest

本文首发逢魔安全实验室技术博客

一、前言

Web安全中很重要的一个部分就是中间件的安全问题,而中间件的安全问题主要来源于两部分,一个是中间件本身由于设计缺陷而导致的安全问题,另一个就是默认配置或错误配置导致的安全风险。 本文作为逢魔安全团队中间件安全风险系列对外公开文章将详细对Tomcat的常见安全风险进行分析归纳。

二、版本管理

类似于Tomcat这种软件项目官方一般都维护了多个版本分支,一般新的产品特性会被更新在最新的大版本当中,而类似于修复bug及漏洞这种就会在旧版本的分支当中得以更新。这就允许开发人员在不破坏生产环境的情况下软件更新。

比如你正在使用的是Tomcat 5.5.26,那么你应该在5.5分支中寻找新的版本(例如5.5.27),升级到这个bug修复版本。当然如果在性能或功能特性上没有新需求时,也是不用升级到tomcat6.0的。

因此,对于Tomcat的使用者来说应该密切关注Apache Tomcat官方的安全漏洞和新版本的发布通知并进行及时升级更新。

http://tomcat.apache.org/security.html

三、运行环境

首先我们必须保证Tomcat不能以高系统权限去运行,比如Linux下的root用户和Windows下的Administrator用户或用户组。我们需要为Tomcat进程创建一个专用的用户,并为该用户提供运行所需的最低系统权限,包括我们需要根据业务需求去详细分配Tomcat涉及的安装目录和应用目录文件夹的读、写及执行的权限。这样一来我们就能极大提高攻击者的攻击成本,比如攻击者通过其他漏洞或缺陷所获得的权限只能是tomcat权限而不是系统最高权限,若想要进一步攻击则只能进行提权操作。

另外我们还需要保证tomcat系统用户的密码口令符合一定的复杂度要求甚至是禁止远程登录。

四、安全配置

4.1 Example Applications

Tomcat安装后需要删除CATALINA_HOME/webapps下的所有文件 (ROOT, balancer, jsp-examples, servlet-examples, tomcat-docs, webdav),以免信息泄露和其他的安全风险。比如示例servlet和JSP的“/ examples”目录,会话session servlet(安装在/ examples / servlets / servlet / SessionExample)允许进行session操作,因为session是全局的,所以这个servlet会带来很大的安全风险,因为攻击者可能通过操纵会话来强制成为应用系统的管理员。但这种基本上只有在一些很老的不安全的系统中才有可能出现。

4.2 Manager Console

从CATALINA_HOME/webapps中删除host-manager和manager后台管理程序。但如果需要在不重新启动Tomcat的情况下重新部署或部署新的web应用时可以选择保留,但需要一个足够强的管理口令,在tomcat-user.xml中配置。

Tomcat Manager 4种角色的大致介绍(下面URL中的*为通配符):

  • manager-gui:允许访问html接口(即URL路径为/manager/html/*)
  • manager-script:允许访问纯文本接口(即URL路径为/manager/text/*)
  • manager-jmx:允许访问JMX代理接口(即URL路径为/manager/jmxproxy/*)
  • manager-status:允许访问Tomcat只读状态页面(即URL路径为/manager/status/*)

Tomcat管理后台使用BASIC认证,在http请求头中有一个Authorization字段,账号密码为“账号:密码”的方式经过base64编码。

常见的弱口令:

admin:admin

admin:123456

admin:tomcat

tomcat:tomcat

tomcat:admin

tomcat:123456t

4.2.1 manager-gui

Tomcat管理控制模块中最常见的就是manager-gui,访问路径为/manager/html,具有部署应用的功能,恶意攻击者常使用该功能部署war文件的webshell后门程序

选择需要部署的war文件点击deploy后即可完成部署,可以在应用列表中点击相应的应用名完成webshell访问

另外在某些场景下也可能用到服务器的本地部署,若一个web应用结构为\WebApp\AppName\WEB-INF\*,利用控制台进行部署的方式如下:进入tomcat的manager控制台的Deploy directory or WAR file located on server区域——在Context path中键入”XXX”(可任意取名)——在WAR or Directory URL:键入\WebApp\AppName(表示去寻找此路径下的web应用)——点击deploy按钮。

然后在%Tomcat_Home%\webapps路径下将会自动出现一个名为XXX的文件夹,其内容即是\WebApp\AppName的内容,只是名字是XXX而已(这和tomcat的自动部署方式一致)

4.2.2 manager-script

Tomcat manager-script的远程部署应用的功能也可以被恶意攻击者利用,通过以下命令请求即可完成应用后门部署

通过/list可以查看已成功部署的应用

另外也有大量敏感信息泄露的风险

攻击者关注的其他页面还有:

http://localhost:8080/manager/text/resources[?type=xxxxx]

http://localhost:8080/manager/text/sessions?path=/examples

http://localhost:8080/manager/text/expire?path=/examples&idle=num

http://localhost:8080/manager/text/findleaks[?statusLine=[true|false]]

http://localhost:8080/manager/text/sslConnectorCiphers

4.2.3 manager-status

manager-status主要是一些只读的tomcat运行状态信息,除了信息泄露外五其他可操作行的风险。

4.2.4 manager-jmx

manager-jmx为Tomcat JMX代理接口,是一个小型的servlet,它可以按以下列格式接收JMX Query、Get、Set和Invoke命令:

  • HTTP://{host}:{port}/manager/jmxproxy/qry= YOURQUERY
  • HTTP://{host}:{port}/manager/jmxproxy/set = YOURCOMMAND

当我们默认直接访问tomcat提供的JMX接口时(http://localhost:8080/manager/jmxproxy/?qry=)会出现所有的MBeans

如果想要具体的MBeans只需要将其name后面的值放在url的后面实际的命令是使用特殊字符的URL编码以标准JMX语法编写的,恶意攻击者可以通过该接口读取tomcat用户密码甚至添加用户

危害最大的是攻击者可以通过jmxproxy执行任意jsp代码导致远程代码执行,方法如本文JMX Service小节中所讲的方法一致,通过invoke命令调用rotate函数将访问日志备份到指定文件的方法,最终执行任意代码。

4.3 admin Manager

Tomcat 5及之前版本存在admin模块,提供了类似于Weblogic、Websphere等商用应用中间件的管理功能,可以方便的实现对Tomcat服务、部署的应用程序、连接池以及其他资源的管理,但不能用来部署应用程序,Tomcat Admin功能作为一个独立的模块,从5.5版本开始作为一个可选模块,在默认情况下是不安装的,需要进行手工安装,通过/admin路径访问控制台

在admin后台恶意攻击者除了获取服务器信息外,主要利用的两个恶意操作是磁盘文件读取和添加tomcat管理账号。首先磁盘文件读取是通过Service->host->actions->Create New Context建立虚拟目录,Document Base填你想浏览的目录,比如c:\,Path可以自定义,例如/formsec,然后直接http://ip/formsec 就可以看到c盘内容。

另外在User Definition中可以对Tomcat的用户进行管理,比如添加账号及权限等。

4.4 JMX Service

Java Management Extension (JMX)服务用来远程监视和管理的Tomcat服务器,如果对外开放并且是空口令或者弱口令的话会产生很多安全问题,通过Java Remote Method Invocation (RMI)进行交互。该服务在Tocmat中默认是不开启的,需要对Catalina.bat/Catalina.sh做一些简单更改

此JMX服务可以配置为支持身份验证,但默认情况下未启用。启用身份验证时(如始终建议的那样),其授权模型允许访问属于只读或读写角色的两个不同用户。

如果您需要授权,添加并更改此项:

  • Dcom.sun.management.jmxremote.authenticate=true
  • Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password
  • Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access

编辑访问授权文件$ CATALINA_BASE / conf / jmxremote.access:

monitorRole readonly  
controlRole readwrite

编辑密码文件$ CATALINA_BASE / conf / jmxremote.password:

monitorRole tomcat  
controlRole tomcat

从上面可以看出,jmxremote.access文件包含两个用户名(monitorRole和controlRole)及其相关角色。然后,jmxremote.password将这些用户的密码设置为tomcat。

始终建议对此服务启用身份验证,并且使用复杂口令。

具体请查考:

http://tomcat.apache.org/tomcat-8.0-doc/monitoring.html#Enabling_JMX_Remote

测试方法

可以通过nmap来发现开启JMX服务的端口,但nmap无法确认是否开启认证

远程访问该端口服务可以使用jdk自带的jconsole或者1.6出来的jvisualvm,

选择远程进程输入jmx服务的ip地址和端口进行连接,其中涉及大量的tomcat服务器敏感信息,包括管理控制台弱口令

当然也可以进行一些控制操作,比如在MBeans–>Catalina—>WebModule—>应用程序名称—>Operations—>stop 关闭指定的应用程序(start启动)

如果有写权限的tomcat用户可以写入后门恶意代码等,其中的 Catalina->Valve->localhost->AccessLogValve->Operations表明rotate函数用于将Tomcat访问日志的副本保存到服务器上的文件中。

但是这里有个缺陷,newFileName定义的文件名可以使用任意目录和文件名后缀,利用日志备份拿webshell的思路,我们可以将含有恶意代码的请求日志备份在web应用目录下获取webshell

首先看一下如何获取应用路径,VM概要中存在tomcat的所在路径,配合webapp列表就可以构造出来

因此在此例中我们可以将日志备份在/usr/local/tomcat/webapps/100/formsec.jsp,拿到webshell。

注意在调用rotate时是不能创建目录的,如果文件存在不会覆盖原文件内容,也不会新建文件。

如果tomcat运行在windows服务器中,并且tomcat是以域用户账号运行的,那么newFileName定义为\\192.168.5.1\test则可能捕获到用户hash进行破解

还有一个可以被黑客恶意利用的操作是listSessionIds(),可以用于劫持除了tomcat manager应用外的每个web应用程序中用户的jsessionid,该操作同样需要写权限,位于

Catalina->Manager->[ApplicationName]->Operations->listSessionIds()

4.5 AJP Listenner

Tomcat最主要的功能是提供Servlet/JSP容器,尽管它也可以作为独立的Java Web服务器,它在对静态资源(如HTML文件或图像文件)的处理速度,以及提供的Web服务器管理功能方面都不如其他专业的HTTP服务器,如IIS和Apache服务器。因此在实际应用中,常常把Tomcat与其他HTTP服务器集成。

Tomcat有两个连接器,一个连接器监听8080端口,负责建立HTTP连接。在通过浏览器访问Tomcat服务器的Web应用时,使用的就是这个连接器。第二个连接器监听8009端口,负责和其他的HTTP服务器建立连接,在把Tomcat与其他HTTP服务器集成时,就需要用到这个连接器。

(图片转自:《Tomcat Port 8009 与AJP13协议》)

AJP是为Tomcat与HTTP服务器之间通信而定制的协议,能提供较高的通信速度和效率。在配置Tomcat与HTTP服务器集成中。

在某些场景下如果8080因防火墙等原因被限制访问但是开放了8009,就会被攻击者恶意利用,用apache等服务器进行集成,绕过8080端口的访问限制

使用ajp进行集成配置

注:参考https://diablohorn.com/2011/10/19/8009-the-forgotten-tomcat-port/

4.6 Debug Mode

Tomcat在进行远程调试时需要开启debug模式,在调试器和JVM之间使用JDWP进行通信。Tomcat的debug默认是不开启的,需要手动配置,默认端口为8000

debug模式对外开放非常危险,攻击者可直接通过JDWP执行系统命令

五、安全漏洞

5.1 CVE-2017-12615& CVE-2017-12617

CVE-2017-12615 Tomcat远程代码执行漏洞由iswin发现。其实算是绕过PUT上传限制,可上传jsp可执行文件,漏洞关键点在tomcatweb.xml文件中修改配置org.apache.catalina.servlets.DefaultServlet的参数readonly默认值为false时,即允许进行delete和put操作。

https://images.zsxq.com/FuFRRklvWBkRG8Kp3q6zZj0KeFrt?e=1874736000&token=kIxbL07-8jAj8w1n4s9zv64FuZZNEATmlU_Vm6zD:qRYm8K7BK5WHvPLKPfl5HEzTf4k=

一般情况下,tomcat不允许put上传jsp文件,但在tomcat7.0.0 to 7.0.79版本中,存在一处缺陷,windows环境下可通过NTFS文件数据流“::DATA”的方式来绕过进行jsp文件的上传,以及通过“::$INDEX_ALLOCATION”来创建文件夹等,这部分知识可以参考https://msdn.microsoft.com/en-us/library/windows/desktop/aa364404(v=vs.85).aspx

后续我和xfk及xxlegend在对该漏洞进行fuzz的时候发现windows环境中“test.jsp.”、”test.jsp%20”、”test.jsp/”等方式均可实现上传并能成功解析执行,而重要的是这几个poc是无版本限制。当然我们也对linux平台的各版本tomcat进行了相同的fuzz操作,发现“test.jsp/”也可以成功上传并解析,因此该漏洞也就影响了Tomcat全版本,这也就是后来的CVE-2017-12617。

https://images.zsxq.com/FgzaG0p5syBJKNbwy03JjleoxFhX?e=1874736000&token=kIxbL07-8jAj8w1n4s9zv64FuZZNEATmlU_Vm6zD:RrfP2lL64L3Z987OESJZCpGyIy8=

5.2 CVE-2017-12616

该漏洞与CVE-2017-12615同时被发现,并且利用方式也类似,如果Tomcat在conf/server.xml配置了VirtualDirContex参数来挂载虚拟目录,访问者通过构造请求访问jsp等web资源时,Tomcat就会将VirtualDirContext提供支持资源中相对应文件的内容以文本形式返回,造成源代码泄露。

对于Windows服务器使用test.jsp%20和test.jsp::$DATA获得源代码,但无法通过test.jsp/获取源代码,不影响linux系统。

5.3 CVE-2016-8735

这个漏洞实质还是JMX反序列化漏洞,Tomcat同样也用了JmxRemoteLifecycleListener这个监听器,但是Tomcat在Oracle修复这个漏洞后自己没有及时更新,导致了反序列还依旧存在。

影响版本:

Apache Tomcat 9.0.0.M1 to 9.0.0.M11

Apache Tomcat 8.5.0 to 8.5.6

Apache Tomcat 8.0.0.RC1 to 8.0.38

Apache Tomcat 7.0.0 to 7.0.72

Apache Tomcat 6.0.0 to 6.0.47

Earlier, unsupported versions may also be affected.

远程命令执行效果如下

关于该漏洞的具体复现可以参考我之前的一篇文章

http://reverse-tcp.xyz/2016/12/10/Apache-Tomcat-Remote-Code-Execution(CVE-2016-8735)

  • Tomcat
  • Penetration Test