甲方代码审核的方法和技巧

《199》一书的作者介绍了腾讯高级工程师

林,他专注于和SecDevOps的建设目前,他从事安全风险评估和代码审计,并在国内大型电信运营商和顶级游戏公司从事运营、维护和安全系统建设。

背景

1,不可避免的

漏洞攻击和防御永远不平等。这句话是用来形容防守者防守整支球队,而进攻者只需要突破一个点就可以进攻然而,在漏洞的攻击和防御中,防御者也有攻击者所没有的优势:他们有代码。与黑盒测试相比,

代码审计具有从代码实现逻辑的源头挖洞的天然优势。与教条式的修复准则相比,代码审计还可以从逻辑上为代码实现中的漏洞修复提出更有针对性和可行性的解决方案,甚至在此基础上发展安全开发组件和框架。

如今,软件开发生命周期法和开发安全操作非常流行,代码审计已经成为甲方深入防御和安全融入业务的唯一途径。在此背景下,甲方实施代码审计势在必行。

此外,应该注意的是,本文中描述的代码审计包括两个部分:自动代码漏洞扫描和手动代码审计

2,与漏洞挖掘的区别

1)与漏洞挖掘不同,

侧重于风险项目。代码审计还将跟踪不能构成漏洞的风险项目,或者要求或建议企业进行修复,特别是在强调深度防御的企业安全建设理念下。

2)关注软件供应链

代码审计还关注应用程序或开发组件的依赖安全性,如npm包是否存在CVE漏洞以及pip源是否安全

3,甲方代码审计与白帽子代码审计的区别

1)目标和初衷导致不同的覆盖范围和使用方法

覆盖范围:不仅在于钻漏洞,还在于发现风险,不仅在于提供强化意见,还在于梳理研发系统,为制定代码规范和构建安全开发组件提供数据支持,不仅在于手工操作,还在于自动化系统的构建。此外,甲方的代码审计强调完全覆盖,而white hat可能只关注单个点,并可能通过突破一个点进行入侵。

2)被审计的代码是不同的

甲方通常审计自己开发的代码,而White Hat通常审计开放源代码,它们在业务逻辑复杂性和代码可读性方面有很大的不同

流程

代码审核是需要在软件开发生命周期和软件开发生命周期的编码实现阶段完成的一件事,这两个阶段分别对应于软件开发生命周期中的实现/验证阶段和软件开发生命周期中的开发/构建/测试阶段,在这两个阶段中,可以在开发和编码构建阶段完成自动代码漏洞扫描。手工代码审计可以在业务测试阶段同时进行。前者是所有业务上线前的必要阶段,而后者可以从新业务、高风险业务和重要业务逐步开始。毕竟,对于甲方庞大的业务代码来说,手工审计能够覆盖的范围总是有限的。

审计风险

方法

甲方代码审核的“陶”部分介绍如下。所谓“道”就是方法论。这一部分包括代码审计的难点、解决难点的总体思路和一些审计技巧。

1、痛点

甲方,特别是大型电信运营商、金融机构和互联网公司,业务规模庞大,随之而来的是高度复杂的代码和业务结构问题。尽管市场上有许多SAST公司能够扫描代码漏洞,但其准确性和误报率很难达到预期。此外,不同熟练水平的人工审计主管和不同的判断标准也会造成一系列的登陆困难。

1)代码和架构是复杂的

数十万、数百万行代码,一个企业分成几十个模块和几十个代码仓库是常见的。

开发语言是多种多样的,有各种各样的自我研究框架、流行的框架和复杂的框架。超过

无疑是审计师和SAST工具的巨大挑战

2)工具调用率

文本框没有工具是所谓的银弹,官方规定,插件调用率很低,需要根据开发语言、编码风格进行定制;

工具无法利用逻辑漏洞与业务逻辑漏洞大量暴露的漏洞情况之间的矛盾;

工具和系统的运行也需要特殊的人力投入,从而不断提高工具的调用率。

3)心理

新手审计员会犯的一个错误是判断这个代码是否是根据他们自己的想法实现的。然而,人们忘记了一个数学问题可能有多个解决方案,尤其是在没有统一的编码标准或最佳实践被每个人认可之前,如果你不遵守这个规则,你将在审计中遇到很多麻烦。考虑到KPI,

审计员认为由于代码审计花费了很长时间,为了反映工作量,他必须说些什么。如果系统没有问题,但是一直在唠叨,开发者会更加不信任你。

对于甲方的代码审核员来说,审核任务多、代码大是正常的。如果只提高速度而不考虑后果,细节将被这样省略,导致审查不完整。

认为高级程序员编写的代码没有问题,但是仍然有错误。此外,在巨大的开发压力下,如何保证高级开发人员不会犯一些安全编码错误?或者不相信新手写的代码,其实只要新手有安全意识的代码和良好的编码习惯,就没有必要写有很多问题的代码。简而言之,开发者需要被平等对待。

2和总体思路

以下七种方法将介绍如何更好地进行代码审核,包括自动手动组合、黑白框组合、前向和后向跟踪、动态和静态组合、过去和现在组合、清单和安全代码规范组合、通读和通读组合。

1)根据预定的规则,自动和手动地将

静态代码分析工具->ast/正则表达式-> review

ast

词法分析->语法分析->AST

逐一组合成识别标记同时,它删除了空白、注释等最后,整个代码将被分成一个令牌列表。将词法分析数组转换成树表达式形式同时,验证语法。如果语法有任何错误,把语法错误扔掉。解析器将删除一些不必要的标记,因此AST不是100%与源代码匹配,解析器覆盖所有代码结构的100%。生成树被称为CST。

以下是一些主流网络开发语言对AST语法分析器的介绍:

在线语法分析器;

PHP-parse Sr;

python-parser;

go-parser;

js-parser;

java-parser

结合开源和商用sast工具进行漏洞和风险扫描并输出初步检测报告,然后手动检查准确性,不断优化sast扫描规则,同时提高漏洞挖掘速度

2)黑白盒结合

黑盒覆盖->白盒强调

通过黑盒覆盖所有业务cgi,同时通过白盒测试覆盖重要业务cgi,通过黑盒快速验证、白盒挖掘根本原因或研究旁路策略实现效率与重要性的平衡。此外,建议使用被动扫描器进行快速流量回放,实现流量采集和漏洞测试的同步执行,从而大大提高测试效率。同时,还建议对cgi和函数进行分类,否则理解业务和代码逻辑的白盒审计成本将非常高。

3)前向和后向跟踪

①前向:变量->函数/敏感操作->输出

$ _ get-> $ param-> eval-> return $ param

跟踪来自参数接收条目的数据流是一种前向跟踪思想其优势在于,它便于理解程序的整体框架,并且相对容易定位逻辑漏洞。但是,当代码量大且代码结构不强时,手动审计成本很高,投资回报可能不明显。在这种情况下,与SAST工具相结合的审计效果会更好。

②反向:函数/敏感操作回溯->输出

eval-> $ param-> $ get-> return $ param

根据敏感关键字回溯传入参数是一种反向跟踪思想本发明的优点是:只需要搜索对应的敏感关键词,就可以快速挖掘漏洞,实现定向挖掘,效率高,质量高;然而,由于没有通读代码,该方法不熟悉程序的整体框架,花费时间查找,并且难以挖掘逻辑漏洞同样,在这种情况下,应该结合SAST工具,因为SAST工具对敏感函数的控制流具有更好的跟踪效果,并且便于手动跟踪后续变量。

4)静态与动态的结合

①静态审计

通过对源代码的静态分析,发现源代码中的逻辑、数据处理和功能没有得到正确使用,从而确认了源代码中可能存在的漏洞这可以通过规则匹配和代码分析来实现,但是这可以通过SAST工具来实现。

规则匹配

通过编写正则表达式匹配开发语言或开发框架的默认变量来匹配高风险函数,如php默认变量$GET、$POST、高风险函数eval()、exec()等

代码分析

通过分析代码的语法来分析代码执行过程。如果采用自动方式,这段代码属于上面提到的AST,所以不同的想法之间有相似之处。

②动态审计

通过运行待审计代码,利用断点调试方法跟踪数据流,判断系统是否存在漏洞这可以通过DAST或IAST工具来实现。注意在开始时,我们只需要注意我们关心的漏洞类型:高风险文件、高风险函数和常规的网络漏洞

5)

是否结合当前使用了框架的易受攻击版本;

是否来自同一个有不良编码习惯或安全意识薄弱的开发人员;

是否存在任何漏洞,这些漏洞可能没有完全修复或其他业务存在类似问题;

函数、模块、类和函数的漏洞可能出现在其他函数模块和类函数中吗

6)核对表和安全编码标准结合

来整理常见的漏洞场景、常见的漏洞类型和常见的功能安全编码模板。通过比较实现方法,编码标准可以参考OWASP安全编码标准,相关清单可以在下一部分使用

7)通读和日常阅读结合阅读技巧的

篇类似的英语阅读文章,先大致读一读,然后根据漏洞类型和业务场景跳过阅读

首先取决于程序

的一般代码结构,例如哪些文件在主目录中,哪些文件在模块目录中,哪些文件在插件目录中,除了注意哪些文件之外,还应该注意文件的大小和创建时间。检查版本管理历史,以获得整个代码更新迭代过程的概述。

关注框架文件、核心功能

功能集文件、配置文件、安全过滤器文件、索引文件,还关注核心功能实现逻辑,如身份认证、权限控制、数据库操作、文件上传等。

3,涵盖

,结合上面提到的总体思路,下面将介绍业务中具体代码审计的三个重要模块。业务基础信息和代码逻辑是基础,平台手段是助推器,流程标准化是关键。

1)在依靠代码仓库和业务基础信息

安全资产管理进行代码审计之前,必须有一个完整的资产市场和相应的业务、负责人和组织结构之间的关系。只有这样,才能在明确安全形势的基础上选择代码审计的对象、重点、方法和手段。

代码获得明确的审计对象后,需要通过资产市场找到开发团队,通过代码仓库的权限申请流程获得代码。在审计

体系结构、cgi接口和业务逻辑之前,有必要了解业务体系结构以初步评估审计范围。了解cgi接口和业务逻辑可以加快审计速度,并快速定位漏洞和风险。

2)平台建设

甲方业务的复杂性决定了代码审计必须走平台建设的道路。通过开放SAST工具和CI系统,可以实现漏洞自动扫描,发现漏洞后可以自动创建漏洞工单,并可以根据现有的审计流程进行审核和手工审计。

配置项系统和sast工具(如SAST工具sonarcube及其插件FindSecurityBug和jenkins配置项系统)是一个低成本的实施方案。

漏洞管理系统进入代码审计阶段的企业通常有比较完善的漏洞管理系统和工单处理流程,可以对sast生成的报表进行分析和过滤,然后推送到漏洞管理系统。

审核流程管理主要定义审核流程的任务跟踪、检查范围和投资回报评估

3)检查表

这里的清单实际上是对审核过程的进一步细化,区分了场景和漏洞、已经做了什么、发现了什么问题、有多少代码、使用了什么技术、花费了多少人工日以及检查周期中的准调用率

审计风险

4)涵盖

个高风险业务:一个月内可以确定一个或n个以上的高风险漏洞

新业务:严格检查新业务在线的安全基线合规性,并要求统一的自动化代码漏洞扫描和手动审计。

重要服务:筛选出重要服务的域名列表,统一提取代码和cgi信息进行黑白框审核。

4和Tips

遵循整体思路。下面将介绍一些快速阅读代码的技巧,利用商业思维的漏洞,提高调用率。

1)如何快速理解代码

简单来说,就是关注开发模式、开发框架,尽可能少读代码,从路由和cgi之间的映射关系入手,结合IDE阅读代码

使用mvc或mvvm架构来理解大多数web系统是根据模型-视图-控制器架构设计和开发的。近年来,越来越流行的mvmm架构就是在这个基础上发展起来的。两者的区别在于mvvm的视图控制抽象了mvc控制器中的业务逻辑,实现了业务逻辑组件的重用审计时,您可以直接转到控制器或视图模型来查找相应的业务逻辑

区分前端代码和后端代码也是近年来流行的开发模式。xss漏洞通常只出现在前端部分。通过区分前端代码和后端代码,只出现在后端逻辑中的漏洞(如sql注入)和未经授权的漏洞可以通过在前端代码部分浪费时间来避免。

首先找到对应于逻辑代码的路由。该路由通常出现在配置或mvc架构的控制器中,并通过文件目录或类函数的公共属性定位,或者直接在url路由表中定义

关于集成开发环境的重要性集成开发环境通常显示类或函数的定义和引用。它可以通过链接快速跟踪代码调用,还可以使用嵌入式搜索功能快速定位关键字,这比在命令行下搜索关键字方便得多。

2)business things

在这里强调业务思维,这意味着您对业务了解得越多,就越能从开发人员和用户的角度考虑设计和使用中可能出现的安全问题,这对逻辑漏洞挖掘非常重要。

使企业能够提供应用程序的设计文档和架构文档,以便快速理解业务逻辑的功能

始终记得用户可以控制请求的每个方面,他们可以以任何顺序访问多阶段函数,他们可以提交格式错误的数据,他们可以忽略某些参数,他们可以伪造某些参数,他们可以修改某些参数。因此,设计必须尽可能全面。

从不同角度考虑了两个因素:应用程序如何处理用户的异常操作和输入,以及不同代码组件和应用程序功能之间的相互依赖操作可能会造成不利影响

考虑设计过程中的每一个假设,并设想违反假设的每一种情况,特别注意用户可以完全控制的假设条件。

3)如何提高呼叫率

主要是关于如何提高问题的准确性和完整性

现代编程侧重于代码调度、脚手架、统一框架和高度封装问题:在框架层或公共类/函数中,过滤和预编译等安全保护可以忽略不计如果用户无法控制,

传入危险函数的参数可以忽略。

依赖组件扫描只是为了提供一种思维方式或缩小审核范围。扫描完工具后,需要对其进行检查。不使用如何使用有问题的函数或类业务,也不将其用作漏洞,而仅用作风险提醒。

访问层已经使用了https,所以没有必要注意安全头异常,如HSTS,但仍然建议程序自己配置安全头,特别是secure/http only/x-content-type-options:no snif等。这不适合接入层中的统一配置。

对于常见的应用场景,如文件操作、命令行操作、数据库操作、用户权限和身份验证,我们需要了解框架的实现并给出相应的安全编码示例。框架文件中给出的例子不一定是最好的。安全方面必须为开发进行安全意识培训,让他知道如何使用框架的API来安全地组合公共功能。

对于应用程序漏洞挖掘,我们需要扩展字典框架的封装可能会引入更多危险的API或危险的特性。在代码审计过程中,这些内容需要添加到危险词词典中。

锐利武器

在上面广泛介绍了代码审计的方法,下面将重点介绍代码审计过程中使用的开源和商业sast工具。

1,开源工具评估

除了cobra系列工具之外,很少有开源sast工具同时支持几种开发语言然而,有许多针对不同语言的开源工具。

1)COBRA

的官方版本支持php/java ast。其他语言使用正则表达式和关键字匹配方法,但用户可以通过重写扫描引擎和自定义规则进行优化。建议在对cobra进行二次开发的基础上,对cobra-W进行关注,重新编写分析报告,注重准确性。

2)bandit

python代码审核工具,它支持ast、丰富的漏洞类型和报告格式、可定制的插件和报告格式

3) nodejs扫描

nodejs代码审计工具,它使用正则表达式匹配方法,基本上涵盖了nodejs的常见漏洞和nodejs开发的最佳实践

gosec使用ast解析器,支持20种漏洞类型检测,是一个相对全面的golang代码审计工具然而,实际测试结果并不理想,需要进一步排除故障。

4)DevSkill/Audit JS/Dependency-Check/Clockwalk

主要用于对pip包、npm包和jar包进行cve漏洞检测,但是误报率很高,因为代码中的许多组件在引入后都没有被使用过,并且可以用作提醒的风险项。

2,商业工具评估

下表对当前主楼的商业工具进行了简单评估。企业在购买时可以做一些参考,因为sast工具在不同的语言中表现不同,并且可能在实际的企业环境中得到更好的测试。

1)CheckMarx

以色列网络安全公司开发的CheckMarx CxSuite目前在行业中广泛使用,下面将简要介绍其CxAudit工具。

检测模型

输入->净化->输出

静态元素表示保存在所谓的文档对象模型中

动态元素表示存储在所谓的数据流图中

DOM和DFG存储在数据库中,可用于创建和查询数据库中的任何内容,包括搜索安全漏洞。

审计风险

2)强化

惠普的强化SCA工具也是目前非常流行的sast工具。其检测模型简要介绍如下:

检测模型

①翻译——首先,通过调用该语言的编译器或解释器,以及其源代码、执行环境、上下文等之间的调用关系,将前端语言代码转换为中间媒体文件NST。分析清楚。

②分析-通过8个静态分析引擎来分析该NST,这些引擎分析不同类型的问题,匹配所有规则库中的漏洞特征,并在发现漏洞后将其捕获。最后,形成包含详细漏洞信息的FPR结果文件,并用AWB打开以供查看。

3,IDE

下面描述了几种集成开发环境工具

1)sast软件插件

SAST(如CheckMarx/Fortid)为主流集成开发环境(如IntellijIDEA/VSCode)提供插件。在集成开发环境中,通过填写服务接口地址和账户秘密信息,可以实现主动触发扫描和报表读取,对开发人员非常友好。然而,实际登陆将会遇到许可证限制的问题,这使得很难有账号,不能隔离权限,也不太可能大规模推广。

2)用户自己编写插件

像sublime一样支持用户自己编写插件,即插件可以自己编写用于代码审计场景。这里推荐使用vulhint kiwi devskim,其中vulhint的配置如下。阅读代码时,高风险函数将被突出显示:

审计风险

案例

下面将简要介绍如何审计PHP、js和Python的代码,其中PHP选择ThinkPHP框架,js选择NodeJS下的Express框架,Python选择Flask框架

1,PHP代码审计

ThinkPHP

漏洞详细信息

版本:ThinkPHP 5.0.14

影响方法:插入,更新

有效负载:

http://localhost/Thinkphp/PUBLIC/INDEX。PHP/INDEX/INDEX/INDEX?Name = INC & NAME = UPDATE XML,0x7E),1)和NAME = 1

审核过程:

1)下载ThinkPHP框架并将其安装到网络服务器,如Nginx/Apache,以构建测试环境

审计风险

3)首先输入有效载荷进行快速验证,并发现注射成功

4)在下面开始代码审计,找到漏洞代码,您可以看到用户传入的参数直接输入到插入函数操作中。然后跟踪插入函数,并通过IDE提示符知道插入是在ThinkPHP \ Library \ Think \ DB \ Builder.php中定义的。向下找到一个分析数据的函数解析数据,跟踪它:

5)查找解析数据有一个逻辑,一旦输入参数数组的第一个元素是inc,它将进入新的函数解析键进行处理,并再次跟踪它

6)发现parseKey没有做任何过滤,并直接将执行结果返回给用户,因此输入updatexml或extractvalue函数会导致sql执行错误,从而返回当前用户信息

2,js代码审核

Express

漏洞详细信息

有效负载:

PostTTP://localhost:9090/Ping/HTTP/1.1

XXX

地址= 127 . 0 . 0 . 1;Whoami

审核流程:

1)检查目录结构,非常典型的MVC架构,您可以猜测路由器放置路由信息、模型放置数据模型、视图放置html信息

审计风险

2)跟踪路由器发现的cgi和后台逻辑之间的对应关系。main是主页,app是业务页面。您可以看到/ping相应的处理模块是appHandler,身份验证是authHandler,然后响应返回到视图的app/ping呈现。

3)跟踪appHandler以找到相应的处理逻辑,并发现用户控制的参数被传递给命令执行的函数而没有任何过滤,从而构成任何命令执行漏洞。

3,Python代码审核

Flask

漏洞详细信息

有效负载:

http://localhost/XSS/reflected/name = alert

审核过程:

1)查看代码路径,参见run.py,查看url和decorator定义的后台逻辑之间的对应关系,并可以直接查看后台逻辑

审计风险

2)发现用户传输的参数被直接抛出到html文件中,而html没有转义数据,导致xss

4,Golang代码审核

漏洞详细信息

有效负载:

post TTP://localhost:8082/sqlhttp/1.1

xx

uid = 1 '或1 = 1-null数据

审核过程:

1)查看代码目录,它也是一个非常典型的MVCapp.go是入口文件,util定义模型,模板定义视图,漏洞定义特定的控制器。

审计风险

2)跟踪应用程序,执行初始化路由,并在主功能中注册应用程序路由

审计风险

3)让我们先看看sql注入的漏洞类型。根据导入模块,我们知道业务逻辑可能存在漏洞/sqli。查找漏洞/功能。按如下方式查找特定定义:

审计风险

4)。那么是否有sql注入取决于UnsafeQueryGetData函数如何过滤或者它是否被预编译。跟踪漏洞/sqli/sqli .查看是否有过滤器,并直接拼接sql语句以形成sql注入

> >> >参考

代码审计:审计思想的示例说明全文阅读

Java代码审计,掌握的就是这样一个“硬看”

全文阅读代码审计

通用代码审计思想

AST抽象语法树简介

thinkhp insert/update SQL injection

大家都在看

相关专题