讀零信任網路:在不可信網路中構建安全系統13執行時安全

躺柒發表於2024-08-09

1. 建立分發系統的信任

1.1. 分發是選擇交付給下游使用者的工件的過程,構建系統會產生許多工件,其中一部分需要交付給下游使用者

1.2. 工件釋出

  • 1.2.1. 在不改變工件內容的情況下指定一個工件作為權威釋出版本的操作被稱為工件釋出

  • 1.2.2. 工件釋出操作自身也需要具備不變性:一旦版本被分配和釋出,就不能改變

  • 1.2.3. 新工件的生產和釋出必須基於更高的版本號

  • 1.2.4. 如何在不改變構建工件的情況下新增版本資訊呢?

  • 1.2.4.1. 比較初級的方法是在釋出過程中巧妙地改變工件,比如,將版本號儲存在構建工件中一個可簡單修改的位置,但不提倡採用這種方法

  • 1.2.4.2. 另一種方法是,釋出工程師明確區分公開發布的版本號和構建編號,將構建編號作為釋出資訊的額外組成部分

>  1.2.4.2.1. 產生的構建工件具有相同的發行版本號,但每個構建都有唯一對應的構建編號
  • 1.2.5. 工件釋出應確保其可驗證性,需要提供機制確保使用者能夠驗證其獲取的工件是正式釋出版本而不是過渡版本,甚至是有缺陷的版本

  • 1.2.5.1. 使用釋出專用金鑰為釋出工件簽名,向使用者證明他們擁有的版本是正式釋出版

  • 1.2.5.2. 釋出一個簽名的清單,列出釋出的版本和對應的加密雜湊

>  1.2.5.2.1. 許多流行的包分發系統(如APT)採用這種方法來驗證從分發系統獲得的版本

1.3. 分發安全

  • 1.3.1. 軟體分發與電力輸送類似,由一個集中的源頭產生電力,經由配電網路傳送給廣大的使用者群體

  • 1.3.2. 與電力輸送不同的是,分發系統必須保護軟體的完整性,並且允許使用者獨立地驗證軟體完整性

  • 1.3.3. 許多廣泛應用的包分發和管理系統,都在分發過程中實現了必要的保護,並允許使用者驗證包的真實性

1.4. 完整性和真實性

  • 1.4.1. 在軟體分發系統中,主要採用雜湊和簽名兩種主要機制來維護完整性和真實性

  • 1.4.2. 透過驗證雜湊值,使用者可以驗證二進位制檔案在離開開發人員後是否被篡改

  • 1.4.3. 需要設計者採用私鑰加密釋出版本的雜湊值,使用者透過解密可驗證軟體是否由權威機構釋出

  • 1.4.4. APT儲存庫包含3種型別的檔案

  • 1.4.4.1. 釋出檔案

>  1.4.4.1.1. 釋出檔案的用途正是防止雜湊修改

>  1.4.4.1.2. 包含關於版本庫的後設資料

  >   1.4.4.1.2.1. 包括版本庫名稱和其使用的分發作業系統版本

>  1.4.4.1.3. 還包括包檔案的校驗和,這樣使用者可先驗證索引的完整性,隨後驗證下載包的完整性

>  1.4.4.1.4. 還必須引入加密簽名

  >   1.4.4.1.4.1. 簽名機制不僅為已簽名檔案提供完整性保證(雜湊包含在簽名中)​,同時還提供了真實性保證,這是由於對簽名的成功解密可以證明生成方確實持有私鑰

  >   1.4.4.1.4.2. 軟體版本庫的維護人員使用私鑰對釋出檔案進行簽名,其中有一個與私鑰相對應的、公開分佈的公鑰

  >   1.4.4.1.4.3. 如果不能對軟體釋出進行簽名,那麼就必須回到標準的安全實踐中

1.4.4.1.4.3.1. 需要保證所有的通訊都是雙向驗證的,這意味著分發系統儲存庫間的出、入以及相互通訊的流量都要雙向驗證

1.4.4.1.4.3.2. 需要確儲存儲庫使用的儲存服務是足夠安全的

  • 1.4.4.2. 包檔案
>  1.4.4.2.1. 包檔案是儲存庫中所有包的索引

>  1.4.4.2.2. 包檔案中儲存了庫中包含的每個包的後設資料索引
  • 1.4.4.3. 包本身

1.5. 建立分發網路的信任

  • 1.5.1. 當為大量的或地理位置分散的消費群體分發軟體時,通常將軟體複製到多個位置或儲存庫,以滿足伸縮性、可用性或效能上的挑戰,這些副本被稱為映象

  • 1.5.2. 軟體作者需要對軟體版本庫進行驗證

  • 1.5.3. 對於訪問的每一個映象都可以檢查釋出簽名,以驗證映象是原始版本的真實副本

  • 1.5.3.1. 可能被強制降級到較老的(已簽名)版本,因為映象伺服器上的工件仍然是合法的

  • 1.5.4. 為了保護客戶端,要確保其總是連線到一個可信的釋出映象

  • 1.5.5. 軟體分發的另一個弱點是缺乏受TLS保護的儲存庫

  • 1.5.5.1. 解決這個問題的一種方法是使用TLS保護包分發網路

  • 1.5.5.2. 透過新增TLS,客戶端可以確保其連線的映象服務可信,並且通訊不會被篡改

2. 人工參與

2.1. 在確保構建了安全的流水線之後,就可以仔細斟酌人工應在什麼位置參與

2.2. 透過將人工參與限制在幾個關鍵點,即可確保在釋出流水線安全的情況下攻擊者不能利用流水線的自動化功能交付惡意軟體

2.3. 將程式碼提交到版本控制系統是一個明確需要人工參與的關鍵點

  • 2.3.1. 根據專案敏感性,要求稽核人員只對已簽名的提交進行檢查以確信提交的真實性

2.4. 選擇最終釋出工件的過程最好有人工參與,可以透過多種機制實現

  • 2.4.1. 只要機制是安全的,如何人工驗證可釋出的二進位制檔案的機制就沒有那麼重要了

2.5. 建立安全系統並採取措施來避免任何可能的威脅,這確實很有誘惑力,但應該平衡潛在的風險和人工負擔

  • 2.5.1. 在軟體釋出量很大的情況下,應該妥善保管簽名金鑰,因為輪轉一個洩露的金鑰代價極大

  • 2.5.2. 對於僅內部使用的軟體,輪轉一個金鑰的工作量相對較少,適當放寬安全操作是合理的

2.6. 使用“程式碼簽名儀式”​,簽名金鑰被儲存在硬體安全模組(HSM)中,並且有多個參與方的授權才能解鎖私鑰,這種機制可以減少此高敏感金鑰的盜竊風險

2.7. 在安全系統中人的注意力是稀缺但重要的資源,隨著軟體釋出率的不斷提高,必須仔細斟酌人員參與的最好時機

3. 信任例項

3.1. 在設計零信任網路時,瞭解基礎設施中執行的內容很重要

3.2. 單向升級策略

  • 3.2.1. 軟體版本號是判斷其版本和評估其新舊的重要因素。針對正在執行的軟體版本,可以根據版本號判斷軟體可能包含哪些漏洞

  • 3.2.2. 誘導使用者進行版本降級,可以將軟體暴露於一個已知的漏洞,這種攻擊很有效,因為被降級的軟體仍然是被授權和信任的,只是版本較老

  • 3.2.3. 如果軟體是為內部分發而構建的,那麼分發系統可能只提供最新版本

  • 3.2.3.1. 這樣可以防止被破壞或錯誤配置的系統降級回滾到一個可能包含已知漏洞的舊版本

  • 3.2.4. 蘋果iOS使用硬體安全晶片來驗證軟體更新,並確保只有在當前安裝的軟體載入之後才能構建簽名軟體

3.3. 授權例項

  • 3.3.1. 相對於簡單地理解已經部署的最新版本,知道正在執行的是什麼版本更為重要

  • 3.3.2. 執行例項必須單獨授權

  • 3.3.3. 選擇以應用為中心的方式實現對執行例項的授權——應用秘密

  • 3.3.4. 大多數執行的應用程式都需要某種秘密才能完成工作

  • 3.3.4.1. API金鑰、X.509證書,甚至是訊息佇列的憑證

  • 3.3.5. 應用程式必須獲取秘密才能執行,並且這個秘密必須有效

  • 3.3.5.1. 一個秘密的有效性(顯而易見)是為執行中的應用程式例項授權的關鍵

  • 3.3.6. 為應用秘密附加一個生命週期,對於限制其濫用非常有效

  • 3.3.6.1. 允許秘密過期機制,透過確保它們不會無限期地執行,從而減輕了“搗蛋”例項的影響

  • 3.3.7. 必須有某個系統負責在執行時生成和注入這些秘密,這是一項重要的職責

  • 3.3.7.1. 承載這個職責的系統最終也是對例項進行授權

  • 3.3.7.2. 將這一職責賦予軟體部署系統合情合理,因為它已經承擔了類似的職責

  • 3.3.8. 與其讓部署系統直接訪問秘密,不如利用一個受信任的第三方,允許部署系統分配策略決定了執行例項可以訪問哪些秘密

  • 3.3.8.1. 部署服務通知秘密管理服務即將發生的變更,並授權新的應用程式例項

  • 3.3.9. 那些能夠創造(潛在的)和檢索秘密的系統的權力很大

  • 3.3.9.1. 權力越大,責任越大

  • 3.3.9.2. 允許一個自治系統產生和分發秘密對組織來說風險太大,在這一環節中可以考慮人員參與

  • 3.3.9.3. 可以在部署環節引入人工審批,需提供TOTP或其他身份驗證碼,並將其用於授權部署系統對秘密進行建立/檢索

3.4. 對秘密進行管理通常是一項艱鉅的任務,因為更改憑證通常是非常煩瑣的

  • 3.4.1. 透過平滑的憑證開通流程能夠提供頻繁輪換憑證的機會,憑證管理流程可以確保只有授權的應用才能在生產環境中繼續執行

4. 執行時安全

4.1. 一旦應用程式被構建,在生產環境中確保它們持續執行的過程就會發生變化

  • 4.1.1. 隨著漏洞被發現,可信的應用程式可能在將來會變得不可信

4.2. 需確保應用程式例項的全生命週期安全、可靠地執行

4.3. 應用程式在整個生命週期中是否始終是經過授權的、值得信任的部署還是不得而知

4.4. 許多攻擊向量都可以破壞已經授權的應用程式例項,並且這些攻擊向量被大量利用

4.5. 安全編碼實踐

  • 4.5.1. 學習安全的編碼實踐,在隔離的環境中部署應用程式,然後主動監視它們,這是值得信賴的生產環境的最後一環

  • 4.5.2. 大多數(甚至是所有的)應用級漏洞都是從一個潛在的“缺陷”​(Bug)開始的,攻擊者可以利用Bug來控制受信任的應用程式進行不當操作

  • 4.5.3. 要真正降低這種風險,需要應用開發人員的思維模式發生轉變,以確保編碼實踐的安全

  • 4.5.4. 應用程式在處理之前沒有對使用者輸入資料進行適當的驗證

  • 4.5.5. 透過幾個層面的防禦機制來應對,應用程式庫將精心構造API,不會輕易信任使用者提交的資料

  • 4.5.6. 清晰的API還可以支援應用軟體的自動掃描

  • 4.5.6.1. 應用程式邏輯也可以被跟蹤分析,識別出那些遺失的必要檢查項

  • 4.5.7. 主動識別已知漏洞是很有用的,但是一些漏洞隱藏過深,難以準確地檢測到,因此,另一種可採用的技術是模糊測試

  • 4.5.7.1. 將隨機資料傳送到執行的應用程式,以檢測意外的錯誤,這些錯誤一旦暴露,往往就會被攻擊者利用,使其在系統中獲得立足點

  • 4.5.7.2. 模糊測試可以作為功能測試套件的一部分執行,甚至可以持續地對線上基礎設施進行此類測試

  • 4.5.8. 程式設計師應該熟悉這些安全實踐,以便提高應用程式的安全性

  • 4.5.9. 讓安全諮詢團隊來檢查他們的應用程式和開發實踐,以識別此類問題

4.6. 隔離

  • 4.6.1. 在零信任網路中,透過限制可訪問的資源集來隔離已部署的應用程式很重要

  • 4.6.1.1. 傳統上,應用程式是在共享環境中執行的,使用者的應用程式在執行環境中執行時,對其如何互動的限制很少

  • 4.6.1.2. 如果應用程式遭到破壞,則共享的環境會產生大量風險,這類挑戰和基於邊界防護模型的安全挑戰類似

  • 4.6.2. 隔離將限制作業系統提供的功能和資源

  • 4.6.2.1. CPU時間(CPU Time)​

  • 4.6.2.2. 儲存訪問(Memory Access)​

  • 4.6.2.3. 網路訪問(Network Access)​

  • 4.6.2.4. 檔案系統訪問(FileSystem Access)​

  • 4.6.2.5. 系統呼叫(System Call)

  • 4.6.3. 在最好的情況下,每個應用程式都獲得了完成其工作所必需的最小訪問許可權,一個受到良好約束的應用即便被攻破,也無法在整個系統中造成更大的破壞

  • 4.6.3.1. 透過隔離可以大大降低受損應用程式的潛在損害

  • 4.6.3.2. 攻擊者橫向移動的企圖難以得逞

  • 4.6.4. 不同的技術

  • 4.6.4.1. SELinux、AppArmor

  • 4.6.4.2. BSD Jail

  • 4.6.4.3. 虛擬化/容器化

  • 4.6.4.4. 蘋果公司的應用沙箱

  • 4.6.4.5. Windows的隔離應用

  • 4.6.5. 隔離通常可以分為兩種型別

  • 4.6.5.1. 虛擬化

>  4.6.5.1.1. 虛擬化通常被認為更安全,因為應用程式執行於虛擬硬體環境中,此環境透過VM執行環境之外的虛擬機器管理程式(Hypervisor)來提供服務

>  4.6.5.1.2. 在虛擬機器管理程式和虛擬機器之間有一個清晰的邊界,其互動介面足夠小

>  4.6.5.1.3. 透過提供對底層硬體的直接訪問能力,虛擬化環境的安全特性正逐步接近共享核心環境
  • 4.6.5.2. 共享核心環境
>  4.6.5.2.1. 共享核心環境(類似於容器化或應用程式策略系統)同樣提供了一些隔離保障,但它與完全虛擬化的系統不一樣

>  4.6.5.2.2. 共享核心執行環境使用更少的資源來執行同一組應用程式,因此其在注重成本的組織中獲得了青睞

4.7. 主動監控

  • 4.7.1. 與所有生產系統一樣,詳細的監測和日誌記錄是至關重要的

  • 4.7.2. 傳統的安全模型將注意力集中在外部攻擊向量上,零信任網路鼓勵對內部活動保證同樣的警覺性

  • 4.7.3. 儘早檢測出攻擊可以採取防護措施,而不至於系統被完全攻破

  • 4.7.4. 可以對整個基礎設施安全事件的常規日誌記錄進行監控

  • 4.7.5. 在釋出流水線的早期或許並無足夠的時間和耐心讓模糊掃描發揮效力,但主動監控策略主張系統上線後也需要持續對其進行掃描

  • 4.7.6. 如果安全掃描會破壞系統的穩定,那麼可能意味著一個更大的潛在問題,甚至是一個漏洞本身

  • 4.7.6.1. 不要刻意規避在生產環境中進行掃描的潛在的“風險”​,而應思考風險從何而來,並努力排除導致這些風險產生的因素,從而確保掃描能夠安全地執行

  • 4.7.6.2. 自動掃描可以成為確保系統行為一致的有效工具

  • 4.7.6.3. 並不是所有的掃描都能產生如此清晰的行動建議,比如對已安裝的軟體進行掃描,識別網路所面臨(或可能面臨)的威脅,並據此決定軟體升級的優先順序

  • 4.7.7. 掃描器

  • 4.7.7.1. 模糊測試(如AFL-Fuzz)

  • 4.7.7.2. 注入掃描(如SQLMap)

  • 4.7.7.3. 網路埠掃描(如Nmap)

  • 4.7.7.4. 通用漏洞掃描(如Nessus)

  • 4.7.8. 一般來說,可疑的(但不關鍵的)事件僅記錄在案,並定期對其進行審查,這種做法是無效的,因為它可能導致報告疲勞,而在很長一段時間內被忽略

  • 4.7.8.1. 對於重要的事件可以讓相關人員進行積極的調查,這些事件有足夠強烈的訊號來喚醒一個人,在大多數情況下,這是一個強大的防線

4.8. 應用程式相互監視

  • 4.8.1. 在應用程式安全監控領域,一種頗為創新的觀點是,參與單個叢集或服務的應用程式可以積極地監控其他應用的健康狀況,並與他人達成共識

  • 4.8.2. 透過允許應用程式相互監視,將獲得高訊雜比的檢測結果,同時在整個基礎設施中分擔責任

  • 4.8.2.1. 這種方法有效地防止了側通道攻擊或者透過多租戶啟用的攻擊,因為這些向量不太可能在整個叢集中共

  • 4.8.3. ​“某些東西是錯誤的”訊號可以觸發基礎設施中的自動操作,這可能意味著撤銷屬於可疑例項的金鑰,將其踢出叢集,甚至向資料中心管理軟體發出通報,由其將此例項下線並隔離,以便後續取證

  • 4.8.4. 當使用主動響應時,可能會快速造成很大的損害

  • 4.8.4.1. 引入拒絕服務攻擊,或者更有可能的是,由於操作員的失誤而關閉了整個服務

  • 4.8.4.2. 在設計主動響應系統時,要放置一些容錯機制

>  4.8.4.2.1. 如果叢集的節點數處於危險的低水平,那麼不應該再觸發將主機踢出叢集的主動響應

相關文章