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系统用户的密码口令符合一定的复杂度要求甚至是禁止远程登录。
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会带来很大的安全风险,因为攻击者可能通过操纵会话来强制成为应用系统的管理员。但这种基本上只有在一些很老的不安全的系统中才有可能出现。
从CATALINA_HOME/webapps中删除host-manager和manager后台管理程序。但如果需要在不重新启动Tomcat的情况下重新部署或部署新的web应用时可以选择保留,但需要一个足够强的管理口令,在tomcat-user.xml中配置。
Tomcat Manager 4种角色的大致介绍(下面URL中的*为通配符):
Tomcat管理后台使用BASIC认证,在http请求头中有一个Authorization字段,账号密码为“账号:密码”的方式经过base64编码。
常见的弱口令:
1 | admin:admin |
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的自动部署方式一致)
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
manager-status主要是一些只读的tomcat运行状态信息,除了信息泄露外五其他可操作行的风险。
manager-jmx为Tomcat JMX代理接口,是一个小型的servlet,它可以按以下列格式接收JMX
Query、Get、Set和Invoke命令:
当我们默认直接访问tomcat提供的JMX接口时(http://localhost:8080/manager/jmxproxy/?qry=)会出现所有的MBeans
如果想要具体的MBeans只需要将其name后面的值放在url的后面实际的命令是使用特殊字符的URL编码以标准JMX语法编写的,恶意攻击者可以通过该接口读取tomcat用户密码甚至添加用户
危害最大的是攻击者可以通过jmxproxy执行任意jsp代码导致远程代码执行,方法如本文JMX
Service小节中所讲的方法一致,通过invoke命令调用rotate函数将访问日志备份到指定文件的方法,最终执行任意代码。
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的用户进行管理,比如添加账号及权限等。
Java Management Extension
(JMX)服务用来远程监视和管理的Tomcat服务器,如果对外开放并且是空口令或者弱口令的话会产生很多安全问题,通过Java
Remote Method Invocation
(RMI)进行交互。该服务在Tocmat中默认是不开启的,需要对Catalina.bat/Catalina.sh做一些简单更改
此JMX服务可以配置为支持身份验证,但默认情况下未启用。启用身份验证时(如始终建议的那样),其授权模型允许访问属于只读或读写角色的两个不同用户。
如果您需要授权,添加并更改此项:
编辑访问授权文件\$ CATALINA_BASE / conf / jmxremote.access:
1 | monitorRole readonly |
编辑密码文件\$ CATALINA_BASE / conf / jmxremote.password:
1 | monitorRole 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()
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执行系统命令
CVE-2017-12615 Tomcat远程代码执行漏洞由iswin发现。其实算是绕过PUT上传限制,可上传jsp可执行文件,漏洞关键点在tomcatweb.xml文件中修改配置org.apache.catalina.servlets.DefaultServlet的参数readonly默认值为false时,即允许进行delete和put操作。
一般情况下,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。
该漏洞与CVE-2017-12615同时被发现,并且利用方式也类似,如果Tomcat在conf/server.xml配置了VirtualDirContex参数来挂载虚拟目录,访问者通过构造请求访问jsp等web资源时,Tomcat就会将VirtualDirContext提供支持资源中相对应文件的内容以文本形式返回,造成源代码泄露。
对于Windows服务器使用test.jsp%20和test.jsp::\$DATA获得源代码,但无法通过test.jsp/获取源代码,不影响linux系统。
这个漏洞实质还是JMX反序列化漏洞,Tomcat同样也用了JmxRemoteLifecycleListener这个监听器,但是Tomcat在Oracle修复这个漏洞后自己没有及时更新,导致了反序列还依旧存在。
影响版本:
1 | Apache Tomcat 9.0.0.M1 to 9.0.0.M11 |
远程命令执行效果如下
关于该漏洞的具体复现可以参考我之前的一篇文章
http://reverse-tcp.xyz/2016/12/10/Apache-Tomcat-Remote-Code-Execution(CVE-2016-8735)