Post

Introduction to Cloud Security (Part 1)

Introduction to Cloud Security (Part 1)

Introduction

Cloud Security là một khía cạnh quan trọng của an ninh mạng hiện đại, đặc biệt khi ngày càng nhiều tổ chức chuyển hạ tầng của họ lên môi trường đám mây. Các lỗi cấu hình sai, quyền truy cập lỏng lẻo và rò rỉ thông tin xác thực là những lỗ hổng phổ biến mà kẻ tấn công có thể khai thác để xâm nhập trái phép vào tài nguyên đám mây.

Loạt bài này sẽ hướng dẫn bạn qua các thử thách bảo mật trong môi trường đám mây, giúp bạn nhận diện và khai thác các lỗi cấu hình sai. Ở đây mình làm theo các lab của flaws.cloud. Nếu mọi người muốn tự thực hành, có thể tìm kiếm trên mạng để làm theo.

Challenges

Level 1

Description

This level is buckets of fun. See if you can find the first sub-domain.

Idea

Đầu tiên ta dùng lệnh host flaws.cloud để truy vấn các Address Record - địa chỉ IP mà tên miền này trỏ tới.

Để ý là flaws.cloud trỏ đến nhiều địa chỉ IP khác nhau, có thể là nó đang dùng 1 dịch vụ đám máy có nhiều server

host command

Tiếp tục chạy lệnh host với một địa chỉ ip bất kì trong ảnh, ta sẽ có được tên miền của địa chỉ IP - truy vấn DNS ngược. Và kết quả cho thấy địa chỉ IP thuộc về Amazon S3, có nghĩa là website flaw.cloud đang được lưu trữ trên dịch vụ S3 Static Website Hosting tại khu vực us-west-2

host command

Để xác định subdomain, ta có thể dùng lệnh aws s3 ls s3://flaws.cloud --no-sign-request để kiểm tra danh sách file lưu trữ trong S3 (nếu bucket này public). Và rồi ta có được kết quả như sau -> cấu hình của S3 này không an toàn, để lộ các file cho phép truy cập từ bất cứ đâu.

list file

Từ đây truy cập để xem file secret để lấy link dẫn đến challenge tiếp theo

Misconfiguration

Như thông thường thì s3 bucket sẽ được setup private và an toàn với các policy quản lý các file. Tuy nhiên trong trường hợp này thì owner đã dùng Static Website Hosting và policy cho phép mọi người truy cập “s3:GetObject”.

Notes: Ta không nên cho phép list directory của web servers và bucket listing.

Level 2

Link: http://level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud

Description

The next level is fairly similar, with a slight twist. You’re going to need your own AWS account for this. You just need the free tier.

Idea

Đầu tiên ta dùng lệnh host level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud để truy vấn các Address Record - địa chỉ IP mà tên miền này trỏ tới.

host command

Tiếp tục chạy lệnh host với một địa chỉ ip bất kì trong ảnh, ta sẽ có được tên miền của địa chỉ IP - truy vấn DNS ngược.

host command

Theo mô tả thì ta thấy nó yêu cầu ta dùng account aws của bản thân. Ta thử dùng cách như trong level 1 thì sẽ thấy như sau:

s3 list

Giờ đây ta cần lập một account và dùng ACCESS_KEYSECRET_ACCESS_KEY để xác thực, từ đó có thể thực hiện các thao tác truy vấn dữ liệu trên S3 bucket hoặc các dịch vụ AWS khác

1
aws configure --profile myacc

s3 list

Misconfiguration

Lệnh liệt kê S3 đầu tiên thất bại vì bucket không còn được đặt ở chế độ public như trước. Chủ sở hữu bucket có thể đã thiết lập Bucket Policy hoặc IAM Policy để cho phép bất kỳ user nào đã xác thực có thể truy cập. Tuy nhiên, cơ chế này không còn tồn tại trong các phiên bản AWS mới nhất.

Notes: Ngoài ra cũng có thể là trường hợp profile myacc có quyền như IAM Policy, ACL hoặc Cross-Account Access để có thể truy cập vô S3 mà myacc không sở hữu

Level 3

Link: http://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud

Description

The next level is fairly similar, with a slight twist. Time to find your first AWS key! I bet you’ll find something that will let you list what other buckets are.

Idea

Tương tự như level 1 và level 2, ta tiếp tục chạy các lệnh host để kiểm tra xem có subdomain nào liên quan hay không. Khi xác thực đó dùng S3 service ta dùng lệnh để truy vấn danh sách file.

s3 list

Tuy nhiên ở đây lại không thấy có sự xuất hiện của file secret như các challenges trước đó. Thay vào đó là 1 folder .git.

Và để xem xét kĩ càng hơn, ta sẽ tải những tập trong S3 bucket này về máy. Ta sử dụng lệnh sau:

1
aws s3 sync s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud . --no-sign-request

Sau một thời gian tìm hiểu, search mạng tìm được có lệnh git có thể xem các nhánh đã bị xóa nhưng commit vẫn tồn tại:

1
git reflog

git command

Dựa vào kết quả ta biết được mình đang ở nhánh b64c8dc - master. Ta có thể chuyển sang nhánh khác để xem các thông tin bên nhánh đó

Sau khi chuyển sang nhánh đó, ta thấy một file có lưu trữ các thông tin xác thực access_keys.txt. Dựa vào đây mình có thể xác minh một tài khoản aws.

git command

Sau khi cấu hình aws sử dụng AWS key và secret, mình có thể list S3 buckets với profile đó.

list s3 buckets

Misconfiguration

Mọi người thường rò rỉ chìa khóa AWS và sau đó cố gắng che đậy những sai lầm mà không thu hồi chìa khóa. Lưu ý luôn luôn thu hồi bất kỳ khóa AWS nào có thể bị rò rỉ hoặc bị đặt sai chỗ.

.git bị lộ, có thể khai thác để:

  • Trích xuất mã nguồn.

  • Tìm thông tin nhạy cảm.

  • Xem lịch sử commit để tìm lỗ hổng.

  • Khai thác thêm nếu có API key hoặc mật khẩu.

Level 4

Link: http://level4-1156739cfb264ced6de514971a4bef68.flaws.cloud/

Description

For the next level, you need to get access to the web page running on an EC2 at 4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud

It’ll be useful to know that a snapshot was made of that EC2 shortly after nginx was setup on it.

Idea

Đầu tiên mình nhận thấy đang dùng ec2 instance kèm credential được lấy từ level 3. Ta nghĩ ngay đến sử dụng lệnh nào đó của awscli để liệt kê các snapshots

1
aws ec2 describe-snapshots --profile level3

Ngoài ra để tìm kiếm cụ thể hơn mình có thể dùng một lệnh khác để tìm các snapshot mà owner chính là profile này

1
aws ec2 describe-snapshots --owner-id self --profile level3

describe snapshot

Để biết snapshot này có được công khai hay không, ta sẽ dùng lệnh sau, nếu "CreateVolumePermissions" có giá trị rỗng [] thì nghĩa là nó không được chia sẻ với bất kì ai.

1
aws ec2 describe-snapshot-attribute --snapshot-id snap-0b49342abd1bdcb89 --attribute createVolumePermission --profile level3

attribute snapshot

Từ đây ta nhận thấy rằng "Group": "all" cho biết snapshot này công khai cho tất cả mọi người.

Ngoài ra ta có thể tìm được thêm region của volume bằng câu lệnh aws ec2 describe-volumes --volume-ids vol-04f1c039bc13ea950 --query "Volumes[0].AvailabilityZone" --profile level3

volume

Từ đây để có thể dùng snapshots này tạo 1 instance trong account aws của mình, ta thực hiện các bước sau đây:

1 Tạo volume từ snapshot

Chạy lệnh sau để tạo một EBS volume từ snapshot (snap-0b49342abd1bdcb89) trong region tương ứng:

1
2
3
4
aws ec2 create-volume --snapshot-id snap-0b49342abd1bdcb89 \
--availability-zone us-west-2a \
--volume-type gp2 \
--profile myacc

2 Tạo EC2 Instance

Vô account aws của bạn tạo 1 ec2 instance vơi region us-west-2a

ec2 instance

3 Gắn volume vào instance

Gắn volume được tạo từ snapshot vô instance đã được tạo ra. Sau đó ta sẽ mount volume vô thư mục

  • Tạo thư mục để mount: sudo mkdir /mnt/mydata

  • Mount volume vào thư mục này: sudo mount /dev/xvdf1 /mnt/mydata

  • Kiểm tra: df -h

Sau khi mount và kiểm tra xong thì mình vô folder /mnt/mydata/ và xem các file trong đó, ở đây là tất cả những thông tin được lưu trữ trong snapshot.

Từ đây mình có thể tìm thấy 1 file là setupNginx.sh nơi lưu trữ các thông tin để hoàn thành challenge này.

get credential

Misconfiguration

AWS cho phép người dùng tạo các snapshot cho EC2 và RDS mục đích chính là để backup data. Tuy nhiên đôi khi họ lại cấu hình sai, không để hạn chế truy cập cho mỗi người sở hữu, dẫn đến các nguy cơ bị attack để lấy AWS key. Từ đây có thể dẫn đến privilege escalation, có thể chạy các dịch vụ khác trên hệ thống.

Để tránh những điều đáng tiếc xảy ra, ta có thể:

  • Kiểm tra và giới hạn quyền truy cập snapshot

  • Sử dụng KMS Encryption cho snapshot

  • Xóa credential khỏi instance khi không cần thiết trước khi tạo snapshot

Level 5

Link: http://level5-d2891f604d2061b6977c2481b0c8333e.flaws.cloud/243f422c/

Description

This EC2 has a simple HTTP only proxy on it. Here are some examples of it’s usage:

http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/flaws.cloud/

http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/summitroute.com/blog/feed.xml

http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/neverssl.com/

See if you can use this proxy to figure out how to list the contents of the level6 bucket at level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud that has a hidden directory in it.

Idea

Ý tưởng đầu tiên khi nhìn thấy HTTP proxy là tôi nghĩ ngay đến SSRF. Ngoài ra, chúng ta biết có một địa chỉ đặc biệt để lấy metadata của EC2 instance, đó là 169.254.169.254 - chính là EC2 Instance Metadata Service nơi có thể truy cập thông tin về instance, bao gồm IAM credentials nếu có role gán cho instance. Thử thực hiện điều đó:

get meta-data

Sau khi xác thực proxy có gửi request đến IMDS, ta có thể lấy được IAM role đang được gán cho instance thông qua request đến: http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/

get IAM

Từ đây chúng ta có thể lấy được temporary credentials để truy cập AWS: 4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws

Sau đó mình dùng các thông tin này để thêm vô file ~/.aws/credentials để tạo ra 1 profile mới.

add credentials

Và cuối cùng dùng profile này để truy cập vô bucket, liệt kê file.

list files

Avoid

Đảm bảo các ứng dụng không cho phép truy cập vào 169.254.169.254 hoặc bất kỳ phạm vi IP cục bộ và riêng tư nào. Ngoài ra, đảm bảo rằng vai trò IAM bị hạn chế càng nhiều càng tốt.

Level 6

Link: http://level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud/ddcc78ff/

Description

For this final challenge, you’re getting a user access key that has the SecurityAudit policy attached to it. See what else it can do and what else you might find in this AWS account.

Access key ID: AKIAJFQ6E7BY57Q3OBGA

Secret: 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

Idea

Sau khi sử dụng Access key và Secret key để tạo mới 1 profile level6, ta có thể dùng nó để kiểm tra thông tin chi tiết của user AWS đang sử dụng credentials trong profile level6.

get user information

Dựa vào kết quả ta biết được UserName - tên của user trong AWS IAM là Level6

Notes: Nếu ARN chứa /service-role/ => đây là service account, có thể có quyền cao. Nếu ARN chứa /admin/ hoặc /privileged/ => có thể là user có quyền mạnh.

Sau đó ta kiểm tra xem có các policies nào được gán cho user này bằng câu lệnh sau:

1
aws --profile level6 iam list-attached-user-policies --user-name Level6

get user policy

Ở đây ta chú ý thấy có 2 policy

  • MySecurityAudit - theo đề bài thi đây có thể là SecurityAudit policy cho phép truy cập để đọc cấu hình metadata như của IAM, S3, EC2, Lambda, CloudTrail, …

  • list_apigateways - đây là 1 custom API, có thể là policy cho phép liệt kê các API Gateway

Để xem chi tiết về policy list_apigateways, ta chạy các lệnh sau:

get detail user policy

Lệnh này sẽ hiển thị các quyền cụ thể của policy. Nếu nó có quyền apigateway:GET, có thể sẽ xem được danh sách API Gateway hiện có trong tài khoản AWS này

get detail user policy

Để tìm được URL API Gateway, cách đơn giản là aws --profile level6 apigateway get-rest-apis --region us-west-2 tuy nhiên lại không được, ta càn phải tìm một cách khác

fail

Format của URL cho REST APIS của AWS API Gateway: https://<api-id>.execute-api.<region>.amazonaws.com/<stage>/<resource>

Ở đây, ta dùng lệnh host như các challenges trước đó, ta xác định được region là us-west-2

Thông thường API Gateway hay được gọi đến để invoke 1 Lambda function. Cho nên chúng ta có thể tìm cách kiểm tra Lambda xem nó có được liên kết với API Gateway không. Vì thế ta cần phải xem danh sách các Lambda functions:

1
aws --profile level6 lambda list-functions --region us-west-2

list functions

Sau đó kiểm tra xem Lambda có event source là API Gateway hay không bằng câu lệnh:

1
aws --profile level6 lambda get-policy --function-name <LambdaFunctionName> --region us-west-2

Dựa vào kết quả ta biết LambdaFunctionName là Level6, ta chạy câu lệnh và có kết quả sau:

lambda functions

Từ đây ta biết được thêm 2 thông tin bên trong url là:

  • api-id: s33ppypa75

  • resource: level6

Giá trị cuối cùng ta cần tìm là stage, và nó được tìm dễ dàng như sau:

find stage

Cuối cùng ta có được url API Gateway: https://s33ppypa75.execute-api.us-west-2.amazonaws.com/Prod/level6

This post is licensed under CC BY 4.0 by the author.