使用 CloudTrail 橫向 AWS 賬戶
在進行云上滲透測試(CPT)時,目標是發現和利用高風險問題,例如權限提升、遠程代碼執行或進入生產環境。我們通常從開發環境中的低權限用戶開始,這個權限一般和剛入職的員工訪問權限差不多。
在一些項目中,權限提升將我們從低權限用戶升級到管理員,而且都是在同一個AWS賬戶中。但是,如果權限提升涉及到離開組織并帶入外部角色,會發生什么?
讓我們看看如何利用 AWS CloudTrail 服務來發現可以橫向的其他 AWS 賬戶。
提升權限
根據我們的經驗,偽裝成剛入職的開發人員索要相關員工所有權限是進行 CPT 時比較常見的做法,之所以這樣做是因為敏感信息存儲在許多地方,如果只將范圍限制在AWS資產上,我們就會錯過作為公司員工可能存在的權限提升路徑。
開發人員可能在開發環境中擁有大量權限,但通常不具備管理員權限,并且肯定不能訪問或修改生產環境中的資產。我們通常會在開發環境中進行詳細的測試,并嘗試通過查找 API 密鑰來提升權限。我們通常會在 S3 存儲桶、Lambda 環境變量、內部 wiki 或存儲在其他地方(例如 GitHub 或 BitBucket 代碼存儲庫)中找到一些。
一旦我們找到一組或多組 AWS API 密鑰,所面臨的的首個問題就是它們有什么訪問權限,以及它們的用途是什么。因為已經對開發環境進行了比較詳細的測試,所以想弄清楚開發環境的密鑰所具備的權限是比較簡單的。但在其他AWS賬戶中,我們能用這些密鑰做什么呢?這取決于權限策略是如何制定的。
其中一些可能很容易弄清楚,例如下面的策略顯示,當前賬戶具有sts:AssumeRole權限,當然前提是策略里的 Effect 值為 Allow
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Example1", "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::123456789012:role/myassumerole" } ]}
但是,如果 API 密鑰所屬賬戶的策略是下面這個樣子要怎么辦?
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Example2", "Effect": "Allow", "Action": "sts:*", "Resource": "*" } ]}
此用戶賬戶也許能夠擔任多個 AWS 賬戶中的角色,但權限策略中沒有任何內容提供有關 AWS 賬戶 ID 或角色名稱的信息。AWS 沒有查詢其他賬戶中可以帶入的角色的機制,因此在滲透期間,我們無法確定我們可以帶入 AWS 賬戶123456789012,但真的是這樣嗎?
Pacu 這個工具里的 iam_enum_roles 模塊可以被用來枚舉 AWS 環境中的角色,該模塊將嘗試猜測目標帳戶中的角色名稱,并確定它們是否可以被帶入。但是使用這個 Pacu 模塊仍然需要我們知道我們想要帶入的目標 AWS 賬戶 ID。如果我們沒有這些信息怎么辦?幸運的是,還有另一種方法可以在其他 AWS 賬戶中查找角色,并結合現有的工具和技術來枚舉權限提升的路徑。
帶入角色
假設我們為一個名為deployBot的賬戶找到了一套有效的API密鑰。在枚舉過程中,我們發現該賬戶的權限比較有限,不過它有sts:assumeRole:*權限,考慮到這個賬戶的名字,我們懷疑我們可以使用它來橫向到另一個環境,但首先我們需要知道準備橫向的帳戶 ID 和角色名稱。
雖然我們可能沒辦法枚舉出可以帶入的所有角色,但如果我們的賬戶擁有cloudtrail:LookupEvents權限,我們或許可以使用 CloudTrail 嘗試并列舉其中一些角色。
在 AWS 中,assumeRole會被 CloudTrail 記錄,詳細信息將被存儲在任何被配置為捕獲此類管理事件的跟蹤中。因此,我們可以查詢 CloudTrail 并搜索這些成功的assumeRole事件,從而嘗試找到我們可以訪問,但我們還不知道的其他 AWS 賬戶。
相關命令如下:
aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=AssumeRole --region us-east-1 | jq '.Events | .[] | .Username as $username | .CloudTrailEvent | fromjson | {timestamp: .eventTime, user: $username, assumedRole: .requestParameters.roleArn}'
此命令的輸出如下所示:
{ "timestamp": "2021-12-23T00:35:45Z", "user": "root", "assumedRole": null}{ "timestamp": "2021-12-23T00:00:26Z", "user": "user1", "assumedRole": "arn:aws:iam::123456789012:role/SecurityAudit"}{ "timestamp": "2021-12-23T00:00:26Z", "user": "user1", "assumedRole": "arn:aws:iam::210987654321:role/SecurityAudit"}{ "timestamp": "2021-12-22T23:50:41Z", "user": "deploybot", "assumedRole": "arn:aws:iam::112233445566:role/deployToProd"}
從這個輸出中,我們可以看到有人試圖使用 root 賬戶來帶入一個角色,但是 AWS 不允許這樣做,所以它失敗了。我們還看到用戶user1帶入了 AWS 賬戶為123456789012和210987654321的角色。但是更有趣的事件是用戶deploybot,他帶入了一個名為deployToProdAWS Account的角色112233445566,這是一個值得關注的線索。
我們與客戶確認后得知該賬戶屬于他們,并且在這樣做之前,我們已經被授權跟蹤這個線索,在確認后,我們將帶入該角色并開始在新的 AWS 賬戶中進行滲透。事情的發展方向取決于分配給AWS112233445566中的deploybot賬戶和資產的權限。
用戶帳戶可能幾乎沒有權限,在這種情況下,這條路徑被證明是一條死胡同。或者,用戶帳戶可能具有完全的管理權限,在這種情況下,我們剛剛成功入侵了客戶的生產帳戶,或者介于兩者之間的任何東西。但更多的時候,通過一些中間的權限升級方法,我們最終會達到破壞關鍵生產資源的目標。關鍵在于 CloudTrail 可用于首先發現此類權限提升路徑的存在。
結論
以上是我們經常遇到的簡化但現實的云滲透測試場景。在枚舉過程中,我們經常會發現客戶沒有告訴我們 AWS 賬戶的憑證或 API 密鑰,但它們為敏感的云資源提供了可行的權限提升路徑。
本文描述的這條命令是一種新方法,通過使用來自 CloudTrail 的信息列出assumeRole事件,從而實現對 AWS 攻擊面的枚舉。這可能會發現現有的跨賬戶關系,否則這些關系可能會被忽視,特別是如果涉及不尋常的角色名稱,這時如果去猜測或使用暴力破解角色名稱的工具就會錯過這些角色。
我們希望這些信息能夠幫助其他云滲透測試人員識別和修復跨賬戶訪問問題。