Accessing Secrets from misconfigured S3 Bucket Version control

Accessing Secrets from misconfigured S3 Bucket Version control

·

9 min read

In this CTF, you will play the role of a Cloud Security Consultant. Your team's services have been enlisted by Huge Logistics to conduct an external assessment of their cloud environment. Your assignment involves assessing an IP range, which includes focusing on the IP address 16.171.123.169.

Assessment Scope

Your tasks encompass:

  • performing web enumeration

  • S3 bucket enumeration

  • identifying, accessing file versions, and capturing the flag in MD5 format.

Lab Scenario

S3 version control, also known as versioning, is a feature provided by Amazon Simple Storage Service (S3) that enables you to preserve multiple versions of an object in a bucket. Each time you upload an object (such as a file) to an S3 bucket that has versioning enabled, a new version of the object is created while retaining the older versions. This can be highly beneficial in terms of data protection, disaster recovery, and maintaining data integrity.

A commonly encountered real-world security issue related to S3 Version Control is the storage of its credentials in JavaScript files and other client-side code. This practice exposes sensitive information, such as API keys or credentials, to anyone with access to or the ability to view the source code of the website. Considering that the website's source code is inherently public, this approach poses a significant risk.

Target Website

  • IP address @ 16.171.123.169

Perform Web Enumeration on Target IP

  • Start by running an Nmap scan to check for Open Ports
nmap -p 1-1000 -T4 16.171.123.169

The Nmap scan indicates the presence of a web server running on port 80, commonly utilized by websites and web applications, as well as a service associated with email submission on port 587 of the target IP address.

  • Copy the IP address 16.171.123.169 to a web browser (e.g. Chrome) to view the web app.

  • Run a web scanner tool (e.g. Niko, WhatWeb) on the Target IP 16.171.123.169

Run the command to install whatweb:

git clone https://github.com/urbanadventurer/WhatWeb.git

The whatweb scan shows that the web app uses elements like the Bootstrap framework, jQuery, password fields (log-in or authentication mechanism), and scripts (JavaScript).JavaScript

  • Next, view the source code of the Web app @ 16.171.123.169 for any embedded links or secrets. (Right-click and select view page source.)

  • At the bottom of the page source, you will notice some JavaScript links pointing to Amazon S3 buckets, which are very common regional endpoint URL formats.

Other different styles of URLs for Amazon S3 bucket Format include

  1. Path-Style URL: This is the original and basic format for accessing objects in an S3 bucket: https://s3.amazonaws.com/bucket-name/object-key

    Note: This style is deprecated but still in use by older buckets.

  2. Virtual Hosted–Style URL: This style allows the bucket name to be part of the domain and is generally more user-friendly: https://bucket-name.s3.amazonaws.com/object-key

  3. Regional Endpoint URL: This style is similar to Virtual Hosted–Style URLs but includes the AWS region where the S3 bucket is located: https://bucket-name.s3-region.amazonaws.com/object-key

    Using the regional endpoint URL format can have benefits in terms of latency, cost, compliance, data residency, and clarity.

  4. Dual Stack Endpoint URL: This style supports both IPv4 and IPv6 addresses and is used for high availability and fault tolerance: https://bucket-name.s3.dualstack.region.amazonaws.com/object-key

  5. S3 Transfer Acceleration URL: This style provides faster uploads and downloads for enabled buckets by using Amazon S3 Transfer Acceleration: https://bucket-name.s3-accelerate.amazonaws.com/object-key

  6. S3 Access Points URL: S3 Access Points are named endpoints with distinct permissions that make it easier to manage shared data sets. The URL structure depends on the access point's name and the account ID: https://access-point-name-account-id.s3-accesspoint.region.amazonaws.com/object-key

NOTE: Each of these URL styles serves different purposes and might be chosen based on factors like performance, accessibility, and security requirements.

  • Now, attempt to gather additional information regarding the JavaScript URL links obtained from the source page of the web application.

<script src="https://huge-logistics-dashboard.s3.eu-north-1.amazonaws.com/static/js/api.js"></script>
<script src="https://huge-logistics-dashboard.s3.eu-north-1.amazonaws.com/static/js/auth.js"></script>

        </body>
        </html>
  • Use the Curl command to fetch the header parameter
curl -I https://huge-logistics-dashboard.s3.eu-north-1.amazonaws.com/

NOTE:

  • curl: The command-line tool used for making requests to URLs.

  • I: This flag tells curl to send an HTTP HEAD request instead of a GET request. A HEAD request retrieves only the headers of the response without the actual content

  • Looking at the second JavaScript URL from the source page ending with *****static/js/auth.js .You will notice that the source code contains a JavaScript function related to authentication. However, this might not appear particularly intriguing at first glance.

<script src="https://huge-logistics-dashboard.s3.eu-north-1.amazonaws.com/static/js/auth.js"></script>

  • Additional information can be obtained from the URL by utilizing the Curl command.
curl -I https://huge-logistics-dashboard.s3.eu-north-1.amazonaws.com/static/js/auth.js

  • Now, see how to fetch the versioning configuration status (Enabled or Suspended) of the S3 bucket using the command:
aws s3api get-bucket-versioning --bucket huge-logistics-dashboard
aws s3api get-bucket-versioning --bucket huge-logistics-dashboard --no-sign-request

An attempt to retrieve the version configuration status was made, but it was unsuccessful due to the absence of AWS credentials configuration and insufficient permissions.

  • The object versions for the S3 bucket can be bypassed without AWS credentials to sign the request, by running the command:
aws s3api list-object-versions --bucket huge-logistics-dashboard --query "Versions[?VersionId!='null']" --no-sign-request

NOTE: The following flags help to bypass it ⇒ --query "Versions[?VersionId!='null']": This option allows you to specify a JMESPath query to filter the results. In this case, it's filtering the versions to include only those where the VersionId is not null and provides a list of actual object versions. ⇒ --no-sign-request: This option tells the AWS CLI not to sign the request with AWS credentials. Useful in cases when accessing publicly accessible S3 objects.

The above scan result shows that the file within the bucket "Key": "private/Business Health - Board Meeting (Confidential).xlsx" has been deleted or is not up-to-date IsLatest": false and any attempt to access the file "Business Health - Board Meeting (Confidential).xlsx" would be void. The reason is that the "IsLatest" field in the output is marked as false, which indicates that the version of the file you're looking at is not the latest version. This suggests that there might be a more recent version of the file available, and attempting to access this specific version might not provide the most up-to-date or accurate information.

# Command to access "Business Health - Board Meeting (Confidential).xlsx"
aws s3api get-object --bucket huge-logistics-dashboard --key "private/Business Health - Board Meeting (Confidential).xlsx" --version-id "HPnPmnGr_j6Prhg2K9X2Y.OcXxlO1xm8" test.xlsx --no-sign-request

NB: When you see "IsLatest": true, this indicates that the file is the latest version in the list of object versions.

Lateral Movement

Let's employ the Lateral Movement technique by exploiting vulnerabilities in the source code of the ***static/js/auth.js URL page and checking the previous version of the "Key": "static/js/auth.js".

Recall from previous steps, the second JavaScript URL from the source page ending with *****static/js/auth.js which appear not intriguing. Now,** from the result scan which contains additional details after running a command to bypass object versions status. One of the result scans shows details of the ***static/js/auth.js URL.

# Command for bypassing object versions status
aws s3api list-object-versions --bucket huge-logistics-dashboard --query "Versions[?VersionId!='null']" --no-sign-request

An important detail from the scan is the VersionId for the Key "static/js/auth.js"

"Key": "static/js/auth.js",
"VersionId": "qgWpDiIwY05TGdUvTnGJSH49frH_7.yh",
  • Run the command below to check the previous version for the Key "static/js/auth.js" With the help of --version-id
aws s3api get-object --bucket huge-logistics-dashboard --key "static/js/auth.js" --version-id "qgWpDiIwY05TGdUvTnGJSH49frH_7.yh" auth_previous.js --no-sign-request

NB: auth_previous.js: This specifies the local filename that the retrieved object will be saved as on your local machine. In this case, the object will be saved as "auth_previous.js".

  • Check your local directory for "auth_previous.js" and use the cat command to open it.

  • Use the credentials details to log in to the Web app @ 16.171.123.169
email':'admin@huge-logistics.com', 'password':'H4mpturTiem213!'

  • On the Web app Dashboard, navigate to the Profile page.

  • On the User Profile page, there appear to be credential keys stored in the Note section. It can be assumed that the Creds looks like the AWS Access key and Secret key format.
Creds: AKIATWVWNKAVBJLHAC2G,mZ9t6IwTMbd9kEucx5BLitltKKy2jPhk/L94xVrg

Setting UP AWS Profile with the AWS Creds

Access Key: AKIATWVWNKAVBJLHAC2G
Secert Key: mZ9t6IwTMbd9kEucx5BLitltKKy2jPhk/L94xVrg
region: eu-north-1
  • Use the command below to create a profile (in this lab, pwned)
aws configure --profile pwned

  • From the JS URL https://huge-logistics-dashboard.s3.eu-north-1.amazonaws.com/, you will notice the S3 bucket name huge-logistics-dashboard. Run the command below to retrieve the content of the URL using the created Profile (in this lab, pwned).
aws --profile pwned s3 ls s3://huge-logistics-dashboard --recursive

NOTE: The flag --recursive in the above command will list all objects in the bucket and its subdirectories.

Retry Object Version Status

Now that you have created an AWS profile with the leaked AWS credentials, re-run the command below to fetch the previous version for the S3 bucket file "Key": "private/Business Health - Board Meeting (Confidential).xlsx"

# Command to access "Business Health - Board Meeting (Confidential).xlsx"
aws s3api get-object --bucket huge-logistics-dashboard --key "private/Business Health - Board Meeting (Confidential).xlsx" --version-id "HPnPmnGr_j6Prhg2K9X2Y.OcXxlO1xm8" test.xlsx --profile pwned

NOTE: Include the profile created --profile pwned and the test.xlsx can be any name of your choice that will contain details of the output.

  • Check the content of the test.xlsx by using the command
libreoffice --calc test.xlsx

If you don’t have LibreOffice installed, use the command sudo apt-get install libreoffice

  • LibreOffice open in GUI the test.xlsx file.

Now You have access to the previous file for Business Health - Board Meeting (Confidential).xlsx

Finally, for the flag, check the 3rd Sheet of the file test.xlsx by navigating to the bottom of your screen.

Lesson Learnt

  • Data Organization and Segregation: Properly organizing and segregating data within an AWS S3 infrastructure is essential for both operational efficiency and security. By placing different types of data in separate buckets, you ensure that data permissions are appropriately managed based on their classification.

  • Least Privilege: It's crucial to grant permissions based on the principle of least privilege. Only trusted entities should have access to the s3:ListBucketVersions and s3:GetObjectVersion permissions. This helps prevent unauthorized access to sensitive data.

  • Data Deletion: Administrators should actively manage data, including cleaning up dangling file versions. This prevents unnecessary exposure of sensitive data and helps maintain a clean data environment.

  • Credential Management: t's crucial to use tools like AWS Secrets Manager or privileged access management (PAM) software for securely managing and storing credentials. This reduces the risk of unauthorized access and potential compromise.

  • Credentials Security: Storing AWS credentials in plain text fields within applications is a bad practice. This can provide malicious actors with access to AWS resources, enabling lateral and vertical movement within a compromised environment. Instead, best practices recommend using secure methods like AWS Secrets Manager or other secret management tools to protect credentials.

  • Sensitive Data Exposure: Sensitive data might inadvertently be exposed through previous file versions created during testing or mistakes. It's important to review and manage old file versions, ensuring they do not contain sensitive information.

  • Data Access Permissions: It's crucial to note that even after a file has been deleted from a bucket, confidential data could still be accessed due to compromised web application credentials. This underscores the importance of setting and controlling access permissions for data stored in S3 buckets.

NOTE

The Command below can be used to delete the previous version of the file Business Health - Board Meeting (Confidential).xlsx

aws s3api delete-object --bucket huge-logistics-dashboard --key "private/Business Health - Board Meeting (Confidential).xlsx" --version-id "HPnPmnGr_j6Prhg2K9X2Y.OcXxlO1xm8"

Special Thanks to Pwnedlabs for creating an Amazing Walkthrough

Reference

Did you find this article valuable?

Support Goodycyb by becoming a sponsor. Any amount is appreciated!