作者:Sherkey
最近在研究Padding Oracle滲透測試,發(fā)現(xiàn)網(wǎng)上沒有詳細講原理的文章。因此自己整理了這樣一篇,希望哪怕是沒有密碼學(xué)基礎(chǔ)的朋友也能看完后完全理解攻擊的原理。
一、基礎(chǔ)知識介紹
本節(jié)針對無密碼學(xué)基礎(chǔ)的讀者,若均理解可直接跳過。
1.1 什么是分組密碼?
以下定義來自維基百科:
在密碼學(xué)中,分組加密(英語:Block cipher),又稱分塊加密或塊密碼,是一種對稱密鑰算法。它將明文分成多個等長的模塊(block),使用確定的算法和?對稱密鑰對每組分別加密解密。
簡單來說,就是將明文進行分組,每組分別加密,最后再連在一起形成密文。AES, DES等加密方法均屬于分組加密。
1.2 什么是PKCS#5?
正如1.1中所說,分組密碼中,需要對明文進行分組。
但是分組要求每個塊的大小都要相同。
那么問題就來了,如果說我的明文是‘testabc’,而我用的分組密碼是五個一組。這樣第一組內(nèi)容是‘testa’,那么第二組只剩下了‘bc’,不夠五個,應(yīng)該怎么辦呢?
這是就要用到一種填充方式,用來把最后空出來的幾位填滿。
而PKCS#5,就是一種由RSA信息安全公司設(shè)計的填充標準。
對于PKCS#5標準來說,一般缺少幾位,就填充幾位那個數(shù)字。
比方說,在上面的例子里,我們有三位空缺,那么就要在空缺處都填上3 。這樣,第二組的內(nèi)容就變成了‘bc333’ 。
這里需要注意的是,比如說,如果每個分組是8字節(jié),我的明文是‘testabcd’,這樣恰好是8字節(jié)了。但是按照PKCS#5的標準,我們?nèi)匀恍枰诤竺嫣砑右粋€塊,塊里的內(nèi)容全部填充為8 (因為一個塊大小為8字節(jié),而第二個塊全部為空,因此有8位需要填充)。
1.3 CBC模式
在密碼學(xué)中,分組密碼有許多的工作模式。
可能有人會問,我們直接分組以后加密不就好了嗎,為什么需要設(shè)計模式呢?
沒錯,其實分組后直接加密也是一種設(shè)計模式,名為電子密碼本(Electronic codebook,ECB)模式。
如圖所示,其實就是每個分組的明文均利用相同的密鑰進行加密。
但是這種模式明顯有個缺點,那就是所有的密鑰都相同,導(dǎo)致相同的明文,一定會被加密成相同的密文。
這樣很顯然是一種不安全的模式。因為它不能提供嚴格的數(shù)據(jù)保密性。可以聯(lián)想一下最簡單的凱撒密碼,相同的明文加密后得到相同的密文,導(dǎo)致這種方式難以阻擋頻率攻擊。
那么為了讓我們加密后的信息更加難以破解,在1976年,IBM發(fā)明了密碼分組鏈接(CBC,Cipher-block chaining)模式。
如下圖所示。
我們可以看到,這里加入了一個初始向量(IV, Initialization Vector)。在第一塊明文進行加密之前,需要先與初始向量進行異或。而產(chǎn)生的密文,將與下一組明文進行異或。在這種方法中,每個密文塊都依賴于它前面的所有明文塊。
這種模式使原本獨立的分組密碼加密過程形成迭代,使每次加密的結(jié)果影響到下一次加密。這樣無疑比ECB模式要安全了許多。
上圖分別是CBC模式下加密和解密的過程。我們可以看到在中間寫著Block Cipher Encryption 的方塊那里即是加密算法,本文中就用AES來舉例。
而Initiallzation Vector(IV)即是初始向量,也是本攻擊方式所重點利用的地方。
1.4 異或
在密碼學(xué)里,異或是一種很重要的運算方式。
具體表現(xiàn)在,一個數(shù)字連著異或兩次另一個數(shù)字后,得到的值還是它本身。
比方說,65 ^ 66 = 3
3 ^ 66 = 65
在下面我們會利用到這個重要的運算。
二、破解過程詳解
文章開頭說了,這是一種針對CBC模式的攻擊。與你具體選擇的是哪種加密方式是沒有關(guān)系的。
也就是說,在上面CBC加密模式的圖里,不管你在‘Block Cipher Decryption’那個框里選的是AES加密,還是DES加密,都無所謂,只要服務(wù)器配置不正確,我們都有機會破解。
那么這是如何做到的呢?在說明攻擊方式之前,我們先來了解一下正常的解密方式是如何的。
2.1 正常解密過程
我們先來分析一下正常狀態(tài)下,服務(wù)器的解密過程。
首先,CBC模式下AES的解密需要知道IV值與密鑰。這個應(yīng)該很好理解?!瓸lock Cipher Decryption’肯定需要知道密鑰來解密,而CBC模式需要IV值來解密。
而服務(wù)器端僅僅保留了密鑰,沒有保留IV值。因為默認情況下加密后的文件會把IV值附在文件開頭,因此服務(wù)器會直接使用傳給它的文件開頭8或16位(視加密方式而定),作為IV值。
在此我們停一下,先舉個例子,詳細解釋一下CBC模式下AES加密過的密文如何正常解密得到明文。
比方說,我們有密文’9F0B13944841A832B2421B9EAF6D9836813EC9D944A5C8347A7CA69AA34D8DC0DF70E343C4000A2AE35874CE75E64C31′ 。這段密文用CBC模式下AES加密,并且已知key和IV值。
接下來我們進行解密。
首先,AES是一種分組密碼,每組由16字節(jié)組成。密文是用十六進制表示的,也就是相鄰兩位數(shù)字合在一起組成一個十六進制數(shù),用來表示一字節(jié)。密文長度為96,按照32一組進行分組,則恰好可以分為三組。我們把這三組密文存到一個數(shù)組C里,以后用C[0], C[1], C[2]來表示這三組密文。
然后我們看一下解密用的圖。
如上圖所示,我已經(jīng)在圖中標出了C[0], C[1], C[2]的位置。我們正常解密時,先用C[0]與Key解密AES,然后得到一個中間值,這個中間值與IV值進行異或,得到第一段明文。而C[0]作為新的IV值,與C[1]在AES解密后的中間值進行異或,從而得到第二段明文。第三段以此類推。這就是一個正常解密的過程。
下圖中把“中間值”這個概念用紅圈表示了出來。千萬千萬要好好看懂解密過程以及“中間值”究竟代表什么,這是本攻擊的關(guān)鍵。
而Padding Oracle 攻擊的重點,就在于上一段提到的中間值。
我們繼續(xù)聊服務(wù)器端正常情況下如何解密。其實和我們上面分析的差不多。區(qū)別在于,我們解密的時候是從左往右,也就是先從C[0]開始解密;而服務(wù)器是從右往左,也就是先解密C[2]。
那么問題又來了:服務(wù)器如何知道自己解密后得到的結(jié)果是否正確呢?
因為服務(wù)器無法判斷解密后明文是否有具體含義,因此它也就不從含義上去判斷。它判斷的方式很簡單粗暴,就是利用Padding值來進行判斷。
在1.2處我們了解了PKCS#5標準下的填充方式。我們已經(jīng)知道,明文加密之前肯定會在末尾附上一段Padding值用來填充。
那么接下來,服務(wù)器從C[2]進行解密。比如說,一開始明文最后Padding值為0×05,也就是最后五位應(yīng)該均為5 。而服務(wù)器解密后,發(fā)現(xiàn)也確實如此,那么它就認為這次解密時正確的。而如果服務(wù)器發(fā)現(xiàn)解密后Padding值為0×05 ,但是只有最后四位的值為0×05 ;或者說它解密后得到的Padding值為0×04 ,但是最后五位都是0×04 ,那么就造成了Padding的值與數(shù)目不相符,服務(wù)器就會認為解密失敗,從而報錯。
我們可以從其他參考文章的描述中看到:
如果解密過程沒有問題,明文驗證(如用戶名密碼驗證)也通過,則會返回正常 HTTP 200如果解密過程沒有問題,但是明文驗證出錯(如用戶名密碼驗證),則還是會返回 HTTP 200,只是內(nèi)容上是提示用戶用戶名密碼錯誤如果解密過程出問題了,比如Padding規(guī)則核對不上,則會爆出 HTTP 500錯誤。其實就是我們剛才說的判斷方式的更具體應(yīng)用。
而知道服務(wù)器的判斷方式以后,我們就可以在這里做文章了。
2.2 攻擊過程
本次攻擊的關(guān)鍵,集中在我用紅圈圈起來的地方。
也就是C[0]. C[1]. C[2]分別用key對AES進行解密,但是還沒有與IV值異或的那個值。本文把那個值稱為中間值。
上圖是正常解密的結(jié)果。而本次攻擊的關(guān)鍵,就在被綠色標注的那一行。
本文把綠色標注那一行的值稱為中間值。
根據(jù)上面的CBC模式解密的圖,我們可以知道,解密會先使用AES解密得到一個中間值,然后在通過中間值與IV值的異或,最后得到明文。
而padding oracle攻擊的本質(zhì),其實就是通過傳遞密文以及自己猜測的IV值,通過觀察服務(wù)器對padding判斷的結(jié)果,進而反推出中間值,最后用中間值與正確的IV異或得到明文。
也就是這個攻擊直接跳過了AES,而針對CBC進行攻擊。
需要注意的是,自己傳遞的IV值與正確的IV值不能混淆。鑒于圖中自己傳遞的IV值為黃色,因此下稱自己傳遞的IV值為黃IV,正確的IV值為原IV。
我們再來想想服務(wù)器是怎么解密的:從右往左。
再看看CBC模式解密的那張圖,從右往左,就是說先解密C[2]。而解密時,就會用C[1]當(dāng)做IV值,來與C[2]解密后得到的中間值進行異或,進而得到明文。
而我們首先需要自己構(gòu)造C[1]中的值,也即在上面圖片中的黃IV值,構(gòu)造以后與C[2]解密得到的中間值進行異或。
并且根據(jù)上面服務(wù)器判斷解密過程是否正確的條件來看,只要最后padding值與個數(shù)相對應(yīng)即可。
因此,我們可以一位一位的構(gòu)造,第一次先通過改變黃IV值,產(chǎn)生padding結(jié)果為1的情況,即可倒推出中間值。
那么我們開始進行破解。
2.3 第一次循環(huán)
還記得我們前面提到的服務(wù)器判斷方式嗎?就是只需要padding的值與個數(shù)相符即可。
而在第一次循環(huán)里,我們只需要構(gòu)造C[1],使得與C[2]產(chǎn)生的中間值異或以后,得到的最后一位為0×01即可。
C[1]是一個十六位的數(shù)組(相鄰兩位算作一個十六進制數(shù))。我們可以使它前15位均為隨機數(shù)。因為如果是隨機數(shù)的話,與中間值異或后的結(jié)果也是一個隨機數(shù),不太可能恰好是0×01,因此就避免了你最后一位得到0×01,而前一位恰好也是0×01導(dǎo)致個數(shù)不符,服務(wù)器判斷為錯的尷尬。C[1]最后一位從00到ff進行嘗試。根據(jù)上面所說,會有一個值恰好與C[2]解密后的中間值異或后會得到0×01這個結(jié)果。這時服務(wù)器返回顯示正確。
返回正確時,意味著如下公式成立:
C1 ^ 中間值的最后一位 = 0×01
那么按照異或運算的性質(zhì),我們不難得到:
中間值的最后一位 = C1 ^ 0×01
這樣我們就成功得到了中間值的最后一位。
2.4 第二次至第N次循環(huán)
Padding值為1的情況結(jié)束后,再用同樣方法嘗試2 。但是要注意,為了讓服務(wù)器判斷正確,我們需要使最后兩位結(jié)果都為2 。那么,倒數(shù)第二位是我們本次循環(huán)的嘗試位,倒數(shù)第一位如何確定呢?
因為我們在padding值為1的時候,已經(jīng)通過嘗試得到了正確的中間值。因此,我們只需要將中間值與0×02進行異或的結(jié)果放到此處即可。
參考下式會更容易理解:
C1?= 上一步得到的中間值最后一位 ^ 0×02
這里可能有人會問,為什么這一步的C1和上一步的不一樣了?
這是因為我們是在通過窮舉法來破解。我們在窮舉的時候,是把整個C[1]都當(dāng)做了可以改變的對象,目的就是通過改變C[1]來解除C[2]的中間值。因此上一步我們求出來了中間值以后,C1就可以被我們繼續(xù)改變了。
而在這一次,我們是為了讓padding值為2,這就意味著最后兩位都需要為0×02。而倒數(shù)第二位是我們這次窮舉需要改變的值,那么我們就需要讓C1與最后一位的中間值異或以后,能得到0×02。
而最后一位中間值我們已經(jīng)求得了。因此在這一輪循環(huán)里,我們要讓C1固定,這樣異或后的結(jié)果為0×02,我們也就可以愉快的繼續(xù)窮舉倒數(shù)第二位了。
之后的操作也與此相同。第n輪循環(huán)的時候,只要把C[1]倒數(shù)第n-1一直到倒數(shù)第一位的值全部固定,使得他們與得到的中間值異或后得到n就可以了。
在整個C[2]破解結(jié)束后,我們會得到這個塊中所有的中間值。這時,我們只需要掏出未經(jīng)改變的C[1] ,也就是原IV,與中間值異或,就可以得到C[2]塊的全部明文了。
之后我們再用相同的方法破解C[1],就能得到全部明文了。
- 蜜度索驥:以跨模態(tài)檢索技術(shù)助力“企宣”向上生長
- Fortinet李宏凱:2025年在中國大陸啟動SASE PoP節(jié)點部署 助力企業(yè)出海
- Fortinet李宏凱:2024年Fortinet全球客戶已超80萬
- 央國企采購管理升級,合合信息旗下啟信慧眼以科技破局難點
- Apache Struts重大漏洞被黑客利用,遠程代碼執(zhí)行風(fēng)險加劇
- Crunchbase:2024年AI網(wǎng)絡(luò)安全行業(yè)風(fēng)險投資超過26億美元
- 調(diào)查報告:AI與云重塑IT格局,77%的IT領(lǐng)導(dǎo)者視網(wǎng)絡(luò)安全為首要挑戰(zhàn)
- 長江存儲發(fā)布聲明:從無“借殼上市”意愿
- 泛微·數(shù)智大腦Xiaoe.AI正式發(fā)布,千人現(xiàn)場體驗數(shù)智化運營場景
- IDC:2024年第三季度北美IT分銷商收入增長至202億美元
- AI成為雙刃劍!凱捷調(diào)查:97%組織遭遇過GenAI漏洞攻擊
免責(zé)聲明:本網(wǎng)站內(nèi)容主要來自原創(chuàng)、合作伙伴供稿和第三方自媒體作者投稿,凡在本網(wǎng)站出現(xiàn)的信息,均僅供參考。本網(wǎng)站將盡力確保所提供信息的準確性及可靠性,但不保證有關(guān)資料的準確性及可靠性,讀者在使用前請進一步核實,并對任何自主決定的行為負責(zé)。本網(wǎng)站對有關(guān)資料所引致的錯誤、不確或遺漏,概不負任何法律責(zé)任。任何單位或個人認為本網(wǎng)站中的網(wǎng)頁或鏈接內(nèi)容可能涉嫌侵犯其知識產(chǎn)權(quán)或存在不實內(nèi)容時,應(yīng)及時向本網(wǎng)站提出書面權(quán)利通知或不實情況說明,并提供身份證明、權(quán)屬證明及詳細侵權(quán)或不實情況證明。本網(wǎng)站在收到上述法律文件后,將會依法盡快聯(lián)系相關(guān)文章源頭核實,溝通刪除相關(guān)內(nèi)容或斷開相關(guān)鏈接。