heartbleed漏洞及内存信息窃取


heartbleed漏洞及内存信息窃取


了解漏洞

Heartbleed漏洞是什么?

Heartbleed漏洞是openssl加密软件库中的一个严重的漏洞。这个漏洞允许在正常情况下通过用于保护因特网的ssl/tls加密来窃取受保护的信息。只要使用的是存在缺陷的OpenSSL实例,无论是服务器还是客户端,都可能因此而受到攻击。
此问题的原因是在实现TLS的心跳扩展时没有对输入进行适当验证(缺少边界检查),因此漏洞的名称来源于“心跳”(heartbeat)。该程序错误属于缓冲区过读,即可以读取的数据比应该允许读取的还多。
这个漏洞在通用漏洞披露(CVE)系统中的编号为CVE-2014-0160。

它的背景和影响是什么?

背景:
OpenSSL于2014年4月7日被公开披露据。信在漏洞披露时,约有17%(大约五十万)通过认证机构认证的互联网安全网络服务器容易受到攻击,导致服务器私钥和用户会话cookie及密码被盗。电子前哨基金会、Ars Technica和布鲁斯·施奈尔均认为心脏出血漏洞是“灾难性的”。福布斯网络安全专栏作家约瑟夫·斯坦伯格写道:“有些人认为,至少就其潜在影响而言,‘心脏出血’是自互联网允许商用以来所发现的最严重的漏洞。”
影响:
经由heartbleed漏洞发动攻击,获得的数据可能包括TLS双方将要交换、但尚未加密的机密内容,包括在用户请求中各种格式的post数据。此外,泄漏的数据还可能含有身份验证密令,如会话cookie及密码,可使攻击者向该服务冒充此用户。
攻击还可能泄漏受攻击双方的私钥,这将使攻击者能解密通信内容(将来或是之前通过被动窃听捕获而存储的通信,除非使用完全正向保密,而在这种情况下,只能解密将来通过中间人攻击截获的通信)。
即使漏洞修复之后,获得受害者认证资料的攻击者仍能伪装成资料的拥有者,只要该资料能被接受(例如,在更改密码或撤销私钥之前)。因此,漏洞对保密性构成了致命威胁。然而,冒充受害人的攻击者也能修改数据,所以间接的后果可能不只是系统机密泄漏那么简单。
一项于2014年4月对美国成人进行的调查显示,60%的人听说过心脏出血漏洞。使用互联网的受访者中有39%的人采取了行动以保护他们的在线账户,如更改密码或注销账户;29%的人认为他们的个人信息因漏洞而处于危险之中;6%的人认为他们的个人信息已遭窃取。

分析漏洞原理

源码中那些地方出现了问题?

我们直接看一下修复后的提交的代码和之前代码的区别:

--- a/ssl/d1_both.c
+++ b/ssl/d1_both.c
@@ -1459,26 +1459,36 @@ dtls1_process_heartbeat(SSL *s)
        unsigned int payload;
        unsigned int padding = 16; /* Use minimum padding */
-       /* Read type and payload length first */
-       hbtype = *p++;
-       n2s(p, payload);
-       pl = p;
        if (s->msg_callback)
                s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
                        &s->s3->rrec.data[0], s->s3->rrec.length,
                        s, s->msg_callback_arg);
+       /* Read type and payload length first */
+       if (1 + 2 + 16 > s->s3->rrec.length)
+               return 0; /* silently discard */
+       hbtype = *p++;
+       n2s(p, payload);
+       if (1 + 2 + payload + 16 > s->s3->rrec.length)
+               return 0; /* silently discard per RFC 6520 sec. 4 */
+       pl = p;
+
        if (hbtype == TLS1_HB_REQUEST)
                {
                unsigned char *buffer, *bp;
+               unsigned int write_length = 1 /* heartbeat type */ +
+                                           2 /* heartbeat length */ +
+                                           payload + padding;
                int r;
 
+               if (write_length > SSL3_RT_MAX_PLAIN_LENGTH)
+                       return 0;
+
                /* Allocate memory for the response, size is 1 byte
                 * message type, plus 2 bytes payload length, plus
                 * payload, plus padding
                 */
-               buffer = OPENSSL_malloc(1 + 2 + payload + padding);
+               buffer = OPENSSL_malloc(write_length);
                bp = buffer;
 
                /* Enter response type, length and copy payload */
@@ -1489,11 +1499,11 @@ dtls1_process_heartbeat(SSL *s)
                /* Random padding */
                RAND_pseudo_bytes(bp, padding);
 
-               r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
+               r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length);
 
                if (r >= 0 && s->msg_callback)
                        s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
-                               buffer, 3 + payload + padding,
+                               buffer, write_length,
                                s, s->msg_callback_arg);
 
                OPENSSL_free(buffer);

从上面的差异我们可以看到,服务器处理心跳原来的方式是首先直接解析type和payload,什么都不做任何的检查。

unsigned int payload;
        unsigned int padding = 16; 
        hbtype = *p++;
        n2s(p, payload);
        pl = p;

修改之后openssl的data进行了16字节的数据对齐,其他格式一致。
修补方式是他加入了两个重要的函数:

  if (1 + 2 + 16 > s->s3->rrec.length)
              return 0; /* silently discard */

if (1 + 2 + payload + 16 > s->s3->rrec.length)
              return 0; /* silently discard per RFC 6520 sec. 4 */

这个判断的目的是为了避免data的length为0这一特殊情况的处理。

从poc中哪里可以体现出漏洞,poc又是怎样利用的漏洞?

从python的poc脚本中最重要的一部分代码可以看到:

hb = h2bin('''
18 03 02 00 03
01 40 00
''')

其中后四位 40 00 是我们请求的数据长度。如果将这个改为其他的数据。比如ff ff就可以请求一个超过我们真是payload长度的数据了。
通过更改请求数据的长度然后就可以利用漏洞读取缓存找中的数据了。

漏洞的复现和利用

安装配置openssl

绝对不能直接卸载原来的openssl。因为有很多依赖,我们直接下载openssl 1.0.1e版本的压缩包,然后解压安装。

$ tar -zxvf   openssl-1.0.1e.tar.gz
$ cd  /openssl-1.0.1e/  //编译安装之前需要执行下面这个否则会报错
$ rm –f /usr/bin/pod2man
$ ./config --prefix=/usr/local/openssl shared -fPIC no-gost
$ //上面的命令,是安装openssl到  /usr/local/openssl 目录,安装之后,编译;
$ make && make install

修改配置文件:
在/etc/ld.so.conf文件的最后面,添加如下内容:

/usr/local/openssl/lib

然后执行:

$ /usr/local/openssl/lib

添加OPESSL的环境变量:
在etc/的profile的最后一行,添加:

export OPENSSL=/usr/local/openssl/bin
export PATH=$OPENSSL:$PATH:$HOME/bin

退出命令界面,再从新登录。(注销一下)

$ cp lib*.so* /usr/lib64          //把这四个文件复制到lib64位置 

依次如下执行:

$ ldd /usr/local/openssl/bin/openssl

查看路径

$ which openssl

查看版本:

$ openssl version
1.png

配置Apache+https

不用卸载原来的apache,直接下线安装2.2版本就行,这样就不用装apr这些依赖,原版本已经存在。
下载安装apache2.2.34:

$ tar –zxvf apache-2.2.34.tar.gz
$ ./configure --prefix=/usr/local/httpd --enable-so --enable-rewrite --enable-ssl --with-ssl=/usr/local/openssl
$ Make && make install

如果编译时出现错误:sort libssl.so.10之类的错误可以直接忽略!
因为这个只是版本的问题,不用理会!我尝试了很多都不能解决这个问题。重装了好几次,最后发现是fedora版本的问题,后面直接忽略了这个报错发现最结果没有影响。
在目录/usr/local/httpd/conf下生成证书:(直接在conf目录下生成证书就不用拷贝了。)

$ openssl genrsa -out server.key 2048   //生成2048位的加密私钥
$ openssl req -new -key server.key -out server.csr   //生成证书签名请求(CSR),这里需要填写许多信息,如国家,省市,公司等
$ openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt    //最后,生成类型为X509的自签名证书。有效期设置3650天,即有效期为10年
2.png

3.png

然后修改httpd.conf的配置文件
将ServerNname的注释取消,改为127.0.0.1:8080
将httpd-ssl的那一行的注释也取消。


4.png

然后重启apache
$ /usr/local/httpd/bin/apachectl  restart

访问指定页面就可以使用https了:


5.png

下载编译安装php5.3.30

$ ./configure --prefix=/usr/local/php   --with-apxs2=/usr/local/httpd/bin/apxs  --with-config-file-path=/usr/local/php/etc   --enable-fpm --enable-mbstring --enable-gd --enable-xml    --with-mysqli=mysqlnd

然后编辑一下:

$ cp php.ini-development  /usr/local/php/etc/php.ini

修改Apache的配置文件httpd.conf

DirectoryIndex index.html index.php #添加index.php
找到:
AddType  application/x-compress .Z
AddType application/x-gzip .gz .tgz
添加如下内容
AddType application/x-httpd-php-source .phps
AddType application/x-httpd-php .php

检查LoadModule php5_module modules/libphp5.so 是否已经添加 libphp5.so文件是否存在。存在就可以,写一个简单的php查看:

6.png

可以用php进行访问。

利用poc进行攻击

从其他主机访问:


7.png

8.png

可以看到我们刚刚生成的私人证书,在其他主机访问则不安全。
下面尝试使用namp自带的脚本进行检测,进行poc攻击:

$ nmap -sV -p 443 --script=ssl-heartbleed 127.0.0.1
9.png

可以看到成功扫出来了漏洞:ssl-heartbleed,危险程度是高。
接着尝试使用网上的脚本进行测试:


10.png

11.png

编译安装配置https+php+mysql环境

下载php5.6.17并编译安装:

$ ./configure --prefix=/usr/local/php  

通过修改心跳包数据、抓包等方式进一步理解heartbleed的漏洞原理;

通过在攻击机执行网上的poc利用 脚本,然后用wireshark抓包观察:
首先攻击机先测试能否访问靶机:


12.png

然后打开wireshark监听网卡,设置过滤指定地址和端口:


13.png

攻击机执行攻击(没有更改长度)脚本:
14.png

抓取到心跳包请求包和响应包,我们点击请求包查看:
15.png

这是正常的请求包,主要这里的payload长度。
下面看看请求包的详细情况:


16.png

后面这16位:
18表示contenet-type:heartbleed(24)
03 02表示 版本
03 表示长度
01 表示是请求
20 00就是payload就是我们要读取的数据的长度。
接着我们进行更改payload的长度进行测试:
17.png

将代码后上面后四位改为ff ff,执行,抓包查看:
18.png

可以看到此时的请求包的payload已经变为了65535。


19.png

因为这里的请求长度就是ff ff。
20.png

同样的响应包的也变成了65535变成了我们更改的64k的数据了,这样我们就成功每次可以读取到64KB数据。
接着我们建立一个简单的php+apache+mysql的网站,然后进行测试。
最新版mysql5.7以上使用SET PASSWORD = '<plaintext_password>’更改密码!!
设置可以使用弱密码set global validate_password_policy=0;
我直接将我数据库的大作业考进知道文件夹然后进行测试:
在攻击机访问我的数据管理系统:
22.png

成功窃取了内存中的数据!!!!

heartbleed漏洞的风险是什么。

如果一个服务器存在heartbleed的漏洞很可能会被攻击者窃取内存中的数据,虽然每次是以最大64kb的数据被窃取,但是很有可能被攻击者窃取了秘钥等重要的信息来进行更危险的攻击。

使用openvas扫描

23.png

可以看到成功扫描出来heartbleed漏洞。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 架构师必须知道的26项PHP安全实践 PHP是一种开源服务器端脚本语言,应用很广泛。Apache web服务器提供...
    meng_philip123阅读 6,051评论 1 161
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,585评论 18 139
  • 如果你看完书中的所有例子,你很可能已经做完你的实验和在已经越狱的iPhone上的研究。因为和许多人一样,几乎所有的...
    fishmai0阅读 15,788评论 2 42
  • httpd相关: httpd程序版本: 。1.3 停止维护 。2.0 。 2.2 event为测试使用 。 2.4...
    ckhzw阅读 384评论 0 0
  • 当你向一个人索要一个答案,如果对方迟疑三秒钟以上,往往,他最终给出的那个答案不是心里真实的答案,而是为了取悦你而刻...
    栀子不开花阅读 271评论 0 1