溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何構(gòu)造CodeDB來探索全新的白盒靜態(tài)掃描方案

發(fā)布時間:2021-12-27 15:42:41 來源:億速云 閱讀:105 作者:柒染 欄目:網(wǎng)絡(luò)安全

如何構(gòu)造CodeDB來探索全新的白盒靜態(tài)掃描方案,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

前言

我用了一個簡單的例子描述了一下基于.QL的掃描思路,但實際在這個領(lǐng)域我可能只見過一個活的SemmleQL(也就是CodeQL的原型)。下面我聊一聊這相關(guān)的東西,也分享一些我嘗試探索的一些全新的靜態(tài)掃描方案。

什么是.QL?

QL全稱Query Language,是一種用于從數(shù)據(jù)庫查詢數(shù)據(jù)的語言。我們常見的SQL就是QL的一種,這是一個很常見的概念。

而.QL是什么呢?Wiki上的解釋是,一種面向?qū)ο蟮牟樵冋Z言,用于從關(guān)系數(shù)據(jù)庫中檢索數(shù)據(jù)。

而.QL又和靜態(tài)分析有什么關(guān)系呢?我們需要理解一個概念叫做SCID。

SCID: Source Code in Database 是指一種將代碼語法解析并儲存進代碼中的操作方法。而這種數(shù)據(jù)庫我們可以簡單的稱之為CodeDB。

當(dāng)我們通過一種方案生成了CodeDB之后,我們就需要構(gòu)造一種QL語言來處理它。當(dāng)然CodeQL正是一種實現(xiàn)了CodeDB并設(shè)計好了相應(yīng)的QL語言的平臺。而Semmle QL設(shè)計的查詢語言就是一種.QL,它同時符合了幾種特點其中包括SQL、Datalog、Eindhoven Quantifier Notation、Classes are Predicates其中涵蓋了針對代碼的不同邏輯而使用的多種解決方案。當(dāng)然,本文并不是要討論CodeQL,所以這里我們并不深入解釋Semmle QL中的解決方案。

.QL的概念最早在2007年被提出,詳情可以參考:

https://help.semmle.com/home/Resources/pdfs/scam07.pdf

為什么使用.QL呢?

在《從0開始聊聊自動化靜態(tài)代碼審計工具》中我曾經(jīng)把基于.QL的認(rèn)為是未來白盒發(fā)展的主要趨勢,其主要原因在于現(xiàn)代普遍使用的白盒核心技術(shù)存在許多的無解問題,在上一篇文章中,我主要用一些基于技術(shù)原理的角度解釋了幾種現(xiàn)代的掃描方案,今天我就從技術(shù)本身聊聊這其中的區(qū)別。

其實我在前文中提到的兩種分析方式,無論是基于AST的分析、還是基于IR/CFG的分析方式,他們的區(qū)別只是技術(shù)基礎(chǔ)不同,但分析的理論差異不大,我們可以粗略的將它們統(tǒng)一叫做Data-flow analysis,也就是數(shù)據(jù)流分析(污點分析可以算作是數(shù)據(jù)流分析的變種)。

數(shù)據(jù)流分析有很多種種類,其本質(zhì)是流敏感的,且通常來說是路徑不敏感的。當(dāng)然,這并不是絕對的,我們可以按照敏感類型將其分類:

流敏感分析:flow-sensitive,考慮語句的執(zhí)行先后順序,這種分析通常依賴CFG控制流圖。

路徑敏感分析:path-sensitive,不僅考慮語句的執(zhí)行順序,還要分析路徑的執(zhí)行條件(比如if條件等),以確定是否存在可實際運行的執(zhí)行路徑。

上下文敏感分析:context-sensitive,屬于一種過程間分析,在分析函數(shù)調(diào)用目標(biāo)時會考慮調(diào)用上下文。主要面向的的場景為同一個函數(shù)/方法在不同次調(diào)用/不同位置調(diào)用時上下文不同的情況。

當(dāng)然,需要注意的是,這里僅指的是數(shù)據(jù)流分析的分類方式,與基于的技術(shù)原理無關(guān),如果你愿意,你當(dāng)然也可以基于AST來完成流敏感的分析工具。

在基于數(shù)據(jù)流的掃描方案中,如果能夠完整的支持各種語法充足的分析邏輯,我們就可以針對每一種漏洞分析相應(yīng)的數(shù)據(jù)流挖掘漏洞??上聦嵤牵瑔栴}比想象的還要多。這里我舉幾個可能被解決、也可能被暫時解決、也可能沒人能解決的問題作為例子。

1、如何判斷全局過濾方案?
2、如何處理專用的過濾函數(shù)未完全過濾的情況?
3、如何審計深度重構(gòu)的框架?
4、如何掃描儲存型xss?
5、如何掃描二次注入?
6、如何掃描eval中出現(xiàn)的偽代碼邏輯?

現(xiàn)代掃描方案不斷進步的同時,或許許多問題都得到一定程度的解決,但可惜的是,這就像是掃描方案與開發(fā)人員的博弈一樣,我們永遠(yuǎn)致力于降低誤報率、漏報率卻不能真正的解決,這樣一來好像問題就變得又無解了起來……

當(dāng)然,.QL的概念的掃描方案并不是為了解決這些問題而誕生的,可幸運的是, 從我的視角來看,基于.QL概念的掃描方案將靜態(tài)掃描走到了新的路中,讓我們不再拘泥于探討如何處理流敏感、約束方案等等。上次我簡單解釋了基于.QL掃描方式的原理。

其核心的原理就在于通過把每一個操作具象化模板化,并儲存到數(shù)據(jù)庫中。比如

a($b);

這個語句被具象為

Function-a  FunctionCall ($b)

然后這樣的三元組我們可以作為數(shù)據(jù)庫中的一條數(shù)據(jù)。

而當(dāng)我們想要在代碼中尋找執(zhí)行a函數(shù)的語句時,我們就可以直接通過

select * from code_db from where type = 'FunctionCall' and node_name = 'Function-a';

這樣的一條語句可以尋找到代碼中所有的執(zhí)行a函數(shù)的節(jié)點。

當(dāng)然,靜態(tài)分析不可能僅靠這樣的簡單語句就找到漏洞,但事實就是,當(dāng)我們針對CodeDB做分析的時候,我們既保證了強代碼執(zhí)行順序,又可以跨越多重壁壘直接從sink點出發(fā)做分析,當(dāng)相應(yīng)的QL支持越來越多的高級查詢又或者是自定義高級規(guī)則之后,或許可以直接實現(xiàn)。

select * where {
    Source : $_GET,
    Sink : echo,
    is_filterxss : False,
}

也正是因為如此,CodeQL的出現(xiàn),被許多人認(rèn)為是跨時代的出現(xiàn),靜態(tài)分析從底層的代碼分析,需要深入到編譯過程中的方式,變成了在平臺上巧妙構(gòu)思的規(guī)則語句,或許從現(xiàn)在來說,CodeQL這種先鋪好底層的方式并不能直接的看到效果,可幸運的是,作為技術(shù)本身而言,我們又有了新的前進方向。

下面的文章,我們就跟著我前段時間的一些短期研究成果,探索一下到底如何實現(xiàn)一個合理的CodeDB。

如何實現(xiàn)一個合理的CodeDB呢?

在最早只有Semmle QL的時候我就翻看過一些paper,到后來的LGTM,再到后來的CodeQL我都有一些了解,后來CodeQL出來的時候,翻看過一些人寫的規(guī)則都距離CodeQL想要達(dá)到的目標(biāo)相去甚遠(yuǎn),之后就一直想要自己試著寫一個類似的玩具試試看。這次在更新KunLun-M的過程中我又多次受制于基于AST的數(shù)據(jù)流分析的種種困難,于是有了這次的計劃誕生。

為了踐行我的想法,這次我花了幾個星期的事件設(shè)計了一個簡易版本的CodeDB,并基于CodeDB寫了一個簡單的尋找php反序列化鏈的工具,工具源碼詳見:

  • https://github.com/LoRexxar/Kunlun-M/tree/master/core/plugins/phpunserializechain

在聊具體的實現(xiàn)方案之前,我們需要想明白CodeDB到底需要記錄什么?

首先,每一行代碼的執(zhí)行順序、所在文件是基本信息。其次當(dāng)前代碼所在的域環(huán)境、代碼類型、代碼相關(guān)的信息也是必要的條件。

在這個基礎(chǔ)上,我嘗試使用域定位、執(zhí)行順序、源節(jié)點、節(jié)點類型、節(jié)點信息這5個維度作為五元組儲存數(shù)據(jù)。舉一個簡單的例子:

test.php

<?php
$a = $_GET['a'];

if (1>0){
    echo $b;
}

上面的代碼轉(zhuǎn)化的結(jié)果為

test_php 1 Variable-$a Assignment ArrayOffset-$_GET@a
test_php 2 if If ['1', '>', '0']
test_php.if 0 1 BinaryOp-> 0
test_php.if 1 echo FunctionCall ('$a',)

由于這里我主要是一個嘗試,所以我直接依賴SQL來做查詢并將分析邏輯直接從代碼實現(xiàn),這里我們直接用sql語句做查詢。

select * from code_db where node_type='FunctionCall' and node_name='echo'

用上述語句查詢出echo語句,然后分析節(jié)點信息得到參數(shù)為$a

然后通過

select * from code_db where node_locate = 'test_php.if' and node_sort=0

來獲取if的條件信息,并判斷為真。

緊接著我們可以通過SQL語句為

select * from code_db where node_name='$a' and node_type='Assignment' and node_locate like 'test_php%' and node_id >= 4

得到賦值語句,經(jīng)過判斷就可以得到變量來源于$_GET。

當(dāng)然,邏輯處理遠(yuǎn)比想像的要復(fù)雜,這里我們舉了一個簡單的例子做實例,通過sort為0記錄參數(shù)信息和條件信息,如果出現(xiàn)同一個語句中的多條指令,可能會出現(xiàn)sort相同的多個節(jié)點,還需要sort和id共同處理...

這里我嘗試性的構(gòu)造了基于五元組的CodeDB生成方案,并通過一些SQL語句配合代碼邏輯分析,我們得到了想要掃描結(jié)果。事實上,雖然這種基于五元組的CodeDB仍不成熟,但我們的確通過這種方式構(gòu)造了一種全新的掃描思路,如果CodeDB構(gòu)造成熟,然后封裝一些基礎(chǔ)的查詢邏輯,我們就可以大幅度解決我在KunLun-M中遇到的許多困境。

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI