兩年前云鼎實驗室的兩位安全技術專家,在世界頂級安全峰會Blackhat USA上做過一次關于使用CodeQL進行二進制靜態分析的演講,創新性地將CodeQL應用到二進制分析領域,到目前為止在世界范圍內也是獨一無二的嘗試。兩年后,隨著AI技術的蓬勃發展,我們將AI和靜態分析技術深度融合,借助LLM和Agent體系,將靜態分析的召回率和精確率都提升到前所未有的高度,并且在騰訊內部生產環境里落地應用,解決了很多現實風險問題。同時,我們也堅定的認為傳統靜態分析技術和CodeQL等分析工具仍有巨大的提升空間。AI和靜態分析不是取代關系,是互相加持的關系。此次在Blackhat上的分享,一定程度上是對我們理念和實踐的一次全面闡述。在此我們整理了一篇文章,將其中的一些技術要點做簡單介紹。
首先,我們在代碼安全掃描實踐工作中,遇到了兩個大的障礙是純粹依靠靜態分析難以解決的:
在污點分析中,因為開源項目眾多,二開和定制化的情況也很多,source和sink點永遠也收集不全,即便依賴知識庫也難以達到好的覆蓋。
在數據流分析中,限于很多編程語言的特性,比如各種異步調用和隱式傳遞,數據流分析經常會斷流。而我們所做的工作也是集中解決如上的這兩個問題。
基于大模型在訓練階段的知識嵌入和代碼能力,業界已經發現大模型可以在代碼中自動識別一些source和sink點,但是直接使用大模型帶來的識別率和準確率無法讓人滿意。我們對應的解決方法是設計了一套多agent組合判定機制,其中包括三個重要角色,分別是Discover agent、Judge agent和Validation agent。三者分別負責發現、判斷和驗證。用這種將一個復雜任務拆解成多個簡單任務,并由多個agent各自負責并循環提升的方式獲得好的效果。目前我們這套流程每天都會自動發現和入庫很多source sink點,并滿足高精度要求。
當然,這里對源代碼的處理不是簡單的直接塞給LLM。中間我們適度地使用了LSP和其它analysis技術,讓agent可以在代碼間形成索引和跳轉,按需獲取必要的代碼片段以及上下文信息。
另一個問題就是靜態分析中最常見的數據流分析,限于很多語言特性數據流的傳播不能保證完整性,一些隱式的方法調用和數據傳遞方式導致靜態分析很難精確和完整的追蹤數據流向。對此我們的解法是改造CodeQL的基礎類庫,將各種斷鏈的情況解決掉。舉幾個例子比如代碼中使用跨線程、反射、符號表等方法將傳播流斷開。
解決這些問題又存在兩個難點,首先需要將CodeQL的DFA(Data Flow Analysis)機制研究清楚,但是CodeQL本身閉源,再加上QL是Datalog類的語言難以調試。我們克服了很多困難進行深入分析,最終把CodeQL的DFA機制研究清楚。具體技術細節這里不做展開,感興趣的同學可以參考我們峰會演講后的材料。
第二個難點就是跨線程、反射等情況下,對方法調用的精確定位比較難,封裝層次、弱引用、繼承關系、命名空間等都是問題。先要解決這些識別問題才能patch CodeQL以實現DFA的強化。最終我們能做到在跨線程、反射、隱式值傳遞等情況下的完整數據流分析。
在做了source/sink自動精整識別和DFA強化后,我們的代碼安全檢測能力如預期的一樣獲得了極大提升,可以7*24小時自動掃描出漏洞信息?;诖宋覀円舶l現了不少高危漏洞。這里拿幾個歷史漏洞來舉例,當你使用原版CodeQL的情況下,如下的漏洞都不會被掃描出來,使用我們強化過的方案都可以做到掃描發現。
最后,我們想拋出一些明確的觀點來供業界參考:
AI不是解決方案,AI是技術手段。大模型在很多場景下可以提供幫助,但是單靠AI遠遠不夠。大模型再怎么訓練本身可以嵌入的知識是有限的,沒有外部LSP等技術的配合大模型沒辦法很好的工作。
靜態分析仍然是很給力的技術手段。AI+靜態分析可以互相促進獲得之前不能達成的效果。兩者相結合是未來代碼分析的最佳形態。
體系和系統化是關鍵。需要一個Driver去驅動各種Agent和工具來一起完成代碼分析任務。