当前位置:首页 > 休闲

apache tomcat远程代码执行漏洞

```html

2017年9月,远程Apache官方紧急发布了一个Tomcat安全公告,代码编号CVE-2017-12615。执行当时我在一家电商公司做运维,漏洞半夜被叫起来打补丁——攻击者只要往服务器上传一个JSP文件,远程就能直接执行任意系统命令。代码更离谱的执行是,这个漏洞利用起来不需要任何认证,漏洞一个普通的远程PUT请求就够了。

问题出在Tomcat的代码DefaultServlet配置上。如果你在conf/web.xml里把readonly参数设成了false,执行Tomcat就会允许HTTP PUT方法上传文件。漏洞本来这个设计是远程为了方便开发者调试,但很多人不知道,代码Tomcat对上传文件的执行扩展名检查存在绕过漏洞。攻击者可以上传一个名为shell.jsp%20的文件,Windows系统会自动去掉末尾的空格,最终服务器上就变成了shell.jsp。或者用shell.jsp::$DATA这种NTFS数据流技巧,同样能绕过检测。

我见过最典型的攻击场景是这样的:一台暴露在公网的Tomcat 7.0.0到7.0.79版本服务器,攻击者先用OPTIONS方法探测是否允许PUT,然后直接构造请求把JSP木马上传到webapps/ROOT目录。整个过程不到三秒。等管理员发现时,服务器已经被用来挖矿或者当跳板了。

修复方案其实很简单。打开conf/web.xml,找到DefaultServlet的配置段,确认readonly参数是true。默认情况下它就是true,但总有人为了图方便改成false。如果业务确实需要PUT上传,那就把readonly设回true,然后单独写一个Servlet来处理上传逻辑,并且严格限制文件类型和路径。

另一个相关的漏洞是CVE-2020-1938,也叫Ghostcat。这个更隐蔽——攻击者能通过AJP协议读取Tomcat应用目录下的任意文件,包括WEB-INF/web.xml。如果应用里恰好有文件上传功能,还能结合文件包含实现RCE。AJP协议默认监听8009端口,很多管理员以为只开放8080就安全了,实际上8009才是后门。

我检查过上百台Tomcat服务器,发现一个规律:出问题的往往不是最新版本,而是那些“稳定运行了三五年没动过”的老系统。管理员觉得没出事就是安全,但攻击工具早就在自动化扫描这些老版本了。Shodan上搜一下Tomcat 7.0.79,至今还能看到大量暴露在公网的实例。

防护措施不用搞得太复杂。第一,升级到最新稳定版,Tomcat 9.0.x或者10.1.x。第二,如果不用AJP,直接在server.xml里注释掉Connector port="8009"那行。第三,把web.xml里的readonly锁死。第四,用WAF拦一下PUT方法和包含jsp的请求路径。这四步做完,90%的Tomcat RCE攻击就跟你没关系了。

最后说个真实案例。去年有个客户中了勒索病毒,排查发现攻击入口就是一台Tomcat 8.5.30。攻击者上传的JSP文件里藏着一段Base64编码的PowerShell脚本,下载了LockBit样本。客户的技术负责人跟我说:“我们以为Tomcat就是个跑Java的容器,没想过它本身也能被攻击。”这话我听过太多次了。Tomcat是应用服务器,不是安全边界。把它当成一个需要定期体检的系统组件来对待,比出事后再救火划算得多。

```

分享到: