如何通过代码审计挖掘REDos漏洞
写这篇文章的目的一是由于目前网上关于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漏洞的更多相关文章
- PHP代码审计6-实战漏洞挖掘-xdcms用户注册页面漏洞
xdcms 源码:xdcms v2.0.8 1.配置 [一直下一步(仅为测试)] #数据库账号root,密码为空:管理员账号/密码:xdcms/xdcms #登录后台 2.查看后台登录页面的配置项[x ...
- PHP代码审计5-实战漏洞挖掘-cms后台登录绕过
cms后台登录绕过 练习源码:[来源:源码下载](数据库配置信息有误,interesting) 注:需进行安装 1.创建数据库 2.设置账号密码,连接数据库 3.1 正常登录后台,抓包分析数据提交位置 ...
- 学习CSRF漏洞并挖掘CSRF漏洞
什么是跨站请求伪造? 跨站请求伪造(英语:Cross-siterequest forgery),也被称为one-clickattack或者session riding,通常缩写为CSRF或者XSRF, ...
- Java Web代码审计流程与漏洞函数
常见框架与组合 常见框架 Struts2 SpringMVC Spring Boot 框架执行流程 View层:视图层 Controller层:表现层 Service层:业务层 Dom层:持久层 常见 ...
- 2020/1/30 PHP代码审计之CSRF漏洞
0x00 CSRF漏洞 CSRF(Cross-site request forgery)跨站请求伪造:也被称为"One Click Attack"或者Session Riding, ...
- 2020/1/29 PHP代码审计之XSS漏洞
0x00 XSS漏洞简介 人们经常将跨站脚本攻击(Cross Site Scripting)缩写为CSS,但这会与层叠样式表(Cascading Style Sheets,CSS)的缩写混淆.因此,有 ...
- 代码审计之DocCms漏洞分析
0x01 前言 DocCms[音译:稻壳Cms] ,定位于为企业.站长.开发者.网络公司.VI策划设计公司.SEO推广营销公司.网站初学者等用户 量身打造的一款全新企业建站.内容管理系统,服务于企业品 ...
- PHP代码审计笔记--CSRF漏洞
0x01 前言 CSRF(Cross-site request forgery)跨站请求伪造.攻击者盗用了你的身份,以你的名义向第三方网站发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻 ...
- [代码审计]php反序列化漏洞
0x01 php面向对象简介 对象:可以对其做事情的一些东西.一个对象有状态.行为和标识三种属性. 类:一个共享相同结构和行为的对象的集合. 每个类的定义都以关键字class开头,后面跟着类的名字. ...
随机推荐
- 看雪CTF第十题
__int64 sub_140006F50() { __int64 v0; // r8@1 __int64 v1; // r9@1 signed __int64 len; // rax@1 __int ...
- 每天学点Linux-选取命令CUT和GREP
选取命令就是将一段数据经过分析后,取出我们所想要的.或者是经由分析关键词,取得我们所想要的那一行!一般来说,选取命令通常是针对一行一行的数据来进行分析的, 并不是整篇信息分析.cut cut命令可以将 ...
- 一文弄懂神经网络中的反向传播法(Backpropagation algorithm)
最近在看深度学习的东西,一开始看的吴恩达的UFLDL教程,有中文版就直接看了,后来发现有些地方总是不是很明确,又去看英文版,然后又找了些资料看,才发现,中文版的译者在翻译的时候会对省略的公式推导过程进 ...
- Linux操作系统配置Go语言编程环境
之前一直在windows下写Go,现在工作环境切换至Linux下,因此写下此文,记录安装Go环境的过程. 操作系统:CentOS7.5 一.安装步骤 1,下载Go语言安装包 yum install g ...
- 在 windows 上安装免安装版的mysql
在 windows 上安装免安装版的 1. 下载路径 https://downloads.mysql.com/archives/community/ 2. 解压 假设解压后的路径为:E:\Enviro ...
- pointcut 切面表达式 切入点表达式
下面给出一些常见切入点表达式的例子. 任意公共方法的执行: execution(public * *(..)) 任何一个以“set”开始的方法的执行: execution(* set*(..)) Ac ...
- 如何查看MySQL单个数据库或者表的大小
总体来说,这些信息存在于information_schema数据库的TABLES表中 mysql> desc information_schema.TABLES; +-------------- ...
- poj3723_Conscription
Conscription Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12393 Accepted: 4350 Des ...
- Linux 的基本操作(系统的安装)
操作系统的安装: 操作系统的安装 这次安装系统也是基于CentOS的安装.把光盘插入光驱,设置bios光驱启动.进入光盘的欢迎界面. 其中有两个选项,可以直接按回车,也可以在当前界面下输入 linux ...
- CAutolock
顾名思义CAutolock就是自动锁的意思,它可以把它之下的代码区锁住一直到其自身被释放掉 后这块代码区中的公共资源才会被其他线程使用.当然这个代码区能尽量少就尽量少,毕竟不能让其他线 程 ...