php点击碰撞按钮弹出提示,文章详情-php hash碰撞攻击与防御(转)--廉鹏林个人博客...

php hash碰撞攻击与防御(转)

发布时间:2021-03-18 12:42:14阅读(583)

一、前言

hash碰撞攻击就是构造恶意的数据是hash表退化为链表,每次插入数据都会遍历链表,消耗大量服务器资源,从而达到攻击目的。php的数组就是利用hash表实现的,对于碰撞的数据,php采用双向链表解决方案,所以可以利用PHP的数组进行hash碰撞攻击。

二、模拟攻击

很多接口都采用json数据格式来传输,通常php都会使用php:input获得数据流,然后使用json_decode解析json数据。例如:$json = file_get_contents('php://input');

$arr = json_decode($json, true);

var_dump($arr);

这种很容易被人利用hash碰撞攻击,导致cpu资源被耗尽。

下面我们来看看构造65536个元素的正常数组和恶意数组所需要的时间:

创建一个test.php脚本,写入$size = pow(2, 16);

$arr = [];

$startTime = microtime(true);

for($i=0,$k=0; $i

$arr[$k] = 0;

}

$endTime = microtime(true);

echo "恶意插入{$size}个元素耗时 ", $endTime - $startTime, " s\n";

file_put_contents('./hash.json', json_encode($arr));

$arr = [];

$startTime = microtime(true);

for($i=0; $i

$arr[$i] = 0;

}

$endTime = microtime(true);

echo "正常插入{$size}个元素耗时 ", $endTime - $startTime, " s\n";

先用php5.6运行此脚本:

872019a24ad80bd3c194094b03d41e48.png

由上图可以看到耗时相差巨大。

下面再用php7运行此脚本:

6342d48a2d6b0dad401e97f12c5ad654.png

由上图可以看出php7比php5.6耗时短的多,这是由于php7优化了hash表的结构和算法,性能提升很多。但恶意插入还是比正常插入耗时长的多。

我们再写一个简单的接口,利用刚才生成的恶意的数据来模拟攻击,同时利用top命令看看系统资源消耗。

脚本:$json = file_get_contents('php://input');

$startTime = microtime(true);

$arr = json_decode($json, true);

$endTime = microtime(true);

echo "解析数据耗时 ", $endTime - $startTime, " s\n";

攻击前的系统资源占用情况:

6dffc3d0b9de041f06dbf5f87eee5e17.png

下面利用curl模拟攻击:

b6cbd7a04febce505132663416512c02.png

同时使用top命令查看:

c46cca2f32afd8094680f56e835ab5d2.png

可以看到cpu资源被耗尽,这还只是一条请求,如果使用ab压力测试,cpu资源会长时间被耗尽。

可以使用以下命令模拟:ab -n 1000 -c 100 -s 1000 -p './hash.json' http://127.0.0.1/test2.php

会发现cpu一直处于100%,要想停下来,只有重启php-fpm。service php-fpm restart

至于hash碰撞攻击的原理,网上很多,我就不详细说了,下面说说怎么防御。

三、hash碰撞攻击的防御

其实不光json_decode有这个问题,牵扯到数组的都会有这个问题。比如GET/POST/COOKIE,均有此问题。

GET/POST/COOKIE可以通过设置max_input_vars来解决。打开php.ini文件,找到此位置,修改其值,默认大小是1000。

67139aa2e374fbd33cba8873dddd1972.png

至于json_decode这个问题,通常都是在接口容易被攻击。

所以通常用以下方法解决:

1、加密传输数据,自家应用接口可以采用对称加密,因为加解密速度快。开放给第三方的接口可以使用非对称加密,虽然加解密速度没有对称加密快,但是更安全点。

2、使用$json = file_get_contents('php://input');获取数据后校验数据长度,根据业务特点规定最大长度,超过这个长度就报错。

3、也可以将接收到的数据转为json对象,而不转成数组。即json_decode()函数不要设置第二个参数为true

4、使用php7以上版本,php7相比于php5,性能提升非常多。

————————————————

版权声明:本文为CSDN博主「zhaoyang_1214」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/u014691098/article/details/84676753

标签:

php

如果对你有用打赏一下吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值