跳到主要内容

代码审计:IRify 代码审计完整流程

· 阅读需 4 分钟
Yak Project
网络安全垂直语言团队

本期文章主要介绍 IRify 在实战中各个页面的功能,以及如何通过扫描结果分析源码漏洞。

本次实战目标⬇️https://github.com/leveryd/go-sec-code

【一次完整的审计流程】

当一次扫描完成时,我们可以在任务列表查看所有扫描结果:

IRify 核心页面功能演示

审计漏洞页面

审计漏洞页面功能如下:

  • 项目/文件/Risk 三级树形结构:左侧文件汇总页面以树形结构展示所有 Risk;
  • 可视化 Risk 分布统计:每个节点右侧都会标注当前节点中子节点的 Risk 总数;
  • 按文件、规则分类的漏洞聚合。

点击某个 Risk 后,右侧审计漏洞页面即可过滤出对应的 Risk 列表,在最右端的操作选项中即可进入代码审计页面。

代码审计页面

代码审计页面中包含了漏洞的详细信息,例如:漏洞位置,漏洞类型,漏洞个数,漏洞的 Use-Def 链等。

【左侧页面】包含 4 个选项:

1、全部:以树形结构查看全部文件

2、漏洞文件:以文件为单位查看 Risk 结果

3、规则汇总:以规则为单位查看 Risk 结果

4、全局过滤函数:暂不支持,等待更新

【中间页面】用户显示源码,包含漏洞详情规则编写两个页面:

  • 自定义漏洞检测规则
  • 规则即时修改与测试
  • 内置常见漏洞模式库

【右侧页面】则用于支持语法流可视化:

  • 图形化展示漏洞触发路径:在审计结果中则会展示从危险函数到漏洞点的所有路径
  • 点击节点跳转对应源码:点击Syntax Flow 审计过程中的图形即可索引到对应的源码位置
  • 支持路径回溯与展开

实战漏洞分析过程

以靶场 go-sec-code 为例,初次扫描该项目,我们可以发现漏洞列表如下:

假设我们要分析 SQL 注入漏洞的成因,即可在代码审计的规则汇总页面中选中与 SQL 注入有关的规则,下层结构就会显示可能包含 SQL 注入漏洞的文件,选择其中一个 Risk 便可跳转到对应的源码中:

这里就定位到了fmt.Sprintf("select * from user where id=%s", id) 这段代码,其后就是关键函数db.QueryRow(sqlStr),由于id由用户控制,因此该代码有 SQL 注入风险。

查询 Use-Def 链

在靶场中,SQL 注入漏洞的触发点比较明显,如果是真实的工程项目 db.QueryRow的参数可能源自于其他函数并可能转手自多个函数,此时便需要 Use-Def 链来定位,定位的方式有两种:

  1. 查找db.QueryRow参数的 def 链中是否包含可被用户控制的fmt.Sprintf
  2. 查找fmt.Sprintf的 use 链中是否包含危险函数db.QueryRow

对应的内置规则如下:

<include('golang-database-sql')> as $db;
<include('golang-user-input')> as $input;
$db.QueryRow(* #-> as $param);
$param & $input as $mid;

路径1中fmt.Sprintf中的下一层即是db.QueryRow,表明 db.QueryRowfmt.Sprintf的 use 链中,因此有 SQL 注入的风险。

处理 Filter 函数

以路径遍历漏洞为例,路径遍历漏洞允许攻击者访问应用程序预期目录之外的文件系统位置,常常是因为应用程序未正确限制用户输入中的路径字符(如 ../ ),导致攻击者能够访问文件系统上的任意文件。

对于这一点,Syntaxflow 提供了 includeexclude语法来指定或排除特定的路径:

排除filepath.Join所在的路径后可以获取存在漏洞风险的路径,点击fmt.Sprint即可定位到漏洞代码:

结语

新功能:扫描对比(即将上线)

后续版本的 IRify 将上线扫描对比功能:

勾选只看新增,在下拉框中选择用于对比的扫描结果,在下面的树形结构中就只会显示新增的 Risk。

敬请期待!


本文首发于 Yak Project 公众号,阅读原文