IAST技术进阶系列:关键语言支持 & 全场景多核驱动

首页 / 业界 / 资讯 /  正文
来源:悬镜安全
发布于:2021-09-30
IAST技术进阶系列(一):关键语言支持

导语:新一代IAST灰盒安全测试技术凭借其极高的检出精度、深度的业务透视能力及高度自动化CI/CD支持能力,正快速由行业头部用户的场景化探索实践向广大中小型用户规模化应用实践演进。由于其特殊的技术原理,使得该项新技术对业务语言的覆盖支持成为关键落地因素之一。

今年6月,中国信息通信研究院(以下简称“中国信通院”)正式发布《交互式应用程序安全测试工具能力要求》行业标准(以下简称“IAST标准”),并于首届DevSecOps敏捷安全大会(DSO 2021)首次公开标准解读。目前,中国信通院已完成首批评估测试,悬镜灵脉IAST是全球首个通过该项专业测评认证的IAST工具。

自IAST标准发布起,中国信通院同步启动了首批IAST工具的测试工作。依托标准要求中的34个功能指标项,在统一并发场景下进行性能检测记录。通过对测试结果分析发现,各厂商IAST工具在以下三方面存在较大差异:

1、对主流编程语言支持的覆盖率;
2、对不同安全漏洞类型及结果的定义规范;
3、配置缺陷和弱密码等低危漏洞或信息漏洞的检测结果。

其中,首当其冲的是对主流编程语言的覆盖率问题。在IAST标准当中,“支持的编程语言”被标定为全标准的第一条测试要求,由此可见其重要性。IAST工具是否支持多种主流编程语言,直接决定了其是否能适配客户各种各样的实际开发场景,进而满足助力客户业务发展的需求。

图:IAST标准中对编程语言的要求

多种编程语言的支持,对用户的意义不是够不够好,而是能不能用。如果用户核心业务使用的语言没有被IAST探针支持,即使IAST产品有100分的其它功能,对用户来说也是0分。

01 IAST工具介绍

IAST(Interactive Application Security Testing, 交互式应用安全测试)是应用程序在进行自动化测试、人工测试等任何与应用程序进行“交互”的同时,能自动分析应用程序安全风险的技术。它可以实时返回结果,因此不会额外增加CI/CD的时间。

相比于其他AST技术,IAST只会分析“交互”产生时所影响到相关代码的安全风险,而不是扫描所有代码、配置文件或遍历整个站点。IAST更适合在QA环节使用,让安全团队在相对不影响开发、测试现有流程的情况下,较早地发现应用程序中存在的安全风险。

需要注意的是,与其他AST技术相比,IAST还是一个比较新的概念,其基于请求、代码数据流/控制流来综合分析应用程序的安全风险。IAST运行时插桩技术可以发现更多应用程序本身的安全弱点,以及应用程序中第三方组件的公开漏洞。由于该技术针对不同语言需要研发不同的插桩探针,因此对于厂商而来,其IAST工具每增加对一种语言的支持,即相当于开发一款新产品,也就意味着IAST工具支持的编程语言越多,厂商所需投入的人力成本和经济成本也就越大。

支持多种编程语言插桩,是IAST技术未来发展的必然趋势,原因在于不同行业由于属性不同,对开发语言有特殊要求。例如金融行业,普遍以Java语言为主;互联网行业则是多语言环境的典型代表,使用的语言五花八门,Java占比较高,同时也会使用Python、Go、Node.js、.Net等语言来适配多种业务场景。如此,一款好的IAST工具支持多语言插桩是必要基础,也是IAST工具厂商在技术上必然的拓展方向。

02 主流编程语言分析

截至2021年7月TIOBE发布的编程语言指数报告,排在前十名的编程语言中,常见的应用开发语言主要有Java、Python、C#、JavaScript、PHP这5种(VB.Net 随着 .Net Core 和 .Net 5.0 的推出,跨平台方面优势将不再明显,因此不再讨论)。

图:TIOBE-2021年7月编程语言排行(TIOBE Index for July 2021)

根据TIOBE指数排行,这里列出了百度指数、Google Trends以及Stack Overflow Trends近年内对Java、PHP、Node.js、Python、C#这些语言的热度检测趋势:

图:近4年间Java、PHP、Node.js、Python、C#编程语言百度指数趋势
 
图:近4年间Java、PHP、Node.js、Python、C#编程语言Google Trends趋势
 
图:近12年间Java、PHP、Node.js、Python、C#编程语言Stack Overflow Trends趋势

通过对比上述各平台的趋势发现,对着数据科学、人工智能等领域的兴起,Python的热度扶摇直上。作为一种动态类型语言,使用Python作为Web应用程序的主要开发语言可以在初期为项目节省大量的时间和成本。例如:早期的YouTube、知乎平台等,均使用Python作为主要的Web开发语言。

但是由于Python在多线程上的硬伤和动态类型语言后期不易维护的特点,很多企业在完成初期的用户积累后,都会选择使用一门静态类型的语言来重构他们的应用,例如Java、C#或者Golang。

Java凭借其简单易懂的语言、活跃的社区支持、以及JVM优秀的跨平台支持,使其成为全球使用最多、最广泛的Web应用程序编程语言。

C#背靠Microsoft,凭借ASP.NET、Razor、良好的社区、宇宙级IDE:Visual Studio,再加上语法和Java、C等语言相近的特点,也在Web应用程序编程语言中占有一席之地,但在国内热度相对较低。

PHP 与 Python 一样,也是一种动态类型语言。由于一定的历史原因,PHP 作为“世界上最好的语言”在国内热度一直较高。低学习门槛、易于开发和部署的特点,让很多企业选择使用 PHP 来编写公司官方网站或者与微信开放平台对接。

Node.js在严格意义上来说并非一门语言,而是使用JavaScript引擎构建的平台。Java、C#契合Web应用程序开发的一部分原因是其能够和JavaScript/TypeScript友好地融合(例如:Jsp技术和Razor技术)而Node.js作为直接使用JavaScript来构建的平台,在这方面有天然优势。同时,由于JavaScript引擎的更迭,其效率越来越高,加上原生支持异步处理等特点,非常适合快速构建Web应用,因此热度也在不断上涨。

目前国内,面向互联网的Web应用程序主要以Java、PHP来编写,内网应用则呈现出多元化的态势,以快速实现功能为主要目标,因此使用Python、Node.js、Golang、C# 来开发的应用占比也相对更高。

03主流语言插桩原理简述

IAST 插桩探针想要分析数据流需要做两件事情。第一点是如何“理解”代码。我们需要根据不同语言来区分,需要关注哪些函数,这些函数里哪些是污点输入?哪些是污点传播?哪些是污点清洗?以及又有哪些是污点汇聚?这个我们可以根据不同的漏洞原理来做分析,第二点,我们如何捕获关键函数的调用情况?这需要我们从各种语言底层做突破,使得我们能读取到关键函数何时被调用、传入了什么参数、数据传递给了谁。下面将针对不同语言,浅析 IAST 插桩捕获关键函数的原理。

图:灵脉IAST支持的部分中间件及框架

作为全球首款通过中国信通院交互式应用程序安全测试工具(IAST)能力认证的产品,灵脉IAST是国内唯一支持Java、PHP、Node.js、Python、.Net、Go等全部主流语言的IAST工具,其中各语言具体支持的部分中间件及框架如上图所示。以下将结合灵脉IAST工具简述主流语言插桩原理。

Java
如果语言本身提供了插桩的接口,那么探针开发的难度将会大大降低。例如Java提供了一个instrumentation 接口。通过该接口,可以以一种标准的方式,在启动应用时添加javaagent参数来加载插桩探针,从而实现动态数据流污点追踪。大致流程如下:

图:Java实现动态数据流污点追踪流程

如图所示,通过红色的JVM Agent路径,就可以获取到Hello类中的方法何时被调用、接受到了哪些参数等信息。更进一步,就可以阻断它的执行(RASP的功能),甚至修改它的执行逻辑。当然,即便官方已经提供了标准做法让插桩探针的研究少走弯路,但是构建成熟的Java探针并非易事。

除Java外,其他一些语言也使用了JVM虚拟机,例如Scala、Kotlin等,这些语言的插桩原理比较类似,不再赘述。

PHP
PHP Core使用C语言编写,默认情况下,PHP开发者使用的所有函数都在PHP Core和C中定义。当PHP程序在运行时,有三个主要组件进行交互:
·用户代码(用户自有代码、框架等);
·扩展(数据库驱动、cURL等);
·PHP Core。

PHP程序通常有如下两种主要运行方式:
·Web模块(如Apache mod_php);
·独立进程(如PHP-FPM),常用于与反向代理通信)。

在PHP中,没有多线程的概念,每一个请求都会生成一个新的进程。因此,很多PHP服务器上同时会处理成百上千个PHP进程。一个进程可以理解为一条请求。当一条请求进行PHP应用程序后,将会经历如下生命周期:
1、 MINIT(模块初始化)
2、 RINIT(请求初始化)
3、 执行响应PHP代码逻辑,生成相应并返回
4、 RSHUTDOWN(请求关闭)
5、 MSHUTDOWN(模块关闭)

PHP插桩检测的主要方式是替换内部函数,将原始请求暂存在特定的位置,并触发探针分析,分析引擎通过比对函数列表检索出被调用的函数并记录,然后释放原始请求,再以同样的方式继续执行,分析之后的内容。流程如下:

图:PHP插桩检测流程

如上图所示,PHP插桩探针包装了原始函数,就像安检一样,你和你的行李(原始数据)需要通过安检仪器后才能进入下一阶段。但在早期的实践中,我们发现过多的“安检”会造成很大的性能损失,因此在灵脉IAST中,研发团队针对性插桩关键函数,配合主动验证功能,在保证对业务影响最小的情况下,实现高效检出。

Node.js
JavaScript的灵活性为Node.js动态插桩检测提供了便利。但是由于Node.js有着众多版本,很多版本之间API变化很大,因此,对于不同Node.js版本插桩探针的构建将会有不少的坑要踩。对于Node.js插桩探针,通常采用和 PHP 类似的方法 ——包装函数。要构建一个Node.js插桩探针,至少需要从以下几个方面着手研究:
1、跟踪导入的模块;
2、构建包装器;
3、构建Hooks。

首先,由于Node.js导入模块时,会将模块保存在本地位置(如node_modules)。通过require语句或者遍历本地模块目录,可以检索出所有需要跟踪/监听的模块。然后,根据上一步得到的模块列表,针对性地筛选出需要包装的方法/函数。接着,将构建的Hooks置于包装后的方法中。最后,当Hooks被触发时,调用引擎对其进行分析。至此,分析引擎将能获取到原始数据,根据需要,我们可以对数据流进行阻断、处理、放行等操作。

与PHP不同的是,在Node.js中导入模块是一个同步的操作,添加一个跟踪器来跟踪模块导入的开销可以忽略不记。触发Hooks会影响代码逻辑的执行时间,但这是不可避免的,和PHP一样,需要筛选出关键函数来进行监控。

Python
得益于Python内建的自省机制,使得在Python上构建插桩探针变得安全可靠。和PHP、Node.js类似,构建Python插桩探针的主要方法同样是包装底层函数。PEP 302提供了import hook的方式,在被引用的模块被加载前,就可以动态地对特定函数添加装饰器,也避免了在其他位置重复引用而导致装饰器失效的糟心问题。

虽然对于使用Python定义的函数进行包装相对容易,但在常用的CPython解释中,很多类都是由C定义(例如,大多数的DB Driver)。好在绝大多数的DB Driver(SQLite、MySQL等)都遵循 PEP 249 ,这样就有机会顺着DB Driver的调用链一路打补丁。对于未遵循DBApi2的DB Driver(NoSQL等),则需要更多的工作量。

.Net
众所周知,.Net技术体系与Java高度重叠。表现在探针产品层面,就是.Net探针与 Java探针在作用原理与产品架构上高度相似。所不同的是,.Net CLR并未提供类似java.lang.instrument包那样易于使用的接口。实际上,.Net探针的主要技术难度集中在如何像Java改写bytecode一样动态地改写JIT阶段的CIL编码。

在实际实现时,.Net探针利用了CLR的Profiling接口,通过C++实现一套类似JVM Instrumentation API的IL改写机构,以将基于C#安全保障业务逻辑注入到关键方法之中。除去这套IL改写机构带来的麻烦外,GAC、mscorlib/System.Private.CoreLib等 .Net特性都最终使得探针在形态上与前述各语言区别较大。

目前,一场变革正在.Net技术世界中发生,无论是转向开源的.Net Core还是作为“下一代”的.Net5/6都在底层上引入了不少变动。幸运的是,在CLR层次上的变动仍然相对保守。因此,目前探针同时具备对传统的 .Net Framework、.Net Core 与最新的 .Net 5/6 环境的适应性。之后,我们也会持续跟踪该领域内的各项进展。

GO
Go 语言是近几年兴起的技术门类,其核心优势在于开发/运行效率高、工具链完善且二进制易于部署。然而,对这种直接编译为二进制的技术体系,利用 Runtime 机制进行插桩的方式就不再有效。因而,Go 探针在形态上与使用体验上与其他探针云泥之别。得益于Go的开源特性,可以直接对Go工具链的源码进行改写。我们通过将 `go build`命令逻辑进行改写,实现`xmirror-go build`命令,即可在项目构建过程中,将安全保障逻辑加入关键方法之中。

对Go语言的支持,是灵脉IAST全覆盖主流编程语言的最后一公里,灵脉IAST Go探针已进入测试验证阶段,很快将在正式版产品中与大家见面。

04 灵脉IAST探针的特点

悬镜灵脉IAST在银行、证券、保险、能源、电力、运营商、智能制造及泛互联网等不同行业的复杂业务场景下进行了广泛的应用和落地实践,沉淀出了高适配、低消耗,高检出、低误报等综合技术优势。目前灵脉IAST探针具有以下特点:

插桩规则动态更新:插桩检测规则并非静态在探针内定义,而是以动态的方式下检测规则集,并且检测规则及规则集均支持自定义,最大程度上避免误报、漏报的产生;

无需修改现有代码:无需修改现有代码,只需在启动时添加参数应用插桩探针(启动时加载),或者在应用启动后通过进程ID(pid)动态加载(热加载)即可完成插桩;

开源组件依赖分析:运行时动态分析应用程序依赖链,通过指纹、同源代码片段匹配等多种手段分析应用程序引入第三方开源组件的风险;

性能优化:经过大量客户验证,对性能影响极小。并提供熔断开关,当阶段内CPU占用超过设定时,自动停用,优先业务顺畅运行;当CPU空闲时自动恢复工作;

多功能探针:主动插桩、被动插桩,甚至RASP插桩,共用同一个探针,可以通过Web界面随时切换工作模式;

脏数据处理:主动模式下,可通过Web界面上的开关控制是否释放脏数据;

自动回归测试:被动模式下,可通过Web界面启动回归测试,再次触发请求,如果漏洞已修复,将自动更新漏洞状态为“已修复”。

05 IAST语言支持的发展

从2012年首次被提出,到近年成为软件安全领域的技术焦点,IAST工具正在向规范化和规模化应用发展。随着IAST行业用户的快速增长,对应用编程语言的覆盖率、IAST检测精度及业务全场景支持已成为评判IAST工具成熟度的主要标准。

目前对Java、PHP、Node.js、Python、.Net、Go等主流语言的覆盖率,相比国内其他厂商仅支持一两款语言,Contrast、悬镜安全和Synopsys处于全面领跑地位。对主流语言的覆盖率,是当前绝大多数IAST工具需要在未来很长一段时间内持续弥补的技术短板。

表:国内外厂商IAST部分功能对比

IAST 技术进阶系列(二):全场景多核驱动

应用缺陷深度检测分析能力是 IAST 技术的首要基础要求。为了满足用户对各类编程语言的检测需求,IAST 交互式应用程序安全测试平台应全面支持 Java、Node.Js、PHP、C#、Python、Go 等主流编程语言。然而,目前国内市场上除 Contrast、悬镜安全和 Synopsys 的 IAST 平台已覆盖全部主流语言外,多数 IAST 平台仅支持一两款语言,检测深度和应用范围也严重受限。此外,运行时插桩精准检测模式配合流量检测模式、日志检测模式和爬虫检测模式进行深度应用安全审查是实现全场景支持的重要手段。

目前国内 IAST 技术发展仍处于成长期,但企业在落地研发运营安全建设时,IAST 平台已成为优先级较高的配套自动化工具产品。行业用户的快速增长,使 IAST 平台正在向规范化和规模化应用发展,IAST 平台对业务全场景支持已成为继应用编程语言覆盖率之后,评判 IAST 平台成熟度的又一主要标准。

悬镜安全作为国内 DevSecOps 体系先行者,结合多年创新经验沉淀,从技术落地实践视角延伸了 IAST 的概念:创造性提出交互式应用安全测试不仅可以从应用内部进行实时分析,只要是“交互”产生的“流量”,均应在 IAST 技术的覆盖范围内。即从广义技术来讲,一套完整的 IAST 方案应当至少覆盖以下检测场景:

插桩检测模式
  动态污点追踪(被动式插桩)
  交互式缺陷定位(主动式插桩)

流量检测模式
  终端流量代理
  主机流量嗅探
  旁路流量镜像

日志检测模式
  Web 日志分析

爬虫检测模式
  纵深嗅探扫描

插桩检测模式

1.动态污点追踪

动态污点追踪是 IAST 技术的主要检测方式。所谓污点追踪,是将数据流抽象为<sources、sanitizers、sinks>三元组的一种污点分析技术。

·sources 代表污点输入源,通常认为,任何从外部输入的数据都是不受信任的污点数据,都有可能对系统造成危害。例如来自用户输入、从文件中读取的数据等。
·sinks 代表污点汇聚点,通常是指将会产生安全问题的敏感操作。例如执行 SQL 语句、执行操作系统命令等。
·sanitizers 是指对污点数据的无害处理。例如清洗、校验、过滤等。

简单来说,污点追踪就是去跟踪那些输入到系统中的污点数据(sources),在代码中流转、传播的过程中没有经过足够的清洗、校验、过滤等无害化操作(sanitizers),就直接进行会产生安全风险的敏感操作(sinks)的数据流。


如上图所示,插桩探针会追踪每一条污点数据流,并找出其中没有经过无害化操作的数据流(变量1 → 变量3)。
根据污点追踪分析过程中是否需要运行应用程序,可以将污点追踪技术分为“静态分析”和“动态分析”两种。和静态污点追踪技术相比,动态污点追踪技术是在应用程序运行过程中进行分析,因此可以获得更多的应用程序上下文信息,并且这些数据流都由交互产生,所以可以在最大程度上保证检测结果的有效性,大大降低误报的产生,也就降低了人工审计结果的成本。

由于动态污点追踪不会重放测试流量,因此在 IAST 技术中也被称为被动式插桩。

2.交互式缺陷定位

由于动态污点追踪技术需要跟踪每一条污点数据流,这样会占用一定的业务服务器资源。为了进一步降低应用插桩带来的性能损耗,交互式缺陷定位是在动态污点追踪技术基础上衍生出的新型 IAST 手段。通过减少动态污点追踪中的触发点(hook 函数),即只对应用执行的关键函数点进行敏感操作判断,并通过一些精心构造重放流量的 Payload 来主动发现潜藏在业务应用里的安全漏洞,同时可以精准定位其所在代码行。由于主动 IAST 的特殊技术优势,当开发者修复完漏洞后,还可以对指定漏洞进行全面回归测试及漏洞修复验证,协助用户快速提高漏洞收敛效率。


如上图所示,插桩探针仅收集关键数据,不会追踪整个污点数据流。服务器收到从插桩探针返回的数据后,会向应用服务器发送构造好的重放流量来验证风险是否存在。

通过交互式缺陷定位的检测模式,不仅解决了传统 DAST 无法精确定位漏洞位置的问题,还有着比传统 SAST 技术低得多的误报率。此外,在脏数据处理上也有着不错的表现,并且可以针对应用测试结果进行全方位复现和验证测试,相比动态污点追踪有着更低的系统开销,对业务系统稳定性的影响也更小。在非复杂数据包加密、内部测试流量管控等特殊场景下,它更加符合敏捷开发和 DevOps 模式下软件产品快速迭代、快速交付的要求。

由于交互式缺陷定位会主动发送 Payload 来验证漏洞,因此在 IAST 技术中也被称为主动插桩。

流量检测模式

1.终端流量代理


终端流量代理检测是流量检测模式中检测成本最低的一种方式,只需要在测试人员的主机配置代理/VPN,将测试流量转发至检测引擎,检测引擎在将正常流量转发至业务服务器的同时,也会将重构的流量同时发送到业务服务器进行安全检测。


如上图所示,测试人员在客户端配置代理(操作系统、浏览器、移动设备等),将流量转发到 IAST 检测引擎。检测引擎接收到流量后,会直接将原始流量转发到目标应用服务器,然后在这个流量进行修改后重新发送到目标服务器,根据重构流量的响应来判断是否存在相关漏洞(如上图中红色部分)。

终端流量代理对于业务的入侵性极低,不依赖业务系统的语言环境,无需对现有业务系统进行修改即可实现高效的检出。

2.主机流量嗅探

主机流量嗅探监测业务服务器的流量网卡,通过嗅探节点将经过主机网卡的所有流量复制到检测引擎端,由引擎端对流量进行重构,重新发送到业务服务器进行检测。


3.旁路流量镜像

旁路流量镜像是基于交换机的镜像功能,将经过交换机下的所有流量通过镜像口导出,在网络出口旁路部署流量镜像,再将测试流量复制到检测引擎端,由引擎端对流量进行重构,重新发送到业务服务器进行检测。


日志检测模式

1.Web 日志分析


Web 日志分析是将 Nginx、Apache 等 Web 服务的日志,通过转发器转发至 Kafka 等消息队列中,再由 IAST 引擎进行消费,引擎端分析日志数据并生成重构流量,发送到业务服务器进行检测。




通过对 Web 日志的分析,可以快速从反向代理服务器中梳理出应用程序资产,并对它们进行安全检测。

爬虫检测模式

1.纵深嗅探扫描


纵深嗅探扫描采用主动 PoC 漏洞验证技术,即通过 Web 爬虫获取网站 Sitemap 后向目标系统发送真实的“攻击”载荷,分析目标系统变化和返回内容,判断是否存在漏洞。使用纵深嗅探扫描需要的成本极低,只需提供 URL 即可自动进行分析。


IAST全场景支持的必要性

与传统开发模式将安全作为补充相比,DevOps 动态环境下的开发安全要求将安全融合于软件开发的全流程,DevSecOps 理念将安全融入软件开发的规划、设计、编码、测试、上线运行等各个环节,强调安全无处不在。IAST 作为 DevSecOps 建设落地的关键平台,通过主被动插桩、流量、日志分析多种检测模式的结合,为动态持续的软件开发环境提供最佳安全测试服务。由此可见,好的 IAST 平台一定能适应各类业务场景。

目前,悬镜灵脉 IAST 灰盒安全测试平台,已兼具主被动插桩、流量、爬虫、日志分析等检测模式,率先实现了全场景支持,可以达到低门槛、低侵入、低消耗的基本要求,柔和无感知地接入业务发布流程。

无论是已有上千个应用资产的企业内部业务系统,还是企业自建的 DevOps 研发运维一体化业务开发模式,亦或是企业采购的第三方开发应用系统,通过灵脉 IAST 全场景支持的检测模式,能够发现新开发业务系统中存在的通用 Web 漏洞、业务逻辑缺陷、系统服务漏洞,以及第三方开源组件成分分析及关联漏洞检查,将安全漏洞的发现和修复时间前置到开发测试环节,大大提升修复效率。