谷歌Flank潛藏3年的Github Action供應鏈攻擊

01

?簡? 介

Flank?[1]?是谷歌 Firebase Test lab 開源在 Github 的一個項目,用于同時對多個安卓和IOS設備進行測試。2024年4月15號 AWS 安全工程師 Adnan Khan 公布了關于該項目代碼倉庫 Github Action CI/CD 存在漏洞的細節[2],漏洞在2020年于此 代碼合并請求[3]?引入,3年多一直沒人發現(這個倉庫谷歌一直有賞金計劃),谷歌把該漏洞歸屬為供應鏈漏洞,并給予該漏洞賞金 $7500 美刀(約 5w+ 人民幣)。

利用該漏洞可以獲得 Flank Github 代碼倉庫的寫權限的 GITHUB_TOKEN 和谷歌云的賬戶密鑰(看給的賞金大概能想到該密鑰能進一步獲取到的權限),該漏洞于2024年4月11號修復。

漏洞整體利用鏈圖解(文章后面會附上復現環境和步驟~):

圖片

另外,具有寫權限的?GITHUB_TOKEN?可以用來發布 GitHub Release 以及 Release 附件,從而發布惡意的編譯后二進制軟件來達到供應鏈攻擊的效果,原文作者由于是 Bug Bounty,滲透講究點到為止,不過本文也會涉及這部分利用手段。

02

?背? 景

Github Action

Github Action?[4]用于在 Github 代碼倉庫中自動化、自定義和執行軟件開發工作流程,也可用于持續集成持續部署流程(即 CI/CD),十分便于開發者使用,而不用專門去部署一套 Jenkins 之類的用于 CICD。具體表現在 Github 上,就是在代碼倉庫根目錄建一個?.github?目錄,里面放著一些定義自動化任務的 yaml/yml 文件,稱之為?workflow?(工作流),

圖片

關于?.github?目錄大家應該挺眼熟的,但一般我們都會忽略不太起眼的它,因為一般它不會存在什么特別的安全漏洞,但本文的重點就是里面的?workflow?。

?workflow?觸發的方式很多,比如在?git push?代碼到倉庫時觸發,亦或是在創建代碼合并請求(Pull Request,下文簡稱?PR?)觸發等,觸發后通過 Github Runner(執行器) 去執行相應的?workflow?,觸發等方式多種多樣,觸發方式寫法一般如下:

圖片

上下?workflow?即是在代碼 push 到 main 分支或者是 PR 入 main 時觸發,運行結果輸出?Hello World?

在本漏洞中,通過在?PR?評論區回復特定關鍵字觸發存在漏洞的?workflow?。

Github Action Secrets

關于 Github Action secrets?[6],比如我們給代碼跑完單元測試后想要自動部署,那部署到相關環境需要的SSH或其他密鑰肯定是不想明文放出來的,比如硬編碼在倉庫代碼中,或者直接寫在倉庫配置文件中,這樣大家就都能在 Github 倉庫文件中看到了。

使用 secrets 的好處是,可以把這類密鑰在跑 workflow 時,通過 Runner 環境變量的形式帶進去。這樣就解決剛剛說的問題了。此外,就算相關代碼不小心把某個上下文變量日志給打了出來,secret 恰好包含在其中,Github Runner 顯示的日志,也會把 secrets 脫敏顯示,也就是說,就算我們主動?print($secret)?,他在 Runner 日志中顯示的也是脫敏數據,如?******?。

以?GITHUB_?開頭的為 Github Runner 內置的一些環境變量或Secret?[5],在 Action 中的 yaml 通過?${{ secrets.GITHUB_TOKEN }}?即可引入,非常方便。

先獻上存在漏洞的 workflow

https://github.com/Flank/flank/blob/v23.10.1/.github/workflows/run_integration_tests.yml

直接看漏洞存在和利用點可能沒那么明顯,下面來分析一下

03

?漏洞發現和利用

其實這類由 PR 引發漏洞,并且是有賞金計劃的,一般在數日內就會被發現。因為多數賞金獵人,基本都是通過自動化的工具對?.github?目錄里的文件進行批量檢測,相關的工具有?gato?[7]?和 gh-workflow-auditor?[8],其中 gato 是原文作者是通過在上一家公司工作開源的自研工具。該漏洞是他對 gato 不斷優化的 gato-x 版發現的,目前優化版 gato-x 還沒開源出來,原作者還在盡可能的優化,然后在不久的將來放出來。

至于這個漏洞為啥一直沒被發現的原因,他和普通的 Action 注入不太一樣,例如下面這個流水線[9]

圖片

如果攻擊者在這個項目 Github 上新建一個 issue 的標題為?test" && ls / && echo "?,會直接造成流水線 runner 里的命令注入

圖片

即,這種 Action 注入是執行命令時直接拼接了外部可控的變量。

而 Flank 觸發流水線時并沒有直接拼接可控變量,只是獲取了 PR 的序號,

圖片

然后通過?gh?命令切換到我們 PR 的代碼上,這時才出現我們可控的部分

圖片

即此時會切換到我們 PR 的代碼,但此時它仍然沒有拼接任何東西。特別是對于自動化工具而言,這里根本就不會檢測出來,因為沒有拼接可控的東西。由于 Github 上的 workflow 太多,一個個找和看,其實是不好找出來的。就像我們看存在問題的 workflow,一下子我們也沒能太看出來存在什么問題,這就是為啥這個漏洞存在這么久才被發現。

原作者檢測工具的設計目的就不太一樣,他是掃描存在觸發風險點的地方,然后在回過頭來看是不是誤報,盡管有接近70%的是誤報。

在看整個 workflow 文件,在項目 PR 評論區回復?@flank-it?會觸發?should_run_it??job,這個 job env 帶有?GITHUB_TOKEN?secret,并且該 token 有該項目的寫權限(如果沒有該項目的寫權限,這個在評論區加個眼睛 👀?的 emoji 是加不上的)

圖片

然后?should_run_it?運行結果?run_integration_tests?為?true?會觸發?env?帶有 GCLOUD_KEY?secret ?的 job

圖片

到這里,還沒講到,Action 注入的,我們可控的惡意代碼在哪呢?目前我們向此倉庫發 PR,然后流水線中?gh checkout 我們的PR?切換到我們的代碼。其實對于一般的流水線,都會有構建操作,即打包代碼之類的,這里用的是?gradle?

圖片

然后?gradle?DSL(領域定義語言)是基于 Groovy的[10]!Gradle 5.0 后,還支持了 Kotlin 語言,也就是說我們可以執行通過任意代碼執行,從而達到任意命令執行!從而達到就可以把這兩個 secret 通過?curl?命令外帶即可(非項目成員記得是看不到流水線運行結果的,所以不能像下面漏洞復現那樣編碼輸出)。

惡意 PR

https://github.com/Flank/flank/pull/2481/files#diff-5625e3601fa0ad3a6a2824239e5a2fde71c149597d31394f9224a08c24be7b9d

然后作者為了規避 harden-runner [11]安全檢測機制,只改了原倉庫的 gradle,其他都是改 fork 到自己倉庫的,因為在自己 fork 的倉庫改,在原倉庫也會留有 commit 信息(雖然最后還是告警了,原文還是有提到其他規避方法的)

由于執行 gradle 沒有代入 secret 環境變量,這里需要用個 trick,即讀取進程內存來獲取 runner 里的 secret。因為就算是不同階段的 job,一般都是在一個容器里執行。

圖片

圖片

03

?漏洞復現

環境搭建(可跳過)

搭建好的復現環境:https://github.com/tarihub/hack-flank-cicd

復現環境的項目配置(自己搭建就需要注意下,免得踩坑):

  • https://github.com/tarihub/hack-flank-cicd/settings/actions 需要在這里勾上 Workflow permissions 的 Read and write permissions 權限,不然小眼睛👀交互打不上(其實主要是模擬原項目給了 GITHUB_TOKEN 的寫權限)

圖片

  • secret 記得 base64編碼一下,不然解碼會失敗

圖片

復現步驟

先fork https://github.com/tarihub/hack-flank-cicd 項目過來,然后把?settings.gradle.kts?改為

圖片

PS:這里的 pastebin 內容就是上面的 讀取進程內存 處,用來讀取 Runner 進程內存中存的 secret

commit 并 push 后發送 PR 到原倉庫,在 PR 評論區留言?@flank-it?觸發 Github Action

圖片

運行過程,這里為了方查看所以直接輸出

圖片

正常情況下利用,由于非項目成員,看不到運行結果,所以需要用 curl 外帶

圖片

就得到 GCLOUD_KEY 和 GITHUB_TOKEN

圖片

base64解碼得?flag{GCLOUD_KEY}?

接下來,我們拿到具有寫權限的 Github_TOKEN 就可以發布 release 附件了,一般項目都會有 release,所以我們先創建一個 release,創建好標簽命名完標題保存即可

https://github.com/tarihub/hack-flank-cicd/releases/new

這里注意,獲取到的?GITHUB_TOKEN?要在流水線運行結束前使用,否則 token 會失效,因此我們可以通過 sleep 等各種方式阻塞流水線的運行

根據 Github 文檔[12],然后要獲取 RELEASE_ID

圖片

圖片

然后通過接口增加/修改 release 附件即可

圖片

圖片

來到 Github Release 頁面就看到我們的惡意附件就上傳上去了

圖片

至于?GCLOUD_KEY?的進一步利用,網上有很多文章介紹,這里就不進一步深入了

05

?總? 結

該漏洞的修復,官方去除了在 PR 評論區留言觸發流水線的方式,并且不會切換到 PR 部分對代碼,只保留了定期觸發流水線,這樣攻擊者就無法觸發可控的攻擊代碼了。

https://github.com/Flank/flank/pull/2482

縱觀漏洞從發現到利用整條利用鏈還是相當精彩的,原來 Github Action CI/CD 還能這樣利用,平常審計代碼都是直接跳過 Github Action 的… 又一次感受到公有云的安全難做,有時候這些密鑰真不知道怎么就泄漏出去了。

因此,廣大開發者使用 Github Action 時也請注意,當 workflow 帶有 secret 時,注意避免各種形式讓未授權人員在 Github runner 中執行外部可控的代碼或邏輯,也應該部署 harden-runner?[11]等相關工具,防止以及監測可能的異常 workflow,從而保障開源代碼的安全。

06

?參考鏈接

[1] https://github.com/Flank/flank

[2] https://adnanthekhan.com/2024/04/15/an-obscure-actions-workflow-vulnerability-in-googles-flank

[3] https://github.com/Flank/flank/pull/1409

[4] https://docs.github.com/zh/actions

[5] https://docs.github.com/zh/actions/security-guides/using-secrets-in-github-actions

[6] https://docs.github.com/zh/enterprise-cloud@latest/actions/security-guides/automatic-token-authentication#about-the-github_token-secret

[7] https://github.com/praetorian-inc/gato

[8] https://github.com/TinderSec/gh-workflow-auditor

[9] https://cycode.com/blog/github-actions-vulnerabilities/

[10] https://docs.gradle.org/current/dsl/index.html

[11] https://github.com/step-security/harden-runner

[12] https://docs.github.com/zh/rest?apiVersion=2022-11-28

本文作者:

tari,首批 CSA CCPTP 認證專家、CSA 大中華區云滲透測試工作組成員

審校:

李鑫,CSA大中華區云滲透測試工作組組長

梁嘉榮,CSA大中華區研究協調員

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/13417.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/13417.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/13417.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

通信網絡時鐘同步(PTP網絡授時服務器)技術探討

通信網絡時鐘同步(NTP網絡授時服務器)技術探討 通信網絡時鐘同步(NTP網絡授時服務器)技術探討 1、著移動通信業務的發展和移動用戶的快速增長, 移動網絡架構向IP化、寬帶化進展。為了適應業務IP化發展趨勢&#xff0c…

02 VUE學習:模板語法

模板語法 Vue 使用一種基于 HTML 的模板語法,使我們能夠聲明式地將其組件實例的數據綁定到呈現的 DOM 上。所有的 Vue 模板都是語法層面合法的 HTML,可以被符合規范的瀏覽器和 HTML 解析器解析。 在底層機制中,Vue 會將模板編譯成高度優化的…

開發vue3,真的可以不用ref/reactive了,也不需要ref.value

什么是Cabloy-Front? Cabloy-Front 是一款支持 IOC 容器的 Vue3 框架。不用ref/reactive,不用ref.value,不用pinia 與UI庫的配合 Cabloy-Front 可以搭配任何 UI 庫使用,并且內置了幾款 UI 庫的項目模版,便于開箱即用…

免費SSL證書簽發安裝指南

一、簽發 1.選擇證書頒發機構(CA):首先,你需要找到一個提供免費SSL證書的CA。有些CA會提供永久免費的SSL證書,而有些則可能只提供有限時間的試用證書,如JoySSL就提供永久免費證書。 2.生成CSR&#xff08…

WPF 鼠標拖拽平移

效果 xaml <ScrollViewer x:Name"scrollViewer" HorizontalScrollBarVisibility"Hidden" VerticalScrollBarVisibility"Disabled" Background"#FFF1ADAD"PreviewMouseDown"ScrollViewer_OnPreviewMouseDown"PreviewMou…

Electron學習筆記(一)

文章目錄 相關筆記筆記說明 一、輕松入門 1、搭建開發環境2、創建窗口界面3、調試主進程 二、主進程和渲染進程1、進程互訪2、渲染進程訪問主進程類型3、渲染進程訪問主進程自定義內容4、渲染進程向主進程發送消息5、主進程向渲染進程發送消息6、多個窗口的渲染進程接收主進程發…

白鯨開源CEO郭煒在2024 DataOps發展大會上獲聘專家

2024年5月15日&#xff0c;白鯨開源CEO郭煒在2024 DataOps發展大會上被正式聘任為DataOps專家&#xff0c;并獲得了榮譽證書。本次大會由中國通信標準化協會主辦&#xff0c;中關村科學城管委會提供支持&#xff0c;大數據技術標準推進委員會&#xff08;CCSATC601&#xff09;…

iisnginx環境一次奇怪的跨域問題解決經過

跨域問題描述&#xff1a; iis網站跨域、nginx 網站跨域 都已配置&#xff0c;訪問接口依然出現跨域問題。 錯誤提示&#xff1a; ccess to XMLHttpRequest at ‘https://xxx.com/gameapi/preserve/get/status’ from origin ‘https://cdn.xxx.com’ has been blocked by CO…

Python簡易信息管理系統

我們將通過一個實例來探討如何使用Python與MySQL數據庫進行交互&#xff0c;以構建一個簡單的學生信息管理系統。這個系統將能夠執行基本的CRUD&#xff08;創建(Create)、讀取(Retrieve)、更新(Update)、刪除(Delete)&#xff09;操作&#xff0c;以管理學生信息。我們將使用m…

Python爬蟲-批量爬取新能源汽車上牌量

前言 本文是該專欄的第27篇,后面會持續分享python爬蟲干貨知識,記得關注。 最近粉絲朋友咨詢新能源汽車上牌量數據的爬取方法,對此在本文中,筆者以某汽車平臺為例,通過python來實現對“新能源汽車上牌量”的數據進行抓取。 具體實現思路和詳細邏輯,筆者將在正文結合完整…

三豐云搭建QQ-bot的服務器-代碼實現(3)

網址&#xff1a;https://www.sanfengyun.com >> 三豐云免費云服務器 代碼實現 書接上回裝飾器&#xff0c;顯而易見&#xff0c;只有裝飾器還不完善&#xff0c;所以我們接著來補充代碼 首先定義一個 MyClient 類 class MyClient(botpy.Client):async def on_ready(…

Nacos :安裝配置、服務注冊

目錄 一、中文官網 二、配置 1、application.properties 2、啟動 Nacos 服務 3、訪問 Nacos 三、服務注冊 1、配置Nacos客戶端的pom依賴 2、添加服務配置信息 3、添加 Nacos 啟動注解 一、中文官網 Nacos官網 | Nacos 官方社區 | Nacos 下載 | Nacos 下載后直接解壓…

0X JavaSE-- ( 遍歷-- for each、Iterator 、)、

for each for each 語句是 JDK5 的新特征&#xff0c;主要用于遍歷數組、集合。 // collection 可以是數組/實現了 Iterable 接口的集合類 for(dataType variable : collection){ // 使用 item 進行操作 } // 遍歷二維數組// 初始化一個二維數組int[][] array {{1, 2, 3},{4…

GO語言核心30講 實戰與應用 (io包,bufio包,os包,網絡服務,http,性能分析)

原站地址&#xff1a;Go語言核心36講_Golang_Go語言-極客時間 一、io包中的接口和工具 1. strings.Builder、strings.Reader 和 bytes.Buffer 這些類型實現了 io 包的很多接口&#xff0c;目的是什么&#xff1f; 是為了提高不同程序實體之間的互操作性。 程序實體是指比如網…

瀏覽器插件Video Speed Controller(視頻倍速播放),與網頁自身快捷鍵沖突/重復/疊加的解決辦法

瀏覽器插件Video Speed Controller&#xff08;視頻倍速播放&#xff09;&#xff0c;與網站自身快捷鍵沖突/重復/疊加的解決辦法 插件介紹問題曾今嘗試的辦法今日發現插件列表中打開Video Speed Controller的設置設置頁面翻到下面&#xff0c;打開實驗性功能。將需要屏蔽的原網…

網絡工程師----第三十一天

DNS&#xff1a; DNS含義&#xff1a;DNS 是 Domain Name System&#xff08;域名解析系統&#xff09; 端口號&#xff1a;DNS為53&#xff08;UDP&#xff09; 域名的層次結構&#xff1a; 域名的分級&#xff1a; 域名服務器&#xff1a; 域名解析過程&#xff1a; 遞歸查…

PHP xdebug

使用場景 一臺MAC上安裝了phpstorm&#xff0c;虛擬機安裝了對應的web程序&#xff0c;需要調試。 坑點&#xff0c;網上教程太多&#xff0c;不如看官網&#xff0c;需要按照xdebug版本來配置php.ini https://www.jetbrains.com/help/phpstorm/2023.3/configuring-xdebug.htm…

【Java】HOT100+代碼隨想錄 動態規劃(上)背包問題

目錄 理論基礎 一、基礎題目 LeetCode509&#xff1a;斐波那契數 LeetCode70&#xff1a;爬樓梯 LeetCode746&#xff1a;使用最小花費爬樓梯 LeetCode62&#xff1a;不同路徑 LeetCode63&#xff1a;不同路徑ii LeetCode343&#xff1a;整數拆分 LeetCode96&#xff1a;不…

vue uniapp 小程序 判斷日期是今天(顯示時分秒)、昨天、本周的周幾、超出本周顯示年月日

效果圖&#xff1a; util.js /*** 轉換時間*/ const messageFormat (datetime) >{ let result "";let currentTime new Date();if(isToday(datetime)){result datetime.substring(11,16);}else if(isYesterday(datetime)){result "昨天";}else if(…

分層解耦-三層架構

分層解耦-三層架構 Controller&#xff1a;控制層&#xff0c;接收前端發送的請求&#xff0c;對請求進行處理&#xff0c;并響應數據 service&#xff1a;業務邏輯層&#xff0c;處理具體的業務邏輯 dao&#xff1a;數據訪問層&#xff08;持久層&#xff09;&#xff0c;負…