日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c++代码健壮性_复活Navex-使用图查询进行代码分析(上)

發布時間:2024/7/23 c/c++ 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++代码健壮性_复活Navex-使用图查询进行代码分析(上) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

從了解到修復 Navex, 其中花了一年多, 從對自動化代碼審計一無所知到學習PL/Static Analysis, 翻閱十幾年前的文檔, 補全Gremlin Step, 理解AST, CFG, DDG, PDG, CPG, 也感謝z3r0yu師傅和Gaba哥的的交流指導.
本文重點在于靜態分析 Joern-圖查詢部分, 后面的動態分析自動生成EXP部分是剪枝的過程, 也相對好實現, 各位有興趣的話, 我會在下一篇文章繼續談論.
這里不得不說的Navex實際的效果沒有描述的那么優秀, 以及作者故意在代碼里埋坑, 畢竟人家也研究了快十年, 留一手也是正常的.
這里不是說一定非要完成/使用Navex, 而是借鑒新鮮的學術思想, 結合實際環境實現相關功能來降低排查漏洞成本.

預備知識

Navex 是什么

下面這段摘自z3r0yu師傅的博文 Navex

NAVEX->Precise and Scalable Exploit Generation for Dynamic Web Applications
出處:27th USENIX Security Symposium
作者:Abeer Alhuzali, Rigel Gjomemo, Birhanu Eshete, and V.N.
單位:Venkatakrishnan University of Illinois at Chicago
資料:Paper | Github
作者在本文中提出了一種以靜態分析作為指導,結合動態分析自動驗證漏洞并構造可用exploit的工具NAVEX。
研究問題:
  • 解決以往自動化審計的誤報以及必須結合人工參與構造Exp的問題;
  • 靜態分析雖然覆蓋率高,但是對于具有動態特性的語言其建模困難。解決方案:
  • 靜態分析階段:使用符號執行創建Web應用程序的各個模塊的行為模型。標記出包含潛在漏洞點的模塊;
  • 動態分析階段:使用Web爬蟲和concolic執行器去發現可能導致攻擊者進入易受攻擊模塊的可能的HTTP導航路徑,之后使用約束求解器生成一組對漏洞進行利用的HTTP輸入序列。
    方案優點:.
  • 動態分析與靜態分析相結合提升了性能,可以應用于大型應用程序;
  • 是一種多類型漏洞的Exp生成框架。
    NAVEX分析了320萬行PHP代碼,自動構建并利用204個漏洞,其中有195個與SQLI和XSS相關,而9個與邏輯漏洞相關。此外NAVEX是第一個可以自動發現并利用EAR漏洞的方案。
  • Joern 靜態分析核心模塊

    Joern 是ShiftLeft公司開發的用于C/C++代碼健壯性分析的平臺. 其核心思想: 將代碼分析問題轉化為用Gremlin去遍歷存儲在Neo4j中的CPG(代碼屬性圖). 其商業產品 Ocular 支持多種語言, 也側面證明 CPG 作為一種 IR, 是可以解決大部分語言的審計問題.

    PS. 靜態分析這部分其實可以使用Codeql代替.

    CPG 代碼屬性圖

    CPG (代碼屬性圖) 的論文可以參考

    Modeling and Discovering Vulnerabilities with Code Property Graphs

    這里用幾張圖簡要描述一下

    原始代碼

    代碼對應的AST(抽象語法樹)

    代碼對應的CFG(控制流程圖)

    代碼對應的PDG(程序依賴圖)

    ](https://blog.riskivy.com/wp-content/uploads/2020/05/4afab12ab74238d1b09a90517beabf9e.png)

    代碼對應的CPG(代碼屬性圖)

    其實以上的信息都可以從AST中獲取, 只是后續的操作提高了單位節點的信息密集度, 對分析過程更友好

    TinkerPop 2.x Gremlin 圖查詢語言

    由于Navex作者是2012年開始研究這個方向, 所以大部分依賴都是遠古版本, 我盡可能的修復了一些, 其中TinkerPop 2.x Gremlin由于官方已經更新 TinkerPop 3.x, 2.x 已經不再維護了, 全網只有一個github上面的歷史文檔

    spmallette/GremlinDocs: Gremlin Documentation and Samples

    或者閱讀TinkerPop 2.x Gremlin的實現源碼

    tinkerpop/gremlin: A Graph Traversal Language (no longer active – see Apache TinkerPop).

    其實更新為最新版的TP3(文檔, 性能和語法都更好), 我也嘗試過, 但是整個框架的Gremlin step需要重寫, 不利于前期探索, TP2目前還夠用, 所以如果后續有需要, 可以考慮整體重構.

    目前的python-joern的實現方式是通過HTTP請求發送Gremlin查詢語言(Groovy實現)到Neo4j的Gremlin插件

    為什么不用Neo4j自帶的Cypher, 因為Gremlin支持Groovy語法, 有更強的操作性, 也兼容其他圖數據庫

    Tinkerpop 2.x Gremlin 基礎知識

    首先得了解Groovy的相關語法

    精通 Groovy

    TinkerPop 2.x Gremlin 文檔查看這個

    tinkerpop/gremlin: A Graph Traversal Language (no longer active – see Apache TinkerPop).

    下面是我添加了一些注釋, 方便理解

    it

    it 是groovy閉包中的默認參數

    list.each {println it }//等于list.each { obj ->println obj }

    id

    Gets the unique identifier of the element.

    每個節點/邊都有唯一的id

    gremlin> v = g.V("name", "marko").next() ==>v[1] gremlin> v.id ==>1 gremlin> g.v(1).id ==>1

    V

    The vertex iterator for the graph. Utilize this to iterate through all the vertices in the graph. Use with care on large graphs unless used in combination with a key index lookup.

    在 TP2中

    g.V() 代表所有節點

    g.v(1) 注意這里是小寫的v, 可以用node_id取值

    g.V("name", "marko") 返回 v.name=="marko" 的節點

    gremlin> g.V ==>v[3] ==>v[2] ==>v[1] ==>v[6] ==>v[5] ==>v[4] gremlin> g.V("name", "marko") ==>v[1] gremlin> g.V("name", "marko").name ==>marko

    E

    The edge iterator for the graph. Utilize this to iterate through all the edges in the graph. Use with care on large graphs.

    返回節點的所有邊

    gremlin> g.E ==>e[10][4-created->5] ==>e[7][1-knows->2] ==>e[9][1-created->3] ==>e[8][1-knows->4] ==>e[11][4-created->3] ==>e[12][6-created->3] gremlin> g.E.weight ==>1.0 ==>0.5 ==>0.4 ==>1.0 ==>0.4 ==>0.2

    in

    Gets the adjacent vertices to the vertex.

    返回當前node的父節點

    參數的調用可以不寫 ()

  • 沒有參數的調用可以不寫 ()
  • 這個技巧在后面存儲路徑信息的時候會用到
  • g.v(4).inE.outV == g.v(4).in

    g.v(4).outE.inV == g.v(4).out

    gremlin> v = g.v(4) ==>v[4] gremlin> v.inE.outV ==>v[1] gremlin> v.in ==>v[1] gremlin> v = g.v(3) ==>v[3] gremlin> v.in("created") ==>v[1] ==>v[4] ==>v[6] gremlin> v.in(2,'created') ==>v[1] ==>v[4] gremlin> v.inE("created").outV ==>v[1] ==>v[4] ==>v[6] gremlin> v.inE(2,'created').outV[0] ==>v[1]

    out

    Gets the out adjacent vertices to the vertex.

    返回當前node的子節點

    gremlin> v = g.v(1) ==>v[1] gremlin> v.outE.inV ==>v[2] ==>v[4] ==>v[3] gremlin> v.out ==>v[2] ==>v[4] ==>v[3] gremlin> v.outE('knows').inV ==>v[2] ==>v[4] gremlin> v.out('knows') ==>v[2] ==>v[4] gremlin> v.out(1,'knows') ==>v[2]

    both

    Get both adjacent vertices of the vertex, the in and the out.

    both 操作表示node 的相鄰節點, 也就有有edge 存在, 且忽略 edge 的方向

    gremlin> v = g.v(4) ==>v[4] gremlin> v.both ==>v[1] ==>v[5] ==>v[3] gremlin> v.both('knows') ==>v[1] gremlin> v.both('knows', 'created') ==>v[1] ==>v[5] ==>v[3] gremlin> v.both(1, 'knows', 'created') ==>v[1]

    Transform

    Transform steps take an object and emit a transformation of it.

    Transform 操作可以返回其后面閉包里面的值

    Identity turns an arbitrary object into a “pipeline”.

    gremlin> x = [1,2,3] ==>1 ==>2 ==>3 gremlin> x._().transform{it+1} ==>2 ==>3 ==>4 gremlin> x = g.E.has('weight', T.gt, 0.5f).toList() ==>e[10][4-created->5] ==>e[8][1-knows->4] gremlin> x.inV ==>[StartPipe, InPipe] ==>[StartPipe, InPipe] gremlin> x._().inV ==>v[5] ==>v[4]

    has

    使用has可以做一些簡單的屬性判斷

    Allows an element if it has a particular property. Utilizes several options for comparisons through T:

    • T.gt – greater than
    • T.gte – greater than or equal to
    • T.eq – equal to
    • T.neq – not equal to
    • T.lte – less than or equal to
    • T.lt – less than
    • http://T.in – contained in a list
    • T.notin – not contained in a list

    It is worth noting that the syntax of has is similar to g.V("name", "marko"), which has the difference of being a key index lookup and as such will perform faster. In contrast, this line, g.V.has("name", "marko"), will iterate over all vertices checking the name property of each vertex for a match and will be significantly slower than the key index approach. All that said, the behavior of has is dependent upon the underlying implementation and the above description is representative of most Blueprints implementations. For instance, Titan will actually try to use indices where it sees the opportunity to do so. It is therefore important to understand the functionality of the underlying database when writing traversals.

    gremlin> g.V.has("name", "marko").name ==>marko gremlin> g.v(1).outE.has("weight", T.gte, 0.5f).weight ==>0.5 ==>1.0 gremlin> g.V.has('age').name ==>vadas ==>marko ==>peter ==>josh gremlin> g.V.has('age',T.in,[29,32]) ==>v[1] ==>v[4] gremlin> g.V.has('age').has('age',T.notin, [27,35]).name ==>marko ==>josh

    [i]

    A index filter that emits the particular indexed object.

    通過下標可以進行取值, 跟Python的數組相似

    gremlin> g.V[0].name ==>lop

    [i..j]

    A range filter that emits the objects within a range.

    下標也可以取范圍. 前閉后開, [0,2)

    gremlin> g.V[0..2].name ==>lop ==>vadas ==>marko gremlin> g.V[0..<2].name ==>lop ==>vadas

    filter

    Decide whether to allow an object to pass. Return true from the closure to allow an object to pass.

    filter操作就是通過一個閉包函數來過濾輸入

    //filter有時會失效,最好用has() g.v(1).outE.has('label','created') //g.v(1).outE.filter{it.label=='created'}groovy
    in filter{}it.xxx() 可能返回 pipe 對象
    可以使用it.xxx().next()
    來獲取第一個節點gremlin> g.V.filter{it.age > 29}.name ==>peter

    dedup

    Emit only incoming objects that have not been seen before with an optional closure being the object to check on.

    用于去除重復元素

    gremlin> g.v(1).out.in ==>v[1] ==>v[1] ==>v[1] ==>v[4] ==>v[6] gremlin> g.v(1).out.in.dedup() ==>v[1] ==>v[4] ==>v[6]

    as

    Emits input, but names the previous step.

    給一個操作設置一個別名, 配合select, loop

    g.v(1).as('sloop').outE.inV.loop('sloop'){it.loops < 2}

    循環體為 .outE.inV. 等價

    g.v(1).outE.inV.loop(2){it.loops < 2}

    gremlin> g.V.as('x').outE('knows').inV.has('age', T.gt, 30).back('x').age ==>29

    select

    Select the named steps to emit after select with post-processing closures.

    select 一般配合as一起使用

    gremlin> g.v(1).as('x').out('knows').as('y').select ==>[x:v[1], y:v[2]] ==>[x:v[1], y:v[4]] gremlin> g.v(1).as('x').out('knows').as('y').select(["y"]) ==>[y:v[2]] ==>[y:v[4]] gremlin> g.v(1).as('x').out('knows').as('y').select(["y"]){it.name} ==>[y:vadas] ==>[y:josh] gremlin> g.v(1).as('x').out('knows').as('y').select{it.id}{it.name} ==>[x:1, y:vadas] ==>[x:1, y:josh]

    sideEffect

    Emits input, but calls a side effect closure on each input.

    官方示例中的是交互console, 可以延伸到下一條語句

    gremlin> youngest = Integer.MAX_VALUE ==>2147483647 gremlin> g.V.has('age').sideEffect{youngest=youngest>it.age?it.age:youngest} ==>v[2] ==>v[1] ==>v[6] ==>v[4] gremlin> youngest ==>27

    sideEffect可以在運行過程中執行指定操作, 但是不會影響遍歷過程, 主要用于收集信息, 盡量不要用于改變節點信息

    在python-joern中, sideEffect的作用域只在當前遍歷過程/語句, 這里比較坑人, 大家注意

    g.V.has('age').sideEffect{youngest=youngest>it.age?it.age:youngest}.transform{youngest}

    ifThenElse

    Allows for if-then-else conditional logic.

    gremlin> g.v(1).out.ifThenElse{it.name=='josh'}{it.age}{it.name} ==>vadas ==>32 ==>lop

    判斷條件選擇分支執行, 這邊傾向于單獨使用groovy的 if語句來處理, 邏輯更清晰

    loop

    Loop over a particular set of steps in the pipeline. The first argument is either the number of steps back in the pipeline to go or a named step. The second argument is a while closure evaluating the current object. The it component of the loop step closure has three properties that are accessible. These properties can be used to reason about when to break out of the loop.

    • it.object: the current object of the traverser.
    • it.path: the current path of the traverser.
    • it.loops: the number of times the traverser has looped through the loop section.

    The final argument is known as the “emit” closure. This boolean-based closure will determine wether the current object in the loop structure is emitted or not. As such, it is possible to emit intermediate objects, not simply those at the end of the loop.

    gremlin> g.v(1).out.out ==>v[5] ==>v[3] gremlin> g.v(1).out.loop(1){it.loops<3} ==>v[5] ==>v[3] gremlin> g.v(1).out.loop(1){it.loops<3}{it.object.name=='josh'} ==>v[4]

    loop應該這里最關鍵的操作, 可以參考

    Loop Pattern · tinkerpop/gremlin Wiki

    大部分的查詢操作都需要loop進行配合

    g.v(1).out.loop(1){it.loops<3}{it.object.name=='josh'}

    大概等價于

    arr = [] for (i=1; i<3; i++){if(it.object.name=='josh'){arr.add(it.object)} } return arr

    結合后面的enablePath, 可以在遍歷的過程中獲取當前所在的完整路徑信息

    g.v(1).out.loop(1){it.loops<3}{it.object.name=='josh' && it.path.contains(g.v(4))}.enablePath

    大概等價于

    arr = [] for (i=1; i<3; i++){if(it.object.name=='josh' && it.path.contains(g.v(4))){arr.add(it.object)} } return arr

    Pipe.enablePath

    If the path information is required internal to a closure, Gremlin doesn’t know that as it can not interpret what is in a closure. As such, be sure to use GremlinPipeline.enablePath() if path information will be required by the expression.

    主要是保存路徑信息

    gremlin> g.v(1).out.loop(1){it.loops < 3}{it.path.contains(g.v(4))} Cannot invoke method contains() on null object Display stack trace? [yN] gremlin> g.v(1).out.loop(1){it.loops < 3}{it.path.contains(g.v(4))}.enablePath() ==>v[5] ==>v[

    Pipe.next

    Gets the next object in the pipe or the next n objects. This is an important notion to follow when considering the behavior of the Gremlin Console. The Gremlin Console iterates through the pipeline automatically and outputs the results. Outside of the Gremlin Console or if more than one statement is present on a single line of the Gremlin Console, iterating the pipe must be done manually. Read more about this topic in the Gremlin Wiki Troubleshooting Page.

    There are some important things to note in the example below. Had the the first line of Gremlin been executed separately, as opposed to being placed on the same line separated by a semi-colon, the name of the vertex would have changed because the Gremlin Console would have automatically iterated the pipe and processed the side-effect.

    gremlin> g.v(1).sideEffect{it.name="same"};g.v(1).name ==>marko gremlin> g.v(1).sideEffect{it.name="same"}.next();g.v(1).name ==>same gremlin> g.V.sideEffect{it.name="same-again"}.next(3);g.V.name ==>same-again ==>same-again ==>same-again ==>peter ==>ripple ==>josh

    next 操作可以從pipe中取出對象 // pipe返回的一般都是生成器對象

    path

    Gets the path through the pipeline up to this point, where closures are post-processing for each object in the path. If the path step is provided closures then, in a round robin fashion, the closures are evaluated over each object of the path and that post-processed path is returned.

    gremlin> g.v(1).out.path ==>[v[1], v[2]] ==>[v[1], v[4]] ==>[v[1], v[3]] gremlin> g.v(1).out.path{it.id} ==>[1, 2] ==>[1, 4] ==>[1, 3] gremlin> g.v(1).out.path{it.id}{it.name} ==>[1, vadas] ==>[1, josh] ==>[1, lop] gremlin> g.v(1).outE.inV.name.path ==>[v[1], e[7][1-knows->2], v[2], vadas] ==>[v[1], e[8][1-knows->4], v[4], josh]

    path操作返回遍歷的所有路徑

    simplePath

    Emit the object only if the current path has no repeated elements.

    gremlin> g.v(1).out.in ==>v[1] ==>v[1] ==>v[1] ==>v[4] ==>v[6] gremlin> g.v(1).out.in.simplePath ==>v[4] ==>v[6]

    simplePath返回沒有環路的path

    toList

    g.v(1).out //返回生成器 g.v(1).out.toList() //返回一個列表, 已經把數據都讀出來了, 可以隨便操作

    intersect

    返回交集

    [1,2,3].intersect([1]) => [1][].intersect([1]) => []

    Navex 排坑

    被刪除的查詢語句

    當你信心滿滿的解決了前面的各種古老依賴, 奇怪版本號問題時, 在最關鍵的查詢語句是丟失的

    如果你真的嘗試運行了, 大概會這樣

    #python static-main.py the query is xss_funcs = ["print", "echo"] sql_query_funcs = ["mysql_query", "mysqli_query", "pg_query", "sqlite_query"] os_command_funcs = ["backticks", "exec" , "expect_popen","passthru","pcntl_exec","popen","proc_open","shell_exec","system", "mail" ]m =[]; queryMapList =[]; g.V().filter{sql_query_funcs.contains(it.code) && isCallExpression(it.nameToCall().next()) }.callexpressions().sideEffect{m = start(it, [], 0, 'sql', false, queryMapList)}.sideEffect{ warnmessage = warning(it.toFileAbs().next().name, it.lineno, it.id, 'sql', '1')}.sideEffect{ reportmessage = report(it.toFileAbs().next().name, it.lineno, it.id)}.ifThenElse{m.isEmpty()}{it.transform{reportmessage}}{it.transform{findSinkLocation(m, warnmessage, 'sql', queryMapList, it)}} Caught exception: <class 'py2neo.error.BadInputException'> groovy.lang.MissingMethodException: No signature of method: com.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine.start() is applicable for argument types: (com.tinkerpop.blueprints.impls.neo4j2.Neo4j2Vertex, java.util.ArrayList, java.lang.Integer, java.lang.String, java.lang.Boolean, java.util.ArrayList) values: [v[721], [], 0, sql, false, []] Possible solutions: wait(), any(), every() None

    很顯然是作者刪除了關鍵函數

    m = start(it, [], 0, 'sql', false, queryMapList) # 篩選sql注入節點

    findSinkLocation(m, warnmessage, 'sql', queryMapList, it) # 查找Sink

    所以你不可能直接復現論文里的靜態分析結果, 世界上除了作者應該沒人知道寫的是啥了, issue中也有人反饋這樣的問題

    python-joern/Analysis.py at e5f651511143938511ae572b7986bfa92c6c4936 · aalhuz/python-joern

    大部分想嘗試的人, 面對這樣未知的領域, 未知的語言, 未知的代碼, 都會就此止步, 可惜了, 我不信邪, 哪怕重新寫一個.

    之后的時間, 去尋找“Tinkerpop Gremlin的教程, 然后學完百度的HugeGraph教程才發現市面上的文檔都是針對Tinkerpop 3.x, 甚至又學習了一個寶藏博主的Tinkerpop 3.x`教程
    PRACTICAL GREMLIN: An Apache TinkerPop Tutorial
    想著觸類旁通, 修復Tinkerpop 2.x 的 Navex, 在一個完全陌生的領域探索必然是緩慢而痛苦的, 又過了很久, 找到 github上面的一份古老文檔
    spmallette/GremlinDocs: Gremlin Documentation and Samples
    這是一份 2012-2015 年的Tinkerpop 2.x文檔, 然后勉強把Tinkerpop 2.x文檔扣了一遍, 中間穿插學習了編譯原理, 離散數學, 南大的靜態分析課程, 也算是知道了什么是靜態分析, 大概的原理和目的也算是清楚了些.
    在瀏覽器相關收藏快100個了的時候, 前后知識點終于打通了, 被迫完成了作者刪除的代碼, 回過頭來看, 也不是特別難, 硬著頭皮寫Gremlin遍歷, 邊查邊寫就是了.

    CPG – Vertex, Edge , Property

    CPG的節點, 邊和屬性信息都記錄在下面這個文件中

    joern/phpjoernsteps/_constants.groovy

    // AST node property keysObject.metaClass.NODE_INDEX = 'id' // 每個node都有自己的id Object.metaClass.NODE_TYPE = 'type' // 節點的類型, 后面`AST node types`有具體描述 Object.metaClass.NODE_FLAGS = 'flags' // 參考`AST node flags`, 賦值, 二元操作,判斷, 文件包含, 目錄信息 Object.metaClass.NODE_LINENO = 'lineno' // 當前節點所處源文件的行數 Object.metaClass.NODE_CODE = 'code' // 引用的函數或者變量的名稱 Object.metaClass.NODE_FUNCID = 'funcid' // 所處文件的文件id Object.metaClass.NODE_ENDLINENO = 'endlineno' // 所處文件的總行數 Object.metaClass.NODE_NAME = 'name' // 函數聲明的函數名稱, 文件的文件名 Object.metaClass.NODE_DOCCOMMENT = 'doccomment' // 注釋// AST node types //g.V().has('type', TYPE_STMT_LIST) Object.metaClass.TYPE_STMT_LIST = 'AST_STMT_LIST' // ...; ...; ...; Object.metaClass.TYPE_CALL = 'AST_CALL' // foo() Object.metaClass.TYPE_STATIC_CALL = 'AST_STATIC_CALL' // bla::foo() Object.metaClass.TYPE_METHOD_CALL = 'AST_METHOD_CALL' // $bla->foo() Object.metaClass.TYPE_PROP = 'AST_PROP' // e.g., $bla->foo Object.metaClass.TYPE_FUNC_DECL = 'AST_FUNC_DECL' // function foo() {} Object.metaClass.TYPE_METHOD = 'AST_METHOD' // class bla { ... function foo() {} ... } Object.metaClass.TYPE_ARG_LIST = 'AST_ARG_LIST' // foo( $a1, $a2, $a3) Object.metaClass.TYPE_PARAM_LIST = 'AST_PARAM_LIST' // function foo( $p1, $p2, $p3) {} Object.metaClass.TYPE_PARAM = 'AST_PARAM' // $p1 Object.metaClass.TYPE_ASSIGN = 'AST_ASSIGN' // $buzz = true Object.metaClass.TYPE_ASSIGN_REF = 'AST_ASSIGN_REF' // $b = &$a Object.metaClass.TYPE_ASSIGN_OP = 'AST_ASSIGN_OP' // $x += 3 Object.metaClass.TYPE_NAME = 'AST_NAME' // names (e.g., name of a called function in call expressions) Object.metaClass.TYPE_VAR = 'AST_VAR' // $v Object.metaClass.TYPE_BINARY_OP = 'AST_BINARY_OP' // e.g., "foo"."bar" or 3+4 Object.metaClass.TYPE_ENCAPS_LIST = 'AST_ENCAPS_LIST' // e.g., "blah{$var1}buzz $var2 beep" Object.metaClass.TYPE_INCLUDE_OR_EVAL = 'AST_INCLUDE_OR_EVAL' // eval, include, require //Abeer Object.metaClass.TYPE_CALLEE = 'Callee' Object.metaClass.TYPE_FUNCTION = 'Function' Object.metaClass.TYPE_ECHO = 'AST_ECHO' // echo Object.metaClass.TYPE_PRINT = 'AST_PRINT' // PRINT//ABEER Object.metaClass.TYPE_IF_ELEM = 'AST_IF_ELEM' // HOLDES THE COND INSIDE IF Object.metaClass.TYPE_DIM = 'AST_DIM' // _POST[x] Object.metaClass.TYPE_ISSET = 'AST_ISSET' // is_set() // TODO and many more...// AST node flags // of AST_ASSIGN.* Object.metaClass.FLAG_ASSIGN_CONCAT = 'ASSIGN_CONCAT' // $v .= "foo" // of AST_BINARY_OP Object.metaClass.FLAG_BINARY_CONCAT = 'BINARY_CONCAT' // "foo"."bar" //Abeer Object.metaClass.FLAG_BINARY_EQUAL = 'BINARY_IS_EQUAL' // x==y Object.metaClass.FLAG_BINARY_NOT_EQUAL = 'BINARY_IS_NOT_EQUAL' // x != y Object.metaClass.FLAG_BINARY_IS_IDENTICAL = 'BINARY_IS_IDENTICAL' // 1 === 1 Object.metaClass.FLAG_BINARY_IS_NOT_IDENTICAL = 'BINARY_IS_NOT_IDENTICAL' // 1 !== 1 // of AST_INCLUDE_OR_EVAL Object.metaClass.FLAG_EXEC_EVAL = 'EXEC_EVAL' // eval("...") Object.metaClass.FLAG_EXEC_INCLUDE = 'EXEC_INCLUDE' // include "..." Object.metaClass.FLAG_EXEC_INCLUDE_ONCE = 'EXEC_INCLUDE_ONCE' // include_once "..." Object.metaClass.FLAG_EXEC_REQUIRE = 'EXEC_REQUIRE' // require "..." Object.metaClass.FLAG_EXEC_REQUIRE_ONCE = 'EXEC_REQUIRE_ONCE' // require_once "..."// TODO and many more...// Other (non-AST) node types // 目錄結構信息 Object.metaClass.TYPE_DIRECTORY = 'Directory' Object.metaClass.TYPE_FILE = 'File'Object.metaClass.TYPE_STRING = 'string'// Edge typesObject.metaClass.DIRECTORY_EDGE = 'DIRECTORY_OF' Object.metaClass.FILE_EDGE = 'FILE_OF' Object.metaClass.AST_EDGE = 'PARENT_OF'// 不清楚, dvwa里面沒有這種邊 Object.metaClass.TYPE_IDENTIFIER_DECL_STMT = 'IdentifierDeclStatement' Object.metaClass.TYPE_PARAMETER = 'Parameter'Object.metaClass.TYPE_FILE = 'File'// Edge typesObject.metaClass.CALLS_EDGE = 'CALLS' // 類中的函數定義 Object.metaClass.CFG_EDGE = 'FLOWS_TO' // 用來描述 ControlFlowObject.metaClass.USES_EDGE = 'USE' Object.metaClass.DEFINES_EDGE = 'DEF' Object.metaClass.DATA_FLOW_EDGE = 'REACHES' // 用來描述 DataFlowObject.metaClass.FUNCTION_TO_AST_EDGE = 'IS_FUNCTION_OF_AST' Object.metaClass.FILE_TO_FUNCTION_EDGE = 'IS_FILE_OF'// Edge keysObject.metaClass.DATA_FLOW_SYMBOL = 'var' // 如果這是一條`REACHES`的邊, 就會有`var`這個key, 其值代表上一個節點流出到下一個節點的變量名//Abeer // phpjoern 自帶的過濾函數檢測, 這里我們不用 Object.metaClass.DATA_FLOW_TAINT_SRC = 'taint_src' Object.metaClass.DATA_FLOW_TAINT_DST = 'taint_dst'

    作者:斗象能力中心 TCC – 小胖虎

    由于篇幅有限,有關漏洞查詢代碼補全分析、完整代碼、安裝與使用、查詢結果分析、總結與參考內容將在 《復活Navex-使用圖查詢進行代碼分析(下)》篇展示,記得持續關注哦~


    如果想要獲得「更多最前沿的安全技術研究與內容」歡迎關注‘斗象智能安全能力中心’

    斗象能力中心 - 斗象智能安全?blog.riskivy.com

    TCC Team長期招聘,包含各細分領域安全研究員[Web/網絡攻防/逆向]、機器學習、數據分析等職位。感興趣不妨發簡歷聯系我們。

    總結

    以上是生活随笔為你收集整理的c++代码健壮性_复活Navex-使用图查询进行代码分析(上)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。