淺談雲上攻防——物件儲存服務訪問策略評估機制研究

雲鼎實驗室發表於2021-08-13

前言

近些年來,越來越多的IT產業正在向雲原生的開發和部署模式轉變,這些模式的轉變也帶來了一些全新的安全挑戰。


物件儲存作為雲原生的一項重要功能,同樣面臨著一些列安全挑戰。但在物件儲存所導致的安全問題中,絕大部分是由於使用者使用此功能時錯誤的配置導致的。據統計,由於缺乏經驗或人為錯誤導致的儲存桶錯誤配置所造成的安全問題佔所有云安全漏洞的16%。


以2017美國國防部承包商資料洩露為例:此次資料洩露事件是由於Booz Allen Hamilton公司(提供情報與防禦顧問服務)在使用亞馬遜S3伺服器儲存政府的敏感資料時,使用了錯誤的配置,從而導致了政府保密資訊可被公開訪問。經安全研究人員發現,公開訪問的S3儲存桶中包含47個檔案和資料夾,其中三個檔案可供下載,其中包含了大量“絕密”(TOP SECRET)以及“外籍禁閱”(NOFORN)檔案。


與此相似的案例有很多,例如Verizon資料洩露事件、道瓊斯客戶資料洩露事件。如何正確的使用以及配置儲存桶,成為了雲上安全的一個重要環節。


儲存桶的訪問控制包含多個級別,而每個級別都有其獨特的錯誤配置風險。在本文中,我們將深入探討什麼是儲存桶、什麼是儲存桶ACL、什麼是儲存桶Policy以及平臺是如何處理訪問許可權,並對錯誤配置儲存桶許可權導致的安全問題進行闡述。透過本文的閱讀,可以很好的幫助理解儲存桶的鑑權方式以及鑑權流程,避免在開發過程中產生由儲存桶錯誤配置導致的安全問題。

首先,我們來看簡單的對物件儲存的概念進行了解。

物件儲存

物件儲存是一種儲存海量檔案的分散式儲存服務,使用者可透過網路隨時儲存和檢視資料。物件儲存使所有使用者都能使用具備高擴充套件性、低成本、可靠和安全的資料儲存服務。


物件儲存可以透過控制檯、API、SDK 和工具等多樣化方式簡單、快速地接入,實現了海量資料儲存和管理。透過物件儲存可以進行任意格式檔案的上傳、下載和管理。


在瞭解物件儲存之後,我們來梳理下ACL、Policy、儲存桶的鑑權方式以及鑑權流程以及使用過程中容易產生的配置錯誤。

儲存桶訪問許可權(ACL)

訪問控制列表(ACL)使用 XML 語言描述,是與資源關聯的一個指定被授權者和授予許可權的列表,每個儲存桶和物件都有與之關聯的 ACL,支援向匿名使用者或其他主賬號授予基本的讀寫許可權。ACL屬性見下表:

圖片

表格 1 ACL屬性表

從控制檯上來看,儲存桶訪問許可權分為公共許可權與使用者許可權,見下圖:

圖片

圖 1儲存桶訪問許可權配置項

從上圖的選項來看,公共許可權和使用者許可權配置共同組成了儲存桶訪問許可權。公共許可權包括私有讀寫、公有讀私有寫和公有讀寫這幾個選項可以選擇,且為單選:

圖片

圖 2公共許可權選項

使用者許可權可以透過新增使用者進行配置,透過填寫賬號ID併為其配置資料讀取、資料寫入、許可權讀取、許可權寫入以及完全控制五個選項。


圖片

圖 3使用者許可權選項

除完全控制選項,其他幾個選項都可以靈活的搭配;而勾選完全控制選項後,則會將前四個選項一同勾選上。控制檯中儲存桶公共許可權以及使用者許可權可配置項如下:

淺談雲上攻防——物件儲存服務訪問策略評估機制研究

表格 2儲存桶訪問許可權

但是公共許可權與使用者許可權有什麼區別與關聯呢?二者又是如何作用於訪問控制列表(ACL)呢?

這些問題,單從控制檯上功能上來看是並不能完全理解的,我們需要透過修改控制檯中不同的公共許可權與使用者許可權組合,對比ACL中內容的變化來分析控制檯上這些配置項的真實作用。

首先我們透過在控制檯中勾選的選項來測試一下公共許可權是如何作用於ACL的。

公共許可權

公共許可權包括:私有讀寫、公有讀私有寫和公有讀寫,我們將依次測試一下在控制檯中勾選後ACL中實際的配置情況。

私有讀寫

只有該儲存桶的建立者及有授權的賬號才對該儲存桶中的物件有讀寫許可權,其他任何人對該儲存桶中的物件都沒有讀寫許可權。儲存桶訪問許可權預設為私有讀寫。

我們將公共許可權設定為私有讀寫,見下圖:

圖片

圖 4設定儲存桶私有讀寫訪問許可權

透過訪問API介面,獲取此時儲存桶ACL規則:

圖片

如上所示,ACL 描述了儲存桶擁有者(Owner)為(使用者 UIN:10001xxx),且此使用者擁有儲存桶的完全控制許可權(FULL_CONTROL)。

值得注意的是,此處XML中許可權配置,並不是因為我們勾選了公共許可權配置中的私有讀寫而來,而是控制檯中使用者許可權裡預設配置中當前賬號的許可權策略,見下圖紅框處:

圖片

圖 5預設配置的當前賬號許可權策略

因此,在公共許可權裡勾選私有讀寫,相當於在ACL中不額外寫入任何配置內容。

公有讀私有寫

任何人(包括匿名訪問者)都對該儲存桶中的物件有讀許可權,但只有儲存桶建立者及有授權的賬號才對該儲存桶中的物件有寫許可權。我們將公共許可權設定為公有讀私有寫,見下圖:

圖片

圖 6配置儲存桶公有讀私有寫訪問許可權

透過訪問API介面,獲取此時儲存桶訪問許可權(ACL)


圖片

從XML內容可見,透過勾選公有讀私有寫,ACL中新增瞭如下配置條目:

圖片

此條配置授予了AllUsers使用者組的READ的許可權,按許可權分類來說,屬於“匿名使用者公有讀”許可權,示意圖如下:

圖片

圖 7公有讀私有寫許可權配置示意圖

公有讀寫

任何人(包括匿名訪問者)都對該儲存桶中的物件有讀許可權和寫許可權。

圖片

圖 8配置儲存桶公有讀寫訪問許可權

透過訪問API介面,獲取此時儲存桶ACL。

圖片

如上所示,透過勾選公有讀寫,ACL中新增瞭如下配置條目。

圖片

與上文的公有讀私有寫許可權相比,新增了AllUsers使用者組WRITE的許可權,即“匿名使用者公有讀寫”許可權,示意圖如下:

圖片

圖 9 公有讀寫許可權配置示意圖

從上述實驗結果來看:公共許可權配置的選項“私有讀寫“、”公有讀私有寫“和公有讀寫”本質上是在ACL中新增AllUsers使用者組的READ與WRITE許可權。公共許可權配置選項的總結如下:

  • 私有讀寫:不在ACL中新增任何額外的許可權配置條目

  • 公有讀私有寫:在ACL中新增AllUsers使用者組READ許可權項

  • 公有讀寫:在ACL中新增AllUsers使用者組READ許可權項、AllUsers使用者組WRITE許可權項

在分析完公共許可權之後,我們來分析一下使用者許可權。

使用者許可權

使用者許可權和公共許可權有什麼區別呢?其實都是修改ACL策略,沒有本質的區別,只是公共許可權在勾選時,生成ACL中ALLUSers的三個許可權,而透過使用者許可權配置的,在ACL中精準到使用者,並且許可權策略也擴充為5個可選項。

圖片

圖 10使用者許可權配置可選項

我們先保持公共許可權的預設設定——私有讀寫,並在控制檯編輯使用者許可權,新增一個ID為123456的賬號。

資料讀取-資料寫入

我們為此賬號設定資料讀取、資料寫入的許可權,見下圖:

圖片

圖 11配置使用者資料讀取寫入許可權

透過訪問API介面,獲取此時儲存桶ACL。

圖片

從XML內容可見,在控制檯新增一個擁有資料讀取、資料寫入許可權的賬號後, ACL中新增瞭如下配置:

圖片

ACL中增加了一個uin為123456的使用者的READ與WRITE許可權,示意圖如下:

圖片

圖 12資料讀取寫入許可權配置示意圖

許可權讀取-許可權寫入

接下來我們保持公共許可權為預設的私有讀寫不變,並在使用者許可權處新增一個ID為123456的賬號,我們為此賬號設定許可權讀取、許可權寫入的許可權,見下圖:

圖片

圖 13配置使用者許可權讀取寫入許可權

透過訪問API介面,獲取此時儲存桶ACL。

圖片

如上所示,在控制檯新增一個擁有許可權讀取、許可權寫入的賬號後, ACL中新增瞭如下配置:

圖片

ACL中增加了一個uin為123456的使用者的READ_ACP與WRITE_ACP許可權,此時123456使用者可以對ACL進行讀取以及更新操作,示意圖如下:

圖片

圖 14許可權讀取寫入許可權配置示意圖

公有讀寫-資料讀取-資料寫入

在這環節中,我們將實驗一下公共許可權與使用者許可權的關係,我們將公共許可權設定為公有讀寫,並在使用者許可權處新增一個ID為123456的賬號,我們為此賬號設定許可權讀取、許可權寫入的許可權,見下圖:

圖片

圖 15配置公有讀寫-資料讀寫許可權

透過訪問API介面,獲取此時儲存桶ACL

圖片

透過對比公共許可權章節中公有讀寫與使用者許可權章節中資料讀取-資料寫入部分的內容可以發現, 在控制檯中配置的公共許可權與使用者許可權是各自作用於ACL中,在ACL中並不互相影響,配置的公有讀寫將會在ACL中新增一個AllUsers使用者組的WRITE與READ許可權,而使用者許可權中新增的123456賬號的資料讀取、資料寫入將在 ACL中加入了一個123456賬號的READ與WRITE許可權。


但是細心的讀者可能會發現一個有意思的問題,在配置使用者許可權時,ACL中預設的Owner的FULL_CONTROL許可權不見了

消失的Owner許可權

對比一下公共許可權章節中私有讀寫部分的ACL,我們發現了一個問題,見下圖:

圖片

圖 16 公有許可權相同、使用者許可權不同時ACL差異性

雖然我們僅僅是在使用者許可權處增加了一個新使用者,並沒有刪除也沒有辦法刪除控制檯中預設的主賬號的完全控制權,但是ACL中預設的擁有完全控制權的主賬號條目不見了,見上圖紅框處。


這樣會不會導致主賬號失去了儲存桶的控制權呢?經過測試發現,主賬號依然擁有儲存桶的完全控制權,這是問什麼呢?

透過查閱官方文件,我們發現了答案:

圖片

資源的擁有者,即Owner始終對資源具備完全控制權,無論ACL中是否存在此項。

儲存桶策略(Bucket Policy)

在分析完ACL之後,我們來看看Policy。儲存桶策略(Bucket Policy)使用 JSON 語言描述,支援向匿名身份或任何 CAM 賬戶授予對儲存桶、儲存桶操作、物件或物件操作的許可權,在物件儲存中儲存桶策略可以用於管理該儲存桶內的幾乎所有操作。Policy屬性見下圖:

圖片

表格 3 Bucket Policy屬性表

我們可以透過在控制檯中新增策略的方式來設定Policy許可權。

圖片

圖 17透過控制檯新增Policy

我們新增一個新策略,該策略允許所有使用者對我們的儲存桶進行所有操作,見下圖:

圖片

圖 18新增新策略

透過訪問API介面,獲取許可權策略。

圖片

可以發現,Policy中以共有四個主要的屬性:Action、Effect、Principal、Resource,分別對應了控制檯中填寫的操作、效力、使用者、資源路徑。與ACL僅可以配置的使用者與許可權選項相比,控制的顆粒更細。

接下來,我們新增一個允許賬號ID為123456的賬號對cos-aclxxx/policy_test路徑的讀操作。

圖片

圖 19 配置賬號指定資源操作許可權

透過訪問API介面,獲取許可權策略。

圖片

在這個Policy中,我們可以看到更細膩的Action與Resource配置。

物件訪問許可權

在物件儲存中,每一個物件同樣存在著可配置的訪問許可權,預設繼承儲存桶的ACL。

圖片

圖 20物件訪問許可權控制檯介面

我們將此物件設定為公有讀私有寫許可權,見下圖:

圖片

圖 21配置物件公有讀私有寫許可權

透過查詢GetObjectAcl API介面,獲取其ACL。

圖片

從ACL可見,與儲存桶的ACL配置項完全一樣,只不過這裡的ACL作用於目標物件而儲存桶ACL作用於儲存桶。

但是物件儲存是如何透過ACL與Policy共同協調控制儲存桶許可權的呢?

我們接下來看一下物件儲存的訪問策略評估流程。

訪問策略評估機制

在開始介紹物件儲存訪問策略評估流程之前,我們先介紹一下幾個流程中涉及到的重要概念:顯示拒絕、顯示允許、隱式拒絕以及三者之間的聯絡:

01顯式拒絕

在使用者策略、使用者組策略、儲存桶 Policy 中針對特定使用者有明確的 Deny 策略。 

02顯式允許

在使用者策略、使用者組策略、儲存桶 Policy、儲存桶 ACL 中透過grant-\*明確指定特定使用者針對特定使用者有明確的 Allow 策略。

03隱式拒絕

在預設情況下(未經配置的情況下),所有請求都被隱式拒絕(deny)。


顯示拒絕、顯式允許、隱式拒絕之間的關係如下:

如果在使用者組策略、使用者策略、儲存桶策略或者儲存桶/物件訪問控制列表中存在顯式允許時,將覆蓋此預設值。任何策略中的顯式拒絕將覆蓋任何允許。

在計算訪問策略時,應取基於身份的策略(使用者組策略、使用者策略)和基於資源的策略(儲存桶策略或者儲存桶/物件訪問控制列表)中策略條目的並集,根據顯示拒絕、顯式允許、隱式拒絕之間的關係計算出此時的許可權策略。


圖片

圖 22儲存桶鑑權流程

透過上圖,我們可以很清楚的理解儲存桶的鑑權流程。

訪錯誤配置導致的安全問題

錯誤使用公有讀寫許可權

在所有錯誤配置導致的儲存桶安全問題中,最常見的一種便是錯誤的使用了公有讀寫許可權導致的安全問題。

圖片

圖 23配置儲存桶公有讀寫訪問許可權

透過上文的分析可知,公有讀許可權可以透過匿名身份直接讀取使用者儲存桶中的資料,存在著嚴重的安全隱患。

但是有些使用者為了避免使用繁雜且細粒度的許可權配置,會錯誤的將其儲存桶設定為公有讀寫,這將導致了其儲存桶中的內容被攻擊者竊取與篡改。正如本文前言中所描述的2017美國國防部承包商資料洩露案例。即便是美國國防部承包商,在使用儲存桶進行物件儲存時,也會犯下這樣的常見錯誤。

因此,為了保障儲存桶安全,建議使用者為儲存桶配置私有讀寫許可權。

儲存桶、物件訪問許可權差異性問題

儲存桶許可權與物件許可權的差異性,往往會為物件資源來安全性問題。

在實際操作中,為了儲存桶的安全起見,儲存桶的公共許可權往往會被設定為私有讀寫,這也是儲存桶的預設公共許可權配置,見下圖:

圖片

圖 24配置儲存桶私有讀寫許可權

儲存桶的私有許可權表明,只有該儲存桶的建立者及有授權的賬號才對該儲存桶中的物件有讀寫許可權,其他任何人對該儲存桶中的物件都沒有讀寫許可權。

但是將儲存桶的公共許可權設定為私有讀寫可以完全保護儲存桶中的中的物件資源不被讀取嗎?

在我們測試的這個儲存桶中,並未設定Policy策略,並且存在著一個名為p2.png的物件。

圖片

圖 25 p2.png物件

而從上文可知,儲存桶中的物件也有著其對應的物件許可權。

在這裡我們將物件p2.png的ACL許可權設定為公有讀私有寫,見下圖:

圖片

圖 26為p2.png物件配置公有讀私有寫

透過訪問p2.png資源url可以發現,此時p2.png物件可以被訪問,見下圖:

圖片

圖 27成功訪問p2.png物件

測試表明,當儲存桶公共許可權設定為私有讀寫時,當儲存桶中的物件公共許可權為公有讀私有寫時,此物件依然是可以被讀取的。

實際原理很簡單,我們為物件p2.png設定了公有讀私有寫ACL策略,此時物件資源p2.png的ACL如下:

圖片

根據上文訪問策略評估機制一章可知,物件p2.png設定了AllUsers使用者組的顯性允許READ許可權,因此當匿名使用者訪問p2.png時,即使儲存桶設定了私有讀寫許可權,依然可以訪問此物件,原理圖見下圖:

圖片

圖 28 訪問p2.png時的鑑權流程

因此,單單依靠儲存桶的訪問許可權,並不能保護其中資源的未授權訪問情況。為儲存桶中資源配置對應的訪問許可權,才可以保證物件的安全性。

錯誤授予的操作ACL許可權

在Policy許可權設定中,如果授權使用者操作儲存桶以及物件ACL的許可權(GET、PUT)見下圖:

圖片

圖 29授予使用者操作ACL許可權

即使Policy中沒有授權該使用者讀取儲存桶、寫入儲存桶、讀取物件、寫入物件的許可權,這個操作依然是及其危險的,因為該使用者可以透過修改儲存桶以及物件的ACL進行越權。

我們在coscmd中配置授權使用者的金鑰資訊後,透過coscmd list列出儲存桶中內容。

圖片

圖 30儲存桶list操作失敗

從返回結果來看,該使用者並沒有讀取儲存桶列表的許可權

經過測試,使用者同樣也沒有下載p2.png物件的許可權,見下圖:

圖片

圖 31下載物件操作失敗

但是我們卻可以查詢儲存桶中物件的ACL,見下圖:

圖片

圖 32成功檢視物件ACL

由於該使用者擁有修改儲存桶中物件ACL的許可權,因此可以透過如下指令授予該使用者讀取p2.png的許可權,見下圖:

圖片

圖 33授予使用者p2.png讀許可權

在修改過p2.png許可權之後,可以順利的將此物件下載到本地。

圖片

圖 34成功下載p2.png物件

資源超範圍限定

在使用儲存桶進行物件讀取或寫入操作時,如果沒有合理的或者錯誤的在Policy中配置使用者允許訪問的資源路徑(resource),則會出現越權訪問,導致使用者資料被惡意上傳覆蓋或被其他使用者下載等安全問題。


在Web應用開發中,經常會發生此類問題。設想以下場景:在一個Web應用使用物件儲存來儲存使用者頭像,且透過前端直傳的方式將使用者上傳的頭像傳至儲存桶中,並希望在儲存桶/avatar/路徑中儲存桶使用者的頭像,由於後端開發時為了方便而進行了不規範的儲存桶Policy配置,在生成使用者用以上傳頭像的臨時金鑰時直接將此臨時金鑰允許訪問的 resource 指定為 qcs::cos:<Region>:uid/<APPID>:<BucketName-APPID>/avatar/*路徑。


這樣以來,系統為每個使用者所生成的用以上傳以及瀏覽頭像的臨時金鑰雖然不盡相同,但是這個臨時金鑰都擁有qcs::cos:<Region>:uid/<APPID>:<BucketName-APPID>/avatar/*路徑中的所有資源的讀寫許可權。

這一錯誤的配置導致了很多嚴重的安全問題,由於在此場景下,Web應用程式使用前端直傳的方式訪問儲存桶,因此後臺生成的臨時金鑰將會傳送給前臺,任意使用者透過網路抓包等手段獲取到的臨時憑據,可參見下圖流量中響應包內容。

圖片

圖 35從流量中獲取臨時憑據

在獲取了臨時金鑰之後,攻擊者憑藉此憑據讀寫qcs::cos:<Region>:uid/<APPID>:<BucketName-APPID>/avatar/*路徑中的任意物件。

攻擊者可以透過此方式覆蓋目錄中其他使用者資源,見下圖:

圖片

圖 36覆蓋其他使用者資源

上圖攻擊者透過test.txt檔案覆蓋了16.png。當然,攻擊者也可以輕易的讀取此目錄中其他使用者的檔案。

針對此問題的修復方式如下:可以透過每個使用者的使用者標識來為每一個使用者設定一個獨用的路徑,例如可以在為使用者生成臨時金鑰時,將policy中resource 指定為 qcs::cos:<Region>:uid/<APPID>:<BucketName-APPID>/avatar/<Username>/*來滿足規範要求;此外,resource 欄位支援以陣列的形式傳入多個值。因此,也可以顯式指定多個 resource 值來完全限定使用者有許可權訪問的最終資源路徑。

寫在後面

物件儲存服務作為一項重要的雲上服務,承擔了儲存使用者資料的重要功能。從上文分析可見,物件儲存服務提供了細粒度的訪問許可權控制功能,以保證使用者資料的安全性。


但是由於使用者使用物件儲存服務時安全意識不足或對訪問許可權以及訪問策略評估機制錯誤的理解,將會導致資料被非法訪問或篡改。這些錯誤的配置包括使用者錯誤的使用公有讀寫許可權、錯誤授予操作ACL許可權、配置資源超過範圍限定以及對儲存桶許可權機制錯誤理解等,這些錯誤的配置將會造成嚴重的安全問題。


因此,深入瞭解物件儲存服務所提供的訪問許可權以及訪問策略評估機制,並始終遵循最小許可權原則,將會為儲存桶中儲存的資料安全構築立體防護體系的一道堅固的門鎖,與此同時,也可以透過檢查儲存桶日誌以及檔案時間戳來排查儲存桶是否被侵害,確保雲上資產的安全。


參考文獻

https://labs.detectify.com/2017/07/13/a-deep-dive-into-aws-s3-access-controls-taking-full-control-over-your-assets/

https://blog.lightspin.io/how-to-access-aws-s3-buckets

https://blog.lightspin.io/risks-of-misconfigured-s3-buckets

https://cloud.tencent.com/document/product/436/40265

https://main.qcloudimg.com/raw/document/intl/product/pdf/436_9511_zh.pdf


相關文章