Pillage Exposed RDS Instances
A walkthrough demonstrating how to exfiltrate data from a public RDS instance.
Last updated
Was this helpful?
A walkthrough demonstrating how to exfiltrate data from a public RDS instance.
Last updated
Was this helpful?
CTF Source:
In this walkthrough, we're provided with a public RDS endpoint and asked to do a security assessment.
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
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 script
View details: nmap --script-help=mysql-info
-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
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 to 0
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.
Show the databases
Select the database user_info
and view its tables
Read the flag
Read plaintext users data
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
Database authentication
The MySQL database utilized a weak password and was easily crackable with automated tools
Recommendation:
Data security
The user_info
data in the MySQL database was not encrypted
Recommendation:
Link in output:
Link to code:
Now that we know the version of MySQL is 8.0.32
, we can view the 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.
If you have installed, we can find this here ls -lh /usr/share/seclists/Passwords/Default-Credentials/ | grep mysql
We’re going to use the nmap script . Looking over the documentation we know our creds file needs to be formatted a certain way,
Consider utilizing AWS IAM for or integrating with AWS Secrets Manager for
Consider utilizing AWS IAM for or integrating with AWS Secrets Manager for
Utilize MySQL’s to enforce strong passwords if authentication will continue to be handled by MySQL
Consider on the data