美文网首页
Codeql进阶源码分析之Java代码漏扫模块1.1(XXE漏洞

Codeql进阶源码分析之Java代码漏扫模块1.1(XXE漏洞

作者: Billie_f310 | 来源:发表于2022-08-30 15:35 被阅读0次

     写在最前面

         在看这一坨的时候,你首先要具备2个要素,第一你知道这个漏洞是如何产生和如何规避。第二这一系列的分析都是都是基于官方的dll库分析,前提是你已经了解了Codeql的语法,以及如何运行和部署此框架!在分析的过程中,会有部分语法的讲解但好像几乎没有,所以必须基于你已经学过了解的基础上去看这个文章。如果你上来就看,我觉得很难看懂,因为这些语法跟所有你学过的语言都有点差别。

    we need freedom

       Codeql作为发现log4j漏洞的安全漏扫框架而红爆全球。但是学习成本极高,人尽皆知,他的扫描库的代码扩展还是很麻烦的,虽然开发的人员可以编写自己的扫描规则或者用别人集成好的dll库扫描,但是语法确实在白盒漏扫框架中算很难。学了那么久 总体来说我觉得Codeql还是趋向于特征函数扫描吧,或者他的优势是生成污染链根据语义搜索查询??不过有很多种情况需要考虑,我觉得有时候还是很鸡肋,但是比自己手动搜索又要方便的很多。今天给带来的是java扫描模块的,XXE漏洞模块的分析。多学点东西总会有点好处吧。

    (PS:此系列的文章是希望帮助大家了解漏洞产生的原理,而不是天天拿个工具扫别人的接口,对于我自己来说也是温故知新,网上很多大牛用codeql找jndi找ldap等稍微看起来高阶漏洞,需要的知识点还是很多的,而且一般人的基础水平上来就搞,也是一知半解,所以我觉得对于初学者来说还是不是很友好的,毕竟在常规工作生活中我们遇到的普通业务漏洞是最多的。)

    什么是XXE漏洞?

       XXE外部实体执行漏洞,从安全角度来讲,由此引发的漏洞称之为XML外部实体攻击,XML作为一种使用较为广泛的数据传输格式,很多应用程序都包含有处理xml数据的代码,许多过时或配置不当的XML处理器都会对外部实体进行引用,如果攻击者可以上传XML文档或者在XML文档,中添加恶意内容,通过易受攻击的代码,就能够攻击包含缺陷的XML处理器,XXE漏洞的出现和开发语言无关,只要是应用程序中对XML数据做了解析,而且这些数据又受用户控制,那么应用程序都可能受到XXE攻击。包括代码中如何防止XXE,网上也有很多案列,更具体可以去百度。不做更详细的分析。

    如何规避XXE漏洞?

     配置一系列的参数,自行百度,下面我也有说。或者参考

    XML External Entity Prevention - OWASP Cheat Sheet Series


    CodQl的扫描检测XXEl漏洞模块分析

         这里就不会再说CodeQl的语法或者安装配置教程,直接上图,XXE漏洞的扫描规则是放在,java下的CWE-601编号目录下,这个编号代表此漏洞的官方标号,我们分析XXE.ql样本的写法,打开后如下图1.1.1扫描入口所示,白字 “第一步”可以看到Sink和Source链的写法,isSource作为方法入口点使用了默认的RemoteFlourResource这个类已经完善的很多了,包括Java的@RequestParam @RequestBody等入口写法,所以没必要重写此方法。所以我们的视线是放在IsSink方法里,也就是污染点方法分析。

         如白字“第二步”所示isSink继承了unsafeXxeSink,这个是扩展的dll库的方法,包含了很多代码的规则分析。所以是我们主要看的。他的实现方式很简单包含3个模块,第一个是不存在留到这个sink点的安全检测(not exist),他的意思就是判断是否有安全方法参与这个xml的读取,如果没有说明有戏。第二个exist你可以看到XmlParserCall我们通过名字也能看到他可能就是一些xml读取的调用方法,也就是存在这些xml读取的方法,如果没有这些方法,这个xxe 漏洞也不能存在,具体下面分析。

    1.1.1扫描入口

    进一步深入,我们先看下上面提出白字第二步中SafeSaxSourceFlowConfig具体实现,如下图1.1.2所示,我门可以看到,其实她又是一个source和sink流。如下图第三步所示,SafeSaxSource是目前方法的source她又自己定义了一个实现方法,目前的sink点我们看到他又用一个类校验了一下,其实就是上个图的sink穿进去的。

    1.1.2 SafeSaxSourceFlowConfig

    进一步深入,我们在看下SafaSaxSource是如何对source进行处理的,如下图1.1.3所示我们发现,他对这个source的处理还是很复杂的,仔细看一下,确实还是很复杂。白字第五步的意思就是找到,类似 xxx.do(value)这种类型的写法,但是xxx我们不能随便找啊,所以他又规定了一个SaxSourceSetReader来限制我们的搜索范围,就像第六步所示他就是为了找到SAXSource.SetXMLReader()注释也写的很清楚了,这种写法。

    1.1.3 SafeSaxSource

    然后我们进入第七步去看看,如下图所示,1.1.4 CreatedSafeXmlReader,红色指针指的东西 。你们可以看到这些东西是为SAXSource.SetXMLReader()用的。类似SAXSource.SetXMLReader(getXmlReader()),这种写法,那些红色指针的地方你们可以看到,都有getXmLreader()这个方法,如果你们不了解。你们可以自己找下这种写法。之所以这么谢是我们并不能保证从源头来的数据到getXmLReader()这个方法是安全的,所以他又用SafeSaxParseFlowConfig 去检查,SafeSaxReaderFlowConfig下,这明显又是2个污染连的判断

    1.1.4CreatedSafeXmlReader

    进一步分析,如果1.1.5,看下SafeSaxParseFlowConfig是什么,很明显,他又是一个污染链,第十步 的source来与于第十一步的实现 。十一步他又限制了这个source的来源,及这个source必须要来源于。SaxParserFactory并且用到的方法是newSaxParser()。好了如果你懂java的xxe写法,那么你明显可以知道 XMLReader xmlReader = saxParserFactory.newSAXParser() 这种写法。这也就是调用getXmLreader()的前一步。

    1.1.5SafeSaxParseFlowConfig

    第十二步的时候我们有看到他用SafeSaxParserFactorytoNewSaxParserFlowConfig做了一个污染链检查,他应该是为了找到 XMLReader xmlReader = saxParserFactory.newSAXParser() 的saxParserFactory是否来自于安全的配置, 我们点进去看如下图所示1.1.6果然又是一个污染链,sink我们不用看了,他的目的就是检测从数据源到sink点newSAXParser()  之间的路程,或者可以说newSAXParser是否来自于安全的saxParserFactory。这个所以我们在点进第十三步看看SafeSaxParserFactory是啥。

    1.1.6SafeSaxParserFactorytoNewSaxParserFlowConfig

    如下图1.1.7所示。就很明了如果你了解安全的saxParserFactory的写法你可以知道。

    factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); factory.setFeature("http://xml.org/sax/features/external-general-entities", false); factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);

    这种写法是可以防止一些xxe的注入具体的话你们可以了解查询下。他的目的就是为了验证这个

    1.1.7SafeSaxParserFactory

    好的,让我们在回头看1.1.3 ,从图片1.1.4到图片1.1.7我们深入讲的是1.1.3图中第七步中的CreatedSafeXmlReader扩展。然而1.1.3图中还有第八步的一个约束及ExplicitlySafeXmlReader这个方法。如下图1.1.8所示很清晰了。

    SAXReader reader = new SAXReader();

    reader.setFeature(DDD,true);

    reader.setFeature(“http://xml.org/sax/features/external-general-entities“, false);

    reader.setFeature(“http://xml.org/sax/features/external-parameter-entities“, false);

    类似这种写法,他对reader多的安全范围也做了限制。保证reader的安全。

    1.1.8ExplicitlySafeXmlReader

    好的,让我们在回头看1.1.3 的第九步,她又是一个约束ConstructedSaxSource.issafe()。其实这个就很好理解了。其实我们之前做的那些步骤都是为了SAXSource.SetXMLReader(getXmlReader())给他服务的,但是还有种写法是  new SAXSource(XMLReader reader, InputSource inputSource) 也就是直接用构造方法的形式把Xmlreader穿进去 ,所以如下图所示1.1.9,就是为了检查这个的,检查的手法和我们上面说的也差不多。自行阅读。

    1.1.9ConstructedSaxSource

      好了,我们分析完了上面的一大坨,他们都是属于最初1.1.1中说的SafeSaxSourceFlowConfig这个里面的实现手法,也就是说,这个dll库的作者认为如果你懂的代码按照他这个规则写Xml读取,那么就是安全的。在1.1.1图中exist函数前面加了 not exist (SafeSaxSourceFlowConfig),就是取反,也就是危险代码,我们codeql不就是为了找危险代码么?

      好了,上面的一大坨都是判断xml读取的安全写法,再让我们回到1.1.1的第二步还有一句不显眼的方法,那就是not parse.issafe(),我们进去再看看。如下图1.1.10所示,是个抽象方法,没错我们去找他的实现

    1.1.10XmlParserCall

    好了,我们去看看这个XmlParserCall里的issafe到底实现了啥。在xmlParsers.qll中搜索XmlParserCall,我们发现XmlParserCall有18处实现方法,显然这个库的搜索范围还是挺狠的,所以我只挑一种分析,我们看下图1.1.11,可以看到第14步是issafe方法,他是一个链条写法。先看第15步他限制的条件是saxBuilder其实里面就是SAXBuilder这个方法体,我们知道SaxBuilder也可以操作XML,第16步其实他检测了一下builder是不是配置安全。

    SAXBuilder builder = new SAXBuilder();

    builder.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);

    builder.setFeature("http://xml.org/sax/features/external-general-entities", false);

    builder.setFeature("http://xml.org/sax/features/external-parameter-entities", false);

    builder.setExpandEntities(false);

    Document doc = builder.build(new File(fileName));

    没错就像我上面说的一样。这种写法才是saxbuilder的安全写法。

    1.1.11XmlParserCall其中的一个实现方法

    XXE漏洞扫描dll库的作者思路

    好了我们看了一大坨,我下面用伪代码来描述一下他的思路。

    main(){

    if(!SafeSaxSourceFlowConfig()&&!parse.isSafe){

    //有漏洞给予提示

        }

    }

    public SafeSaxSourceFlowConfig(){//安全检查写法

    检查第一种://写法

    SAXSource saxSource=new SAXSource(XXX输入流)

     checkXMLReaderFactory() //是否有安全配置的Factory

    checkgetXMLReader();//是否有安全配置的Xmlreader

    XMLReader saxReader = XMLReaderFactory.createXMLReader(xxx);

    //由安全的factory配置出安全的reader

     saxSource.setXMLReader(saxReader);//塞入xmlReader

    检查第二种写法 ://

    SAXSource saxSource= new SAXSource(XMLReader reader, InputSource inputSource);//

    //构造体直接初始化reader的写法。检测这种写法的安全性

    }

    public parse.isSafe(){//检查各种写法的和Xml有关函数调用的安全性

    checkSaxBuilder()//如果有saxbuilder的写法检测相关安全配置

    checkcreateXMLEventReader();//如果有createXMLEventReader使用,检查安全性

    ;共18种特征检查。此处省略部分检查方法

    具体特征检查参考XML External Entity Prevention - OWASP Cheat Sheet Series

    }

    总结

    我觉得从头顺一遍可以感觉到这个dll写的还是很完美的,考虑到了很多写法不仅包括特征函数,还有各种流的分析。如果我把所有的可能分析一遍可能要写很多篇文章,但是最难最绕的sink source我已经写出来了。这只是我的理解,如果你不仔细看的话,可能确实有点绕。

    预告

    如果来自现实的项目中 ,我觉还是有很多东西可以绕过这个检测规则的,虽然他考虑的很完美,但在后期我会写一下漏网之鱼。但是总而言之这个XXE.dll真的很强了。佩服佩服!我很久没写博客了,也没什么粉丝,Codeql的资料非常的少,也有很多人不愿意分享出来。Codeql确实很强不得不服!

    相关文章

      网友评论

          本文标题:Codeql进阶源码分析之Java代码漏扫模块1.1(XXE漏洞

          本文链接:https://www.haomeiwen.com/subject/ycrfnrtx.html