Fortify规则教程3

  • A+
所属分类:代码审计

StrcuturalRule和Characterization Rule:

前面的教程请看fortify规则教程1,2

对于简单的规则来说,都是无法满足我们的规则判断的,因为过程复杂,且误报的情况比较多,所以我们需要严格限定部分的内容来减少误报,有的人会说 规则写的严格会导致漏报吗?

那我告诉你,大部分情况下还是不会影响的。(这里我们不谈数据流构造的时候soundness问题,那就扯不清楚了,就只说大众理解的规则上来看的误报和漏报问题)

漏报只存在于数据流无法连接的情况下,这个是什么意思呢?

那就是:

  1. 缺乏source sink,这里指的是代码直接的source sink。

  2. 第三方包里的方法。数据流经过这些地方的时候会断开,导致无法最后流动到sink点。

例如有一个方法叫做clean_data,这个方法是security.filter.clean_data方法。例如代码如果用了esapi等包里的方法进行清除的话,就不会数据流经过那边,自然就没办法检测出来漏洞。

对于这样的概念,在fortify里叫做passthrough,在codeql里叫做addtionalStepflow。

 

Fortify的Structural rule在2个规则里会用到,一个是structuralrule本身,另一个是characterization rule。对应的结构分别是

<StructuralRuleformatVersion="20.1"language="java">

                <RuleID>A42F2AEE-7A09-49FE-9696-8484AAC9136E2</RuleID>

                <VulnKingdom>Security Features</VulnKingdom>

                <VulnCategory>Password Management</VulnCategory>

                <VulnSubcategory>Hardcoded Password</VulnSubcategory>

                <DefaultSeverity>4.0</DefaultSeverity>

                <Descriptionref="desc.semantic.java.password_management_hardcoded_password">

                    <Explanationappend="true"><![CDATA[This issue is being reported by a custom rule.]]></Explanation>

                </Description>

                <Predicate><![CDATA[

                        Function f: f.parameters contains [Variable v: v.annotations[0].type.name matches "org.springframework.web.bind.annotation.RequestParam" ]

                   

                    ]]></Predicate>

            </StructuralRule>

 

            <CharacterizationRuleformatVersion="3.17"language="java">

                <RuleID>82AA0CDC-E6C2-430D-9759-F33E967E96E5C</RuleID>

                <StructuralMatch><![CDATA[

                    Function f: f.parameters contains [Variable v: v.annotations[0].type.name matches "org.springframework.web.bind.annotation.RequestParam" ]

                ]]></StructuralMatch>

                    <Definition><![CDATA[

                        TaintSink(c,{+MyBatisSelectQuery,+PRIVATE,+WEB,+XSS,+DATABASE})

                ]]></Definition>

            </CharacterizationRule>

 

如果你不知道这个,你可以用custom rule edtior来生成一个这样的规则的模版 ,这个很简单,点点就会了。

 

目前看到大家都用dataflow模块来做安全检测,但是可以看到大部分规则都是带了.* 来匹配,很多地方是有误报的。

比如以下规则

Fortify规则教程3

代码都是package->class->method形式,然后定义了init开头的方法是危险的,但是也没严格定义参数,参数只是说了not VALIDATED_PRIVACY_XXX  这个是一个taintflag标记,官方定义了一组这个规则,大部分情况是method的参数可能是其他的一个自定义的类,这是最常见的 !然而自己的类的一些字段可能是string的,导致进入sink后取出来拼接。但是这样的规则就会大量误报,甚至一些自定义类的字段是Long Int也会触发规则,是个猪都知道这样的场景是误报。

但是dataflow规则只能输入.*来匹配。无法对字段类型做判断,这个时候我们就要用到这个characterization rule。这个规则是用来对场景做分组的,设置taintflag用的。

 

再举个例子,我们要约束source为spring的@Requestmapping的方法做为控制器入口,那么根据上面的dataflow规则显然是很难满足我们的需要的,但是如果用

<CharacterizationRuleformatVersion="3.17"language="java">

                <RuleID>34711D7A-C2BC-40B3-B1DE-B5C48EF65646</RuleID>

                <StructuralMatch><![CDATA[

                    Function f: f.parameters contains [Variable v: v.annotations[0].type.name matches "org.springframework.web.bind.annotation.RequestParam" ]

                ]]>

                </StructuralMatch>

                <Definition><![CDATA[

                    TaintEntrypoint(v, {+XSS})

                ]]></Definition>

            </CharacterizationRule>

就可以很好的解决这个问题了。

这个规则就是寻找一个函数f,他的第一个参数是带了RequestParam注解。和codeQL那种关系查询方法很像了。

这个是根据语法树来匹配对应的代码,对于fortify来说,这个叫做nst。

我们可以编写一个简单的规则来查找全部的function

Fortify规则教程3


然后打开一个function看就是这样的结构,根据tab的对应来看.Arguments是第一级属性。

那怎么了解有哪些属性呢?加博主微信,博主给你文档。

版本是18.2,最新的是23,还算新吧。

Fortify规则教程3

那我怎么让他显示这个tree呢?

可以用

sourceanalyzer -cp "**/**.**" "**/**/*.java" -no-default-rules -rules 2.xml -scan -f fortify-example.fpr -D com.fortify.sca.MultithreadedAnalysis=true  -Ddebug.dump-structural-tree 2> tree-no-default-rule.tree


主要是这个-D参数,这个参数再官方手册上找不到,哪怕sourceanalyzer -h也看不到。。。

所以我们要改进一个sink,且这个sink的参数必须被用到@select的注解里,那就可以用

Fortify规则教程3

但是这里有一个问题,fortify好像对第三方的注解支持有问题,我并不能搜到ibatis的@select注解。

 

官方的20规则里,mybatis的注解sink 是一个由dataflow标签包裹的,里面的class package method均为.* ,即全部的方法。然后加了一个label。这个label是mybatis_mapper_label,这就像是加了一个taintflag一样,真正的处理逻辑的是一个js。。

Fortify规则教程3

 

Fortify规则教程3



在关键的地方会打上这个mybatis select query标记。然后dataflow的数据找到满足条件就会触发。

 

SuppressionRule

在fortify里,这个规则的作用是用来屏蔽你要的规则,

例如

Fortify规则教程3

这样的话,ruleID中的内容就不会再运行起来。这个规则对于10+M的原生规则来说是很有用的,因为我们不需要什么spring配置错误之类的一大堆的有的没的,很低危的漏洞。

 

其他有什么问题再群里说吧。顺便说一句上面的规则不仅限于java ,其他语言也适用


Fortify规则教程3


原文始发于微信公众号(xsser的博客):Fortify规则教程3

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: