利用burp外掛Hackvertor繞過waf並破解XOR加密
我最近在開發一個burp外掛Hackvertor,你們可能不知道。它的特點是基於標籤轉碼,比burp內建的decoder強大得多。基於標籤轉碼的原理是通過標籤對它的內容進行轉碼,然後將轉碼後的內容傳遞給外層標籤繼續轉碼,這讓你可以輕易的進行多重轉碼。
比如,如果你想對字串進行base64編碼,那麼你可以使用base64標籤,如下所示:
<@base64_0>test<@/base64_0>
當然,你可以進行多重編碼,比如,你想先對字串進行hex編碼,然後再進行base64編碼,那麼你就可以先用hex標籤,然後外層再使用base64標籤將它包起來,如下所示:
<@base64_1><@hex_0(" ")>test<@/hex_0><@/base64_1>
hex標籤有一個分隔符引數,會將每一個hex字元分開,這裡的分隔符是空格,然後被空格分開的test會被傳遞到標籤函式中。
Hackvertor用法
載入這個外掛後,會在burp的主介面中新增一個tab,叫Hackvertor。在這個tab下,有一個輸入框和一個輸出框。在輸入框中輸入你要進行轉換的內容,選中它,然後選擇一個標籤,Hackvertor會自動進行轉碼並且將結果顯示在輸出框中。如果你想再次轉碼的話,旁邊還有一個convert按鈕。標籤也有分類,比如Encode和Decode等,這樣你就可以很容易找到你要的標籤。Hackvertor的選項卡也跟repeater一樣,讓你可以多次使用這個工具。Hackvertor選項卡如圖所示:
繞過Cloudflare WAF
最近,我在repeater中發起實際的請求中,使用了Hackvertor的標籤功能。你可以在repeater請求中單擊右鍵,選擇Hackvertor選單,在請求中新增標籤,在請求傳送到伺服器之前,它會自動進行轉碼。當然,你也可以在Intruder中使用,不過要先在repeater中定義,然後傳送到Intruder中,這個用法非常強大,因為你可以使用佔位符來進行多重編碼。你甚至可以在proxy選項中使用它,不過這在預設情況下是不開啟的。如果你想開啟的話,你可以在Burp選單中選中Hackvertor,然後點選新增到proxy選項卡中。
現在,我就來展示一下如何在repeater中使用標籤來繞過Cloudflare WAF。將下面的url傳送到repeater中https://waf.party/xss/xss.php?x=
在等號後面輸入下面的程式碼:
<img/src/onerror=alert(1)>
在repeater中選中alert(1),右鍵單擊選中的文字,然後選擇Hackvertor,然後選擇xss,選擇throw_eval。這會在請求中新增標籤,新增完之後,選擇go,你就可以在響應的內容中看到包含如下內容:
<img/src/onerror=window.onerror=eval;throw'=alert\x281\x29'>
如果你想驗證它是否確實有效,你只需要在request中右擊,然後在上下文選單中選擇Hackvertor並且複製url,這會生成一個所有標籤都被轉碼之後的url。如果你僅僅只是使用Burp的copy URL命令,它只會複製帶有標籤的url。
解碼rotN
研究這個是起源於我女兒的一個問題。當時我穿著2016年BSides Manchester會議的一件T恤,T恤正面有很多行二進位制資料,也就是01010101等等,然後,我女兒就問我,“老爸,這些數字都是什麼意思啊?”,我告訴她這些都是二進位制資料並且問她想不想對這些資料進行解碼。然後,我們就開始將這些資料輸入到Hackvertor中,我發現,這些二進位制被解碼後,乍一看是一些base64編碼的字串,不過,它又看起來像是rot編碼的字串,經過測試確實是rot編碼,於是我們破解了這些rot編碼的字串並且得到了資訊內容。重點不是這個,而是,這件事引發了我的思考,如果Hackvertor能夠自動解碼rot編碼的字串就太好了。
這就需要從隨機的雜亂無章的語句中識別英語。為此,我建立了一個is_like_english標籤,一開始我以為可以使用二元字母模型和三元字母模型來查詢常見字母並且識別出英語單詞,但是並沒有我想的這麼簡單。於是我就Google了一番,發現了一個很不錯的 ofollow,noindex">網站 。他們使用的是4個字母的四元序列和4字母序列在英語中出現的頻率。網站上還有一些簡單的Python指令碼,根據對單詞和四元字母組合的分析得到一個分數。我借鑑了這些思路,用Java重寫了程式碼並且在Hackvertor中得以實現。
下一步是完善自動解碼器。自動解碼器也是一種標籤,它可以自動判斷字串是如何編碼的並且能夠對其進行多次解碼。我寫了一個簡單的正則表示式,用來查詢on或者更多的a-z字元,後面緊跟著空格,逗號或者連字元。然後迴圈25次來暴力破解rot編碼的字串,並從每一次的破解中得到一個分數,我計算了平均值,如果最高的得分比平均值還高出20的話,那麼它就可以自動解碼rot編碼了。
下面這張圖片就是我當時穿的T恤,這裡我就不告訴大家這些二進位制解碼後的字串了,有興趣的話可以自己去解碼:
<@auto_decode_0>01010111 01101101 00110101 01101000 01100011 01001000 01010110 01111001 01011010 01101101 01100100 01111001 01011010 01010011 01000010 01000111 01100101 01101101 00110101 00110101 01100101 01010011 00110001 01000111 01100011 01000111 00110101 00110101 01100011 01101001 01000010 01010011 01100001 00110010 01001110 01111001 01011010 01011000 01011010 00110110 01100011 01101101 01000110 01101110 01100010 01101110 01101011 01100111 01010111 01101101 00110101 01110111 01100100 01011000 01011010 01101000 01100011 01100111 00111101 00111101<@/auto_decode_0>
James也有一件這樣的T恤,不過上面的二進位制不太一樣,所以我把他T恤上的二進位制資料輸入到了Hackvertor中,看看是否能夠自動解碼出訊息,最終成功的解碼出來了。二進位制資料如下,你可以自己貼上到輸入框中試一試
<@auto_decode_10>01011010 01101110 01100001 01110000 01110101 01110010 01100110 01100111 01110010 01100101 00101100 00100000 01100110 01100010 00100000 01111010 01101000 01110000 01110101 00100000 01100111 01100010 00100000 01101110 01100001 01100110 01101010 01110010 01100101 00100000 01110011 01100010 01100101<@/auto_decode_10>
解密XOR重複金鑰加密
本來我準備這篇部落格就寫到這裡了,不過James又提出了挑戰,問我能不能夠破解重複XOR加密。於是,我在一個非常優秀的網站 practical cryptography 上學習了所有關於XOR和頻率分析的知識。第一步就是判斷金鑰的長度,你可以使用頻率分析方法來對每一個key進行判斷。這裡我使用30作為最大的金鑰長度來進行猜測。我將每一個字元儲存在一個頻率表中,並且每次當他們出現在密文中時對它們進行遞增。當你得到了所有字元的頻率時,你就可以計算出每列和頻率的重合指數(或者叫漢明距離)。當我獲得了每個key的重合指數(IC),我就得到了top7的key,並且通過除以選定的金鑰長度來將IC規範化,然後使用IC對前top7進行排序,並將top1作為猜測金鑰返回。
我花了大量時間來嘗試提高金鑰猜測的準確性,並且多次重寫程式碼。trustedsignal網站上有一篇 部落格 寫到,你可以使用第五和第六位的最大公分母來提高檢測金鑰長度的準確性,不過在我的測試中,卻無法提高準確性,不知道為什麼。不管怎樣,只要你得到了金鑰長度,只需要迴圈遍歷密文和每個字元並對其進行XOR,並根據每個字元的結果來得到一個分數。這裡我是用的是Alexey Hellman的 Python指令碼 來對我的程式碼進行XOR的。
最後我重用了is_like_english函式來判斷文字的分數來確定是否轉換成功。如果文字內容不多,確實可以成功,但是如果內容太多的話就失敗了,因為文字越長,ngram(多元模型)的得分就越低,所以我將固定值更改為平均值之間的差異百分比,這樣無論密文多長都能成功。不過,對於太短的密文,XOR解密還是會失敗,我想可能是因為密文長度不夠,所以無法執行頻率分析來判斷金鑰長度和每個解密字元的分數。
為了演示自動解碼功能,我已經使用金鑰對一段文字進行了XOR操作並且進行了hex編碼,當你在輸入框中輸入這段密文時,Hackvertor會自動進行hex解碼,猜測金鑰長度然後自動破解XOR加密,甚至還會提供再次編碼的正確的標籤,如下所示:
<@auto_decode_8>1C090C1E05041C101C523D296324212F000D020C04061D001C216F36383668231619064521010606376F3724732E080D0F561617171A003B3B3A6B3630110C18031717074F1037292C39366808174C0545061B00523E2E372E7D68231A4B03161B1A0852313A373F3A26064E0E120217541C1133212D223D2F41170E150D1C1B031D35366F6B2A27144308170B521D0B173C3B2A2D2A68150B0E5613170616523E2E372E203C41151E1A0B17060E103B232A3F3A2D124D4B391000541D17212A22393020041118560300111E07372137272A68140D08191317064F10202E2D2F732604144B00101E1A0A00332D2A273A3C1843081A0401070A01723B2B2A276823161906451B074F063A2A632D3A3A12174B020A52060A023D3D3765<@/auto_decode_8>
現在人們經常使用重複異或加密,希望這個功能能夠防止某些應用程式使用這個看起來合法的加密方式。
謝謝大家!