openssl-heartbleed漏洞学习

  • 了解漏洞

Heartbleed漏洞:

Heartbleed漏洞是openssl的一个漏洞,这个严重漏洞(CVE-2014-0160)的产生是由于未能在memcpy()调用受害用户输入内容作为长度参数之前正确进行边界检查。攻击者可以追踪OpenSSL所分配的64KB缓存、将超出必要范围的字节信息复制到缓存当中再返回缓存内容,这样一来受害者的内存内容就会以每次64KB的速度进行泄露。

背景和影响:

SSL(安全套接层)协议是使用最为普遍网站加密技术,而OpenSSL则是开源的 SSL 套件,为全球成千上万的web服务器所使用。Web服务器正是通过它来将密钥发送给访客然后在双方的连接之间对信息进行加密。URL中使用 https打头的连接都采用了SSL加密技术。在线购物、网银等活动均采用SSL技术来防止窃密及避免中间人攻击。

Heartbleed漏洞之所以得名,是因为用于安全传输层协议(TLS)及数据包传输层安全协议(DTLS)的 Heartbeat扩展存在漏洞。Heartbeat扩展为TLS/DTLS提供了一种新的简便的连接保持方式,但由于OpenSSL 1.0.2-beta与OpenSSL 1.0.1在处理TLS heartbeat扩展时的边界错误,攻击者可以利用漏洞披露连接的客户端或服务器的存储器内容,导致攻击者不仅可以读取其中机密的加密数据,还能盗走用于加密的密钥。

通过读取网络服务器内存,攻击者可以访问敏感数据,从而危及服务器及用户的安全。敏感的安全数据,如服务器的专用主密钥,可使攻击者在服务器和客户端未使用完全正向保密时,通过被动中间人攻击解密当前的或已存储的传输数据,或在通信方使用完全正向保密的情况下,发动主动中间人攻击。

漏洞还可能暴露其他用户的敏感请求和响应,包括用户任何形式的POST请求数据,会话cookie和密码,这能使攻击者可以劫持其他用户的服务身份。在其披露时,约有17%或五十万通过认证机构认证的互联网安全网络服务器被认为容易受到攻击。

漏洞让特定版本的openSSL成为无需钥匙即可开启的“废锁”,入侵者每次可以翻检户主的64K信息,只要有足够的耐心和时间,就可以翻检足够多的数据,拼凑出户主的银行密码、私信等敏感数据。

漏洞原理:

问题出heartbeat扩展,在源码d1_both.c中,进入openssl源码目录,找到该源码,找到以下代码:

openssl-heartbleed漏洞学习_第1张图片

开始我们得到指针p,指向一条SSLv3记录中的数据。结构体SSL3_RECORD的定义如下:

openssl-heartbleed漏洞学习_第2张图片

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

如下图,接下来,程序将分配一段由访问者指定大小的内存区域,这段内存区域最大为 (65535 + 1 + 2 + 16) 个字节。变量bp是用来访问这段内存区域的指针。

openssl-heartbleed漏洞学习_第3张图片

宏s2n与宏n2s干的事情正好相反:s2n读入一个16 bit长的值,然后将它存成双字节值,所以s2n会将与请求的心跳包载荷长度相同的长度值存入变量payload。然后程序从pl处开始复制payload个字节到新分配的bp数组中——pl指向了用户提供的心跳包数据。最后,程序将所有数据发回给用户。

openssl-heartbleed漏洞学习_第4张图片

Bug出在用户可以控制变量payload和pl。直接影响在s2n代码下面的memcpy函数——如果用户并没有在心跳包中提供足够多的数据,比如pl指向的数据实际上只有一个字节,那么memcpy会把这条SSLv3记录之后的数据(长度为payload)——无论那些数据是什么——都复制出来。

  • 漏洞的复现与利用

安装openssl:

下载受到该漏洞影响的openssl版本,我选择的是openssl-1.0.1b。

  1. 使用wget在官网下载源码包;

wget  http://www.openssl.org/source/openssl-1.0.1b.tar.gz

  1. 解压源码包,tar xzvf openssl-1.0.1b.tar.gz
  2. 进入解压后的文件目录:

  1. 创建openssl安装目录:mkdir /usr/local/ssl
  2. 执行命令:./config --prefix=/usr/local/ssl  shared  -fPIC  no-gost

--prefix:安装路径,

shared 是为了生成动态共享库,用来替换系统在的openssl共享库(主要是libssl.so和libcrypto.so 文件),这个非常关键,不使用的话虽然安装了漏洞版的openssl,但是最后发现Linux内核的openssl的版本仍然没有被替换,导致实验失败,因此该实验一定要保证内核版本也是openssl漏洞版本

 

  1. 执行make && make install,如果报如下错误:

执行rm -f /usr/bin/pod2man,再执行make install即可

  1. 进入到/usr/local/ssl/lib目录下,将libssl.so 和libcrypto.so 分别软连接或者直接拷贝到/usr/lib/x86_64-linux-gnu 和/lib/x86_64-linux-gnu目录下:

openssl-heartbleed漏洞学习_第5张图片

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

/usr/local/openssl/lib

  1. 添加OPESSL的环境变量:

在/etc/profile的最后一行,添加:

export OPENSSL=/usr/local/ssl/bin

export PATH=$OPENSSL:$PATH:$HOME/bin

  1. 移除老版本的openssl,创建新的软连接;这个地方注意路径

mv /usr/bin/ssl /usr/bin/openssl.old

mv /usr/include/ssl /usr/include/openssl.old

ln -s /usr/local/ssl/bin/openssl /usr/bin/openssl

ln -s /usr/local/ssl/include/openssl /usr/include/openssl

ln -sf /usr/local/ssl/lib/libcrypto.so.1.0.0 /lib/libcrypto.so.6

echo "/usr/local/ssl/lib" >>/etc/ld.so.conf

ldconfig -v

openssl-heartbleed漏洞学习_第6张图片

  1. 重启系统,然后输入如下内容:

显示openssl-1.0.1b表示安装成功

安装apache2服务:

  1. 下载apache2的源码包wget http://mirrors.shu.edu.cn/apache//httpd/httpd-2.2.34.tar.gz
  2. 解压源码包:tar xzvf httpd-2.2.34.tar.gz
  3. 创建apache2安装目录:mkdir /usr/local/httpd

创建apr的安装目录:mkdir /usr/local/apr

创建apr-util的安装目录:mkdir /usr/local/apr-util

  1. 进入解压完成后的文件目录,找到apr的安装源码:

cd /httpd-2.2.34/srclib/apr

安装apr至/usr/local/apr:./configure --prefix=/usr/local/apr && make && make install

  1. 找到apr-util的安装源码:/httpd-2.2.34/srclib/apr-util

安装至/usr/local/apr-util:./configure  --prefix=/usr/local/apr-util/ --with-apr=/usr/local/apr && make && make install

  1. 进到目录:/httpd-2.2.34/

安装apache2至/usr/local/httpd:./configure --prefix=/usr/local/httpd --enable-so --enable-rewrite --enable-ssl --with-ssl=/usr/local/ssl --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util && make && make install

  1. 安装完成后,vim /usr/local/httpd/conf/httpd.conf,修改配置文件,将红圈内容的#去掉:

openssl-heartbleed漏洞学习_第7张图片

  1. vim /usr/local/httpd/conf/extra/httpd-ssl.conf,修改配置文件:

确定是443端口:

openssl-heartbleed漏洞学习_第8张图片

SSL密钥的存放位置,需要把对应的两个server文件放在对应的目录,这里选择不修改,直接把server.crt和server.key放在/usr/local/httpd/conf/里:

openssl-heartbleed漏洞学习_第9张图片

DocumentRoot为要访问的页面的位置,如index.html 文件位置

 

openssl-heartbleed漏洞学习_第10张图片

  1. 进入到/usr/local/httpd/conf目录,下面的命令可以被用来产生一个自签名的证书。

首先,生成2048位的加密私钥:openssl genrsa -out server.key 2048

openssl-heartbleed漏洞学习_第11张图片

然后,生成证书签名请求(CSR),这里需要填写许多信息,如国家,省市,公司等:openssl req -new -key server.key -out server.csr(“.“表示为空)

 

最后,生成类型为X509的自签名证书。有效期设置365天,即有效期为1年:

 openssl x509 -req -days 3650 -in server.csr -signkey server.key -out s

  1. 关闭防火墙:systemctl stop firewalld
  2. 进入/usr/local/httpd/bin,启动apache服务:

./apachectl start

  1. 访问https://127.0.0.1,出现以下页面即配置成功:

 

openssl-heartbleed漏洞学习_第12张图片

Heartbleed漏洞利用测试

将网上的POC文件保存为sqltest.py,发送到127.0.0.1,得到回复:

openssl-heartbleed漏洞学习_第13张图片

openssl-heartbleed漏洞学习_第14张图片

(1)POC程序首先发送向OpenSSl服务端程序发送“hello”数据包。

(2)收到反馈信息后证明服务端开启并且连接正常。

(3)向服务端发送经修改过的心跳包。

(4)接收服务端返回的数据,并解析出心跳包中的三个变量(分别为SSL3_RECORD结构体中的type、length、data)。

(5)判断type类型变量的值,是否为空,如果为空则服务端未返回数据,判断为没有该漏洞;如果为21则判断服务器报错,判断为没有漏洞;如果为24则心跳包正常,继续判断返回数据长度是否大于3,如果大于3则说明返回了大量服务端越界访问的内存数据,判定为存在该漏洞。

 

心跳包的构造大致如下:

第二行01表示请求方向,40 00表示响应包的长度,占2个字节。此次dump 16 kb内存,如果将40 00 改为ff ff 可以dump 64 kb 内存

进行使用openvas对该存在漏洞的系统扫描

Nmap扫描结果:

发现heartbleed bug:

openssl-heartbleed漏洞学习_第15张图片

Openvas的扫描结果:

openssl-heartbleed漏洞学习_第16张图片

 

 

 

 

你可能感兴趣的:(网络安全)