基于Checkmarx对某CMS系统SQL注入漏洞的实践

发布时间: 2020-02-18      作者:并擎科技

前几天拜读了W12信息安全实验室的《漏洞预警到审计复现的入门案例》一文,看到安服团队的同学对CNVD漏洞预警中提到的某CMS系统做了SQL注入漏洞的重现,应用安全团队的小伙伴们也跃跃欲试,当然我们使用的是更熟悉也更擅长的Checkmarx CxSAST白盒代码审计工具。

       下载了存在漏洞的CMS版本的源代码后,为了提高效率,我们将与预警漏洞不相关的代码移除,并且只使用SQL注入的相关规则,在Checkmarx CxSAST中进行了扫描。然而得到的结果居然是:


       看来是漏报了这个SQL注入问题,这个结果可谓是意料之外、情理之中,毕竟白盒工具多多少少总会存在一定的误报和漏报。但是这个难不倒我们应用安全团队的小伙伴们,毕竟Checkmarx CxSAST作为一款国际上率先的代码审计安全产品,提供了强大的自定义规则工具来应对误报和漏报问题。

 

TipsCxSAST提供了大量预定义的查询规则,用于在源代码中使用每种编程语言的标准代码库来识别已知的安全漏洞。但是,如果待扫描的代码项目包含专有或深奥的框架,那么CxSAST可能不能识别所有的漏洞,或者可能产生误报。此时可以使用CxAudit“教授”CxSAST的查询如何识别这些元素。

 

       首先我们还是来分析代码的逻辑,从安服团队同学的重现过程中,我们看到可攻击的入口包括control_ajaxeditinfo()这个方法中传的nickname参数,继续跟踪分析该参数在代码中的传递过程,执行数据库更新的动作是调用父类的model方法得到的某个model类中的saveinfo方法。通过几次诸如此类的跟踪溯源,发现了实际执行数据库交互的位置,为mysqlClass中的query方法:


 

         由于Checkmarx CxSAST是基于数据流分析的,我们先分别查看是否能找到攻击的发起点、攻击的结束点,以及它们之间是否存在完整的数据流。

 

TipsCxSAST 是基于数据流来分析代码的安全漏洞的。以SQL注入为例,若从外部可传入参数的代码位置到执行数据库交互的代码位置之间,存在着一条完整的数据流,并且中间没有经过任何过滤的手段,这条数据流就会被认为存在SQL注入安全漏洞。

 

       攻击的发起点为可传入参数nicknamerequest请求,这个用Checkmarx CxSAST默认的规则即可找到;而攻击的结束点,即执行数据库交互的query方法,却未能被默认规则查找到。再进一步验证,发现从request请求,到query方法中的func()方法,实际上存在了完整可达的数据流。那么我们需要做的事情就很明确了,只需要“告诉”CxSAST,代码中的query方法或者func方法也属于SQL注入攻击的结束点。

       接下来看一下Checkmarx CxSAST默认的规则是如何查找SQL注入攻击的结束点的。意外发现,CMS代码中的func函数实际对应的“mysql_unbuffered_query“

mysqli_query“在默认规则里其实是有提到的:


         那么为何CMS代码中的没有识别呢?其原因也很简单,因为在CMS代码中,这两个方法是作为字符串的形式,通过三目运算符的形式赋值给func,之后在下一句里执行该方法来实现的。而Checkmarx CxSAST在进行规则匹配时,对这两个方法做了“methods”的限定,也就是必须作为实际方法存在,而非字符串形式存在的mysql_unbuffered_querymysqli_query才能被默认规则查询到。

 

TipsCxSAST查询代码元素时,不仅仅是简单的关键字匹配,也会涉及到目标代码元素的类型、位置、相互关系等,可以根据实际的需求更精确地定位到相关代码元素。

 

       既然如此,那我们只需要将mysql_unbuffered_querymysqli_queryfunc方法关联起来即可,经过一系列调试,通过重载并复写SQL注入规则中的Find_DB_In()方法,调用了CxQL提供的几个API,实现如下:


       将规则进行保存,再次扫描,成功发现SQL注入的安全问题:


       总计找到30SQL注入漏洞,展开图形模式后看到:


       Checkmarx CxSAST贴心的为我们指明了较佳修复位置(红色方块),即是说,我们只要在query方法处做统一的过滤即可,而不必对每一个可能出现潜在漏洞的输入点做过滤。

 

TipsCxSAST提供的较佳修复建议位置,可以极大的提高安全问题处理效率,节约漏洞的修复成本。

 

       至此本次实践的目的已经达到。当然我们的探索并不限于此,基于Checkmarx CxSAST提供的非常灵活的自定义化规则功能,我们也可以继续尝试用其他方式来完成规则的优化。例如在本例中,代码实现了mysqlClass类,实现了对数据库连接、交互方法的封装,如果该封装方法能够在企业的其他代码中作为一个通用手段,我们完全也可以基于此来定制一份企业专用的规则,如下所示:


 

       使用该规则,同样能找到存在的SQL注入漏洞。

 

TipsCxSAST可以根据企业的代码风格,制定属于企业特有的规则,查找需要的代码安全、质量问题。