行业新闻

复活Navex:使用图查询进行代码分析

复活Navex:使用图查询进行代码分析

从了解到修复 [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.

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.loops3}
==>v[5]
==>v[3]
gremlin> g.v(1).out.loop(1){it.loops3}{it.object.name=='josh'} 
==>v[4]

loop应该这里最关键的操作, 可以参考

Loop Pattern · tinkerpop/gremlin Wiki

大部分的查询操作都需要loop进行配合

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

大概等价于

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

结合后面的enablePath, 可以在遍历的过程中获取当前所在的完整路径信息

g.v(1).out.loop(1){it.loops3}{it.object.name=='josh' i3; i++){ if(it.object.name=='josh' 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)  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

3a12a2b4908cbb9d546c9dcbc43341be.png

大部分想尝试的人, 面对这样未知的领域, 未知的语言, 未知的代码, 都会就此止步, 可惜了, 我不信邪, 哪怕重新写一个.

之后的时间, 去寻找“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 keys

Object.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 =  10  }{ it.object.containsLowSource().toList() != []}.path().toList()

这里拆开来讲讲

g.V().filter{sql_query_funcs.contains(it.code) 10 }{ it.object.containsLowSource().toList() != []} .path() //这里一定要保存路径信息 .toList() //把路径信息从生成器里读出来, 保存成List方便后续操作

callexpressions

从上一步返回的满足条件的code节点中, 获取他们的AST_CALL节点

/**
 Traverse to enclosing call expression.
 */
Gremlin.defineStep('callexpressions', [Vertex, Pipe], { i ->
    _().matchParents { isCallExpression(it) }
})

/**
 Walk the tree into the direction of the root stopping at the
 enclosing statement and output all parents that match the supplied
 predicate. Note that this may include the enclosing statement node.
 */
Gremlin.defineStep('matchParents', [Vertex, Pipe], { p ->
    _().parents().loop(1) { !isStatement(it.object) } { p(it.object) }
})

// A node is a statement node iff its parent is of type TYPE_STMT_LIST
// Note that each node except for the root node has exactly one
// parent, so count() is either 0 or 1
// TODO: we want something more here. In particular, we would also
// like to return 'true' for if/while/for/foreach/... guards (called
// "predicates" in the CFG), and we have to think about what we want
// for statements that enclose other full-fledged statements, e.g., an
// if-statement node which has a body consisting of many other
// statements.
Object.metaClass.isStatement = { it ->
    it.parents().filter { it.type == TYPE_STMT_LIST }.count() == 1
}

Object.metaClass.TYPE_STMT_LIST = 'AST_STMT_LIST' // ...; ...; ...;

loop循环体为

.statements().inE('REACHES').outV

statements 寻找该节点的父节点中的 TYPE_STMT_LIST -> AST_STMT_LIST

/**
 Traverse to statements enclosing supplied AST nodes. This may be
 the node itself.
 */
Gremlin.defineStep('statements', [Vertex, Pipe], {
    _().ifThenElse { isStatement(it) }
    { it }
            { it.parents().loop(1) { !isStatement(it.object) } }
});

// A node is a statement node iff its parent is of type TYPE_STMT_LIST
// Note that each node except for the root node has exactly one
// parent, so count() is either 0 or 1
// TODO: we want something more here. In particular, we would also
// like to return 'true' for if/while/for/foreach/... guards (called
// "predicates" in the CFG), and we have to think about what we want
// for statements that enclose other full-fledged statements, e.g., an
// if-statement node which has a body consisting of many other
// statements.
Object.metaClass.isStatement = { it ->
    it.parents().filter { it.type == TYPE_STMT_LIST }.count() == 1
}

Object.metaClass.TYPE_STMT_LIST = 'AST_STMT_LIST' // ...; ...; ...;

.inE('REACHES').outV

REACHES 是DataFlow的数据流向边, 代表了变量的传递

loop的条件为

.loop('sloop'){ it.loops  10  }{ it.object.containsLowSource().toList() != []}
==>
arr = []
for (i=1;i10;i++){
    if (it.object.containsLowSource().toList() != []){
        arr.add(it.object)   
    }
}
return arr

containsLowSource 查找该节点是否包含来自如下可控输入的变量

["_GET", "_POST", "_COOKIE", "_REQUEST", "_ENV", "HTTP_ENV_VARS", "HTTP_POST_VARS", "HTTP_GET_VARS"]

Gremlin.defineStep('containsLowSource', [Vertex, Pipe], {
    def attacker_sources2 = ["_GET", "_POST", "_COOKIE", "_REQUEST", "_ENV", "HTTP_ENV_VARS", "HTTP_POST_VARS", "HTTP_GET_VARS"]
    _().ifThenElse { isAssignment(it) }
    {
        it
                .as('assign')
                .as('assign')
                .rval()
                .children()
                .loop('assign') { it.object != null } { true }
                .match { it.type == "AST_VAR" }
                .filter { attacker_sources2.contains(it.varToName().next()) }
    }

    {
        it
                .astNodes()
                .match { it.type == 'AST_VAR' }
                .filter { attacker_sources2.contains(it.varToName().next()) }
                .in('PARENT_OF')
    }
            .dedup()


});

// checks whether a given node represents an assignment
Object.metaClass.isAssignment = { it ->
    it.type == TYPE_ASSIGN ||
            it.type == TYPE_ASSIGN_REF ||
            it.type == TYPE_ASSIGN_OP
}

Object.metaClass.TYPE_ASSIGN = 'AST_ASSIGN' // $buzz = true
Object.metaClass.TYPE_ASSIGN_REF = 'AST_ASSIGN_REF' // $b = 

/**
 Traverse to i'th children.

 @param i The child index
 */
Gremlin.defineStep('ithChildren', [Vertex, Pipe], { i ->
    _().children().filter { it.childnum == i }
})

/**
 Return all nodes in the subtrees rooted in the current vertices and
 filter them according to a predicate p.

 @param p The predicate
 */
Gremlin.defineStep('match', [Vertex, Pipe], { p ->
    _().astNodes().filter(p)
})

/**
 Traverse from an AST_VAR node to the name of the variable
 */
Gremlin.defineStep('varToName', [Vertex, Pipe], {
    _().filter { it.type == TYPE_VAR }.ithChildren(0).code
})

路径查询返回结果

('len:', 26)
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/4832' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 4802, u'type': u'AST_CALL', u'id': 4832, u'lineno': 9}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/4829' labels=set([u'AST']) properties={u'childnum': 2, u'funcid': 4802, u'type': u'AST_ASSIGN', u'id': 4829, u'lineno': 9}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123318' start=u'node/4821' end=u'node/4829' type=u'REACHES' properties={u'var': u'getid'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/4821' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 4802, u'type': u'AST_ASSIGN', u'id': 4821, u'lineno': 8}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123319' start=u'node/4814' end=u'node/4821' type=u'REACHES' properties={u'var': u'id'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/4814' labels=set([u'AST']) properties={u'childnum': 0, u'funcid': 4802, u'type': u'AST_ASSIGN', u'id': 4814, u'lineno': 5}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/5097' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 5028, u'type': u'AST_CALL', u'id': 5097, u'lineno': 10}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/5094' labels=set([u'AST']) properties={u'childnum': 3, u'funcid': 5028, u'type': u'AST_ASSIGN', u'id': 5094, u'lineno': 10}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123357' start=u'node/5086' end=u'node/5094' type=u'REACHES' properties={u'var': u'getid'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/5086' labels=set([u'AST']) properties={u'childnum': 2, u'funcid': 5028, u'type': u'AST_ASSIGN', u'id': 5086, u'lineno': 9}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123359' start=u'node/5047' end=u'node/5086' type=u'REACHES' properties={u'var': u'id'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/5047' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 5028, u'type': u'AST_ASSIGN', u'id': 5047, u'lineno': 6}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123358' start=u'node/5040' end=u'node/5047' type=u'REACHES' properties={u'var': u'id'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/5040' labels=set([u'AST']) properties={u'childnum': 0, u'funcid': 5028, u'type': u'AST_ASSIGN', u'id': 5040, u'lineno': 5}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/5167' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 5137, u'type': u'AST_CALL', u'id': 5167, u'lineno': 9}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/5164' labels=set([u'AST']) properties={u'childnum': 2, u'funcid': 5137, u'type': u'AST_ASSIGN', u'id': 5164, u'lineno': 9}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123376' start=u'node/5156' end=u'node/5164' type=u'REACHES' properties={u'var': u'getid'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/5156' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 5137, u'type': u'AST_ASSIGN', u'id': 5156, u'lineno': 8}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123377' start=u'node/5149' end=u'node/5156' type=u'REACHES' properties={u'var': u'id'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/5149' labels=set([u'AST']) properties={u'childnum': 0, u'funcid': 5137, u'type': u'AST_ASSIGN', u'id': 5149, u'lineno': 5}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/5997' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 5953, u'type': u'AST_CALL', u'id': 5997, u'lineno': 10}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/5993' labels=set([u'AST']) properties={u'childnum': 3, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 10, u'type': u'AST_BINARY_OP', u'id': 5993, u'funcid': 5953}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123581' start=u'node/5985' end=u'node/5993' type=u'REACHES' properties={u'var': u'query'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/5985' labels=set([u'AST']) properties={u'id': 5985, u'childnum': 2, u'type': u'AST_ASSIGN', u'lineno': 9, u'funcid': 5953}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123588' start=u'node/5972' end=u'node/5985' type=u'REACHES' properties={u'var': u'id', u'taint_src': u'san-sql:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/5972' labels=set([u'AST']) properties={u'id': 5972, u'childnum': 1, u'type': u'AST_ASSIGN', u'lineno': 7, u'funcid': 5953}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123587' start=u'node/5965' end=u'node/5972' type=u'REACHES' properties={u'var': u'id', u'taint_dst': u'san-sql:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/5965' labels=set([u'AST']) properties={u'id': 5965, u'childnum': 0, u'type': u'AST_ASSIGN', u'lineno': 5, u'funcid': 5953}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/6067' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 5953, u'type': u'AST_CALL', u'id': 6067, u'lineno': 27}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/6063' labels=set([u'AST']) properties={u'childnum': 2, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 27, u'type': u'AST_BINARY_OP', u'id': 6063, u'funcid': 5953}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123584' start=u'node/5993' end=u'node/6063' type=u'REACHES' properties={u'var': u'result'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/5993' labels=set([u'AST']) properties={u'childnum': 3, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 10, u'type': u'AST_BINARY_OP', u'id': 5993, u'funcid': 5953}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123581' start=u'node/5985' end=u'node/5993' type=u'REACHES' properties={u'var': u'query'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/5985' labels=set([u'AST']) properties={u'id': 5985, u'childnum': 2, u'type': u'AST_ASSIGN', u'lineno': 9, u'funcid': 5953}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123588' start=u'node/5972' end=u'node/5985' type=u'REACHES' properties={u'var': u'id', u'taint_src': u'san-sql:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/5972' labels=set([u'AST']) properties={u'id': 5972, u'childnum': 1, u'type': u'AST_ASSIGN', u'lineno': 7, u'funcid': 5953}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123587' start=u'node/5965' end=u'node/5972' type=u'REACHES' properties={u'var': u'id', u'taint_dst': u'san-sql:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/5965' labels=set([u'AST']) properties={u'id': 5965, u'childnum': 0, u'type': u'AST_ASSIGN', u'lineno': 5, u'funcid': 5953}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/6164' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 6133, u'type': u'AST_CALL', u'id': 6164, u'lineno': 9}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/6160' labels=set([u'AST']) properties={u'childnum': 2, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 9, u'type': u'AST_BINARY_OP', u'id': 6160, u'funcid': 6133}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123608' start=u'node/6152' end=u'node/6160' type=u'REACHES' properties={u'var': u'query'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/6152' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 6133, u'type': u'AST_ASSIGN', u'id': 6152, u'lineno': 8}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123610' start=u'node/6145' end=u'node/6152' type=u'REACHES' properties={u'var': u'id'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/6145' labels=set([u'AST']) properties={u'childnum': 0, u'funcid': 6133, u'type': u'AST_ASSIGN', u'id': 6145, u'lineno': 5}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/6725' labels=set([u'AST']) properties={u'id': 6725, u'childnum': 1, u'type': u'AST_CALL', u'lineno': 19, u'funcid': 6565}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/6721' labels=set([u'AST']) properties={u'childnum': 8, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 19, u'type': u'AST_BINARY_OP', u'id': 6721, u'funcid': 6565}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123686' start=u'node/6710' end=u'node/6721' type=u'REACHES' properties={u'var': u'query'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/6710' labels=set([u'AST']) properties={u'id': 6710, u'childnum': 7, u'type': u'AST_ASSIGN', u'lineno': 18, u'funcid': 6565}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123689' start=u'node/6671' end=u'node/6710' type=u'REACHES' properties={u'var': u'name'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/6671' labels=set([u'AST']) properties={u'childnum': 6, u'funcid': 6565, u'type': u'AST_ASSIGN', u'id': 6671, u'lineno': 15}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123688' start=u'node/6660' end=u'node/6671' type=u'REACHES' properties={u'var': u'name'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/6660' labels=set([u'AST']) properties={u'childnum': 5, u'funcid': 6565, u'type': u'AST_ASSIGN', u'id': 6660, u'lineno': 14}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123687' start=u'node/6588' end=u'node/6660' type=u'REACHES' properties={u'var': u'name'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/6588' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 6565, u'type': u'AST_ASSIGN', u'id': 6588, u'lineno': 6}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/6725' labels=set([u'AST']) properties={u'id': 6725, u'childnum': 1, u'type': u'AST_CALL', u'lineno': 19, u'funcid': 6565}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/6721' labels=set([u'AST']) properties={u'childnum': 8, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 19, u'type': u'AST_BINARY_OP', u'id': 6721, u'funcid': 6565}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123686' start=u'node/6710' end=u'node/6721' type=u'REACHES' properties={u'var': u'query'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/6710' labels=set([u'AST']) properties={u'id': 6710, u'childnum': 7, u'type': u'AST_ASSIGN', u'lineno': 18, u'funcid': 6565}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123693' start=u'node/6651' end=u'node/6710' type=u'REACHES' properties={u'var': u'message'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/6651' labels=set([u'AST']) properties={u'childnum': 4, u'funcid': 6565, u'type': u'AST_ASSIGN', u'id': 6651, u'lineno': 11}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123692' start=u'node/6612' end=u'node/6651' type=u'REACHES' properties={u'var': u'message'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/6612' labels=set([u'AST']) properties={u'childnum': 3, u'funcid': 6565, u'type': u'AST_ASSIGN', u'id': 6612, u'lineno': 10}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123691' start=u'node/6599' end=u'node/6612' type=u'REACHES' properties={u'var': u'message', u'taint_src': u'san-sql:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/6599' labels=set([u'AST']) properties={u'childnum': 2, u'funcid': 6565, u'type': u'AST_ASSIGN', u'id': 6599, u'lineno': 9}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123690' start=u'node/6577' end=u'node/6599' type=u'REACHES' properties={u'var': u'message', u'taint_dst': u'san-sql:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/6577' labels=set([u'AST']) properties={u'childnum': 0, u'funcid': 6565, u'type': u'AST_ASSIGN', u'id': 6577, u'lineno': 5}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/7137' labels=set([u'AST']) properties={u'id': 7137, u'childnum': 1, u'type': u'AST_CALL', u'lineno': 19, u'funcid': 6977}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/7133' labels=set([u'AST']) properties={u'childnum': 8, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 19, u'type': u'AST_BINARY_OP', u'id': 7133, u'funcid': 6977}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123736' start=u'node/7122' end=u'node/7133' type=u'REACHES' properties={u'var': u'query'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/7122' labels=set([u'AST']) properties={u'id': 7122, u'childnum': 7, u'type': u'AST_ASSIGN', u'lineno': 18, u'funcid': 6977}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123739' start=u'node/7083' end=u'node/7122' type=u'REACHES' properties={u'var': u'name'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/7083' labels=set([u'AST']) properties={u'childnum': 6, u'funcid': 6977, u'type': u'AST_ASSIGN', u'id': 7083, u'lineno': 15}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123738' start=u'node/7072' end=u'node/7083' type=u'REACHES' properties={u'var': u'name'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/7072' labels=set([u'AST']) properties={u'childnum': 5, u'funcid': 6977, u'type': u'AST_ASSIGN', u'id': 7072, u'lineno': 14}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123737' start=u'node/7000' end=u'node/7072' type=u'REACHES' properties={u'var': u'name'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/7000' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 6977, u'type': u'AST_ASSIGN', u'id': 7000, u'lineno': 6}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/7137' labels=set([u'AST']) properties={u'id': 7137, u'childnum': 1, u'type': u'AST_CALL', u'lineno': 19, u'funcid': 6977}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/7133' labels=set([u'AST']) properties={u'childnum': 8, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 19, u'type': u'AST_BINARY_OP', u'id': 7133, u'funcid': 6977}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123736' start=u'node/7122' end=u'node/7133' type=u'REACHES' properties={u'var': u'query'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/7122' labels=set([u'AST']) properties={u'id': 7122, u'childnum': 7, u'type': u'AST_ASSIGN', u'lineno': 18, u'funcid': 6977}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123743' start=u'node/7063' end=u'node/7122' type=u'REACHES' properties={u'var': u'message'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/7063' labels=set([u'AST']) properties={u'childnum': 4, u'funcid': 6977, u'type': u'AST_ASSIGN', u'id': 7063, u'lineno': 11}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123742' start=u'node/7024' end=u'node/7063' type=u'REACHES' properties={u'var': u'message'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/7024' labels=set([u'AST']) properties={u'childnum': 3, u'funcid': 6977, u'type': u'AST_ASSIGN', u'id': 7024, u'lineno': 10}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123741' start=u'node/7011' end=u'node/7024' type=u'REACHES' properties={u'var': u'message', u'taint_src': u'san-sql:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/7011' labels=set([u'AST']) properties={u'childnum': 2, u'funcid': 6977, u'type': u'AST_ASSIGN', u'id': 7011, u'lineno': 9}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123740' start=u'node/6989' end=u'node/7011' type=u'REACHES' properties={u'var': u'message', u'taint_dst': u'san-sql:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/6989' labels=set([u'AST']) properties={u'childnum': 0, u'funcid': 6977, u'type': u'AST_ASSIGN', u'id': 6989, u'lineno': 5}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/7320' labels=set([u'AST']) properties={u'id': 7320, u'childnum': 1, u'type': u'AST_CALL', u'lineno': 17, u'funcid': 7184}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/7316' labels=set([u'AST']) properties={u'childnum': 6, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 17, u'type': u'AST_BINARY_OP', u'id': 7316, u'funcid': 7184}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123755' start=u'node/7305' end=u'node/7316' type=u'REACHES' properties={u'var': u'query'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/7305' labels=set([u'AST']) properties={u'id': 7305, u'childnum': 5, u'type': u'AST_ASSIGN', u'lineno': 16, u'funcid': 7184}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123757' start=u'node/7266' end=u'node/7305' type=u'REACHES' properties={u'var': u'name'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/7266' labels=set([u'AST']) properties={u'childnum': 4, u'funcid': 7184, u'type': u'AST_ASSIGN', u'id': 7266, u'lineno': 13}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123756' start=u'node/7207' end=u'node/7266' type=u'REACHES' properties={u'var': u'name'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/7207' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 7184, u'type': u'AST_ASSIGN', u'id': 7207, u'lineno': 6}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/7320' labels=set([u'AST']) properties={u'id': 7320, u'childnum': 1, u'type': u'AST_CALL', u'lineno': 17, u'funcid': 7184}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/7316' labels=set([u'AST']) properties={u'childnum': 6, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 17, u'type': u'AST_BINARY_OP', u'id': 7316, u'funcid': 7184}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123755' start=u'node/7305' end=u'node/7316' type=u'REACHES' properties={u'var': u'query'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/7305' labels=set([u'AST']) properties={u'id': 7305, u'childnum': 5, u'type': u'AST_ASSIGN', u'lineno': 16, u'funcid': 7184}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123760' start=u'node/7227' end=u'node/7305' type=u'REACHES' properties={u'var': u'message'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/7227' labels=set([u'AST']) properties={u'childnum': 3, u'funcid': 7184, u'type': u'AST_ASSIGN', u'id': 7227, u'lineno': 10}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123759' start=u'node/7218' end=u'node/7227' type=u'REACHES' properties={u'var': u'message'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/7218' labels=set([u'AST']) properties={u'childnum': 2, u'funcid': 7184, u'type': u'AST_ASSIGN', u'id': 7218, u'lineno': 9}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/123758' start=u'node/7196' end=u'node/7218' type=u'REACHES' properties={u'var': u'message'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/7196' labels=set([u'AST']) properties={u'childnum': 0, u'funcid': 7184, u'type': u'AST_ASSIGN', u'id': 7196, u'lineno': 5}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/8770' labels=set([u'AST']) properties={u'id': 8770, u'childnum': 1, u'type': u'AST_CALL', u'lineno': 20, u'funcid': 8611}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/8766' labels=set([u'AST']) properties={u'childnum': 9, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 20, u'type': u'AST_BINARY_OP', u'id': 8766, u'funcid': 8611}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124065' start=u'node/8755' end=u'node/8766' type=u'REACHES' properties={u'var': u'query'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/8755' labels=set([u'AST']) properties={u'id': 8755, u'childnum': 8, u'type': u'AST_ASSIGN', u'lineno': 19, u'funcid': 8611}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124074' start=u'node/8652' end=u'node/8755' type=u'REACHES' properties={u'var': u'user'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/8652' labels=set([u'AST']) properties={u'childnum': 3, u'funcid': 8611, u'type': u'AST_ASSIGN', u'id': 8652, u'lineno': 10}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124073' start=u'node/8643' end=u'node/8652' type=u'REACHES' properties={u'var': u'user'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/8643' labels=set([u'AST']) properties={u'childnum': 2, u'funcid': 8611, u'type': u'AST_ASSIGN', u'id': 8643, u'lineno': 9}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124072' start=u'node/8636' end=u'node/8643' type=u'REACHES' properties={u'var': u'user'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/8636' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 8611, u'type': u'AST_ASSIGN', u'id': 8636, u'lineno': 8}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/8770' labels=set([u'AST']) properties={u'id': 8770, u'childnum': 1, u'type': u'AST_CALL', u'lineno': 20, u'funcid': 8611}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/8766' labels=set([u'AST']) properties={u'childnum': 9, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 20, u'type': u'AST_BINARY_OP', u'id': 8766, u'funcid': 8611}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124065' start=u'node/8755' end=u'node/8766' type=u'REACHES' properties={u'var': u'query'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/8755' labels=set([u'AST']) properties={u'id': 8755, u'childnum': 8, u'type': u'AST_ASSIGN', u'lineno': 19, u'funcid': 8611}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124064' start=u'node/8746' end=u'node/8755' type=u'REACHES' properties={u'var': u'pass', u'taint_src': u'san-string:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/8746' labels=set([u'AST']) properties={u'childnum': 7, u'funcid': 8611, u'type': u'AST_ASSIGN', u'id': 8746, u'lineno': 16}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124063' start=u'node/8707' end=u'node/8746' type=u'REACHES' properties={u'var': u'pass', u'taint_dst': u'san-string:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/8707' labels=set([u'AST']) properties={u'childnum': 6, u'funcid': 8611, u'type': u'AST_ASSIGN', u'id': 8707, u'lineno': 15}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124062' start=u'node/8698' end=u'node/8707' type=u'REACHES' properties={u'var': u'pass'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/8698' labels=set([u'AST']) properties={u'childnum': 5, u'funcid': 8611, u'type': u'AST_ASSIGN', u'id': 8698, u'lineno': 14}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124061' start=u'node/8691' end=u'node/8698' type=u'REACHES' properties={u'var': u'pass'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/8691' labels=set([u'AST']) properties={u'childnum': 4, u'funcid': 8611, u'type': u'AST_ASSIGN', u'id': 8691, u'lineno': 13}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/9525' labels=set([u'AST']) properties={u'id': 9525, u'childnum': 1, u'type': u'AST_CALL', u'lineno': 15, u'funcid': 9397}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/9521' labels=set([u'AST']) properties={u'childnum': 6, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 15, u'type': u'AST_BINARY_OP', u'id': 9521, u'funcid': 9397}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124202' start=u'node/9510' end=u'node/9521' type=u'REACHES' properties={u'var': u'query'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/9510' labels=set([u'AST']) properties={u'id': 9510, u'childnum': 5, u'type': u'AST_ASSIGN', u'lineno': 14, u'funcid': 9397}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124210' start=u'node/9416' end=u'node/9510' type=u'REACHES' properties={u'var': u'user'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/9416' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 9397, u'type': u'AST_ASSIGN', u'id': 9416, u'lineno': 6}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124209' start=u'node/9409' end=u'node/9416' type=u'REACHES' properties={u'var': u'user'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/9409' labels=set([u'AST']) properties={u'childnum': 0, u'funcid': 9397, u'type': u'AST_ASSIGN', u'id': 9409, u'lineno': 5}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/9525' labels=set([u'AST']) properties={u'id': 9525, u'childnum': 1, u'type': u'AST_CALL', u'lineno': 15, u'funcid': 9397}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/9521' labels=set([u'AST']) properties={u'childnum': 6, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 15, u'type': u'AST_BINARY_OP', u'id': 9521, u'funcid': 9397}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124202' start=u'node/9510' end=u'node/9521' type=u'REACHES' properties={u'var': u'query'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/9510' labels=set([u'AST']) properties={u'id': 9510, u'childnum': 5, u'type': u'AST_ASSIGN', u'lineno': 14, u'funcid': 9397}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124201' start=u'node/9501' end=u'node/9510' type=u'REACHES' properties={u'var': u'pass', u'taint_src': u'san-string:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/9501' labels=set([u'AST']) properties={u'childnum': 4, u'funcid': 9397, u'type': u'AST_ASSIGN', u'id': 9501, u'lineno': 11}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124200' start=u'node/9462' end=u'node/9501' type=u'REACHES' properties={u'var': u'pass', u'taint_dst': u'san-string:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/9462' labels=set([u'AST']) properties={u'childnum': 3, u'funcid': 9397, u'type': u'AST_ASSIGN', u'id': 9462, u'lineno': 10}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124199' start=u'node/9455' end=u'node/9462' type=u'REACHES' properties={u'var': u'pass'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/9455' labels=set([u'AST']) properties={u'childnum': 2, u'funcid': 9397, u'type': u'AST_ASSIGN', u'id': 9455, u'lineno': 9}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/9701' labels=set([u'AST']) properties={u'id': 9701, u'childnum': 1, u'type': u'AST_CALL', u'lineno': 13, u'funcid': 9651}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/9697' labels=set([u'AST']) properties={u'childnum': 4, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 13, u'type': u'AST_BINARY_OP', u'id': 9697, u'funcid': 9651}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124233' start=u'node/9686' end=u'node/9697' type=u'REACHES' properties={u'var': u'query'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/9686' labels=set([u'AST']) properties={u'id': 9686, u'childnum': 3, u'type': u'AST_ASSIGN', u'lineno': 12, u'funcid': 9651}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124238' start=u'node/9663' end=u'node/9686' type=u'REACHES' properties={u'var': u'user'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/9663' labels=set([u'AST']) properties={u'childnum': 0, u'funcid': 9651, u'type': u'AST_ASSIGN', u'id': 9663, u'lineno': 5}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/9701' labels=set([u'AST']) properties={u'id': 9701, u'childnum': 1, u'type': u'AST_CALL', u'lineno': 13, u'funcid': 9651}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/9697' labels=set([u'AST']) properties={u'childnum': 4, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 13, u'type': u'AST_BINARY_OP', u'id': 9697, u'funcid': 9651}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124233' start=u'node/9686' end=u'node/9697' type=u'REACHES' properties={u'var': u'query'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/9686' labels=set([u'AST']) properties={u'id': 9686, u'childnum': 3, u'type': u'AST_ASSIGN', u'lineno': 12, u'funcid': 9651}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124232' start=u'node/9677' end=u'node/9686' type=u'REACHES' properties={u'var': u'pass', u'taint_src': u'san-string:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/9677' labels=set([u'AST']) properties={u'childnum': 2, u'funcid': 9651, u'type': u'AST_ASSIGN', u'id': 9677, u'lineno': 9}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124231' start=u'node/9670' end=u'node/9677' type=u'REACHES' properties={u'var': u'pass', u'taint_dst': u'san-string:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/9670' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 9651, u'type': u'AST_ASSIGN', u'id': 9670, u'lineno': 8}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/13369' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 13255, u'type': u'AST_CALL', u'id': 13369, u'lineno': 19}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/13365' labels=set([u'AST']) properties={u'childnum': 3, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 19, u'type': u'AST_BINARY_OP', u'id': 13365, u'funcid': 13255}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124975' start=u'node/13350' end=u'node/13365' type=u'REACHES' properties={u'var': u'insert'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/13350' labels=set([u'AST']) properties={u'childnum': 2, u'funcid': 13255, u'type': u'AST_ASSIGN', u'id': 13350, u'lineno': 18}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124980' start=u'node/13341' end=u'node/13350' type=u'REACHES' properties={u'var': u'pass_new', u'taint_src': u'san-string:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/13341' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 13255, u'type': u'AST_ASSIGN', u'id': 13341, u'lineno': 15}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124979' start=u'node/13302' end=u'node/13341' type=u'REACHES' properties={u'var': u'pass_new', u'taint_dst': u'san-string:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/13302' labels=set([u'AST']) properties={u'childnum': 0, u'funcid': 13255, u'type': u'AST_ASSIGN', u'id': 13302, u'lineno': 14}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/124978' start=u'node/13280' end=u'node/13302' type=u'REACHES' properties={u'var': u'pass_new'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/13280' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 13255, u'type': u'AST_ASSIGN', u'id': 13280, u'lineno': 8}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/13845' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 13725, u'type': u'AST_CALL', u'id': 13845, u'lineno': 18}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/13841' labels=set([u'AST']) properties={u'childnum': 3, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 18, u'type': u'AST_BINARY_OP', u'id': 13841, u'funcid': 13725}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/125044' start=u'node/13826' end=u'node/13841' type=u'REACHES' properties={u'var': u'insert'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/13826' labels=set([u'AST']) properties={u'childnum': 2, u'funcid': 13725, u'type': u'AST_ASSIGN', u'id': 13826, u'lineno': 17}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/125049' start=u'node/13817' end=u'node/13826' type=u'REACHES' properties={u'var': u'pass_new', u'taint_src': u'san-string:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/13817' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 13725, u'type': u'AST_ASSIGN', u'id': 13817, u'lineno': 14}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/125048' start=u'node/13778' end=u'node/13817' type=u'REACHES' properties={u'var': u'pass_new', u'taint_dst': u'san-string:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/13778' labels=set([u'AST']) properties={u'childnum': 0, u'funcid': 13725, u'type': u'AST_ASSIGN', u'id': 13778, u'lineno': 13}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/125047' start=u'node/13756' end=u'node/13778' type=u'REACHES' properties={u'var': u'pass_new'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/13756' labels=set([u'AST']) properties={u'childnum': 0, u'funcid': 13725, u'type': u'AST_ASSIGN', u'id': 13756, u'lineno': 7}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/14032' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 13931, u'type': u'AST_CALL', u'id': 14032, u'lineno': 16}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/14028' labels=set([u'AST']) properties={u'childnum': 3, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 16, u'type': u'AST_BINARY_OP', u'id': 14028, u'funcid': 13931}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/125066' start=u'node/14013' end=u'node/14028' type=u'REACHES' properties={u'var': u'insert'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/14013' labels=set([u'AST']) properties={u'childnum': 2, u'funcid': 13931, u'type': u'AST_ASSIGN', u'id': 14013, u'lineno': 15}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/125071' start=u'node/14004' end=u'node/14013' type=u'REACHES' properties={u'var': u'pass_new', u'taint_src': u'san-string:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/14004' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 13931, u'type': u'AST_ASSIGN', u'id': 14004, u'lineno': 12}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/125070' start=u'node/13965' end=u'node/14004' type=u'REACHES' properties={u'var': u'pass_new', u'taint_dst': u'san-string:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/13965' labels=set([u'AST']) properties={u'childnum': 0, u'funcid': 13931, u'type': u'AST_ASSIGN', u'id': 13965, u'lineno': 11}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/125069' start=u'node/13943' end=u'node/13965' type=u'REACHES' properties={u'var': u'pass_new'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/13943' labels=set([u'AST']) properties={u'childnum': 0, u'funcid': 13931, u'type': u'AST_ASSIGN', u'id': 13943, u'lineno': 5}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/15558' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 15417, u'type': u'AST_CALL', u'id': 15558, u'lineno': 31}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/15554' labels=set([u'AST']) properties={u'childnum': 3, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 31, u'type': u'AST_BINARY_OP', u'id': 15554, u'funcid': 15417}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/125405' start=u'node/15539' end=u'node/15554' type=u'REACHES' properties={u'var': u'insert'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/15539' labels=set([u'AST']) properties={u'childnum': 2, u'funcid': 15417, u'type': u'AST_ASSIGN', u'id': 15539, u'lineno': 30}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/125410' start=u'node/15530' end=u'node/15539' type=u'REACHES' properties={u'var': u'pass_new', u'taint_src': u'san-string:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/15530' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 15417, u'type': u'AST_ASSIGN', u'id': 15530, u'lineno': 27}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/125409' start=u'node/15491' end=u'node/15530' type=u'REACHES' properties={u'var': u'pass_new', u'taint_dst': u'san-string:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/15491' labels=set([u'AST']) properties={u'childnum': 0, u'funcid': 15417, u'type': u'AST_ASSIGN', u'id': 15491, u'lineno': 26}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/125408' start=u'node/15435' end=u'node/15491' type=u'REACHES' properties={u'var': u'pass_new'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/15435' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 15417, u'type': u'AST_ASSIGN', u'id': 15435, u'lineno': 8}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/16277' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 16040, u'type': u'AST_CALL', u'id': 16277, u'lineno': 69}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/16273' labels=set([u'AST']) properties={u'childnum': 3, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 69, u'type': u'AST_BINARY_OP', u'id': 16273, u'funcid': 16040}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/125512' start=u'node/16258' end=u'node/16273' type=u'REACHES' properties={u'var': u'insert'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/16258' labels=set([u'AST']) properties={u'childnum': 2, u'funcid': 16040, u'type': u'AST_ASSIGN', u'id': 16258, u'lineno': 68}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/125519' start=u'node/16249' end=u'node/16258' type=u'REACHES' properties={u'var': u'pass_new', u'taint_src': u'san-string:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/16249' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 16040, u'type': u'AST_ASSIGN', u'id': 16249, u'lineno': 65}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/125518' start=u'node/16210' end=u'node/16249' type=u'REACHES' properties={u'var': u'pass_new', u'taint_dst': u'san-string:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/16210' labels=set([u'AST']) properties={u'childnum': 0, u'funcid': 16040, u'type': u'AST_ASSIGN', u'id': 16210, u'lineno': 64}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/125517' start=u'node/16168' end=u'node/16210' type=u'REACHES' properties={u'var': u'pass_new'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/16168' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 16040, u'type': u'AST_ASSIGN', u'id': 16168, u'lineno': 51}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/16579' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 16362, u'type': u'AST_CALL', u'id': 16579, u'lineno': 61}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/16575' labels=set([u'AST']) properties={u'childnum': 3, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 61, u'type': u'AST_BINARY_OP', u'id': 16575, u'funcid': 16362}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/125563' start=u'node/16560' end=u'node/16575' type=u'REACHES' properties={u'var': u'insert'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/16560' labels=set([u'AST']) properties={u'childnum': 2, u'funcid': 16362, u'type': u'AST_ASSIGN', u'id': 16560, u'lineno': 60}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/125570' start=u'node/16551' end=u'node/16560' type=u'REACHES' properties={u'var': u'pass_new', u'taint_src': u'san-string:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/16551' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 16362, u'type': u'AST_ASSIGN', u'id': 16551, u'lineno': 57}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/125569' start=u'node/16512' end=u'node/16551' type=u'REACHES' properties={u'var': u'pass_new', u'taint_dst': u'san-string:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/16512' labels=set([u'AST']) properties={u'childnum': 0, u'funcid': 16362, u'type': u'AST_ASSIGN', u'id': 16512, u'lineno': 56}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/125568' start=u'node/16490' end=u'node/16512' type=u'REACHES' properties={u'var': u'pass_new'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/16490' labels=set([u'AST']) properties={u'childnum': 1, u'funcid': 16362, u'type': u'AST_ASSIGN', u'id': 16490, u'lineno': 50}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/122239' labels=set([u'AST']) properties={u'id': 122239, u'childnum': 0, u'type': u'AST_CALL', u'lineno': 40, u'funcid': 121984}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/122234' labels=set([u'AST']) properties={u'childnum': 13, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 40, u'type': u'AST_BINARY_OP', u'id': 122234, u'funcid': 121984}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/149605' start=u'node/122223' end=u'node/122234' type=u'REACHES' properties={u'var': u'query'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/122223' labels=set([u'AST']) properties={u'id': 122223, u'childnum': 12, u'type': u'AST_ASSIGN', u'lineno': 39, u'funcid': 121984}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/149614' start=u'node/122071' end=u'node/122223' type=u'REACHES' properties={u'var': u'user'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/122071' labels=set([u'AST']) properties={u'childnum': 4, u'funcid': 121984, u'type': u'AST_ASSIGN', u'id': 122071, u'lineno': 22}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/149613' start=u'node/122062' end=u'node/122071' type=u'REACHES' properties={u'var': u'user'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/122062' labels=set([u'AST']) properties={u'childnum': 3, u'funcid': 121984, u'type': u'AST_ASSIGN', u'id': 122062, u'lineno': 21}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/149612' start=u'node/122055' end=u'node/122062' type=u'REACHES' properties={u'var': u'user'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/122055' labels=set([u'AST']) properties={u'childnum': 2, u'funcid': 121984, u'type': u'AST_ASSIGN', u'id': 122055, u'lineno': 20}>]
--------------------------------------------------
[Node graph=u'http://localhost:7474/db/data/' ref=u'node/122239' labels=set([u'AST']) properties={u'id': 122239, u'childnum': 0, u'type': u'AST_CALL', u'lineno': 40, u'funcid': 121984}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/122234' labels=set([u'AST']) properties={u'childnum': 13, u'flags': [u'BINARY_BOOL_OR'], u'lineno': 40, u'type': u'AST_BINARY_OP', u'id': 122234, u'funcid': 121984}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/149605' start=u'node/122223' end=u'node/122234' type=u'REACHES' properties={u'var': u'query'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/122223' labels=set([u'AST']) properties={u'id': 122223, u'childnum': 12, u'type': u'AST_ASSIGN', u'lineno': 39, u'funcid': 121984}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/149603' start=u'node/122165' end=u'node/122223' type=u'REACHES' properties={u'var': u'pass', u'taint_src': u'san-string:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/122165' labels=set([u'AST']) properties={u'childnum': 8, u'funcid': 121984, u'type': u'AST_ASSIGN', u'id': 122165, u'lineno': 27}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/149602' start=u'node/122126' end=u'node/122165' type=u'REACHES' properties={u'var': u'pass', u'taint_dst': u'san-string:'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/122126' labels=set([u'AST']) properties={u'childnum': 7, u'funcid': 121984, u'type': u'AST_ASSIGN', u'id': 122126, u'lineno': 26}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/149601' start=u'node/122117' end=u'node/122126' type=u'REACHES' properties={u'var': u'pass'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/122117' labels=set([u'AST']) properties={u'childnum': 6, u'funcid': 121984, u'type': u'AST_ASSIGN', u'id': 122117, u'lineno': 25}>,
 Relationship graph=u'http://localhost:7474/db/data/' ref=u'relationship/149600' start=u'node/122110' end=u'node/122117' type=u'REACHES' properties={u'var': u'pass'}>,
 Node graph=u'http://localhost:7474/db/data/' ref=u'node/122110' labels=set([u'AST']) properties={u'childnum': 5, u'funcid': 121984, u'type': u'AST_ASSIGN', u'id': 122110, u'lineno': 24}>]
--------------------------------------------------

遍历已有路径查询repair

Paths = []

// 向下遍历筛选未经过滤的 VulnerablePath
for ( vpaths in VulnerablePaths){   //遍历所有存在分析风险的路径, 循环取出每一个path进行分析
    vlen = vpaths.size()            
    p = []

    for (int i = 1; i  vlen ; i+=2) {  // path结构是 [v_call,v,e,v,e,v] 这种格式的, 所以1+=2, 遍历节点
        node = vpaths[i];
        if ( i+1  vlen){   // 因为[v_call,v,e,v,e,v]的形式, 最后一个节点是没有边信息的, 所要边界检查一下
            source_var = vpaths[i+1].var;   // 取出DataFlow边(`REACHES`)上传递的变量名, 给后面做变量筛查
        }
        else{           //最后一个var可能来自于 `$var_id = repair($_POST['id'])` 所以要特殊处理
            source_var = vpaths[i].match {
                        it.type == "AST_VAR" 
        }else{      // 否则p=[], i=vlen, 循环结束
            p = []
            i = vlen
        }
    }
    // 如果p=[], 该path被过滤, 不考虑
    if(p.isEmpty()){
        continue
    }
    else{       // 如果p != [], 该path存在风险, 添加该路径到结果`Paths`中
        Paths.add(vpaths)
        p =[]
    }

}

上述代码中引用的getFuncName

// gets the function name of a call expression
Object.metaClass.getFuncName = { it ->
    if (it.type == TYPE_CALL) {
        // have to call .next() because the calls to ithChildren()
        // implictly convert the vertex 'it' into a Gremlin pipeline, but
        // we know that only one vertex is spit out at the end and we want
        // its 'code' property
        it.ithChildren(0).ithChildren(0).next().code
    } else if (it.type == TYPE_STATIC_CALL ||
            it.type == TYPE_METHOD_CALL) {
        it.ithChildren(1).next().code
    } else {
        null
    }
}

完整代码

import json
from pprint import pprint

from Analysis import Analysis

attackType = "sql"
sa = Analysis(7474)
query = sa.prepareQueryStatic(attackType)

query = """
sql_query_funcs = ["mysql_query", "mysqli_query", "pg_query", "sqlite_query"]

repairs = ["md5", "addslashes", "mysqli_real_escape_string", "mysql_escape_string"]

Paths = []

VulnerablePaths = g.V().filter{sql_query_funcs.contains(it.code)   10  }{ it.object.containsLowSource().toList() != []}.path().toList()


for ( vpaths in VulnerablePaths){
    vlen = vpaths.size()
    p = []

    for (int i = 1; i  vlen ; i+=2) {
        node = vpaths[i];
        if ( i+1  vlen){
            source_var = vpaths[i+1].var;
        }
        else{
            source_var = vpaths[i].match {
                        it.type == "AST_VAR" 
        }else{
            p = []
            i = vlen
        }
    }

    if(p.isEmpty()){
        continue
    }
    else{
        Paths.add(vpaths)
        p =[]
    }

}


result = []
for (x in Paths){
    result.add([x[0].toFileAbs().next().name, x[0].lineno, getFuncName(x[0])])
    for (int i = 1; i  x.size() ; i+=2){
        result.add([x[i].toFileAbs().next().name, x[i].lineno, x[i].match{it.type == 'AST_VAR'}.resolveCallArgsNew3()])
    }
    result.add("------------------")
}

result

"""

result, elapsed_time = sa.runTimedQuery(query)
print(query)
print("result:")
# print (result)
# exit()
if type(result) == list:
    print("len:", len(result))
    for x in result:
        # print(type(x), type("AST_CALL"))
        print(x)
    exit()
try:
    print (json.dumps(result, indent=2))
except:
    print (result)

安装与使用

安装 Navex -> python-joern for php

如果按照论文作者的github来安装, 最多到 python-joern 查询这一步就走不下去了,

如上文, 作者删除最关键的漏洞查询语句

这边我整理一下资源, 上传到github, 因为有些资源不是很好找, 而且代码不全, 我花费了了大量的业余时间修补填坑

https://github.com/UUUUnotfound/Navex_fixed

  1. 目录结构
ubuntu@ubuntu:~/Navex$ tree  -L 2
.
├── batch-import        # 批量数据导入Neo4j
│   ├── batch_importer_21.zip
│   ├── import.bat
│   ├── import.sh
│   ├── lib
│   └── readme.md
├── joern               # joern, 这里主要使用 `phpast2cpg`
│   ├── AUTHORS
│   ├── build
│   ├── build.gradle
│   ├── build.sh
│   ├── docs
│   ├── eclipse
│   ├── gremtest
│   ├── joern-parse
│   ├── joern-server.sh
│   ├── LICENSE
│   ├── phpast2cpg
│   ├── projects
│   ├── python
│   ├── README.md
│   ├── RELEASE_NOTES
│   └── settings.gradle
├── neo4j-community-2.1.8  # Neo4j图数据库, 默认数据库文件存放位置`data/graph.db`
│   ├── bin
│   ├── CHANGES.txt
│   ├── conf
│   ├── data
│   ├── lib
│   ├── LICENSES.txt
│   ├── LICENSE.txt
│   ├── NOTICE.txt
│   ├── plugins
│   ├── README.txt
│   ├── system
│   └── UPGRADE.txt
├── phpjoern            # 主要用`php2ast`来生成`nodes.csv`, `rels.csv`
│   ├── 1.php
│   ├── AUTHORS
│   ├── conf
│   ├── LICENSE
│   ├── php2ast
│   ├── README.md
│   └── src
├── php_src             # 这里存放测试文件源码, 我这里准备的是`dvwa`, `graph.db`是我生成好的Neo4j数据
│   ├── dvwa
│   └── graph.db
└── python-joern        # 用来连接`localhost:7474`进行图查询, `main_test.py`是demo文件, 可以查询sql注入
    ├── Analysis.py
    ├── docs
    ├── exploitFinding.py
    ├── ExploitSeed.py
    ├── joern
    ├── LICENSE
    ├── main_test.py
    ├── README.md
    ├── setup.py
    ├── static-main.py
    ├── staticResults.py
    └── testing
  1. 安装依赖
git clone https://github.com/UUUUnotfound/Navex_fixed
cd Navex_fixed
sudo apt install php7.0 php-ast python-dev graphviz libgraphviz-dev pkg-config python-setuptools python-pip openjdk-8-jdk groovy -y
sudo pip install py2neo==2.0.7 -i https://pypi.tuna.tsinghua.edu.cn/simple 
grape install commons-net commons-net 3.3
grape install com.github.jsqlparser jsqlparser 1.1

运行Navex -> python-joern for php

  1. 生成CPG数据并导入Neo4j
APP_NAME=dvwa
mkdir workspace ?php

if( isset( $_COOKIE[ 'id' ] ) ) {
    // Get input
    $id = $_COOKIE[ 'id' ];

    // Check database
    $getid  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $getid ); // Removed 'or die' to suppress mysql errors

    // Get results
    $num = @mysqli_num_rows( $result ); // The '@' character suppresses errors
    if( $num > 0 ) {
        // Feedback for end user
        $html .= 'pre>User ID exists in the database./pre>';
    }
    else {
        // Might sleep a random amount
        if( rand( 0, 5 ) == 3 ) {
            sleep( rand( 2, 4 ) );
        }

        // User wasn't found, so the page wasn't!
        header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );

        // Feedback for end user
        $html .= 'pre>User ID is MISSING from the database./pre>';
    }

    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

?>

dvwa/vulnerabilities/sqli_blind/source/low.php

?php

if( isset( $_GET[ 'Submit' ] ) ) {
    // Get input
    $id = $_GET[ 'id' ];

    // Check database
    $getid  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $getid ); // Removed 'or die' to suppress mysql errors

    // Get results
    $num = @mysqli_num_rows( $result ); // The '@' character suppresses errors
    if( $num > 0 ) {
        // Feedback for end user
        $html .= 'pre>User ID exists in the database./pre>';
    }
    else {
        // User wasn't found, so the page wasn't!
        header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );

        // Feedback for end user
        $html .= 'pre>User ID is MISSING from the database./pre>';
    }

    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

?>

dvwa/vulnerabilities/sqli/source/low.php

?php

if( isset( $_REQUEST[ 'Submit' ] ) ) {
    // Get input
    $id = $_REQUEST[ 'id' ];

    // Check database
    $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( 'pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '/pre>' );

    // Get results
    while( $row = mysqli_fetch_assoc( $result ) ) {
        // Get values
        $first = $row["first_name"];
        $last  = $row["last_name"];

        // Feedback for end user
        $html .= "pre>ID: {$id}br />First name: {$first}br />Surname: {$last}/pre>";
    }

    mysqli_close($GLOBALS["___mysqli_ston"]);
}

?>

dvwa/vulnerabilities/brute/source/low.php

?php

if( isset( $_GET[ 'Login' ] ) ) {
    // Get username
    $user = $_GET[ 'username' ];

    // Get password
    $pass = $_GET[ 'password' ];
    $pass = md5( $pass );

    // Check the database
    $query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( 'pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '/pre>' );

    if( $result 
        $avatar = $row["avatar"];

        // Login successful
        $html .= "p>Welcome to the password protected area {$user}/p>";
        $html .= "img src=\"{$avatar}\" />";
    }
    else {
        // Login failed
        $html .= "pre>br />Username and/or password incorrect./pre>";
    }

    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

?>

虽说存在一些误报, 但是基本实现了漏洞分析查询的功能

漏报原因分析

  1. dvwa/vulnerabilities/sqli/source/medium.php
?php

?php

if( isset( $_POST[ 'Submit' ] ) ) {
    // Get input
    $id = $_POST[ 'id' ];

    $id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);

    $query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
    $result = mysqli_query($GLOBALS["___mysqli_ston"], $query) or die( 'pre>' . mysqli_error($GLOBALS["___mysqli_ston"]) . '/pre>' );

    // Get results
    while( $row = mysqli_fetch_assoc( $result ) ) {
        // Display values
        $first = $row["first_name"];
        $last  = $row["last_name"];

        // Feedback for end user
        $html .= "pre>ID: {$id}br />First name: {$first}br />Surname: {$last}/pre>";
    }

}

// This is used later on in the index.php page
// Setting it here so we can close the database connection in here like in the rest of the source scripts
$query  = "SELECT COUNT(*) FROM users;";
$result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( 'pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '/pre>' );
$number_of_rows = mysqli_fetch_row( $result )[0];

mysqli_close($GLOBALS["___mysqli_ston"]);
?>

Medium级别的代码利用mysql_real_escape_string函数对以下特殊符号进行转义

  • \x00
  • \n
  • \r
  • \
  • '
  • "
  • \x1a

但是此处为数字型注入不需要单引号, 可以绕过

$query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";

所以这里还有优化空间, 比如多一步判断注入类型, 然后忽略无效的过滤

  1. dvwa/vulnerabilities/sqli/source/high.php
?php

if( isset( $_SESSION [ 'id' ] ) ) {
    // Get input
    $id = $_SESSION[ 'id' ];

    // Check database
    $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
    $result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( 'pre>Something went wrong./pre>' );

    // Get results
    while( $row = mysqli_fetch_assoc( $result ) ) {
        // Get values
        $first = $row["first_name"];
        $last  = $row["last_name"];

        // Feedback for end user
        $html .= "pre>ID: {$id}br />First name: {$first}br />Surname: {$last}/pre>";
    }

    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);        
}

?>

这里使用的是$_SESSION [ 'id' ]注入, 通过访问

dvwa/vulnerabilities/sqli/session-input.php

其实该点可控 $_SESSION[ 'id' ] = $_POST[ 'id' ];

?php

define( 'DVWA_WEB_PAGE_TO_ROOT', '../../' );
require_once DVWA_WEB_PAGE_TO_ROOT . 'dvwa/includes/dvwaPage.inc.php';

dvwaPageStartup( array( 'authenticated', 'phpids' ) );

$page = dvwaPageNewGrab();
$page[ 'title' ] = 'SQL Injection Session Input' . $page[ 'title_separator' ].$page[ 'title' ];

if( isset( $_POST[ 'id' ] ) ) {
    $_SESSION[ 'id' ] =  $_POST[ 'id' ];
    //$page[ 'body' ] .= "Session ID set!br />br />br />";
    $page[ 'body' ] .= "Session ID: {$_SESSION[ 'id' ]}br />br />br />";
    $page[ 'body' ] .= "script>window.opener.location.reload(true);/script>";
}

$page[ 'body' ] .= "
form action=\"#\" method=\"POST\">
    input type=\"text\" size=\"15\" name=\"id\">
    input type=\"submit\" name=\"Submit\" value=\"Submit\">
/form>
hr />
br />

button onclick=\"self.close();\">Close/button>";

dvwaSourceHtmlEcho( $page );

?>

但是从单文件来看, 该输入点不可控, 所以产生了漏报, 如果优化需要解析 include等节点进行跨文件判断

  1. dvwa/vulnerabilities/sqli_blind/source/medium.php
?php

if( isset( $_POST[ 'Submit' ]  ) ) {
    // Get input
    $id = $_POST[ 'id' ];
    $id = ((isset($GLOBALS["___mysqli_ston"]) 

    // Check database
    $getid  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $getid ); // Removed 'or die' to suppress mysql errors

    // Get results
    $num = @mysqli_num_rows( $result ); // The '@' character suppresses errors
    if( $num > 0 ) {
        // Feedback for end user
        $html .= 'pre>User ID exists in the database./pre>';
    }
    else {
        // Feedback for end user
        $html .= 'pre>User ID is MISSING from the database./pre>';
    }

    //mysql_close();
}

?>

这里也是数字型注入的问题, 不再赘述

总结

本文重点在于静态分析部分的修复, 动态分析部分其实相对简单一些, 也就是剪枝的过程, 后续也可以实现.

我的想法是:

  1. 静态分析使用JoernCodeql等工具来实现, 然后生成导航图
  2. exp使用固定poc+ 动态变异 fuzzing 的思想
  3. 动态爬虫使用论文中所使用的crawler4j 或者最近比较火的crawlergo
  4. 然后后端使用Baidu Raspprvd来实现监控是否执行成功

PS.也可以实现一种类似动态跃点的标记, 比如挖掘反序列化的利用链, 具有某些特性的的节点,

比如 $a=$this->$ppp; $a->arr($b);

那么这个点只是L1级别的信息, 但是配合unserialize, 配合其他的类的__call,

将这些L1的标记组合起来,就能组合成存在风险的L2级别的安全风险.

最近对自动化审计AEG这方面比较感兴趣, 欢迎讨论.

参考

https://github.com/UUUUnotfound/Navex_fixed