人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動態(tài)

解析OpenSSL程序概念及震驚業(yè)界的“心臟出血”漏洞

發(fā)布日期:2021-12-09 06:47 | 文章來源:CSDN

OpenSSL的各種概念解析:

公鑰/私鑰/簽名/驗(yàn)證簽名/加密/解密/非對稱加密

我們一般的加密是用一個密碼加密文件,然后解密也用同樣的密碼.這很好理解,這個是對稱加密.而有些加密時,加密用的一個密碼,而解密用另外一組密碼,這個叫非對稱加密,意思就是加密解密的密碼不一樣.初次接觸的人恐怕無論如何都理解不了.其實(shí)這是數(shù)學(xué)上的一個素數(shù)積求因子的原理的應(yīng)用,如果你一定要搞懂,百度有大把大把的資料可以看,其結(jié)果就是用這一組密鑰中的一個來加密數(shù)據(jù),可以用另一個解開.是的沒錯,公鑰和私鑰都可以用來加密數(shù)據(jù),相反用另一個解開,公鑰加密數(shù)據(jù),然后私鑰解密的情況被稱為加密解密,私鑰加密數(shù)據(jù),公鑰解密一般被稱為簽名和驗(yàn)證簽名.

因?yàn)楣€加密的數(shù)據(jù)只有它相對應(yīng)的私鑰可以解開,所以你可以把公鑰給人和人,讓他加密他想要傳送給你的數(shù)據(jù),這個數(shù)據(jù)只有到了有私鑰的你這里,才可以解開成有用的數(shù)據(jù),其他人就是得到了,也看懂內(nèi)容.同理,如果你用你的私鑰對數(shù)據(jù)進(jìn)行簽名,那這個數(shù)據(jù)就只有配對的公鑰可以解開,有這個私鑰的只有你,所以如果配對的公鑰解開了數(shù)據(jù),就說明這數(shù)據(jù)是你發(fā)的,相反,則不是.這個被稱為簽名.

實(shí)際應(yīng)用中,一般都是和對方交換公鑰,然后你要發(fā)給對方的數(shù)據(jù),用他的公鑰加密,他得到后用他的私鑰解密,他要發(fā)給你的數(shù)據(jù),用你的公鑰加密,你得到后用你的私鑰解密,這樣最大程度保證了安全性.

RSA/DSA/SHA/MD5

非對稱加密的算法有很多,比較著名的有RSA/DSA ,不同的是RSA可以用于加/解密,也可以用于簽名驗(yàn)簽,DSA則只能用于簽名.至于SHA則是一種和md5相同的算法,它不是用于加密解密或者簽名的,它被稱為摘要算法.就是通過一種算法,依據(jù)數(shù)據(jù)內(nèi)容生成一種固定長度的摘要,這串摘要值與原數(shù)據(jù)存在對應(yīng)關(guān)系,就是原數(shù)據(jù)會生成這個摘要,但是,這個摘要是不能還原成原數(shù)據(jù)的,嗯....,正常情況下是這樣的,這個算法起的作用就是,如果你把原數(shù)據(jù)修改一點(diǎn)點(diǎn),那么生成的摘要都會不同,傳輸過程中把原數(shù)據(jù)給你再給你一個摘要,你把得到的原數(shù)據(jù)同樣做一次摘要算法,與給你的摘要相比較就可以知道這個數(shù)據(jù)有沒有在傳輸過程中被修改了.

實(shí)際應(yīng)用過程中,因?yàn)樾枰用艿臄?shù)據(jù)可能會很大,進(jìn)行加密費(fèi)時費(fèi)力,所以一般都會把原數(shù)據(jù)先進(jìn)行摘要,然后對這個摘要值進(jìn)行加密,將原數(shù)據(jù)的明文和加密后的摘要值一起傳給你.這樣你解開加密后的摘要值,再和你得到的數(shù)據(jù)進(jìn)行的摘要值對應(yīng)一下就可以知道數(shù)據(jù)有沒有被修改了,而且,因?yàn)樗借€只有你有,只有你能解密摘要值,所以別人就算把原數(shù)據(jù)做了修改,然后生成一個假的摘要給你也是不行的,你這邊用密鑰也根本解不開.

 CA/PEM/DER/X509/PKCS

一般的公鑰不會用明文傳輸給別人的,正常情況下都會生成一個文件,這個文件就是公鑰文件,然后這個文件可以交給其他人用于加密,但是傳輸過程中如果有人惡意破壞,將你的公鑰換成了他的公鑰,然后得到公鑰的一方加密數(shù)據(jù),不是他就可以用他自己的密鑰解密看到數(shù)據(jù)了嗎,為了解決這個問題,需要一個公證方來做這個事,任何人都可以找它來確認(rèn)公鑰是誰發(fā)的.這就是CA,CA確認(rèn)公鑰的原理也很簡單,它將它自己的公鑰發(fā)布給所有人,然后一個想要發(fā)布自己公鑰的人可以將自己的公鑰和一些身份信息發(fā)給CA,CA用自己的密鑰進(jìn)行加密,這里也可以稱為簽名.然后這個包含了你的公鑰和你的信息的文件就可以稱為證書文件了.這樣一來所有得到一些公鑰文件的人,通過CA的公鑰解密了文件,如果正常解密那么機(jī)密后里面的信息一定是真的,因?yàn)榧用芊街豢赡苁荂A,其他人沒它的密鑰啊.這樣你解開公鑰文件,看看里面的信息就知道這個是不是那個你需要用來加密的公鑰了.

實(shí)際應(yīng)用中,一般人都不會找CA去簽名,因?yàn)槟鞘鞘斟X的,所以可以自己做一個自簽名的證書文件,就是自己生成一對密鑰,然后再用自己生成的另外一對密鑰對這對密鑰進(jìn)行簽名,這個只用于真正需要簽名證書的人,普通的加密解密數(shù)據(jù),直接用公鑰和私鑰來做就可以了.

密鑰文件的格式用OpenSSL生成的就只有PEM和DER兩種格式,PEM的是將密鑰用base64編碼表示出來的,直接打開你能看到一串的英文字母,DER格式是二進(jìn)制的密鑰文件,直接打開,你可以看到........你什么也看不懂!.X509是通用的證書文件格式定義.pkcs的一系列標(biāo)準(zhǔn)是指定的存放密鑰的文件標(biāo)準(zhǔn),你只要知道PEM DER X509 PKCS這幾種格式是可以互相轉(zhuǎn)化的.


心臟出血的OpenSSL
去年,OpenSSL爆出史上最嚴(yán)重的安全漏洞,此漏洞在黑客社區(qū)中被命名為“心臟出血”漏洞。360網(wǎng)站衛(wèi)士安全團(tuán)隊對該漏洞分析發(fā)現(xiàn),該漏洞不僅是涉及到https開頭的網(wǎng)址,還包含間接使用了OpenSSL代碼的產(chǎn)品和服務(wù),比如,VPN、郵件系統(tǒng)、FTP工具等產(chǎn)品和服務(wù),甚至可能會涉及到其他一些安全設(shè)施的源代碼。

受影響版本

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等版本。

漏洞描述

OpenSSL在實(shí)現(xiàn)TLS和DTLS的心跳處理邏輯時,存在編碼缺陷。OpenSSL的心跳處理邏輯沒有檢測心跳包中的長度字段是否和后續(xù)的數(shù)據(jù)字段相符合,攻擊者可以利用這點(diǎn),構(gòu)造異常的數(shù)據(jù)包,來獲取心跳數(shù)據(jù)所在的內(nèi)存區(qū)域的后續(xù)數(shù)據(jù)。這些數(shù)據(jù)中可能包含了證書私鑰、用戶名、用戶密碼、用戶郵箱等敏感信息。該漏洞允許攻擊者,從內(nèi)存中讀取多達(dá)64KB的數(shù)據(jù)。

前幾日的漏洞分析文章主要聚焦在開啟HTTPS的網(wǎng)站上,普通網(wǎng)民可能認(rèn)為只有網(wǎng)站自身業(yè)務(wù)會受到這個漏洞的影響。從360網(wǎng)站衛(wèi)士Openssl心血漏洞在線檢測平臺(wangzhan.#/heartbleed)的監(jiān)控數(shù)據(jù)得知,心血漏洞的輻射范圍已經(jīng)從開啟HTTPS的網(wǎng)站延伸到了VPN系統(tǒng)和郵件系統(tǒng),目前共發(fā)現(xiàn)國內(nèi)共有251個VPN系統(tǒng)和725個郵件系統(tǒng)同樣存在漏洞,其中不乏很多政府網(wǎng)站、重點(diǎn)高校和相關(guān)安全廠商。

為了更好讓大家明白,Openssl心血漏洞到底是哪個環(huán)節(jié)出了問題,我們利用OpenSSL lib庫編寫了一個不依賴與任何業(yè)務(wù)的獨(dú)立server程序,來一步步實(shí)際調(diào)試一遍代碼,以此證明不僅是https的網(wǎng)站有問題,只要使用了存在該漏洞的OpenSSL libssl.so庫的應(yīng)用程序都存在安全漏洞!

測試環(huán)境

OS:CentOS release 6.4 (Final)
OpenSSL: Version 1.0.1f(沒有打開OPENSSL_NO_HEARTBEATS編譯選項)
編寫Server程序:監(jiān)聽端口9876
漏洞測試

利用網(wǎng)上python驗(yàn)證腳本(https://gist.github.com/RixTox/10222402)進(jìn)行測試

構(gòu)造異常heartbeat數(shù)據(jù)包,主要添加異常的length字段值。

測試一:

藍(lán)色的01表示的是心跳包的類型為request方向。對應(yīng)源代碼中就是#define TLS1_HB_REQUEST 1

紅色的20 00表示的心跳請求包的length字段,占兩個字節(jié),對應(yīng)的長度值為8192。

HeartBeat Response包


復(fù)制代碼
代碼如下:
[root@server test]# python ssltest.py 127.0.0.1 -p 9876 > 1</p> <p>Sending heartbeat request…</p> <p>… received message: type = 24, ver = 0302, length = 8211</p> <p>Received heartbeat response:</p> <p>WARNING: server returned more data than it should – server is vulnerable!</p> <p>Received heartbeat response:

藍(lán)色的02表示的是心跳包的類型為response方向。

對應(yīng)源代碼中就是#define TLS1_HB_RESPONSE 2

紅色的20 00表示的心跳響應(yīng)包的length字段,占兩個字節(jié),對應(yīng)的長度值為8192。和request包的length值一樣。

綠色部分就是非法獲取到的越界數(shù)據(jù)(可能包含用戶名、密碼、郵件、內(nèi)網(wǎng)IP等敏感信息)。

測試二:

在測試一的基礎(chǔ)上,修改了request心跳包的length字段的值,從20 00 修改到 30 00

HeartBeat Requst包

30 00兩個字節(jié)對應(yīng)的長度為12288(8192+4096)

HeartBeat Response包

復(fù)制代碼
代碼如下:

[root@server test]# python ssltest.py 127.0.0.1 -p 9876 > 1</p> <p>Sending heartbeat request…</p> <p>… received message: type = 24, ver = 0302, length = 12307</p> <p>Received heartbeat response:</p> <p>WARNING: server returned more data than it should – server is vulnerable!</p> <p>Received heartbeat response:</p> <p>0000: 02 30 00 D8 03 02 53 43 5B 90 9D 9B 72 0B BC 0C .0….SC[...r...</p> <p>0010: BC 2B 92 A8 48 97 CF BD 39 04 CC 16 0A 85 03 90 .+..H...9.......</p> <p>0020: 9F 77 04 33 D4 DE 00 00 66 C0 14 C0 0A C0 22 C0 .w.3....f.....".</p> <p>0030: 21 00 39 00 38 00 88 00 87 C0 0F C0 05 00 35 00 !.9.8.........5.

兩個測試用例中,response的length長度值總是比request的長度多出來了19個byte,為什么?

因?yàn)?,TLS和DTLS在處理類型為TLS1_HB_REQUEST的心跳請求包邏輯中,在從堆空間上申請內(nèi)存大小時,有4部分決定type+length+request的數(shù)據(jù)長度+pad,其中type,length,pad字段分為占1byte,2byte,16byte,所以response的數(shù)據(jù)總是比request的多出來19byte。

源碼分析

概要說明

該漏洞主要是內(nèi)存泄露問題,而根本上是因?yàn)镺penSSL在處理心跳請求包時,沒有對length字段(占2byte,可以標(biāo)識的數(shù)據(jù)長度為64KB)和后續(xù)的data字段做合規(guī)檢測。生成心跳響應(yīng)包時,直接用了length對應(yīng)的長度,從堆空間申請了內(nèi)存,既便是真正的請求data數(shù)據(jù)遠(yuǎn)遠(yuǎn)小于length標(biāo)識的長度。

相關(guān)解析源碼說明

存在該漏洞的源文件有兩個ssl/d1_both.c和ssl/t1_lib.c。

心跳處理邏輯分別是dtls1_process_heartbeat和tls1_process_heartbeat兩個函數(shù)。

dtls1_process_heartbeat函數(shù)處理邏輯:

Step1.獲取心跳請求包對應(yīng)的SSLv3記錄中數(shù)據(jù)指針字段,指向request的請求數(shù)據(jù)部分。

復(fù)制代碼
代碼如下:

unsigned char *p = &s->s3->rrec.data[0];

record記錄的數(shù)據(jù)格式應(yīng)該包含了三個字段:type, length, data;分別占1byte,2byte,length的實(shí)際值。

Step2.

復(fù)制代碼
代碼如下:

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

做了兩件事,獲取了type類型以及l(fā)ength字段的值(存放到payload中),然后將pl指向真正的data數(shù)據(jù)。

Step3.

復(fù)制代碼
代碼如下:

/* 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;

悲劇開始上演了。沒有判斷請求記錄中的真正數(shù)據(jù)長度,直接用length字段的值來申請空間。對應(yīng)于測試一中的異常數(shù)據(jù)包的話,buffer申請的內(nèi)存大小就是8211byte。但是實(shí)際應(yīng)該申請的大小僅僅就幾個字節(jié)。

Step4.

復(fù)制代碼
代碼如下:

/* Enter response type, length and copy payload */
*bp++ = TLS1_HB_RESPONSE;
s2n(payload, bp);
memcpy(bp, pl, payload);
bp += payload;

悲劇形成了。填充響應(yīng)記錄,第一個字節(jié)填充類型,第二、三個字節(jié)填充request記錄中l(wèi)ength的值,緊接著,將request的data填充為響應(yīng)的data數(shù)據(jù)。異常情況下,payload對應(yīng)的長度遠(yuǎn)遠(yuǎn)大于真正應(yīng)該使用的合法的data數(shù)據(jù)長度,這樣,就導(dǎo)致了非法越界訪問相鄰內(nèi)存空間的數(shù)據(jù)。

tls1_process_heartbeat函數(shù)的處理邏輯和dtls1_process_heartbeat一樣,此處就不再做詳細(xì)分析了。

附:ssl_server.c

編譯方式(請根據(jù)實(shí)際環(huán)境自行修改相關(guān)路徑)


復(fù)制代碼
代碼如下:
gcc -g -o ssl_server ssl_server.c -I/root/openssl_101f_prex/include/ -L/root/openssl_101f_prex/lib/ -lssl

該代碼是文中用于調(diào)試存在漏洞的libssl.so庫的server端,供對該漏洞感興趣的安全研究人員、安全愛好者們自行后續(xù)調(diào)試。希望這段獨(dú)立的代碼能讓大家意識到這個漏洞持續(xù)的高等級威脅:截至目前,心血漏洞僅僅是剛開始出血,避免這個漏洞引起互聯(lián)網(wǎng)業(yè)務(wù)大血崩此刻就要開始更多的行動了!

C/C++ Code復(fù)制內(nèi)容到剪貼板
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<netinet/in.h>
  5. #include<sys/types.h>
  6. #include<sys/socket.h>
  7. #include“openssl/bio.h”
  8. #include“openssl/rsa.h”
  9. #include“openssl/crypto.h”
  10. #include“openssl/x509.h”
  11. #include“openssl/pem.h”
  12. #include“openssl/ssl.h”
  13. #include“openssl/err.h”
  14. #defineserver_cert“./server.crt”
  15. #defineserver_key“./server.key”
  16. #defineca_cert“./ca.crt”
  17. #definePORT9876
  18. #defineCHK_NULL(x)if((x)==NULL)exit(1)
  19. #defineCHK_ERR(err,s)if((err)==-1){perror(s);exit(1);}
  20. #defineCHK_SSL(err)if((err)==-1){ERR_print_errors_fp(stderr);exit(2);}
  21. intmain()
  22. {
  23. interr;
  24. intlisten_sd=-1;
  25. intsd=-1;
  26. structsockaddr_insa_serv;
  27. structsockaddr_insa_cli;
  28. intclient_len;
  29. SSL_CTX*ctx=NULL;
  30. SSL*ssl=NULL;
  31. X509*client_cert=NULL;
  32. char*str=NULL;
  33. charbuf[4096];
  34. SSL_METHOD*meth=NULL;
  35. SSL_library_init();
  36. SSL_load_error_strings();
  37. ERR_load_BIO_strings();
  38. OpenSSL_add_all_algorithms();
  39. meth=(SSL_METHOD*)SSLv23_server_method();
  40. ctx=SSL_CTX_new(meth);
  41. if(NULL==ctx){
  42. gotoout;
  43. }
  44. //SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL);
  45. //SSL_CTX_load_verify_locations(ctx,ca_cert,NULL);
  46. if(SSL_CTX_use_certificate_file(ctx,server_cert,SSL_FILETYPE_PEM)<=0){
  47. gotoout;
  48. }
  49. if(SSL_CTX_use_PrivateKey_file(ctx,server_key,SSL_FILETYPE_PEM)<=0){
  50. gotoout;
  51. }
  52. if(!SSL_CTX_check_private_key(ctx)){
  53. printf(“Privatekeydoesnotmatchthecertificatepublickey\n”);
  54. gotoout;
  55. }
  56. listen_sd=socket(AF_INET,SOCK_STREAM,0);
  57. if(-1==listen_sd){
  58. gotoout;
  59. }
  60. memset(&sa_serv,‘\0′,sizeof(sa_serv));
  61. sa_serv.sin_family=AF_INET;
  62. sa_serv.sin_addr.s_addr=INADDR_ANY;
  63. sa_serv.sin_port=htons(PORT);
  64. err=bind(listen_sd,(structsockaddr*)&sa_serv,sizeof(sa_serv));
  65. if(-1==err){
  66. gotoout;
  67. }
  68. err=listen(listen_sd,5);
  69. if(-1==err){
  70. gotoout;
  71. }
  72. client_len=sizeof(sa_cli);
  73. sd=accept(listen_sd,(structsockaddr*)&sa_cli,&client_len);
  74. if(-1==err){
  75. gotoout;
  76. }
  77. printf(“Connectionfrom%d,port%d\n”,sa_cli.sin_addr.s_addr,sa_cli.sin_port);
  78. ssl=SSL_new(ctx);
  79. if(NULL==ssl){
  80. gotoout;
  81. }
  82. SSL_set_fd(ssl,sd);
  83. err=SSL_accept(ssl);
  84. if(NULL==ssl){
  85. gotoout;
  86. }
  87. /*
  88. printf(“SSLconnectionusing%s\n”,SSL_get_cipher(ssl));
  89. client_cert=SSL_get_peer_certificate(ssl);
  90. if(client_cert!=NULL){
  91. printf(“Clientcertificate:\n”);
  92. str=X509_NAME_oneline(X509_get_subject_name(client_cert),0,0);
  93. CHK_NULL(str);
  94. printf(“\tsubject:%s\n”,str);
  95. Free(str);
  96. str=X509_NAME_oneline(X509_get_issuer_name(client_cert),0,0);
  97. CHK_NULL(str);
  98. printf(“\tissuer:%s\n”,str);
  99. Free(str);
  100. X509_free(client_cert);
  101. }
  102. else
  103. printf(“Clientdoesnothavecertificate.\n”);
  104. */
  105. err=SSL_read(ssl,buf,sizeof(buf)–1);
  106. if(err==-1){
  107. gotoout;
  108. }
  109. buf[err]=‘\0′;
  110. printf(“Got%dchars:’%s’\n”,err,buf);
  111. err=SSL_write(ssl,“Ihearyou.”,strlen(“Ihearyou.”));
  112. CHK_SSL(err);
  113. out:
  114. if(-1!=sd){
  115. close(sd);
  116. }
  117. if(-1!=listen_sd){
  118. close(listen_sd);
  119. }
  120. if(ssl){
  121. SSL_free(ssl);
  122. }
  123. if(ctx){
  124. SSL_CTX_free(ctx);
  125. }
  126. return0;
  127. }

版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。

相關(guān)文章

實(shí)時開通

自選配置、實(shí)時開通

免備案

全球線路精選!

全天候客戶服務(wù)

7x24全年不間斷在線

專屬顧問服務(wù)

1對1客戶咨詢顧問

在線
客服

在線客服:7*24小時在線

客服
熱線

400-630-3752
7*24小時客服服務(wù)熱線

關(guān)注
微信

關(guān)注官方微信
頂部