Note – joern

Introduction

基本操作

  • 安装过程按照Docs中的:
./joern-install.sh --interactive

之后进入安装目录,./joern

  • 项目管理
// 导入项目
importCode(inputPath="<ProjectPaht>", projectName="<ProjectName>")

importCode("/Users/fe1w0/Project/SoftWareAnalysis/java-sec-code",projectName="java-sec-code")

// 查看工程
workspace

// 关闭当前项目
close

// 打开工程
open(ProjectNmae)

查询

  • 选择起点

    • cpg.call
      • cpg.call.argument.code("")
      • cpg.call.argument.code("").astParent.l
    • cpg.method
    • cpg.assignment
  • 筛选节点
    • where
    • filter
  • 筛选输出信息
    • map
  • help
    • help.cpg
// 查询 cpg 的基本元数据 
// l 表示 toList , 也可以用 toJson
// Tab 键可以补全查询命令
cpg.metaData.l

// 列出 所有的 method
cpg.method.l

// 过滤 method
cpg.method.map( m => List(m.fullName, m.name)).take(3).l

// 查看 caller 函数
cpg.method.name("readObject").caller.l

// 正则匹配
cpg.method.name("getRequestBody").callee.name("convert.*").l

// 在 SpringBoot 项目中,大部分 web 接口都有 `@RequestMapping` 之类的注解
cpg.method.where(_.annotation.name(".*Mapping")).map(n=>(n.name, n.annotation.code.l)).l

查找哪些函数调用了getRequestBody方法:

  • 反向查找
    • 第一种就是从给定的方法 getRequestBody开始反向查找所有的调用方,看看调用方是否具有相关的注解
    • 反向查找所有的caller,直到有相关的注解为止
cpg.method.name("getRequestBody").repeat(_.caller)(_.until(_.annotation.name(".*Mapping"))).size
  • 正向查找
    • 从所有带有相关注解的方法,正向向下展开查找。
    • 正向查找,非常费时,搜索成本极高
cpg.method.where(_.annotation.name(".*Mapping")).repeat(_.callee)(_.until(_.name("getRequestBody"))).size

重复操作:

  • repeat..times..:重复指定次数。
    • 例如:x.repeat(_.caller)(_.times(5)) 重复调用五次 caller 查询。
  • repeat..until..:重复操作直到满足 until 中指定的条件。
    • 例如:x.repeat(_.caller)(_.until(_.name("foo"))),重复调用 caller 查询,直到找到一个方法名为 foo 的方法,找不到就返回空。
  • repeat..emit..times..:同 repeat..times..,emit 的作用是将搜索过的节点加入结果集,无论是否到达指定的 times 次数,可以简单理解为or关系。如果 emit 没有指定参数,则将所有搜索过的节点加入结果集,如果指定了参数,只将符合条件的节点加入结果集中。
    • 例如:x.repeat(_.caller)(_.emit(_.isMethod).times(5)),这个查询会将查询 5 次 caller 的结果加入结果集,同时将搜索路径上所有满足 isMethod (即所有Method节点)的节点也加入结果集中。
  • repeat..emit..until..:同 repeat..until..,其中 emit 的作用同上,不再赘述。
    • 例如:x.repeat(_.caller)(_.emit.until(_.name("foo"))),该查询会重复调用 caller 查询,直到找到方法名为 foo 的方法,同时会记录所有的搜索过的节点。可以简单的理解为将符合emit条件的节点或符合until条件的节点都加入结果集,但循环的终结依然是until指定的条件。

控制流分析

获取当前的调用链路

cpg.method.name("getRequestBody").enablePathTracking.repeat(_.caller)(_.until(_.annotation.name(".*Mapping"))).path.l

// or

cpg.method.where(_.annotation.name(".*Mapping")).enablePathTracking.repeat(_.callee)(_.until(_.name("getRequestBody"))).path.l (不推荐)

结果是正确的,就是有重复的项,不太理解

数据流分析

Joern 中也可以执行 数据流分析,需要定义好 source 和 sink ,之后调用 reachableBy 函数执行数据流分析。

查询格式: sink.reahableBy(source)

// 定义 source
def source = cpg.method.where(_.annotation.name(".Mapping")).parameter

// 定义 sink
def sink = cpg.call.name("openConnection")

// 调用分析
// dedup 去重
// p  print
sink.reachableByFlows(source).dedup.p

画图

  • 可视化
    • plotDotAst
    • plotDotCfg
    • plotDotCpg14
    • plotDotPdg
    • plotDotCdg
    • plotDotDdg
  • 导出dot
    • dotAst
    • dotDdg
  • joern-export

Say Goodbye

  • close 关闭项目
  • exit 退出项目

References:

要深入的话,还得去阅读官方手册

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇