在AWS Elastic Beanstalk中利用SSRF
譯者注:本文將出現大量AWS官方詞彙,對於一些中文字面意思難以理解的詞彙,為便於讀者理解將在首次出現時同時給出中英詞彙,方便讀者在AWS官方文件中查閱。( 中文文件 與 英文文件 )
本文,我們“ Advanced Web Hacking ”培訓課程的首席培訓師 Sunil Yadav 將討論一個案例研究:識別並利用一種伺服器端請求偽造(SSRF)漏洞來訪問敏感資料(例如原始碼)。此外,該部落格還討論了可能導致(使用持續部署管道,即Continuous Deployment pipeline)部署在AWS Elastic Beanstalk上應用程式遠端程式碼執行(RCE)的風險點。
AWS Elastic Beanstalk
AWS Elastic Beanstalk(譯者注:官方譯為平臺即服務技術,通常以英文原文出現,故不作翻譯)是AWS提供的一款平臺即服務(PaaS)產品,主要用於部署和擴充套件各種開發環境的Web應用程式(如Java,.NET,PHP,Node.js,Python,Ruby和Go等)。它支援自動化的部署,容量分配,負載均衡,自動擴充套件(auto-scaling)和應用程式執行狀況監視。
準備環境
AWS Elastic Beanstalk支援Web伺服器(Web Server)和工作執行緒(Worker)兩種環境配置。
- Web伺服器環境 – 主要適合執行Web應用程式或Web API。
- 工作執行緒環境 – 適合後臺工作,長時間執行的流程。
在zip或war檔案中提供有關應用程式,環境和上傳應用程式程式碼的資訊來配置新應用程式。
圖1:建立Elastic Beanstalk環境
新環境配置後,AWS會自動建立S3儲存桶(Storage bucket)、安全組、EC2例項以及 aws-elasticbeanstalk-ec2-role ( 預設例項配置檔案,按照預設許可權被對映到EC2例項)。<br />從使用者計算機部署程式碼時,zip檔案中的原始碼副本將被放入名為 elasticbeanstalk – region-account-id 的S3儲存桶中。
圖2:Amazon S3儲存桶
Elastic Beanstalk預設不加密其建立的Amazon S3儲存桶。這意味著預設情況下,物件以未加密的形式儲存在桶中(並且只能由授權使用者訪問)。詳見: https : //docs.aws.amazon.com/elasticbeanstalk/latest/dg/AWSHowTo.S3.html 預設例項配置檔案的託管策略 – aws-elasticbeanstalk-ec2-role:
- AWSElasticBeanstalkWebTier – 授予應用程式將上傳日誌和除錯資訊分別上傳至Amazon S3和AWS X-Ray的許可權。
- AWSElasticBeanstalkWorkerTier – 授予日誌上傳,除錯,指標釋出(metric publication)和Woker例項任務的許可權,其中包括佇列管理,領導選擇(leader election)和定期任務。
- AWSElasticBeanstalkMulticontainerDocker – 授予Amazon Elastic容器服務協調叢集任務的許可權。
策略“ AWSElasticBeanstalkWebTier ”允許對S3儲存桶有限的列取,讀取和寫入許可權。只有名稱以“ elasticbeanstalk- ” 開頭且有遞迴訪問許可權的儲存桶才能被訪問。
圖3:託管策略 – “AWSElasticBeanstalkWebTier”
詳見: https : //docs.aws.amazon.com/elasticbeanstalk/latest/dg/concepts.html
分析
在日常滲透測試中,我們遇到了某應用程式的伺服器端請求偽造(SSRF)漏洞。通過對外部域進行 DNS呼叫 (譯者注:屬於帶外攻擊OOB一種)確認漏洞,並通過訪問僅允許localhost訪問的“http://localhost/server-status”進一步驗證漏洞,如下面的圖4所示。 http://staging.xxxx-redacted-xxxx.com/view_pospdocument.php?doc=http://localhost/server-status
圖4:通過訪問受限頁面確認SSRF
在SSRF確認存在後,我們(使用 https://ipinfo.io 等服務)通過伺服器指紋識別確認服務提供商為亞馬遜。此後,我們嘗試通過多個端點查詢 AWS元資料 ,例如:
- http://169.254.169.254/latest/dynamic/instance-identity/document
- http://169.254.169.254/latest/meta-data/iam/security-credentials/aws-elasticbeanstalk-ec2-role
通過API“ http://169.254.169.254/latest/dynamic/instance-identity/document”中獲取帳戶ID和地區資訊:
圖5:AWS元資料-獲取帳戶ID和地區資訊
圖6:AWS元資料-獲取訪問金鑰ID、加密訪問金鑰和令牌
注意:“ aws-elasticbeanstalk-ec2-role” 中 IAM安全憑證表示應用程式部署在Elastic Beanstalk上。<br />我們進一步在AWS命令列介面(CLI)中配置,如圖7所示:
圖7:配置AWS命令列介面
“aws sts get-caller-identity”命令的輸出表明令牌有效,如圖8所示:
圖8:AWS CLI輸出:get-caller-identity
到目前位置,一切順利,可以確定這是個標準的SSRF漏洞。不過好戲還在後頭…..我們好好發揮下:最初,我們嘗試使用AWS CLI執行多個命令來從AWS例項獲取資訊。但是如下面的圖9所示,由於安全策略,大多數命令被拒絕訪問:
圖9:ListBuckets操作上的訪問被拒絕
之前介紹過託管策略“AWSElasticBeanstalkWebTier”只允許訪問名稱以“elasticbeanstalk”開頭的S3儲存桶:<br />因此,我們需要先知道儲存桶名稱,才能訪問S3儲存桶。Elastic Beanstalk建立了名為elasticbeanstalk-region-account-id的Amazon S3儲存桶。我們使用之前獲取的資訊找到了儲存桶名稱,如圖4所示。
- 地區:us-east-2
- 帳號:69XXXXXXXX79
儲存桶名稱為“ elasticbeanstalk- us-east-2-69XXXXXXXX79 ”。我們使用AWS CLI以遞迴方式列出它的桶資源: aws s3 ls s3//elasticbeanstalk-us-east-2-69XXXXXXXX79/
圖10:列出Elastic Beanstalk的S3儲存桶
我們通過遞迴下載S3資源來訪問原始碼,如圖11所示。aws s3 cp s3:// elasticbeanstalk-us-east-2-69XXXXXXXX79 / / home / foobar / awsdata -recursive
圖11:遞迴複製所有S3 Bucket Data
從SSRF到RCE
現在我們有許可權將物件新增到S3儲存桶中,我們通過AWS CLI向S3儲存桶中上傳一個PHP檔案(zip檔案裡webshell101.php),嘗試實現遠端程式碼執行。然而並不起作用,因為更新的原始碼未部署在EC2例項上,如圖12和圖13所示:
圖12:在S3儲存桶中通過AWS CLI上傳webshell
圖13:當前環境中Web Shell的404錯誤頁面
我們圍繞這個開展了一些實驗並整理了一些可能導致RCE的潛在利用場景:
- 使用CI/CD AWS CodePipeline(持續整合/持續交付AWS管道)
- 重建現有環境
- 從現有環境克隆
- 使用S3儲存桶URL建立新環境
使用CI/CD AWS CodePipeline:AWS管道是一種CI/CD服務,可(基於策略)在每次程式碼變動時構建,測試和部署程式碼。管道支援GitHub,Amazon S3和AWS CodeCommit作為源提供方和多個部署提供方(包括Elastic Beanstalk)。有關其工作原理可見 此處AWS官方部落格 :
在我們的應用程式中,軟體版本管理使用AWS Pipeline,S3儲存桶作為源倉庫,Elastic Beanstalk作為部署提供方實現自動化。首先建立一個管道,如圖14 所示:
圖14:管道設定
選擇S3 bucket作為源提供方,S3 bucket name並輸入物件鍵,如圖15所示:
圖15:新增源階段
配置構建提供方或跳過構建階段,如圖16所示:
圖16:跳過構建階段
將部署提供方設定為Amazon Elastic Beanstalk並選擇使用Elastic Beanstalk建立的應用程式,如圖17所示:
圖17:新增部署提供程式
建立一個新管道,如下面的圖18所示:
圖18:成功建立新管道
之後在S3儲存桶中上傳一個新檔案(webshell)來執行系統命令,如圖19所示:
圖19:PHP webshell
在源提供方配置的物件中新增該檔案,如圖20所示:
圖20:在物件中新增webshell
使用AWS CLI命令將存檔檔案上傳到S3儲存桶,如圖21所示:
圖21:S3儲存桶中的Cope webshell
aws s3 cp 2019028gtB-InsuranceBroking-stag-v2.0024.zip s3://elasticbeanstalk-us-east-1-696XXXXXXXXX/
更新檔案時,CodePipeline立即啟動構建過程。如果一切正常,它將在Elastic Beanstalk環境中部署程式碼,如圖22所示:
圖22:管道觸發
管道完成後,我們就可以訪問Web shell並對系統執行任意命令,如圖23所示。
圖23:執行系統級命令
成功實現RCE! 重建現有環境 : 重建環境會終止刪除、所有資源並建立新資源。因此,在這種情況下,它將從S3儲存桶部署最新的可用原始碼。最新的原始碼包含部署的Web shell,如圖24所示。
圖24:重建現有環境
成功完成重建過程後,我們可以訪問我們的webshell並在EC2例項上執行系統命令,如圖25所示:
圖25:從webshell101.php執行系統級命令
從現有環境克隆:如果應用程式所有者克隆環境,它將再次從S3儲存桶中獲取程式碼,該儲存桶將部署一個帶有Web shell的Web應用。克隆環境流程如圖26所示:
圖26:從現有環境克隆
建立新環境: 在建立新環境時,AWS提供了兩個部署程式碼的選項,一個用於直接上傳存檔檔案,另一個用於從S3儲存桶中選擇現有存檔檔案。通過選擇S3儲存桶選項並提供S3儲存桶URL,將會使用最新的原始碼進行部署。而被部署的最新原始碼中含有Web shell。
參考文件:
- https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/concepts.html
- https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/iam-instanceprofile.html
- https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/AWSHowTo.S3.html
- https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html
- https://gist.github.com/BuffaloWill/fa96693af67e3a3dd3fb
- https://ipinfo.io