您好,登錄后才能下訂單哦!
本帖最后由 simeon 于 2014-4-11 10:54 編輯 www.antian365.com simeon 一、openssl漏洞形成原因 4月7日,互聯(lián)網(wǎng)安全協(xié)議OpenSSL被曝存在一個(gè)十分嚴(yán)重的安全漏洞。在***社區(qū),它被命名為“心臟出血”,表明網(wǎng)絡(luò)上出現(xiàn)了“致命內(nèi)傷”。利用該漏洞,***可以獲取約30%的https開頭網(wǎng)址的用戶登錄賬號(hào)密碼,其中包括購(gòu)物、網(wǎng)銀、社交、門戶等類型的知名網(wǎng)站。該漏洞最早公布時(shí)間為4月7日,原文作者為Sean Cassidy 在其blog上發(fā)表“existential type crisis : Diagnosis of the OpenSSL Heartbleed Bug”(http://blog.existentialize.com/d ... heartbleed-bug.html)。2014年4月7日OpenSSL發(fā)布了安全公告,在OpenSSL1.0.1版本中存在嚴(yán)重漏洞(CVE-2014-0160),此次漏洞問題存在于ssl/dl_both.c文件中。OpenSSL Heartbleed模塊存在一個(gè)BUG,當(dāng)***者構(gòu)造一個(gè)特殊的數(shù)據(jù)包,滿足用戶心跳包中無法提供足夠多的數(shù)據(jù)會(huì)導(dǎo)致memcpy把SSLv3記錄之后的數(shù)據(jù)直接輸出,該漏洞導(dǎo)致***者可以遠(yuǎn)程讀取存在漏洞版本的openssl服務(wù)器內(nèi)存中長(zhǎng)大64K的數(shù)據(jù)。 1.漏洞分析 漏洞存在文件ssl/dl_both.c,漏洞的補(bǔ)丁從這行語(yǔ)句開始: int dtls1_process_heartbeat(SSL *s) { unsigned char *p = &s->s3->rrec.data[0], *pl; unsigned short hbtype; unsigned int payload; unsigned int padding = 16; /* Use minimum padding */ 結(jié)構(gòu)體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記錄中包含一個(gè)類型域(type)、一個(gè)長(zhǎng)度域(length)和一個(gè)指向記錄數(shù)據(jù)的指針(data)。在dtls1_process_heartbeat中: /* Read type and payload length first */ hbtype = *p++; n2s(p, payload); pl = p; SSLv3記錄的第一個(gè)字節(jié)標(biāo)明了心跳包的類型。宏n2s從指針p指向的數(shù)組中取出前兩個(gè)字節(jié),并把它們存入變量payload中——這實(shí)際上是心跳包載荷的長(zhǎng)度域(length)。注意程序并沒有檢查這條SSLv3記錄的實(shí)際長(zhǎng)度。變量pl則指向由訪問者提供的心跳包數(shù)據(jù)。 這個(gè)函數(shù)的后面進(jìn)行了以下工作: unsigned char *buffer, *bp; int r; /* 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; 所以程序?qū)⒎峙湟欢斡稍L問者指定大小的內(nèi)存區(qū)域,這段內(nèi)存區(qū)域最大為 (65535 + 1 + 2 + 16) 個(gè)字節(jié)。變量bp是用來訪問這段內(nèi)存區(qū)域的指針。 /* Enter response type, length and copy payload */ *bp++ = TLS1_HB_RESPONSE; s2n(payload, bp); memcpy(bp, pl, payload); 宏s2n與宏n2s干的事情正好相反:s2n讀入一個(gè)16 bit長(zhǎng)的值,然后將它存成雙字節(jié)值,所以s2n會(huì)將與請(qǐng)求的心跳包載荷長(zhǎng)度相同的長(zhǎng)度值存入變量payload。然后程序從pl處開始復(fù)制payload個(gè)字節(jié)到新分配的bp數(shù)組中——pl指向了用戶提供的心跳包數(shù)據(jù)。最后,程序?qū)⑺袛?shù)據(jù)發(fā)回給用戶。 2.用戶可以控制變量payload和pl成為可利用漏洞 如果用戶并沒有在心跳包中提供足夠多的數(shù)據(jù),會(huì)導(dǎo)致什么問題?比如pl指向的數(shù)據(jù)實(shí)際上只有一個(gè)字節(jié),那么memcpy會(huì)把這條SSLv3記錄之后的數(shù)據(jù)——無論那些數(shù)據(jù)是什么——都復(fù)制出來。 二、可利用POC及其測(cè)試 1、poc獲取 漏洞公布后不久網(wǎng)上就出現(xiàn)了國(guó)外牛人們寫的POC,在該漏洞發(fā)布的第一時(shí)間我們對(duì)此漏洞進(jìn)行了分析與驗(yàn)證是否能夠獲取一些敏感信息。漏洞發(fā)布的同時(shí)***可利用的腳本也已經(jīng)在網(wǎng)絡(luò)中流傳。下面漏洞利用腳本的下載地址: http://s3.jspenguin.org/ssltest.py (python腳本) http://pan.baidu.com/s/1nt3BnVB (python腳本) https://github.com/decal/ssltest-stls/blob/master/ssltest-stls.py https://raw.githubusercontent.co ... ter/ssltest-stls.py 網(wǎng)上在線檢測(cè): http://possible.lv/tools/hb/ http://filippo.io/Heartbleed/ 2. poc代碼 將以下代碼保存為ssltest.py文件,Poc代碼如下:
3.具體測(cè)試方法 openssl.py / ssltest.py,用法:python openssl.py ip/域名 -p 端口 網(wǎng)上POC作者公布的代碼每次只dump 16kb 內(nèi)存,如果需要dump 64kb內(nèi)存需要做如下修改: hb = h3bin(''' 18 03 02 00 03 01 40 00 //此處修改為01 ff ff ''') 將“for b in xrange(0, len(s), 16)”改成“for b in xrange(0, len(s), 64)” 后期還出現(xiàn)支持支持smtp, pop3, imap, ftp, or xmpp的POC(http://lcx.cc/?i=4276)。 三、openssl檢測(cè)技術(shù) 利用openssl心臟出血漏洞利用代碼,筆者第一時(shí)間進(jìn)行測(cè)試,測(cè)試分為兩個(gè)方面,一個(gè)是通過網(wǎng)頁(yè)在線檢測(cè),另外就是通過腳本直接獲取內(nèi)存內(nèi)容。 1.網(wǎng)頁(yè)檢測(cè) 網(wǎng)頁(yè)檢測(cè)使用網(wǎng)站“http://possible.lv/tools/hb/”效果較好,打開該頁(yè)面后,在輸入框中輸入網(wǎng)站域名地址即可,如果默認(rèn)端口不是443,則需要輸入具體的端口,例如www.somesite.com:4433,則表示端口為4433,檢測(cè)會(huì)有進(jìn)度條顯示,100%后,會(huì)在下面顯示檢測(cè)結(jié)果。如圖1所示,則表示不存在漏洞。隨機(jī)更換一個(gè)網(wǎng)站地址,如圖2所示,獲取該網(wǎng)站存在漏洞。 圖1在線檢測(cè)漏洞 圖2獲取kuaiyinpan.com存在漏洞 2.通過py腳本進(jìn)行檢測(cè) 在linux 終端窗口中輸入“python ssltest.py 66.175.219.225 -p 443”命令,如圖3所示獲取該漏洞提示信息“ver=0302”該版本表示存在漏洞。在獲取的內(nèi)容中可能會(huì)包含用戶密碼和用戶名等信息。 圖3通過py腳本進(jìn)行測(cè)試 3.對(duì)存在漏洞的網(wǎng)站進(jìn)行掃描檢測(cè) 下載nmap最新版本,在本地進(jìn)行編譯,或者使用命令進(jìn)行更新“nmap --script-updatedb”,或者下載“wgethttps://svn.nmap.org/nmap/scripts/ssl-heartbleed.nse”,世界測(cè)試過程中直接下載該腳本會(huì)缺少一些模塊,然后通過以下命令進(jìn)行掃描: nmap -p 443 --script ssl-heartbleed 66.175.219.225 如果存在漏洞,則會(huì)給出該漏洞的相關(guān)提示,如圖4所示。 圖4掃描檢測(cè)存在漏洞服務(wù)器 4.通用Snort規(guī)則檢測(cè) 由于眾所周知的SSL協(xié)議是加密的,我們目前沒有找到提取可匹配規(guī)則的方法,我們嘗試編寫了一條基于返回?cái)?shù)據(jù)大小的檢測(cè)規(guī)則,其有效性我們會(huì)繼續(xù)驗(yàn)證,如果有問題歡迎反饋。alert tcp $EXTERNAL_NET any -> $HOME_NET 443 (msg:"openssl Heartbleed attack";flow:to_server,established; content:"|18 03|"; depth: 3; byte_test:2, >, 200, 3, big; byte_test:2, <, 16385, 3, big; threshold:type limit, track by_src, count 1, seconds 600; reference:cve,2014-0160; classtype:bad-unknown; sid:20140160; rev:2;) Snort規(guī)則說明:此次漏洞主要針對(duì)的SSL協(xié)議。是針對(duì)心跳數(shù)據(jù)包前4個(gè)字節(jié)中包含\x18\x03,而在數(shù)據(jù)包第5個(gè)字節(jié)和第6個(gè)字節(jié)的數(shù)值按大尾模式轉(zhuǎn)化成數(shù)值在200和16385之間,在后面則是一些報(bào)警和過濾功能,日志記錄里,每10分鐘記錄一次。 四、修復(fù)建議 1.openssl心臟出血漏洞受影響版本 通過實(shí)際測(cè)試,受影響版本: OpenSSL 1.0.2-beta OpenSSL 1.0.1 - OpenSSL 1.0.1f 不受影響版本: OpenSSL 1.0.1g is NOT vulnerable OpenSSL 1.0.0 branch is NOT vulnerable OpenSSL 0.9.8 branch is NOT vulnerable 2.修復(fù)建議 (1)升級(jí)openssl軟件。要解決此漏洞,建議服務(wù)器管理員或使用1.0.1g版,或使用-DOPENSSL_NO_HEARTBEATS選項(xiàng)重新編譯OpenSSL,從而禁用易受***的功能,直至可以更新服務(wù)器軟件。(OpenSSL官方)最新版本升級(jí)地址為:https://www.openssl.org/source/. (2)重新編譯OpenSSL并去掉DOPENSSL_NO_HEARTBEATS擴(kuò)展。 $ echo -e "B\n" | openssl s_client -connect targetwebsite:443 -tlsextdebug 2>&1| grep 'heartbeart' (3)如果不能升級(jí)OpenSSL可以更新IPTable防火墻規(guī)則。t# Log rules iptables -t filter -A INPUT -p tcp --dport 443 -m u32 --u32 \ "52=0x18030000:0x1803FFFF" -j LOG --log-prefix "BLOCKED: HEARTBEAT" # Block rules iptables -t filter -A INPUT -p tcp --dport 443 -m u32 --u32 \ "52=0x18030000:0x1803FFFF" -j DROP 3.centos修復(fù)方法參考 (1)yum方法安裝 yum search openssl yum install openssl /etc/init.d/nginx restart #然后重啟nginx (2)下載編譯安裝 wget http://www.openssl.org/source/openssl-1.0.1g.tar.gz cd openssl-1.0.1g ./config make && make install /etc/init.d/nginx restart #重啟nginx 參考文章: (1)http://blog.existentialize.com/d ... heartbleed-bug.html (2)http://drops.wooyun.org/papers/1381 (3)http://bbs.safedog.cn/thread-60096-1-1.html (4)http://www.techweb.com.cn/ucweb/news/id/2025856 (5)測(cè)試工具包下載地址: http://www.antian365.com/forum.p ... id=12061&extra= http://www.antian365.com/tools/0day/openssl.zip (6)判斷是否支持Heartbeat的NSE腳本http://www.freebuf.com/articles/system/31499.html |
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。