Jack Writeup - Tryhackme

Compromise a web  server running WordPress, obtain a low privileged user and escalate your privileges to root using a Python module.

How this helps your pentesting career:

    • Web-application Pentesting, specifically WordPress
    • Practice brute-forcing authentication
    • Remote-Code-Execution with WordPress malicious plugin
    • Practice Linux Privilege Escalation to get root.
    • Good OSCP practice

Task 1: Deploy & Root

After the machine boots up, the WordPress site looks like this:


An Nmap service scan show there are 2 open ports: 22 (ssh) and 80 (Apache httpd):

Important information from this scan:

  • OS: Linux, probably Ubuntu
  • Web Service running Apache/2.4.18, WordPress 5.3.2
  • /wp-admin/ is disallowed in robots.txt
  • OpenSSH 7.2p2

Upon accessing /wp-admin/, I realized I had to first add jack.thm to my /etc/hosts file, providing the machine IP: https://i1.wp.com/i.imgur.com/RhB85ol.png?w=1200&ssl=1


Get Shell Access

The WordPress login page lets us know that ‘jack’ is a valid username. 


The main exploit for OpenSSH 7.2p2 checks if a provided username is valid or not.  In this case, I tried both ‘jack’ and ‘Jack’ but both were not valid: https://i1.wp.com/i.imgur.com/0bsFTZI.png?w=1200&ssl=1

Let’s try exploiting the web service on port 80.

A truncated output of the wpscan results is shown below:

root@kali:/usr/share/KaliLists# wpscan --url jack.thm -e u,vp --plugins-detection aggressive

         __          _______   _____
         \ \        / /  __ \ / ____|
          \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
           \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
            \  /\  /  | |     ____) | (__| (_| | | | |
             \/  \/   |_|    |_____/ \___|\__,_|_| |_|

         WordPress Security Scanner by the WPScan Team
                         Version 3.7.7
       Sponsored by Automattic - https://automattic.com/
       @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart

[+] URL: http://jack.thm/
[+] Started: Fri Oct  2 15:38:58 2020

Interesting Finding(s):

[+] http://jack.thm/
 | Interesting Entry: Server: Apache/2.4.18 (Ubuntu)
 | Found By: Headers (Passive Detection)
 | Confidence: 100%

[+] http://jack.thm/robots.txt
 | Interesting Entries:
 |  - /wp-admin/
 |  - /wp-admin/admin-ajax.php
 | Found By: Robots Txt (Aggressive Detection)
 | Confidence: 100%

[+] http://jack.thm/xmlrpc.php
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%
 | References:
 |  - http://codex.wordpress.org/XML-RPC_Pingback_API
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner
 |  - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access

[+] http://jack.thm/readme.html
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%

[+] Upload directory has listing enabled: http://jack.thm/wp-content/uploads/
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%

[+] http://jack.thm/wp-cron.php
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 60%
 | References:
 |  - https://www.iplocation.net/defend-wordpress-from-ddos
 |  - https://github.com/wpscanteam/wpscan/issues/1299

[+] WordPress version 5.3.2 identified (Insecure, released on 2019-12-18).
 | Found By: Rss Generator (Passive Detection)
 |  - http://jack.thm/index.php/feed/, <generator>https://wordpress.org/?v=5.3.2</generator>
 |  - http://jack.thm/index.php/comments/feed/, <generator>https://wordpress.org/?v=5.3.2</generator>


[+] Enumerating Vulnerable Plugins (via Aggressive Methods)
 Checking Known Locations - Time: 00:01:39 <===============================================================> (2375 / 2375) 100.00% Time: 00:01:39
[+] Checking Plugin Versions (via Passive and Aggressive Methods)

[i] No plugins Found.

[+] Enumerating Users (via Passive and Aggressive Methods)
 Brute Forcing Author IDs - Time: 00:00:02 <========================> (10 / 10) 100.00% Time: 00:00:02

[i] User(s) Identified:

[+] jack
 | Found By: Rss Generator (Passive Detection)
 | Confirmed By:
 |  Wp Json Api (Aggressive Detection)
 |   - http://jack.thm/index.php/wp-json/wp/v2/users/?per_page=100&page=1
 |  Author Id Brute Forcing - Author Pattern (Aggressive Detection)
 |  Login Error Messages (Aggressive Detection)

[+] wendy
 | Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)
 | Confirmed By: Login Error Messages (Aggressive Detection)

[+] danny
 | Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)
 | Confirmed By: Login Error Messages (Aggressive Detection)


Relevant info include:

  • /wp-admin/ page
  • /xmlrpc.php page that only allows POST requests
  • /wp-content/uploads/ directory is enabled
  • WP version 5.3.2
  • Users:
    • jack
    • wendy
    • danny
  • No plugins found

A search for “WordPress 5.3.2 exploit” results in: https://www.tenable.com/plugins/was/112478, but none of the listed vulnerabilities seem relevant to us (XSS in block editor, etc.).

Brute-force password cracking. 

Wpscan can use a wordlist to brute force passwords.  It will perform an attack against xmlrpc.php (we found this from the inital WPScan). 

I don’t know much about The Shining (the theme this room is based on), so I created a custom wordlist based on the shining fandom wiki page with CeWL.

CeWL was set to grab words at least 6 characters long and visits links with a depth of 1 at https://stephenking.fandom.com/wiki/Jack_Torrance.


This did not yield any results.  I also tried the hak5.txt wordlist from SecLists/Passwords/Leaked Databases/hak5.txt

This also did not work.  After some more research, the wordlist that will brute force one of the user’s passwords is part of the Kali Linux’s included wordlists.  The version of Kali I’m using did not include this directory of wordlists, but I found a Github repository hosting just that: https://github.com/3ndG4me/KaliLists

With the password, we can authenticate the user and log into the WordPress Dashboard:

Upon going to the ‘Tools’ section, we are met with an empty page.  Our user does not have an admin account for this WP site.

The provided hint from THM says:  “Wpscan user enumeration, and don’t use tools (ure_other_roles)

A search for ‘ure_other_roles’ says there is a vulnerability in the “User Role Editor < 4.25” WordPress plugin. It allows any registered user to gain administrator access.  This means a user can submit an arbitrary role, such as administrator when editing their own profile, and the plugin will them give them that role.

… but from the earlier WPScan enumeration, we found 0 plugins installed. 

Regardless, let’s try to update the user profile and intercept that POST request with BurpSuite.

As a test, I added “&ure_other_roles=administrator” at the end of the POST request and forwarded it.  The profile was successfully updated, and now we have a couple new options on the sidebar that we didn’t have before:

Looks like the vulnerability was actually successful even though we didn’t identify the User Role Editor plugin during enumeration.  Upon selecting the plugins menu from the sidebar, we are met with three installed plugins:

**Hmm, I’m not sure why WPScan didn’t identify the plugins before; I even set the plugin detection option to “aggressive”.  More research will have to be done, but the hint really helped.  Now that we have WordPress admin access, we can attempt to get a shell on the machine. 

Before we do that, we have access to the Tools section of the sidebar, and can see more details about the server it is running on:

To get a shell, we can use a malicious plugin made for WP, written in PHP.  One can be found from the SecLists package from either Github or with ‘apt install seclists’.

The file we are looking for is in …./seclists/Web-Shells/WordPress and named ‘plugin-shell.php’.   WordPress recognizes plugins as .zip files, so let’s zip up the plugin shell:

To install this plugin, we hit the ‘Upload Plugin’ button, browse for our plugin-shell.zip file, and click install:

Normally, we would need to activate a plugin in order to use it, but we get a fatal error when we try to do just that:

Regardless, let’s try to send a shell command to the plugin file.  When installing a plugin, WP creates a new folder with the same name as the uploaded .zip to /wp-content/plugins/.  This means our web-shell is located at /wp-content/plugins/plugin-shell/plugin-shell.php.  This web shell takes a shell command as part of the ‘cmd’ GET parameter. 

Let’s send the command ‘whoami’ to the web-shell:

Awesome!  From here, we can get the user flag, then escalate privileges to get the root flag (remember to url-encode space characters with %20):

Privilege Escalation

We currently have remote code execution through a malicious WordPress plugin.  Let’s try to get an actual shell (meterpreter). 

First, let’s generate a meterpreter reverse tcp payload with msfvenom: Let’s use port 443 for the reverse shell because there’s a high chance outbound traffic is allowed through the firewall on port 443.

To transfer the payload, a Python3 http.server is started in the same directory as the payload.  Then, from the target machine, we can use wget to download the file:

Once the payload is on the target, we can change the permissions to make it executable, and run it.

But before we run it, we have to start a meterpreter listener with the /multi/handler module:

Awesome, now we have a meterpreter shell!  Let’s examine the ‘reminder.txt’ file that was in the Jack user’s home directory:

Backups are usually located in /var/backups.  Let’s check there:
In the backups directory, there is a ‘id_rsa‘ private SSH key with full permissions.  We can download this to our attacker machine and see if we can use it to SSH into this machine as Jack.

This is easily done since we are in a meterpreter shell:

This private key needs to only have read permissions or else SSH will freak out and not proceed.  Let’s change the permissions with ‘chmod 600 id_rsa’:

Now we have a regular interactive shell, logged in as the low privileged user, Jack. 

Where do we go from here?  The hint for the root flag says: “Python”, and the description of the room says “…and escalate your privileges to root using a Python module”. 

I explored two options:

      1. Search for all python files on the system.
      2. Search for a process started from a python script. 

When I searched the filesystem for python files, I got a lot of junk results from various Python installs in the /usr/ directory.  To filter those, I used the invert option for the grep command: This ‘checker.py‘ file looks interesting.

To snoop on the processes running on the machine without special permissions, I am going to use Pspy, an open source project on Github.  It will monitor any processes in real-time, and display the command line options related to each process.  The Github page is found here: https://github.com/DominicBreuker/pspy.

The 32-bit version was downloaded to Kali and then a Python3 http server was used to transfer the program over to the Jack machine, and executed:

It will list all the current processes running, then will monitor and update in real-time when a new process is started.  Keeping an eye on the output shows us a Python process running every 2 minutes:

It is the same python script we found with the ‘find’ command!

We do not have permission to modify or execute ‘checker.py’, but we can read it:

‘checker.py’ imports the os module and then calls the os.system function.  The module in question may be ‘os’. 

To find out where the os module is stored, we can try to call the script with the -v option (https://www.tutorialspoint.com/Where-are-the-python-modules-stored): Searching in that location for the module shows that os.py is writable for our group:

We can add a reverse shell script to the end of the os.py file, and theoretically, when checker.py runs, we should get a reverse shell back to our Kali machine.  I found a suitable Python2.7 shell here: http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet.

Remember to start a listener on the specified port, and in less than 2 minutes, we should have a shell as the root user:


This was the first ‘difficult’ level THM room I’ve attempted.  I had some hiccups finding the correct wordlist to use to brute force the WP user password.  This was also the first time I used WPScan, and the method of modifying a python module for privilege escalation was new too.  Pspy is highly valuable and I will save it to my repertoire. I had so much fun solving this room and it’s so rewarding each time a part of the puzzle clicks into place. 

This site hex-men.tech actually runs on WordPress, so it was super cool to exploit it 🙂 KEEP YOUR PLUGINS UPDATED.

I hope to apply these methods in future CTFs and engagements.  Peace!

Leave a Reply