Hackthissite Realistic 第6關心得

網址:https://www.hackthissite.org/missions/realistic/6/index.html

本關重點:XEcryption弱點、已知明文攻擊

題目:From: ToxiCo_Watch
Message: Hello esteemed hacker, I hope you have some decent cryptography skills. I have some text I need decrypted.
I work for this company called ToxiCo Industrial Chemicals, which has recently come under fire because of the toxic chemicals we are dumping into the river nearby. Ecological inspectors have reported no problems, but it is widely speculated that they were paid off by ToxiCo management because the water pollution near the ToxiCo factory has always been a serious and widely publicized issue.
I have done some packet sniffing on my network and I have recovered this email that was sent from the CEO of the company to Chief Ecological Inspector Samuel Smith. However, it is encrypted and I cannot seem to decode it using any of my basic decryption tools. I have narrowed it down to the algorithm used to encrypt it, but it is beyond my scope. I was hoping you can take a look at it.
Please check it out,
more details are on the page. If you can unscramble it and reply to this message with the original text, it would be much appreciated. Thank you.
大意是熱心的環保駭客攔截到化學公司內部的信件,其內容可以幫助社會大眾了解公司真面目。但信件已被加密,於是請你解密(題目有提醒你加密演算法是 XEcryption )。



了解 XEcryption
以下以E(A)代表經過XEcryption加密的字串A,E(A,pw=k)代表金鑰是k。

1.E(A)會任意產生3個數字,這三個數字相加剛好等於ascii(A)。

E(A) = .10.20.35
10+20+35=65=ascii(A)
如果是字串AB
E(AB) = .12.22.31.15.30.21
12+22+31=65=ascii(A)
15+30+21=66=ascii(B)
以此類推...

2.E(A, pw=k),若是加密有用到金鑰k,則k也會任意產生3個數字並且和A的3個數字相加。

E(A, pw=k) = .110.70.38
110+70+38=218=65+153=ascii(A)+ascii(k)
如果是金鑰key
E(A, pw=key) = .122.261.151
122+261+151=534=65+153+145+171=ascii(A)+ascii(k)+ascii(e)+ascii(y)
以此類推...

可以發現到每個字串被任意3個數字取代,並加上金鑰的任意3個數字,而金鑰內容其實不重要,重要的是金鑰字串的ascii總和。但是,XEcryption沒有滿足密碼學中的字元移位特性,因此明文的文法和密文的文法基本上是一樣的,這就成了演算法弱點。

反解XEcryption
因為我們有了密文,也知道此密文來自於公司內部CEO和主管們之間的信件,因此合理推論明文一定會有CEO或是主管的名字。雖然網路上有人說可以用一篇文章中出現最多次的空白字元(space)來反解密文,但我覺得以文章中有時候不一定空白字元是出現最多次,所以我會以我們題目中有的提示為關鍵字來嘗試。

接著我們嘗試整理一下反解的流程
1. 將密文的所有數字,3個一組相加,找出最大值。最找出後可以知道金鑰絕對小於某個數。
2. 猜測明文可能含有的字串(the、of、at、Samuel Smith等等)。
3. 從ascii =0 開始到最大值,暴力猜測密文和明文的關係。

例如,我猜測Samuel Smith會出現明文,於是我先以金鑰為0加密Samuel Smith字串,然後比對題目的秘聞看是否有出現一樣的組合,若有就以ascii=0去解看看密文,並根據解出來的內容判斷是否為真。若沒有則開始嘗試ascii=1,2,3...直到最大值。

以下是javascript的解密程式
<html>
<head></head>
<body>
<script>
function decrypt(){
       var cipher = document.getElementById("ciphertext").value;
       cipher.replace(/(\r\n|\n|\r)/gm,"");
       var str_cipher = cipher.split(".");
       var tmp_int = 0, max = 0;
       var tmp_cipher = "";
       for( var x = 1; x < str_cipher.length; x=x+3){
              tmp_int = 0;
              for( var y = 0; y < 3; y++ ){
                     tmp_int += parseInt(str_cipher[y + x],10);
              }
              max = (max > tmp_int ? max : tmp_int);
              tmp_cipher = tmp_cipher + tmp_int.toString() +".";
       }
       var plain = document.getElementById("possibleplain").value;
       var tmp_plain="";
       for(var pw = 0; pw <= max; pw++){
              tmp_plain="";
              for( var x = 0; x < plain.length; x++){
                     tmp_int = pw + plain.charCodeAt(x);
                     tmp_plain = tmp_plain + tmp_int.toString() + ".";
              }
              if(tmp_cipher.search(tmp_plain) > 0){
                     tmp_cipher = tmp_cipher.split(".");
                     tmp_plain="";
                     for(var x=0 ;x < tmp_cipher.length; x++){
                            tmp_int = parseInt(tmp_cipher[x]) - pw;
                            tmp_plain += String.fromCharCode(tmp_int);
                     }
                     document.getElementById("plaintext").value = tmp_plain;
                     document.getElementById("password").value = pw.toString();
                     break;
              }
              else{
                     //continue
                     document.getElementById("plaintext").value = "try again " + pw.toString();
              }
       }
}
</script>
輸入密文<br>
<textarea name="text" id="ciphertext" rows="8" cols="40"></textarea><br>
輸入可能的明文內容<br>
<input type="text" id="possibleplain"><br>
<input type="button" onclick="decrypt();" value="解密看看"><br>
密碼是<br>
<input type="text" id="password" disabled><br>
明文是<br>
<textarea name="text" id="plaintext" rows="8" cols="40"></textarea>
</body>
</html>


留言

這個網誌中的熱門文章

資安JAVA(十一):X-XSS-Protection

資安JAVA(十):X-Content-Type-Options

資安JAVA(十二):Log Forging