这是迄今为止第一个让我觉得后怕的攻击方式,涉及的范围广难以防御,攻击效果立竿见影。大量的网站和web接口都未做hash碰撞攻击的防御,一拿一个准。
随着restful风格的接口普及,程序员默认都会使用json作为数据传递的方式。json格式的数据冗余少,兼容性高,从提出到现在已被广泛的使用,可以说成为了web的一种标准。无论我们服务端使用什么语言,我们拿到json格式的数据之后都需要做jsondecode(),将json串转换为json对象,而对象默认会存储于hash table,而hash table很容易被碰撞攻击。我只要将攻击数据放在json中,服务端程序在做jsondecode()时必定中招,中招后cpu会立刻飙升至100%。16核的cpu,16个请求就能达到dos的目的。
所有测试程序都在mac pro下进行,为了测试方便我只构造了65536条json键值对,真正发起攻击时可以构造数十万甚至百万千万的数据。
攻击数据我已经转换为json格式
<a href="https://raw.githubusercontent.com/laynefyc/php_thread_demo/master/hash.json">hash攻击json数据</a>
<a href="https://raw.githubusercontent.com/laynefyc/php_thread_demo/master/hashnomal.json">普通json数据</a>
<a href="https://raw.githubusercontent.com/laynefyc/php_thread_demo/master/javahash.json">java版本hash攻击数据</a>
一. javascript测试
我们只需要在js中输入一行代码就能看到效果,普通数据和hash攻击数据都是65536行键值对。我本地测试的效果如下:
通过chrome自带的任务管理器可以看出cpu马上升到100%,将近1分钟才执行完成,而普通的数据几毫秒就能执行完成;
二. php测试
php中我们通过file_get_contents远程去拿数据,运行对比一下时间,相差10多秒,php-fpm单进程占用cpu 100%。
三. java测试
四. 其他语言还在研究中……
hashtable是很通用的数据结构,数据结构与算法上专门有一节课来说它,所以hash collision是普遍存在的,各语言在实现上只是散列算法和table存储上有细微差别。
为了验证java的hash碰撞攻击也生效,我整个端午假期都在看java hashtable相关的文章,经过努力最后还是成功的生成了攻击数据。过程非常不简单,这也验证了一个思想--所有高个上的东西最后分解出来都是基础的数据结构知识。
几年前php的版本还是5.2,我们可以把所有的hash key都放在post请求的body中,比如:
<a href="https://www.test.com/create-account">https://www.test.com/create-account</a> post data: k1=0&k2=0&k3=0...k999998=0&k999999=0
服务端拿到数据后会将所有参数存储到hash table($_post)中,通过这种方式能很方便的实现攻击。但是现在这种方式行不通了,因为我们很容易就能在nginx层和php层限制http请求的参数个数和大小。php默认只允许1000个参数,这个量级对服务器完全没影响。
现在是2017年,json格式和restful风格的接口已经非常流行。带给我们便捷编码的同时,也给hash collision dos提供了新的方式。现在很多restful风格的接口如下:
<a href="https://www.test.com/v1">https://www.test.com/v1</a> data: {"action":"create-account","data":""}
如上接口,我们直接把攻击的数据放入data参数中,服务端接收到数据后肯定会做jsondecode(),很方便的就达到了攻击的目的。
要想防御hash collision dos攻击,行业内已经有很多成熟的方案了,不过都是建议换语言或者重写hashtable。这里只说当前json格式解析的问题。首先我们需要增加权限验证,最大可能的在jsondecode()之前把非法用户拒绝。其次在jsondecode()之前做数据大小与参数白名单验证。旧项目的改造与维护成本如果很高,建议自己重写jsondecode()方法。
写了这么多,其实最有乐趣的地方还是如何生成攻击数据。之后我会详细的写这部分。最后,golang和python能躲过hash collision dos测试吗?敬请期待