摘要:採用生物信息的技術讓人難以接受的是無法進行更新祕密信息,如果需要更換可能需要重新設計相關的算法和信息採樣的算法,可能會要求所有虛擬用戶同時更換設備和祕密信息。身份認證策略、訪問控制策略、會話管理策略這三個方面基本上屬於整個軟件安全的基石,如果這三個方面缺少了相應控制或者實現的大方向上存在問題,那麼對於整個軟件的影響極大,可能是顛覆性的需要推到重建。

生命以負熵爲食 —— 《生命是什麼》薛定諤

背景

我想作爲一個信息安全從業者,無論是在滲透測試、代碼審計亦或是其他安全服務中都會接觸到各種各樣的漏洞。把這些漏洞進行簡單分類可能能夠得到幾十類漏洞,當然幾乎所有的漏洞類型在 common Weakniss Enumeration 都有相應的描述。

面對類型如此豐富漏洞,我們要如何進行處理呢?

要知道人類的本質是懶惰,逐條進行分析驗證幾乎是不可能的。而且滲透測試、紅藍對抗等服務在本質上都是爲了達到以點帶面的目的,那麼這個面在哪裏是值得我們去思考的問題。

廢話扯完了,進入正題。

安全策略清單

本文所說的安全策略,即系統採用的方式用於處理可能存在的安全風險。

我這邊簡單的梳理了一下,在考慮軟件安全時需要考慮的幾個方面的問題,圖如下:

身份認證策略、訪問控制策略、會話管理策略這三個方面基本上屬於整個軟件安全的基石,如果這三個方面缺少了相應控制或者實現的大方向上存在問題,那麼對於整個軟件的影響極大,可能是顛覆性的需要推到重建。

對抗中間人: 對於中間人攻擊大部分人的看法可能是屬於軟件後期的部署問題,採用https/HSTS就沒什麼問題(問題可能並沒有這麼簡單),不過我還是把它納入到框架。

輸入輸出: 這可能有點老生常談,不過我覺得清楚的瞭解對於軟件而言什麼是輸入,什麼是輸出,可能會更好進行分析。

敏感數據:在網絡逐漸形成虛擬社會的背景下,其開放性的特徵必然會引起有關部門的注意,作爲一項重要的合規項應當在初期就納入考慮到。同時如果出現相應的問題,軟件修復起來極其頭疼,完全可能出現修不完的情況,在投產的過程觸犯了相應的法規造成的損失可能也 極其巨大

軟件技術棧: 白話一點的說法就是軟件都用了什麼技術。

配置管理: 一些意料之外漏洞可能都出自於錯誤的配置管理,諸如交易日誌泄露

異常處理: 安全對抗的本質是獲取信息,儘可能的獲取一些常規獲取不到的信息,異常是一項比較重要的來源。

身份認證

概念

在虛擬世界中的身份認證同現實世界中一樣,首先需要識別人,建立在識別的基礎能夠去開展各項業務,產生、處理、使用、存儲數據。 只是目前而言,由於你是真實存在的,不會出現類似於證明你是你問題,而虛擬身份的更像是一個物化的概念,那麼身份認證就是能夠證明虛擬身份是屬於現實的你。

所以在虛擬世界這是一個必須要解決的問題——如何讓真實的你與虛擬世界中虛擬的你進行綁定。

那麼最直接的方式就是提供祕密——只有賬號的擁有者持有的信息。例如在賬號註冊時輸入的密碼信息、密保信息

換句話說,在虛擬的世界中只要能夠提供賬號的相關的祕密信息,就能聲明賬號的所有權。因爲對於全知全能的程序而言,它都是僅僅收到了這個祕密,你和他並沒有區別。

舉個例子:

alkaid登錄賬號alkaid,輸入了密碼password,程序驗證通過,允許以alkaid賬號執行相關業務
person2 不知道通過什麼途徑知道了,alkaid/password的認證信息,程序驗證通過,允許以alkaid賬號執行相關業務。

風險與處理

現在身份認證應該就是很清晰了,其實就是驗證虛擬賬號的祕密信息,那麼要知道只要是驗證信息就會返回成功和失敗的結果,從一定程度這也是一類信息泄露,只是信息泄露的量較少,通過不斷累積信息,就能最終破獲祕密信息,也是身份認證主要的風險點。

這類風險的直接體現就是暴力枚舉破解賬號。

當然,這風險屬於無法解決的,我們只能採用降低風險,使風險可控的方式:

解決累積信息的特點。

賬號鎖定機制

由於完美解決1是相對困難的(主要是引入的不可用風險不一定能被接受),也可以採用提高目標的信息量的方式,在有限的時間維度內,無法破解賬號

提供祕密信息的複雜度,例如密碼的複雜度

採用驗證碼技術,防止通過機器突破現實人的極限。

減少單次信息累積的量

模糊失敗的錯誤提示

其實還有其他的無法解決的風險,例如祕密信息被竊取。所以一般還會要求提供更換祕密信息的功能。

採用生物信息的技術讓人難以接受的是無法進行更新祕密信息,如果需要更換可能需要重新設計相關的算法和信息採樣的算法,可能會要求所有虛擬用戶同時更換設備和祕密信息。

會話管理

概念

由於HTTP協議屬於無狀態(每個數據包都是獨立的,僅根據數據包無法判斷之前發過哪些數據包)的協議,同時在身份認證一節中已經說明大部分的業務操作是需要基於虛擬身份進行的,那麼在完成身份認證後,後續數據包無法回溯之前的數據包,從而導致無法證明自己確實能夠持有聲明的虛擬身份。

當然如果每次都帶着身份的祕密信息請求進行確實是可以進行身份認證,但是頻繁的使用這類祕密信息可能會增加祕密信息泄露的風險。

現實的生活中由於時間和空間的限制,基本上不存在這類風險,我們也很難進行參考。

不過這類問題反過來——如何讓服務器知曉是你這個真實的人在操作你的擁有的虛擬身份(問題又回到了身份認證)

同身份認證一章節所述,那就是掌握祕密信息。

即服務器與我商量一個只有我們兩個人知道的臨時祕密,來替代原先虛擬身份的祕密。

臨時祕密作爲虛擬身份的祕密的替代品,在每次訪問時都進行提供。—— 臨時祕密即我們一般而言的sesssionID(會話ID)。

會話管理,即圍繞sessionID是怎麼進行處理的。

再繞一點,是不是覺得會話像是系統給我開設的臨時虛擬身份,但是同時具有原先虛擬身份的信息?

確實沒錯,會話從某種程度上來講與賬號其實沒有區別,也能夠提供相應的信息存儲,只不過會話是臨時的。

風險與處理

會話與賬號相似,其面對的風險也與身份認證相同。

但是由於是相似(如果完全相同,又會回到最開始的問題——無法證明自己確實能夠持有聲明的虛擬身份),會話最大的一個特徵是臨時性。 由於預置的時間屬性,基本我們採用2中的複雜度方式。

如何來儘可能的保證的複雜度呢?

隨機生成的符號組合。(避免組合單詞,賬號信息等,從信息熵的角度來說,儘可能避免與已知信息相關聯,關聯的越多,這段數據包含的信息越少,越容易被猜測)

一定長度的保證(每一位的長度增加,破解難度都是成倍提高)

訪問控制

概念

鑑於可能會與我們學習過的MAC、DAC、RBAC混淆,這節討論的東西不是這些具體的策略,談論這些具體的策略,可能搜索一下google、wiki來得更加方便和準確,是討論訪問控制解決什麼問題,面對什麼樣的風險。

涉及到訪問控制,自然有兩個概念,主體和客體。

主體

一般指提出訪問請求的對象。在實現身份認證和會話管理的基礎上,主體相對明確,有兩類構成

虛擬身份代表的主體

沒有虛擬身份,(代表了所有未授權的情況)

客體

一般指被訪問的資源。 具體哪些資源其實在相關的系統裏是很難明確的,這裏我僅提及兩類,功能和數據。 它們應該是在各類系統中最最常見的兩類資源。

分析

既然是虛擬時間,如果排除了空間和時間的影響,其本質應該是一樣的,現實中與安全性質類似場景包括消防、防盜、安保等

這裏以我居住的小區爲例,alkaid 住在A小區1幢11層1111房間。

我需要回到我的房間需要經過,小區的門禁、1幢的門禁、1幢的電梯梯控、1111房間的鑰匙、密碼。

我們講現實的場景與虛擬的場景進行映射,幫助進行分析也方便大家思考,發現一些我可能沒有提到的東西。

小區的門禁,相當於系統的身份認證,通過門禁確認我屬於小區的住戶

進入小區後,處於會話管理的範疇內,當我只持有1幢的門禁和梯控,相當於只允許我訪問某些功能。

而房間鑰匙則對應着我的數據訪問權限。

而小區的跑道和綠化則屬於授權用戶的公共資源, 小區外的其他則屬於任何人都能訪問的資源

小區中遍佈的監控能夠支持對行爲的審計

總結

在訪問控制方面,我們至少需要幾點:

功能級別訪問控制

針對用戶數據或者其他資源的數據級的訪問控制

梳理公共資源以及個人的資源

監控與審計

風險與處理

風險也圍繞着我們在上文所說的幾點

相關資源的訪問控制(即門禁的設計)。

根據系統不同的需要,對不同的資源設置相應的訪問權限。畢竟在一般情況下,我房間應該只有我以及我授權的相關人員能夠進入

需要評估和確認訪問權限設計的有效性,滿足最小化的原則

對於資源默認的訪問權限應當是拒絕

授權繞過/未授權訪問

在系統變更過程中是否持續對資源進行梳理和監控

側信道/信息推測

例子的描述: 房間裏會有窗戶,可能透過窗戶能夠看到一些 或者 分析你的生活習慣推測一些信息。 從描述來看,風險相較於其他幾項較少

之前提到過,我們忽略了時間和空間的影響。在虛擬世界中可能會存在直接訪問到我個人房間的情況,所以一般情況下我們首先需要去驗證訪問者是否持有認證通過後持有的虛擬身份。(一般這個操作在軟件系統中會作爲全局攔截器來實現,相當於將所有的資源納入到門禁的範圍內,避免在實現新增功能時,忘了考慮這類情況,從而產生風險【該類情況即使通過審計發現,也無法進行追溯】。)

對抗中間人

背景

在前文中提到的三大基石策略——身份認證、訪問控制和會話管理,在通信過程都涉及到與遠程服務器交換祕密信息,同時在實際的業務過程中,也包含了大量的個人隱私信息。

如果這些信息被竊取,可能會對社會、個人造成巨大的影響。

概念

在具體討論怎麼對抗中間人之前,我們首先來看看中間人到底是什麼?

從名字來看,中間——那肯定是在什麼之間。

信息系統常見幾個重要的主體,應用、操作系統、網絡鏈路、客戶端、服務端,通信過程如下:

一般而言,我們所考慮的中間人攻擊的情況是圖中虛線的框框——網絡設備,攻擊者可能控制了相關的路由器或者交換機,進而對應用的相關數據包進行監聽、篡改。

一般不考慮應用與操作系統、操作系統與網卡之間攔截,一方面由於這些操作都需要對客戶端/服務端的操作系統進行控制,如果能進行控制,那麼有其他更加豐富的方式獲 取相關的數據,包括但不僅限於hook相關的技術、屏幕錄像。 另一方面,由於需要獲取操作系統的控制權,一般而言是個例,不具有普遍性,在資源有限的情況,不會進行考慮。同時在這類場景下,更關鍵是需要解決惡意攻擊者獲得操作系統控制權的問題。

當然,如果有特殊的要求確實需要納入到考慮範圍的情況,那肯定需要在應用層面去完成,自然是最方便的途徑,從數據的源頭進行防護,設計的要求同針對網絡設備的中間人一致。

對抗中間人攻擊,不可能去解決掉中間人,而不可能去保證每個人一個人的鏈路的安全。

需要解決如何在不可性的鏈路上去構建一個可信或者相對可信的鏈路。

風險與處理

風險其實在背景裏已經提到了就是信息被竊取、篡改,而處理的解決方式就是需要去構建可信信道。

具體的風險可以細化成以下四種:

虛擬身份或者臨時身份被竊取

重放

監聽(隱私信息採集等)

業務數據包被篡改

從風險可知,構建的可信信道需要滿足

數據被加密,防止被竊取身份,被採集信息

加密應該保證每個對象與對象之間不同(如果是現代密碼學算法應該保證每組通信採用不同的密鑰)。

需要支持完整性的校驗

需要支持對抗重放數據——即每個數據包有自己的標識

已有技術

提到中間人,不得不提到的一定是SSL、TLS,以及結合http協議形成的https,一般情況其代碼實現已經集成在操作系統中。

理想情況下,TLS或者SSL協議能夠達成我們的目標 ,但是它們在構建可信信道的過程中,依賴於數字證書技術。如果不當使用數字證書,例如自簽證書、不可信CA濫發證書,那麼可信信道就無法構建。

無共享信息的可信信道,基本上無法建立,除了量子。

那麼爲了部分解決SSL/TLS的數字證書問題,只能採取增加部分預置信息的方式,例如HSTS——瀏覽器緩存證書,SSL Pinning——內置證書進行比較

注意事項

由於SSL/TLS是對抗中間人的完整性校驗和對抗重放,重放的另一個威脅源來自客戶端自身在應用層發起的請求,這類情況無法適用SSL/TLS。

一般建議在應用層面的核心業務,再次實現完整性校驗和對抗重放的技術。例如交易。

異常處理

滲透測試的小夥伴應該會這樣的體會——只有當輸入信息與我們預期的正常情況存在出入的時候,纔會引起注意,例如頁面500報錯、異常的業務流程、預計之外數據輸出。

所以異常可以算是一切攻擊的源頭,如果所有的情況都能符合預期,那麼我想攻擊者的途徑應該會少很多吧。

可惜的是人非聖賢,異常難以避免。

對研發而言,我們希望異常越清晰越好,查看異常越簡單越好,能夠協助我們儘快的定位bug,分析業務。

在攻擊者在挖掘漏洞的過程,同樣希望異常越清晰越好,與開發者們的預期一致,在頻繁的上線和更新代碼的過程中,經常會遺忘掉這些暗門,從而使攻擊者能夠從研發留下的痕跡中收穫不少敏感信息。

所幸的是目前部分框架已經支持對 全局異常的統一處理

剩下的需要解決的是配置問題,在下文中也會單獨的講這個問題,不過在這個篇章裏索性就先提一點。

研發人員和攻擊者都關注異常信息,自然不可能把異常信息全都屏蔽,那麼對於研發人員可能是一場災難。

那麼如何把兩者劃開來呢,測試環境自不必說,對於生產環境而言,攻擊者能接觸到的應用頁面、通信的數據包,而研發人員在授權的情況下,理論上可以接觸到所有數據的,所以我們可控制異常信息的輸出,輸出到攻擊者無法接觸的地方,例如操作系統的某個固定目錄下、統一的日誌收集平臺。

當然有個後話,如何保證相關目錄的安全、日誌平臺安全以及哪些數據需要隱藏又是我們需要繼續考慮的問題。

注意事項

異常處理的手段其實在本質上並不能解決信息泄露的問題,只是通過對異常處理的控制,儘可能地降低從異常中獲取的信息量,提高攻擊者的攻擊成本和利用難度,從而降低風險。

(沒有任何回顯,本身就是一種異常。只是造成這類異常的情況豐富且複雜,從而降低從異常中獲取得信息量)

PS:信息量/信息熵等概念,可自行搜索瞭解,本質上是爲了量化信息。

配置管理

對於應用系統而言,經常需要部署在不同的運行環境,我們引入了配置從而避免了因爲環境的變動就需要對應用進行重新編碼,重新測試的情況,同時各種各樣的配置項可以支持各式各樣的組件和程序不同的運行方式,極大的提高了效率。

場景一 不同的運行環境

跨平臺的編程語言解決了應用需要在不同操作系統部署的問題,優化了大量的時間投入。但是它們沒辦法解決不同抽象的運行環境,例如開發環境、測試環境、準生產、生產環境,不同的抽象運行環境對應着不同的組件、網絡以及信息安全的要求。

開發環境/測試環境:對於信息安全的要求應該是最低,同時也是輸出信息最爲豐富、系統最不穩定的。

準生產/生產環境:對於信息安全有明確的要求,僅保留必要的輸出,系統最爲穩定。

風險與處理

在從開發環境切換到準生產/生產環境,難免需要更新具體的配置,一般而言會考慮引入編譯的配置選項來解決,實現一鍵切換,例如maven的profile屬性,不同的屬性值對應了不同的策略,包括不同的打包策略、不同的配置文件。

這類方式是提高系統可靠性的重要方式,但是也存在一些副作用,需要使用者進行控制。

如果管理不當,開發者有可能接觸到生產環境的具體配置信息,對生產經營產生影響

如果打包策略/配置文件未進行檢查和校驗,導致多個環境信息被一起打包。

如果缺少對具體配置項的檢查,導致生產環境採用了測試環境的配置,進而可能產生信息泄露事件。

各個組件(中間件、容器等)的配置。雖然目前有docker一類的容器技術,用於實現運行環境的標準化配置,但是標準化配置不是一個不再需要關注的點而是一個更加需要關注的點,試想如果某個標準化上配置存在弱口令賬號或者所有的標準化環境共享一個賬號,會帶來什麼樣的風險。

場景二 日誌管理

日誌功能相關的組件越來越成熟,大多通過配置進行實現,索性就納入到了配置管理模塊。

日誌是目前所有系統審計的重要依據,同時也是發現攻擊者和內鬼的重要手段,但是隨着SSL/TLS等相關加密方式普及,位於通信鏈路上的相關設備越來越難以捕獲到明文信息,應用系統自身的日誌顯得越來越重要。 我想隨着雲相關技術的進一步推廣,應用系統的日誌會更加重要。

如何管理這些日誌,採集哪些日誌就是需要進行考慮的。

風險與處理

日誌最好也能有全局的日誌控制。

當然,如果需要最大發揮日誌的價值,一般是需要彙集到統一的日誌平臺,用於支持搜索。而日誌往往包含了最詳盡的業務信息,從某種意義上而言,這些日誌可能是在誘導犯罪。(不知道是不是對前文中關於臨時身份有印象,拿到這些臨時身份的令牌,就可以完成身份竊取)

一類風險是正式這些日誌信息造成,我們需要有明確的規定有指導數據記錄,例如敏感信息、個人隱私信息、令牌、身份等信息,不要存儲全文,需要進行部分的模糊化。

另一類風險正是引入日誌平臺其本身帶入的風險。

日誌的具體配置不當,例如本地的日誌文件存放到了web的相關目錄,從而能直接訪問,造成大量信息泄露。(相關實例可自行搜索)

場景三 權限配置

目前越來越來多的應用支持複雜的權限配置和資源配置,有效維護這類信息,能夠大幅度降低安全風險。

具體涉及的權限內容,可查看訪問控制策略章節瞭解

軟件技術棧

概念

軟件技術棧——我姑且這麼寫如果有更好的名稱可以私信我,這裏主要想提一提應用系統中那些無法進行掌控的第三方組件,例如java的第三方jar、框架、中間件。

對於現在的應用程序而言,從零開始的搭建已經有點不可能了,不是技術不可能,而是業務上不可能,我們需要速度,在已有輪子的前提下,肯定不需要再造輪子,即使造輪子,你有能力保證造的輪子就比別人的好使嗎?

但是呢,這類第三方的代碼與我們編寫的代碼在運行時共享的是同樣的權限、系統資源,如果這些代碼出現了問題,又當如何?

風險與處理

至少需要能管理、瞭解到底用了哪些第三方的代碼。唯有這樣,在相關的第三方出現安全問題時,能夠快速響應,做到止損。(相關工具:SCA——軟件成分分析軟件)

儘可能不使用存在已知問題的組件,不使用停止維護/維護不當的第三方內容(如果是開源的,己方有能力維護可以不納入考慮)。

敏感數據

敏感數據現在是屬於法律法規領域最關注的一個點了,雖然互聯網上的應用五花八門,但是所有這些虛擬身份的背後都是一個唯一的實體人。生命以負熵爲食,人天生喜歡規律也是有規律的,大量數據可能能夠重新去定義一個實體人,通過定向的投放去影響和控制人,甚至盜取這個人的現實身份,這也是爲什麼敏感數據會成爲各國法律法規的關注點。

所以在應用系統設計的初期,我們必須需要明確哪些是所謂的敏感數據,以及圍繞着敏感數據的生命週期要如何處置

哪些是敏感數據

個人隱私

CISSP ALL in One 在隱私章節裏給出部分屬於隱私的數據類型,如下:

敏感的業務數據

財務相關交易記錄

…… 需要根據具體內容去決定

敏感數據的生命週期

一般而言,生命週期至少包括數據的產生、存儲、使用、銷燬,該過程映射到實際的應用系統中可能還需要進行更加細節的處理。

傳輸

應用系統涉及到信息交互,那麼首先要新增的一個過程就是傳輸,在傳輸過程中的敏感信息要如何進行處理是需要進行明確。明文傳輸肯定是不行的。

產生

我覺得更明確的詞,應該是採集。

採集就涉及到到底是採用完整的數據,還是部分關鍵即可,如果是部分關鍵,那麼將採集出的數據直接轉成Hash摘要可作爲一種參考方式。

存儲

避免明文存儲

如果不需要明文的敏感數據,建議採用hash算法等方式轉化數據,僅用於對比

如果需要明文的敏感數據進行操作,建議採用加密算法保障

其他情況

使用

使用可能涉及到多個場景,例如客戶端頁面的展示、業務操作的需要,如不必要進行展示,儘量不進行展示。

銷燬

一般這類敏感數據是需要提供銷燬數據的功能的,是真正從數據庫清空相關信息,而不是通過標誌位實現的假刪除方式

注意: 這裏的說明,僅僅是提供敏感數據相關策略的參考,具體內容以相關的法律法規以及業務自行設計。

輸入輸出

概念

輸入與輸出,絕大多數的漏洞都在體現在這方面,假如一個系統完全沒有輸入和輸出,開個玩笑,如果真有這個系統,有和沒有又有什麼區別?

輸入與輸出,這兩個詞雖然簡單但是裏面缺少了一個東西——主體,什麼東西的輸入輸出。

假如實體服務器,那麼輸入輸出基本上就是我們在通信鏈路上來回輸送的數據,但是這些數據有點駁雜,沒有辦法再進一步的處理,唯一能做是採用一些全局的過濾器或者攔截器,但是誤殺又太高。

所有站在這個維度,雖然實現起來相對容易,但是把握度的難度會比較困難

假如把實體的粒度劃的再細一點,定義成應用軟件(軟件,而非系統)。從這個維度來看,系統的輸入和輸出類型就豐富來起來

輸入:來自文件系統上的文件、數據庫中的數據、中間件/容器傳遞的業務數據、其他組件的數據輸入、

輸出:文件系統、數據庫、其他組件、中間件/容器

此時的輸入輸出可以看得出與部分漏洞有了聯繫,例如與文件系統相關的文件上傳漏洞、任意文件讀取漏洞

記住,原則上一切的輸入和輸出都不可信,只是經過校驗和過濾的數據才能提高可信度。

風險與處理

通過縮小實體的粒度,我們更加明確了輸入與輸出,後續的風險便是圍繞着具體的輸入信息和輸出的信息進行分析,構建針對性的過濾和處理。

當然,這種方法因爲縮小了粒度所以在實現上就要複雜的多,主要是分析工作量增大,需要有針對性。

引用

深度解讀SSL/TLS實現

SpringBoot開發詳解(六)– 異常統一管理以及AOP的使用

*本文原創作者:alka1d,本文屬於FreeBuf原創獎勵計劃,未經許可禁止轉載

相關文章