Pillage Exposed RDS Instances
A walkthrough demonstrating how to exfiltrate data from a public RDS instance.
CTF Source: Pwned Labs
Overview
In this walkthrough, we're provided with a public RDS endpoint and asked to do a security assessment.
Pre-Requisites
Install awscli:
(brew/apt) install awscli
Install nmap:
(brew/apt) install nmap
Install seclists:
(brew/apt) install seclists
Install mysql cli:
apt install mariadb-client-core
Walkthrough
Discovering RDS
Given an RDS endpoint, we’re going to perform a port scan to identify potential database instances running.
Now that we know of an open port let’s run some more tests with nmap.
Before running, it’s important to understand what we’re doing.
nmap -Pn -sV -p3306 --script=mysql-info exposed.cw9ow1llpfvz.eu-north-1.rds.amazonaws.com
-Pn
assumes the host is online so skips ping-sV
attempts to get the version of the service running on the port--script=mysql-info
is a “Safe” enumeration scriptView details:
nmap --script-help=mysql-info
Link in output: https://nmap.org/nsedoc/scripts/mysql-info.html
Link to code: https://svn.nmap.org/nmap/scripts/mysql-info.nse
Brute-Forcing MySQL
Now that we know the version of MySQL is 8.0.32
, we can view the documentation and discover that unless the configuration was updated, the default username is: root
and it may not have a password. Let’s try to connect.
-h
connect to a remote host, without this it will attempt to connect to a local mysql db-u
specify the username--skip-password
attempt authentication without a password
Bonus, there’s also an nmap script that will do the same as above --script=mysql-empty-password
and also check for anonymous user.
No dice. Not to worry, we can attempt to brute-force the password.
Let’s first ensure we have a good password list e.g., mysql-betterdefaultpasslist.txt
If you have Seclists installed, we can find this here
ls -lh /usr/share/seclists/Passwords/Default-Credentials/ | grep mysql
We’re going to use the nmap script mysql-brute. Looking over the documentation we know our creds file needs to be formatted a certain way,
a file containing username and password pairs delimited by '/'
Our file is currently delimited by :
so let’s fix that.
We’ll copy this creds file to our local directory so we don’t butcher the original.
cp /usr/share/seclists/Passwords/Default-Credentials/mysql-betterdefaultpasslist.txt .
Then we’ll use sed
to change the :
to a /
Now we can confirm the changes.
We’re ready to run our brute-force attack!
It’s important to understand that brute-forcing is noisy and may trigger an account lockout policy.
brute.delay=10
this increases the timeout, the default is set to0
which may cause the script to fail to find any results
It looks like we found valid creds! dbuser:123
. Let’s attempt to connect to MySQL with these.
Nice. We’re in! Let’s see what data there is.
Exfiltrating Data
Show the databases
Select the database user_info
and view its tables
Read the flag
Read plaintext users data
Wrap-Up
In this scenario, we were tasked with identifying security concerns on an AWS RDS instance and we discovered a few issues:
Database public exposure
The instance was publicly exposed and there are few use cases where this is needed
Recommendation:
Turn off public access if possible
If public access is required, consider restricting access via Security Groups to only approved IP addresses
Consider utilizing AWS IAM for database authentication or integrating with AWS Secrets Manager for password authentication
Database authentication
The MySQL database utilized a weak password and was easily crackable with automated tools
Recommendation:
Consider utilizing AWS IAM for database authentication or integrating with AWS Secrets Manager for password authentication
Utilize MySQL’s password validation component to enforce strong passwords if authentication will continue to be handled by MySQL
Data security
The
user_info
data in the MySQL database was not encryptedRecommendation:
Consider implementing encryption on the data
Last updated