“心脏出血”(Heartbleed)被称为互联网史上最严重的安全漏洞之一,波及了大量常用网站、服务,包括很多人每天都在用的 Gmail 等等,可能导致用户的密码、信用卡轻易泄露。但是我们可能对它还不是很了解,可能觉得,这不关我事。

我随便找了个规模还算比较大的网站(域名就不说了),然后在调试器里看看返回信息:

 

可以看到,这个网站的服务器也用了OpenSSL。其实 OpenSSL 的使用率还是挺高的,如果你经常上网,那么可以说,你几乎每天都在跟 OpenSSL 打交道,你的各种个人信息存储在各种各样的网站上,一旦某个网站因为 Heartbleed 泄漏了你的重要信息,比如信用卡,银行卡什么的,那么可能你就会因此有所损失。

好奇的人们或许更想知道OpenSSL的程序员到底犯了什么错误,好在有 xkcd 这样的geek网站,用最最通俗易懂的方式,向大家展示了这个漏洞的原理:

 

正好煎蛋那边有翻译:

 

所谓heartbleed的说法,源自于「心跳检测」,就是用户发通过起TSL 加密链接,发起 Client Hello询问,测服务器是否正常在线干活(形象的比喻就是心脏脉搏),服务器发回Server hello,表明正常建立SSL通信。每次询问都会附加一个询问的字符长度pad length,bug来了,如果这个pad length大于实际的长度,服务器还是会返回同样规模的字符信息,于是造成了内存里信息的越界访问……

漫画里,用户meg请求返回 “HAT 五百个字母”,然后色服器返回了内存中包括HAT之后的前500个字,也就是说伺服器将 “五百个字母” 这句话理解为了 显示500个字母 然后将其他人在同时伺服器里操作的前500个字母返回给meg看,而这里面包含很多私密信息。

看起来这个内存泄露越界BUG很2吗?

那么在代码层面再看看?假设心跳信息结构体定义为:

struct hb {
int type;
int length;
unsigned char *data;
};

type为心跳的类型,length为data的大小,其中关于data字段的内容结构为:

type字段占一个字节,payload字段占两个字节,其余的为payload的具体内容,详情如下所示:

字节序号 备注
0 type
1-2 data中具体的内容的大小为payload
3-len 具体的内容pl

当服务器收到消息后,会对该消息进行解析,也就是对data中的字符串进行解析,通过解析第0位得到type,第1-2位得到payload,接着申请(1+2+payload)大小的内存,然后再将相应的数据拷贝到该新申请的内存中。

以下举个简单的示例来说明该问题,假如客户端发送的data数据为"006abcdef",那么服务器端解析可以得到type=0, payload=06, pl='abcdef',申请(1+2+6=9)大小的内存,然后再将type, payload, pl写到新申请的内存中。

如果大家都是老实人,那么上述流程不会出现任何问题。可是世界上总是存在着那么多不“安分”的人,他们会非常的不诚实,比如客户端发送的字符串“abcdef”明明只有6个,而我非得把payload设置为500,如果服务器傻不拉几的不做任何边界检查,直接申请(1+2+500)大小内存,而且更过分的是还把"abcdef********"所有的内容拷贝到新申请的内存处,并发回给客户端。

这样那些不安分的人就获得了服务器上很多非常敏感的信息,这些信息可能包括银行帐号信息,电子交易信息等等诸多安全信息。

当然真实的结构体定义是这样的:

typedef struct ssl3_record_st
{
int type; /* type of record */
unsigned int length; /* How many bytes available */
unsigned int off; /* read/write offset into 'buf' */
unsigned char *data; /* pointer to the record data */
unsigned char *input; /* where the decode bytes are */
unsigned char *comp; /* only used with decompression - malloc()ed */
unsigned long epoch; /* epoch number, needed by DTLS1 */
unsigned char seq_num[8]; /* sequence number, needed by DTLS1 */
} SSL3_RECORD;

每条SSLv3记录中包含一个类型域(type)、一个长度域(length)和一个指向记录数据的指针(data)。

在 dtls1_process_heartbeat 里有这样的语句:

/* Read type and payload length first */
hbtype = *p++;
n2s(p, payload);
pl = p;

SSLv3记录的第一个字节标明了心跳包的类型。宏n2s从指针p指向的数组中取出前两个字节,并把它们存入变量payload中——这实际上是心跳包载荷的长度域(length)。注意程序并没有检查这条SSLv3记录的实际长度。变量pl则指向由访问者提供的心跳包数据。

经常看到很多漏洞利用工具命名变量时,都会使用变量名payload,莫非 OpenSSL 的编写者也经常搞漏洞之类的东西么?

这次OpenSSL HeartBleed漏洞是怎么一回事呢?的更多相关文章

  1. CentOS修复“OpenSSL Heartbleed漏洞”方法

    转载 http://www.coolhots.net/article/229.shtml

  2. OpenSSL重大漏洞-Heartbleed之漏洞利用脚本POC讲解

    OpenSSL Security Advisory [07 Apr 2014] ======================================== TLS heartbeat read ...

  3. OpenSSL Heartbleed “心脏滴血”漏洞简单攻击示例

    OpenSSL Heartbleed漏洞的公开和流行让许多人兴奋了一把,也让另一些人惊慌了一把. 单纯从攻击的角度讲,我已知道的,网上公开的扫描工具有: 1.  Nmap脚本ssl-heartblee ...

  4. OpenSSL Heartbleed "心脏滴血"漏洞简单攻击示例

    转自:http://www.lijiejie.com/openssl-heartbleed-attack/ OpenSSL Heartbleed漏洞的公开和流行让许多人兴奋了一把,也让另一些人惊慌了一 ...

  5. OpenSSL Heartbleed原因小结

    User发送心跳报文给Server,Server复制心跳报文的内容回应User. memcpy(bp, p1, payload); Server拷贝心跳报文的内容给Client时,如果拷贝的字节数目超 ...

  6. OpenSSL 安全漏洞: heartbleed

    Heartbleed 是 2014年4月7日被广泛报道的一个 OpenSSL 安全漏洞,号称是灾难. 利用它能读取服务器上最多64k的内存,只要该服务器可以通过ssl连接.   Heartbleed ...

  7. [漏洞复现] [Vulhub靶机] OpenSSL Heartbleed Vulnerability (CVE-2014-0160)

    免责声明:本文仅供学习研究,严禁从事非法活动,任何后果由使用者本人负责. 0x00 背景知识 传输层安全协议SSL 安全套接字协议SSL(Secure Sockets Layer),及其继任者传输层安 ...

  8. 汉澳sinox不受openssl心血漏洞影响并分析修复其漏洞代码

    OpenSSL 心血(HeartBleed)漏洞 是openssl 在 2014-04-07 发布的重大安全漏洞(CVE-2014-0160)这个漏洞使攻击者可以从server内存中读取64 KB的数 ...

  9. heartbleed漏洞利用

    1.  heartbleed漏洞扫描: 2.  heartbleed漏洞利用: poc.py      117.52.93.111 貌似没有打到管理员账号密码,可能是管理员没登录,其实,可以写一个自动 ...

随机推荐

  1. STM32CubeMx配置SPI注意的一个问题

    这样配置SPI引脚 然后这样配置SPI参数 生成立这样的配置代码 /* SPI2 init function */static void MX_SPI2_Init(void){ /* SPI2 par ...

  2. python函数(2017-8-2)

    1. def 函数名(形式参数) 函数体 return "123" 函数执行了return之后就不再执行下面的代码 2. 默认形参实参的位置一一对应 如果要调整位置,指定形参名字 ...

  3. 【Markdown】Markdown的使用(自用)

    # 欢迎使用 Cmd Markdown 编辑阅读器 我们理解您需要更便捷更高效的工具记录思想,整理笔记.知识,并将其中承载的价值传播给他人,Cmd Markdown 是我们给出的答案 -- 我们为记录 ...

  4. R语言学习笔记(十一):零碎知识点(26-30)

    26--aggregate( ) 函数aggregate()对分组中的每一个变量调用tapply()函数. aggregate(a,list,f) 第二个参数必须是列表.也就是因子部分. 第三个参数即 ...

  5. c/c++指针理解

    指针的概念 指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址.要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占 ...

  6. oracle 11g XE 学习版添加scott用户方法全步骤

    安装企业版的orcale是不是太费时费力了?若只是学习用途的话,不妨试试轻便版的XE版本,同样是官网下载的,但是这个安装起来比完整版简便多了. 首先,你得先安装好orcale 11g XE 版本:(这 ...

  7. P1509 找啊找啊找GF

    P1509 找啊找啊找GF 题目背景 "找啊找啊找GF,找到一个好GF,吃顿饭啊拉拉手,你是我的好GF.再见." "诶,别再见啊..." 七夕...七夕...七 ...

  8. Vue-router用法

    #全局守卫- router.beforeEach(to,from,next){} #全局后置钩子- router.afterEach(to,from){} #路由独享守卫- beforeEnter(t ...

  9. ubuntu 14.04安装nginx+php

    转自:http://www.cnblogs.com/helinfeng/p/4219051.html 基于最新的Ubuntu 14.04(2014年9月)搭建nginx.php.mysql环境,以下全 ...

  10. abo dto属性验证的坑

    问题回现: public class ShipmentRequestDto { public string FromPhoneNumber { get; set; } /// <summary& ...