CICD-Pipelines-漏洞

深入探討 CI/CD Pipeline漏洞(IV):透過軟體證明防止工件投毒

在我們之前的帖子中關於 CI/CD Pipelines, 我們看到 如何破解一個 CI/CD 這種情況 想必 受到保護。

讓我們回顧一下上一篇文章中的觀點: 我們從一些開始 pipeline 那很容易受到 間接中毒 Pipeline 執行 (I-PPE),為了解決這個問題,我們決定將其拆分。 pipeline 分成兩部分:

  • 該1st pipeline (建置 CI),符合 D-PPE 和 I-PPE 標準,會檢出 PR 程式碼,進行構建,並產生工件。
  • 2nd pipeline (測試 CI),對於 D-PPE 和 I-PPE 也是安全的,可以檢出基礎程式碼(以避免 shell 腳本修改),並針對工件執行原始腳本。 
  • 為了同步測試 CI pipeline 在建置 CI 之後運行 pipeline, 我們用了 工作流程運行 觸發。 

我們將其命名為方案三。

CICD安全

雖然如我們在那篇文章中提到的,還有其他解決方案,但出於教學目的,我們決定實施這個“解決方案”,以便深入探討其脆弱性。 CI/CD pipelines.

之後,我們看到瞭如何透過以下方式破解這種情況: 毒害文物。這就是我們所說的 神器中毒即修改(破解)的能力 pipeline 透過修改邏輯 pipeline 神器。

這種方法有什麼問題?我們看到,當任何用戶「創建」一個新物件時,問題就出現了。 pipeline. 

如果使用者開啟一個包含新內容的 PR pipelineGitHub 將執行該操作。 pipeline  (在某些條件下,正如我們所看到的) 在文中).

然後用戶就可以建立一個新的 pipeline 與 Build CI 同名!是的,這很令人驚訝,但 GitHub 允許你創建兩個。 pipeline同名的! !

當使用者提交包含這些變更的 PR 時, 新的” pipeline 將被執行(上傳被污染的工件) 以及部署 CI pipeline 之後將執行該腳本,導致「修改後的」shell腳本覆蓋位於以下位置的「原始」shell腳本: pipeline 工作區。因此,這種「解決方案」並不能避免 I-PPE 漏洞(如下圖)。

CICD-Pipelines

問題是什麼?至少存在以下幾個問題:

  1. 首先, 如何確保建置過程沒有被竄改? 在這種情況下,惡意使用者能夠利用其權限修改預期的建置流程。 pipeline 製造一件有毒的物品。
  2. 其次, 如何判斷一件文物的來源?

這些問題將我們拋入…的懷抱 軟體認證 領域! !

軟體認證

An 證明 是一塊 數據 代表 事件證明在現實世界中,我們通常稱這些為 認證.

例如,當實驗室進行血液檢測時,檢測數據會被記錄並認證。血液檢測結果就是如此。 可驗證 以及 可追溯的.

軟體供應鏈認證

更貼近我們的 IT 領域,你可以猜到這個過程如果翻譯成例如編譯過程會是什麼樣子。

軟體認證

此類證明將包含有關編譯伺服器環境和工具、材料(原始碼)以及產品/工件(二進位程式碼)的資訊。

顯然,為了確保可信度,證明文件必須由經授權的證明人(經過認證且不可否認)出具。 

可能你們中的一些人會想…那什麼是… 簽名與證明的區別?

代碼簽名和證明

從高層次來看, 一步對社區作出貢獻,最終決定推出別具意義 它是使用密鑰對和工件創建的。密鑰對由公鑰和私鑰組成。 

程式碼簽名

使用者使用私鑰對工件進行簽名,其他人可以使用公鑰驗證簽名。私鑰必須保密,公鑰則廣泛分發。

簽名可以用於 為了證明私鑰持有者使用私鑰對文物進行了簽署。

簽名 不要證明 

  • 用戶的 意圖 在文物上簽名(他們可能被騙了),或者 
  • 用戶意圖進行任何 關於該文物的具體說法 

證明書使用者不是直接對工件進行簽名,而是創建某種形式的簽名。 文件 捕捉到他們的意圖 在簽署文物之後以及任何 具體訴求 這是作為此簽名的一部分而做出的。

整體證明框架

最常見的框架是 整體證明框架

  • 定義一個 standard 證明文件的格式 將主題(即被描述的製品)與關於該製品的已認證元資料綁定在一起。 
  • 提供了一套 預定義謂詞 用於在整個軟體供應鏈中以及跨軟體供應鏈傳遞經過認證的元數據

讓我們詳細了解一下證明文件的格式。

An 證明書 數位簽名文件 包含 聲明。

聲明 是證明文件的中間層,將其與特定文件綁定。 主題 並明確識別出以下類型: 謂詞:

  • 主題:“ 對該物品進行加密安全的引用 (通常透過哈希值),以及
  • 謂詞一組特定的 索賠 關於該工件的描述被稱為聲明。這些聲明可以用來表達(並在之後證明)你能想到的任何事情!它們可以代表人工審批、工件來源、自動化測試結果、稽核追蹤等等! 

當該聲明經過加密簽署後,它就被稱為一​​份聲明。 證明書

CI/CD安全場景 3

這樣,例如,Alice 創建了一個關於某個物品的聲明,並使用她的私鑰對其進行簽名,從而創建了一個證明。

  • 鮑伯就可以 驗證簽名 在那份證明中,允許他 相信這些說法 內。 

然後,鮑伯就可以利用這些主張了。 決定 是否允許使用此文物。

軟體認證組

認證能否協助解決文物中毒問題?

在對證明進行了以上介紹之後,讓我們回到我們的問題。 證明如何幫助我們解決問題,即避免人工製品污染?

惡意使用者能夠繞過「官方」機制來創建工件,即透過使用他/她自己的… pipeline 產生該工件。 

如果我們能夠證明下載的這些工件是用官方版本建構的,那就太棒了。 pipeline這只是我們可以稱之為「篡改點」的一個例子,但可能還有很多其他的篡改點。

SSCS篡改點

如上圖所示,篡改點不只一個。這樣,消費者 pipeline (本例為測試 CI)必須評估 建置過程的完整性 以及 文物本身的完整性.

在我們的例子中,被污染的人工製品是透過引入一個新的(被污染的)人工製品而創造出來的。 pipeline 這會篡改建置過程。但惡意使用者可能還能夠:

  • 從程式碼庫檢出後修改程式碼。 SCM 產生惡意二進位文件
  • 將編譯產生的正確二進位檔案替換為任何其他惡意二進位檔案。
  • 破壞工件註冊表並上傳以任何其他方式建置的惡意工件
  • 等。

 如您所見,可能存在多個「篡改」點。

這裡最重要的是什麼?顯然是保護所有那些「篡改」點。但歸根究底,最重要的是 也就是說,產品的「消費者」可以評估產品的完整性,並決定是否繼續使用該產品。

我們可以 評估文物的完整性 有兩種方式。 

一種方法是透過評估 出處 該文物。

透過生成 出處證明我們提供關於該工件的有用元資料(經過適當認證且不可否認)。 在以下範例中,我們將使用 Xygeni SALT (Software Attestations Layer for Trust),用於產生、註冊和驗證軟體證明的元件。

防篡改版本
      - name: Building ...         run: |           # mvn will compile and create target/MyApp.war           mvn clean package                     - name: Generating provenance         run: |               #!/usr/bin/env bash                 shopt -s expand_aliases               alias salt=$PWD/salt_pro/xygeni_salt/salt                     echo " "               echo "-----------"               echo "Generating Provenance with CLI ..."               salt at slsa \                   --basedir ${GITHUB_WORKSPACE}/target \             --key="${PRIVATE_KEY}" \             --public-key=${GITHUB_WORKSPACE}/Test1_public.pem \               --key-password=${KEY_PASSWD} \               --output-unsigned=${GITHUB_WORKSPACE}/cli_provenance_${PIPELINE}_unsigned.json \                   --pipeline ${PIPELINE} --pretty-print \                   --file ./MyApp.war                     

在上面的程式碼中,你可以看到第一個步驟是建立 war 文件,第二個步驟是產生 war 檔。 出處證明為了做到這一點, pipeline 使用私鑰,證明中也包含了公鑰。 

幕後,Xygeni 的 該命令將證明存儲在 總帳 (又稱證明登記處, 記錄 在我們的例子中是這樣,但您可以使用任何其他方法)。 完成這些之後,消費者 pipeline 可以包含 Xygeni 的 驗證引擎 驗證文物的來源並評估文物的完整性。

 - name: 'Verifying the attestation'         run: |           #!/usr/bin/bash   	    echo " "           echo "-------"           # Calculate sha256sum for the artifact           SHA_SUM=$(sha256sum ./MyApp.war | cut -f1 -d ' ')   	    # Recover the attestation Id from the sha256sum           ATT_ID=$(echo $(salt -q registry search --digest sha256:$SHA_SUM --format json) | jq -r .[-1].gitoidSha256)             echo " "           echo "-------"           # Download the provenance attestation           echo "Downloading the provenance attestation ..."           salt -q reg get --id=$ATT_ID --format=json > ${GITHUB_WORKSPACE}/provenance_kk.signed.json             echo " "           echo "-------"           echo "Verifying provenance ..."           salt verify \               --basedir ${GITHUB_WORKSPACE} \               --attestation=${GITHUB_WORKSPACE}/provenance_kk.signed.json \               --public-key=${GITHUB_WORKSPACE}/Test1_public.pem \               --file ./MyApp.war 

驗證過程評估以下內容:

  • 工件 sha256sum 有效 (即,存在關於該「主題」的證明文件),
  • 證明文件已妥善認證 (它是使用相應的私鑰生成的) 

此驗證過程可以評估工件和證明文件是否有效。

但是,正如你所記得的,在我們的案例中,該工件是由「惡意」程式產生的。 pipeline (即並非原版,而是修改版) pipeline那我們必須繼續檢查另一個方面: 該文物由「原件」產生。 pipeline不是其他任何一種。 

為此,只需添加一行簡單的程式碼來檢查該條件,例如:

   echo " "           echo "-------"           # Download the provenance attestation           echo "Downloading the provenance attestation ..."           salt -q reg get --id=$ATT_ID --format=json > ${GITHUB_WORKSPACE}/provenance_kk.signed.json           WFR=$(jq -r .payload ${GITHUB_WORKSPACE}/provenance_kk.signed.json |base64 -d | jq -r .predicate.buildDefinition.internalParameters.environment.GITHUB_WORKFLOW_REF)           echo $WFR | grep cicd_top10_3_salt\/.github\/workflows\/build.yml 

如果該工件並非由我們的「安全性」環境生成,則此附加檢查將失敗。 pipeline.

如果文物是由我們最初的…生成的 pipeline (cicd_top10_3_salt/.github/workflows/build.yml),grep 指令將成功執行,否則將失敗,導致程式崩潰。 pipeline 併中止所有後續步驟。

“建造者” pipeline 這只是需要檢查的篡改點之一,但正如前面提到的,還有其他一些篡改點需要檢查。

例如, 如果在程式碼庫檢出之後、建置指令執行之前,原始碼被竄改了怎麼辦? 在這種情況下,要建置的程式碼與儲存在…中的程式碼不同。 SCM. 

檢查這個篡改點非常簡單,只需檢查每一步材料的雜湊值即可。

SHA_ATT_MATERIAL=$(jq -r .payload ${GITHUB_WORKSPACE}/provenance_kk.signed.json | base64 -d | jq -r .predicate.attestations[0].predicate.materials[].digest[]) SHA_STEP_MATERIAL=$(jq -r .payload ${GITHUB_WORKSPACE}/provenance_kk.signed.json | base64 -d | jq -r .predicate.attestations[3].predicate.materials[0].digest[]) 

結論

總之, 軟體認證 是對一段軟體所做的斷言,即關於軟體製品或軟體製品集合的經過驗證的聲明(元資料)。

軟體認證是對原始工件/程式碼簽署的一種概括。認證是一份已簽署的文件(採用特定格式,通常基於 JSON),它將元資料與工件關聯起來。它們代表了每個建置步驟中輸入(材料)和輸出(產生的工件)之間的關聯證據。

證明文件提供了建構最終軟體工件所執行步驟的可驗證記錄,包括每個步驟的輸入材料和運行的建置命令。

總之,軟體認證是檢視我們建置過程中許多不同完整性方面的絕佳機制。 

看完這部劇了嗎?別擔心!隨時可以跳回“中毒 Pipeline 執行(PPE)或任何其他再次引起你興趣的帖子!

敬請期待,我們將深入探討軟體認證和 build security 在後續的部落格文章中。 

中毒 Pipeline 執行(PPE)

深入探討 CI/CD Pipeline漏洞(I)

間接中毒 Pipeline 執行(I-PPE)

深入探討 CI/CD Pipeline漏洞(二)

偽造品中毒和程式碼注入

深入探討 CI/CD Pipeline漏洞(三)
sca-tools-software-composition-analysis-tools
優先處理、補救並保護您的軟體風險
註冊免費帳號。
不需要信用卡。

確保您的軟體開發和交付安全

使用 Xygeni 產品套件