写这篇文章的目的一是由于目前网上关于java代码审计的资料实在是太少了,本人作为一个java代码审计的新手,深知学习java代码审计的难受之处,所以将自己学习过程中挖掘的一些漏洞写成博客发出来希望可以给后人一些帮助,同时也可以记录下自己的成长过程。目的二是由于这次挖掘的漏洞REDOS,个人觉得这个漏洞还是很有意思的,很早就知道这个漏洞了但是从来没有挖到过,终于在一个月前挖到了,很开心,记录一下。

先介绍下REDOS这个漏洞吧,可能很多人并不是很熟悉这个漏洞,一是由于这种漏洞造成的影响是拒绝服务,影响似乎不是很严重;二是这种漏洞一般需要通过白盒测试才能发现,通常的黑盒测试很难发现这种漏洞。

OWASP的对它的描述是:正则表达式拒绝服务(Regular expression Denial of Service-ReDoS)是一种拒绝服务攻击(Denial of Service),它利用了大多数正则表达式实现可能会导致极端情况的原因,这些极端情况导致它们工作得非常缓慢(与输入大小呈指数关系),然后攻击者可以使用正则表达式导致程序进入这些极端情况,然后挂起很长时间。

说白了就是,应用程序中经常会有使用正则表达式去匹配字符串的情况,(1)如果开发人员对正则表达式的原理并不是很熟悉写出了类似“^(a+)+$”这样的正则,(2)由于业务需求,正则是动态构造的,且受用户控制。这两种情况,程序都可能受到REDOS攻击。大家可能第一眼看到“^(a+)+$”不会觉得这个正则有什么问题,这里也就是为什么说要懂原理才行。因为这里其实涉及到了编译原理的知识,我尽量讲清楚:

正则表达式引擎分成两类,一类称为DFA(确定性有限状态自动机),另一类称为NFA(非确定性有限状态自动机)。两类引擎要顺利工作,都必须有一个正则式和一个文本串,一个捏在手里,一个吃下去。DFA捏着文本串去比较正则式,看到一个子正则式,就把可能的匹配串全标注出来,然后再看正则式的下一个部分,根据新的匹配结果更新标注。而NFA是捏着正则式去比文本,吃掉一个字符,就把它跟正则式比较,然后接着往下干。一旦不匹配,就把刚吃的这个字符吐出来,一个一个吐,直到回到上一次匹配的地方。也就是说对于同一个字符串中的每一个字符,DFA都只会去匹配一次,比较快,但特性较少,而NFA则会去匹配多次,速度相比会慢很多但是特性多啊,所以用NFA作为正则表达式引擎的会多些。现在我们再来看^(a+)+$,大家应该能看出些问题了,当我们用它去匹配“aaaax”这个字符串时,他需要尝试2^4=16次才会失败,当我们这个字符串再长一点时,需要尝试的次数会成指数增长,aaaaaaaaaaX就要经历2^10=1024次尝试。

如下图:

可以看到java、php、python都是用的NFA(JS中好像也是),也就是说这些语言中用了正则的api都是可能存在问题的哦。比如java中比较常见的split,replaceAll等,这些方法中既可以接受字符串也可以接受正则表达式的。

说了这么多,准备进入正题吧,为什么一个月前就发现漏洞了,现在才写博客呢,本来是想等作者修复漏洞后再写博客的,但是因为github上的作者到现在都没有回复我,似乎并不准备修复,而我也懒得等了,直接将漏洞披露出来吧,毕竟漏洞影响不大,并且漏洞和程序上下文的联系也不大,复现的时候只需要将缺陷代码单独拿出来在本地复现即可。

这整个java文件是将文件转化为pdf格式的一个工具类,在转化文件格式的同时还需要 将文件名的后缀也修改下。如上两个方法就是用来修改文件名后缀的。getOutputFilePath(String inputFilePath)用于将文件名的后缀修改为.pdf,而文件名后缀是通过getPostfix(String inputFilePath)这一方法截断文件名中最后一个.后面的内容来获取的。简单介绍下String.replaceAll(a,b)的意思就是将String中的字符串a全部替换成字符串b。比如说”aabbcc”.replaceAll(“a”,”b”),输出结果为“bbbbcc”,上面也说了a可以是正则表达式 当”aabbcc”.replaceAll(“(a)+”,”b”),输出结果为“fbbcc”。再回过头看代码,如果我们已知参数inputFilePath是可控的,怎样设置这个值才能触发REDOS攻击呢?

首先参数inputFilePath的后缀必须控制成一个真正表达式的样,我们可以先设置为.(a+)+,而.(a+)+作为正则表达式去匹配inputFilePath时,inputFilePath的前半部分必须符合这个正则才不至于匹配没开始就结束了,所以inputFilePath的前半部分也应该类似.aaaa这样,再和后缀拼凑起来就是.aaa.(a+)+

Ok,本地搭建环境测试一下:

发现程序运行的很快,关键是成功替换了字符串。回顾之前的说的,之所以能造成REDOS攻击是因为一直匹配失败,引擎才会反复尝试导致攻击的。怎样让他匹配失败呢又一直尝试呢?只需要将后缀.(a+)+改为.(a+)+$。这个正则的意思就是字符串必须以a结尾才行。修改之后重新运行:

发现虽然运行很快但是不会替换字符串了,也就是说匹配失败。

那我们再将inputFilePath改下,让程序匹配的时间长一些,如下图:

发现程序一直在运行,说明攻击成功了。

总结一下,挖掘REDOS漏洞,一是需要对程序中用到了正则的api有些了解(replaceAll只是最为常见的,其实还有很多),后面有时间的话我也会对这些api做些整理;二是要对正则有一定的了解才方便构造poc。

如何通过代码审计挖掘REDos漏洞的更多相关文章

  1. PHP代码审计6-实战漏洞挖掘-xdcms用户注册页面漏洞

    xdcms 源码:xdcms v2.0.8 1.配置 [一直下一步(仅为测试)] #数据库账号root,密码为空:管理员账号/密码:xdcms/xdcms #登录后台 2.查看后台登录页面的配置项[x ...

  2. PHP代码审计5-实战漏洞挖掘-cms后台登录绕过

    cms后台登录绕过 练习源码:[来源:源码下载](数据库配置信息有误,interesting) 注:需进行安装 1.创建数据库 2.设置账号密码,连接数据库 3.1 正常登录后台,抓包分析数据提交位置 ...

  3. 学习CSRF漏洞并挖掘CSRF漏洞

    什么是跨站请求伪造? 跨站请求伪造(英语:Cross-siterequest forgery),也被称为one-clickattack或者session riding,通常缩写为CSRF或者XSRF, ...

  4. Java Web代码审计流程与漏洞函数

    常见框架与组合 常见框架 Struts2 SpringMVC Spring Boot 框架执行流程 View层:视图层 Controller层:表现层 Service层:业务层 Dom层:持久层 常见 ...

  5. 2020/1/30 PHP代码审计之CSRF漏洞

    0x00 CSRF漏洞 CSRF(Cross-site request forgery)跨站请求伪造:也被称为"One Click Attack"或者Session Riding, ...

  6. 2020/1/29 PHP代码审计之XSS漏洞

    0x00 XSS漏洞简介 人们经常将跨站脚本攻击(Cross Site Scripting)缩写为CSS,但这会与层叠样式表(Cascading Style Sheets,CSS)的缩写混淆.因此,有 ...

  7. 代码审计之DocCms漏洞分析

    0x01 前言 DocCms[音译:稻壳Cms] ,定位于为企业.站长.开发者.网络公司.VI策划设计公司.SEO推广营销公司.网站初学者等用户 量身打造的一款全新企业建站.内容管理系统,服务于企业品 ...

  8. PHP代码审计笔记--CSRF漏洞

    0x01 前言 CSRF(Cross-site request forgery)跨站请求伪造.攻击者盗用了你的身份,以你的名义向第三方网站发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻 ...

  9. [代码审计]php反序列化漏洞

    0x01 php面向对象简介 对象:可以对其做事情的一些东西.一个对象有状态.行为和标识三种属性. 类:一个共享相同结构和行为的对象的集合. 每个类的定义都以关键字class开头,后面跟着类的名字. ...

随机推荐

  1. 【GMT43智能液晶模块】例程十三:FATFS实验——文件操作

    实验原理: STM32F429上带有SDIO控制器,GMT43液晶模块上将SDIO连接到TF卡座.本实验 将Micro SD卡插入TF卡座上即可.通过FATFS创建test.txt文件,并且写入数据0 ...

  2. 【iCore4 双核心板_ARM】例程三十二:UART_IAP_ARM实验——更新升级STM32

    实验现象及操作说明: 1.本例程共有两个代码包,APP和IAP,IAP程序功能实现将APP程序升级至STM32中. 2.直接上电或烧写程序将执行升级的APP应用程序. BIN升级文件产生方法: 1.编 ...

  3. modelsim如何使用tcl脚本来写编译文件

    对于modelsim进行仿真,可以通过GUI来进行仿真,当然更加快速的方法可以使用TCL脚本文件进行快速仿真. Modelsim采用TCL脚本文件仿真的具体流程如下所示:      具体的操作步骤如下 ...

  4. tensorflow c/c++库使用方法

    tensorflow目前支持最好的语言还是python,但大部分服务都用C++ or Java开发,一般采用动态链接库(.so)方式调用算法,因此tensorflow的c/c++ API还是有必要熟悉 ...

  5. 最全36种python设计模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用.设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案.这些解决方案是众多软件开发人员经过 ...

  6. mysql关联表修改语句

    UPDATE tb_irms_trans_pip2optseg a,`tb_irms_trans_pip` b SET a.district=b.district WHERE a.prop_id=b. ...

  7. login流程

    DirServer增加,修改-后台网页操作 维护所有分区的当前信息创建,修改,上报分区信息分区:状态,版本号,注册量等 一.loginserver定时从dir同步所有区服的信息 登陆相关 1.CmdI ...

  8. Factory——工厂方法

    一.定义 GOF上对工厂方法的意图如此描述:定义一个用于创建对象的接口,让子类决定实例化哪个类.Factory Method使一个类的实例化延迟到其子类. 作为类的开发者,我们通常会在类中提供构造器方 ...

  9. php代码画足球场

    用代码画了个足球场 原图: 代码画出的效果图: 代码如下: // 创建一个 200X200 的图像 $img = imagecreate(800, 500); // 分配颜色 $bg = imagec ...

  10. 萌新 学习 vuex

    vuex官网文档 https://vuex.vuejs.org/zh-cn/ 注: Mutation事件使用commit触发, Actions事件使用dispatch触发 安装 npm install ...