縱深防御這個在安全行業被用的很爛的詞,乙方的顧問寫方案時信手捏來,我想大家的理解可能并不一致。其實我比較贊同lake2用的“河防”以及數字公司用的“塔防”的概念,這些都是比較貼近實際的。下面的篇幅僅從自己的理解來展開,并且主題限定在大規模生產(服務)網絡而不是辦公網絡。
互聯網安全的核心
當下各安全公司都偏愛APT和大數據威脅情報之類的概念,在辦公網絡我想這些是他們圈地運動的戰場,不過生產網絡似乎仍然遙遠。自動化運維的交互模型跟大幅度人機操作的辦公網絡完全不同,而且現在號稱機器學習的方法在實操中表現的很一般,效果不如對攻防模型抽象后定義規則的方式。這里并不是在否定機器學習的方法,只是表達離成熟還尚有距離(我不是在說QVM,請不要對號入座)。
先說一下互聯網安全的一些理念性的東西,首先沒有漏洞是不可能的,互聯網追求快速交付,把安全做的太厚重是“不滿足業務需求的”,為追求極致的低缺陷率而大幅增加發布成本是不切實際的,但是互聯網安全有幾個比較核心的需求:快速檢測、有限影響、快速溯源,快速恢復。
通俗解釋一遍就是:允許帶著一些問題上線,但是有bug或入侵我能快速檢測到而不是無知無覺的狀態,就算發生了攻擊或入侵,我能做到入侵者所獲取的權限和造成的影響盡可能的小,并且我有途徑或快照還原入侵過程做根因分析,安全事件能在基本不響應不中斷業務的情況下恢復到健康狀態。當然這個話題也太大,這次只討論其中關于“有限影響”的部分,在談及防御之前先看一下攻擊路徑:
Plan-A:通常路徑,從目標系統正面找漏洞,遠程直接rootshell在現代基本沒有了,大多數是從應用為入口,先獲取上層應用的權限,然后通過上傳webshell等方式間接獲得系統shell,最后提權獲得rootshell,后面繼續擴大戰果的事情就不提了,安全建設的思路自然是要反過來,阻止你擴大戰果。
Plan-B:如果正面沒有明顯可利用的漏洞的話就需要曲折迂回,從周圍信任域開始下手,這個信任域是廣義上的,包括可arp重定向的,可嗅探的,可會話中間人的,可鏈路劫持的,相同內網的,口令滿足同一規律的,互聯互通信任關系的,災備或鏡像站點等,獲取一個點后再折返,之后的路徑與A類似。
Plan-C:直接針對生產網絡不行的話,就需要考慮社會工程學了,針對管理員和辦公網絡的APT,水坑攻擊,針對應用后臺管理員的社會工程學技巧,搞定SA自然也就搞定了所有服務器。
縱深防御體系
安全建設是反入侵視角,針對攻擊活動中的每一步“埋點”,埋點的寓意在于我假設攻擊者到了這一步,我要阻止他進入下一步或者不能帶著完全的火力進入下一步還能全身而退。當然這里只針對有限影響,入侵檢測之類的部分這里先不展開,后續會有專門的話題。
第一層安全域劃分,這個安全域是對業務的抽象,并不是對物理服務器的劃分,在大規模分布式架構中,同一個安全域的機器可能并不一定位于同一個物理機房,但是他們對應相同的安全等級,共享一組相同的訪問控制策略,只對其他安全域或Internet暴露有限的協議和接口,即使攻擊者滲透了其他相鄰的服務器,也只能掃描和訪問這個安全域內有限的幾個端口,沒辦法自由滲透,這個問題主要解決Plan-B曲線救國時被入侵者“誤傷”,以及獲得單點root后進一步滲透的擴散,希望能把安全事件爆發的最大范圍抑制在一個安全域中,而不是直接擴散到全網。
第二層是基于數據鏈路層的隔離,只有2層隔離了才能算真正隔離,否則只在3層以上做ACL也是不行的,仍然會被ARP。2層使用VPC,vxlan,vlan等方法相當于在安全域的基礎上對一組服務器以更細的粒度再畫一道圈,進一步抑制單點淪陷后受害源擴大的問題。在不是特別大的網絡中可以直接跳過安全域到這一步。當然安全域的概念在任何時候都是存在的,僅僅是在做劃分的事情但不去套這個名詞。
二層之上就是協議端口狀態過濾,這是絕大多數“防火墻”的場景。解決的還是對黑客暴露的攻擊面的問題,即使我的加固做的不到位,不必要的服務沒有清理干凈,開放了有問題的端口,甚至有些端口上跑著的服務還有漏洞,但是因為被防火墻過濾了,路由不可達,所以攻擊者利用不了,他只能在對外或對信任域暴露的端口上去想辦法。本質一點就是給攻擊者提供“窄帶”,有限的訪問通道。不過在有復雜嵌套引用關系的大規模生產網絡中,出于運維成本的考慮,有時候訪問控制策略不會做的很細粒度,因為那樣的話如果有臺機器掛了換個ip都麻煩。這也是安全的妥協,我之后會有單獨篇幅講做安全是否需要妥協,應該如何妥協,底線是什么。
再往上一層是現在討論的最多的一層,其實從圖中也可以看出你平日的工作都是聚焦于哪層。這一層單獨拆開都可以再建一個縱深防御的子體系。應用層通常是暴露在Internet上的攻擊面,這一層主要是解決認證鑒權、注入跨站上傳之類的應用層漏洞,盡可能把入侵者堵在第一人口之外。如果你在開發WAF,那你對應的也是這一層的工作。
應用層上方是容器、運行時環境。這里的目標是假設我的服務器上的應用程序有漏洞,且攻擊者找到了漏洞,我不希望這個漏洞能被成功利用直接跳轉到系統權限,而是希望能在這一步阻止他,辦法就是通過容器加固,比如阻止一些危險函數的運行,比如上傳了webshell但是不被解析執行,比如你想執行eval()并用種種方法變形編碼字符竄拼接逃過了應用層的檢測,但是到了運行時其實是相同的底層指令,那么無論你在上層多么努力的變形我都會希望在更底層把你揪出來,哪怕不直接阻斷我也至少報個警。在絕大多數入侵活動中,上傳或生成webshell是從應用權限向系統權限轉化的關鍵一步,所以這一層的防御也是比較重要的。以后如果有時間單獨篇幅講如何對抗webshell。
對抗攻擊
如果不幸之前的都沒阻止攻擊者,對方已經得到了普通用戶的shell”$”,那么我肯定不希望你繼續得到rootshell,對抗的辦法就是大家常見的那些系統加固項,那些文章洋洋灑灑寫了一大堆主要就是用在這個場景的,不過最主要的還是對抗本地提權以及內核提權,攻擊免疫或稱攻擊緩解機制例如SMEP、SMAP、DEP、各種ASLR,stack-canay,read-only .PLT .GOT等都是在這里“埋點”,其他的諸如umask=022等也是在這里埋點,似乎看上去這些不太需要安全team的介入,好像都是OS默認的機制?
其實不然,安全做到偏執的程度還是有自己出手的地方,Android出手比標準的Linux更快一點,也許以后就真的沒太多需要自己出手的地方了。不過當下各種基于LXC的容器,越來越多的multi tenant的云環境,隔離的機制完全依賴于kernel的健壯性,這些場景下對抗這一層的攻擊都顯得尤為重要。
如果被拿走了root自然是很令人不爽的事,但還不是最令人不爽的。如果有一天當你的1萬臺服務器中有500臺被人搞了,而且還不能推斷是不是裝了kernel rootkit的情況下,這種感覺是最要命的,你生了個腫瘤手術摘掉也就算了,那種情況就像你手術完都不確定摘了沒,即便500臺服務器備份數據重裝系統都不徹底,而且近似于你某個子業務要處于離線狀態這種極其影響可用性的事情業務部門會把你逼瘋掉。
所以不是特別需求要干掉LKM,/dev/kmem,限制/dev/mem的全地址空間讀寫,另外kernel MAC內核強制訪問控制也能限制root只能做有限的事情,盡管理論上內核提權還是能控制一切,不過要在沒有開發環境的服務器上實現完整的kernel rootkit功能并保證不在用戶態留下蛛絲馬跡的概率還是比較低。這樣做還有一個好處,把入侵檢測聚焦于用戶態,不要動不動就去裝一堆內核級別的重量級玩意兒,大規模高并發的生產環境傷不起。
在云計算環境中,上面那步可能還不算是單點滲透的終結,更底層還有hypervisor,如果攻擊者逃逸出VM那就比較狼狽了,每個廠商都需要考慮一下VMM的保護方案,現在hypervisor這一層很薄不會做的很重,似乎還沒有特別成熟和通用的辦法,不過肯定會發展起來,會有更多類似于XSM這樣的方案。
結語
在一個真正建立縱深防御的系統中,入侵者一般到不了root這一步就會被揪出來,只不過完整的縱深防御要以后的篇幅慢慢寫了,這里只是選取了其中一個維度來試圖解讀這個概念。另一方面,完整的縱深防御體系只有大型互聯網公司才可能全覆蓋,因為跟安全建設成本有關,所以又涉及另外兩個話題:不同規模企業的安全需求和同一公司在不同安全建設階段的需求,以后再展開。