CVE-2019-0232:Apache Tomcat RCE漏洞

Apache Tomcat是在Apache Software Foundation (ASF)支持下开发的开源Java Servlet容器,实现了多个Java EE规范,包括Java Servlet, JavaServer Pages (JSP), Java Expression Language (EL), WebSocket,提供一个Java代码运行的纯Java HTTP web服务器环境。

4月15日,Nightwatch Cybersecurity公布了Apache Tomcat的Common Gateway Interface (CGI) Servlet的远程代码执行漏洞。攻击者利用该高危漏洞可以滥用Tomcat CGI Servlet输入有效性错误导致的操作系统命令注入来执行任意命令。

漏洞分析

CGI是用来管理web服务器与应用交互的协议。CGI Servlet是用来生成来自查询字符串的命令行参数的,默认是禁用的。但是运行在Windows机器上的启用了CGI Servlet参数enableCmdLineArguments的Tomcat服务器由于Java Runtime Environment (JRE)传递命令行参数到Windows时的bug可能会导致远程代码执行。

在Apache Tomcat中,文件web.xml用来为加载到Tomcat实例的所有web应用定义默认值。CGI Servlet是默认提供的servlets。Servlet支持符合CGI说明的外部应用的执行。CGI Servlet映射到URL模式“/cgi-bin/*”,表明所有执行的CGI应用必须在web应用中。

通过调用CreateProcess()函数来启动Windows操作系统中的新进程,该函数将以下命令作为字符串:

int CreateProcess( …, lpComandLine, … )

在Windows中,参数并不是以字符串数组的形式传递的,二是以单个命令行字符串的形式传递的。这要求程序用GetCommandLine() API来提取命令行参数,来分析命令行,然后用CommandLineArgvW() helper函数来分析参数字符串。

如下图所示:

Cmdline = “program.exe hello world”

CVE-2019-0232:Apache Tomcat RCE漏洞_第1张图片

图1. Windows中的命令行字符串

Argv[0]->program.exe
Argv[1]->hello
Argv[2]->world

漏洞是因为从JRE到Windows的命令行参数的不适当传递引发的。

对Java应用来说,ProcessBuilder()是在CreateProcess()函数之前被调用的。然后参数会传递给ProcessImpl()的静态方法开始,这是一个与平台无法的类。在ProcessImpl()的Windows实现中,开始方法调用ProcessImpl()的所有构造器来为CreateProcess调用创建命令行。

CVE-2019-0232:Apache Tomcat RCE漏洞_第2张图片

图2. Java apps的命令行字符串

ProcessImpl() 构建了Cmdline,并传递给CreateProcess() Windows函数,然后CreateProcess()在cmd.exe shell环境中执行.bat和.cmd文件。如果文件要运行的文件含有.bat或.cmd扩展,要运行的镜像就会变成cmd.exe。CreateProcess()会在Stage 1重启,并将batch文件的名传递给cmd.exe作为第一个参数。

hello.bat …中的结果会变成‘C:\Windows\system32\cmd.exe /c “hello.bat …”‘。因为CommandLineToArgvW 的引用规则与cmd的引用规则不同,也就是说需要应用其他的引用规则来避免cmd.exe翻译时的命令行注入。

因为Java (ProcessImpl())对cmd.exe传递的参数的调用没有额外的引用,cmd.exe处理的参数会被执行,如果参数没有以适当的方式传递给cmd.exe就会引发问题。

cmd.exe分析的参数

cmd的作用就是一个文本预处理器,给定一个命令行,cmd负责进行一系列的文本转化,然后将这些转化后的命令行交给CreateProcess()。

转化的过程会将环境变量名替换为对应的值。转化一般是由&, ||, &&操作符来触发的,将命令行分割为多个部分。所有的cmd转化都是由以下元字符来触发的:(, ), %, !, ^, “, <, >, &, and |。

Cmd在处理元字符“时,会复制“到新的命令行,然后复制其他命令行字符到新的命令行,并不会考虑这些字符串是否元字符。

如果用cmd的元字符“来保护参数,使用引号可以产生意外的行为。将不可信的数据作为命令行参数椽笔,不匹配发送时就可能会产生安全漏洞,比如:

hello.bat “dir \”&whoami”
0: [hello.bat]
1: [&dir]

其中cmd会将&元字符作为命令分隔符,因为&是在引号区域外的。因此,whoami可以被任意代码所替代。在运行上面的hello.bat时会得到下面的输出结果:

CVE-2019-0232:Apache Tomcat RCE漏洞

图3. 运行“hello.bat”的输出结果

利用该问题可以用Apache Tomcat来执行任意代码,结果如下:

CVE-2019-0232:Apache Tomcat RCE漏洞_第3张图片

图4. Apache Tomcat中的命令执行

为了成功执行命令注入,需要添加一些参数,并在web.xml文件中启用CGI Servlet。

CVE-2019-0232:Apache Tomcat RCE漏洞_第4张图片

图5. web.xml

Apache Software Foundation在Apache Tomcat CGI Servlet中引入了新的参数cmdLineArgumentsDecoded来解决CVE-2019-0232漏洞。只有当enableCmdLineArguments被设置为true时才使用cmdLineArgumentsDecoded参数。它定义了一个解码的命令行参数必须匹配的正则模型“[[a-zA-Z0-9\Q-_.\\/:\E]+]”,如果不匹配请求就会被拒绝。天空彩

CVE-2019-0232:Apache Tomcat RCE漏洞_第5张图片

图6. Apache Tomcat补丁

建议

Apache Software Foundation建议运行Apache Tomcat的用户升级软件到最新版本:

Version  建议补丁

Apache Tomcat 9->Apache Tomcat 9.0.18 or later

Apache Tomcat 8->Apache Tomcat 8.5.40 or later

Apache Tomcat 7->Apache Tomcat 7.0.93 or later

而且用户应当将CGI Servlet初始化参数enableCmdLineArguments设置为False来预防潜在的漏洞滥用。

你可能感兴趣的:(CVE-2019-0232:Apache Tomcat RCE漏洞)