好望角“Cape Of Good Hope”位於印度洋溫暖的莫三比克厄加勒斯洋流與南極洲水域寒冷的本格拉洋流相遇的地方,當航海者在經歷過狂風暴雨的洗禮,越過這個風暴角,便會獲得財富和希望。
好望角也是2019 KCTF晉級賽Q1最後一站,最後這道題,又會帶給我們怎樣的驚喜呢?讓我們一起來看看吧!
本道題目算是一道入門題,有超過100支隊伍破解出來,戰隊 kali-go以47分鐘率先破解本題。
出題團隊
戰隊成員:widesoft
個人主頁:https://bbs.pediy.com/user-68717.htm
看雪CTF crownless 評委 點評
《初入好望角》作為本次看雪CTF晉級賽Q1的最後一題,是一道簡單的送分題,基於.net2.0,使用了AES加密。參賽者只需要編寫簡單的程式碼,即可解密得到flag。
題目設計思路
一道.net平臺下入門題目。使用了較常用的網站使用者名稱/密碼加密方法。程式使用Visualstudio自帶的Dotfuscator做了簡單混淆,幾乎沒有什麼強度。可以逆向檢視程式碼或透過修改IL再重新編譯的方式爆破。
破解思路
本題解題思路由看雪論壇 SnowMzn 提供
0x001-----程式逆向
由於程式是.net語言開發,因此使用DnSpy開啟程式,啟動程式後,使程式斷在入口點處。
在這裡可以看到程式碼
程式碼邏輯很簡單,將輸入的字串進行加密處理後,與字串**4RTlF9Ca2+oqExJwx68FiA==**比較。
0x002-----演算法分析
演算法中的bytes和bytes3為固定值,bytes2為輸入的值。
由於之前對C#語言並不是很瞭解,因此猜測演算法中,是使用bytes和bytes3為金鑰,使用CryptoStream加密bytes2,最後將加密後的位元組陣列進行Base64加密。
因此解密演算法的思路為:
1、首先將 **4RTlF9Ca2+oqExJwx68FiA==**字串解密為十六進位制字串;
2、使用CryptoStream解密,得出flag。
0x003-----編寫指令碼
使用C#編寫解密指令碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
byte[] bytes = Encoding.UTF8.GetBytes("Kanxue2019CTF-Q1");
byte[] bytes3 = new PasswordDeriveBytes("Kanxue2019", null).GetBytes(32);
//string key_base64 = "4RTlF9Ca2+oqExJwx68FiA==";
//StringBuilder key = new StringBuilder();
//foreach (byte b in Convert.FromBase64String(key_base64).ToArray())
//{
// //Format as hex
// key.AppendFormat("{0:X2}", b);
//}
//Console.WriteLine("{0}", key.ToString());
string ret1 = "E114E517D09ADBEA2A131270C7AF0588";
ICryptoTransform transform = new RijndaelManaged
{
Mode = CipherMode.CBC
}.CreateDecryptor(bytes3, bytes);
byte[] inputByteArray = new byte[ret1.Length / 2];
for (int x = 0; x < ret1.Length / 2; x++)
{
int i = (Convert.ToInt32(ret1.Substring(x * 2, 2), 16));
inputByteArray[x] = (byte)i;
}
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write);
cryptoStream.Write(inputByteArray, 0, inputByteArray.Length);
cryptoStream.FlushFinalBlock();
byte[] inArray = memoryStream.ToArray();
memoryStream.Close();
cryptoStream.Close();
string returnStr = "";
for (int i = 0; i < inArray.Length; i++)
{
returnStr += inArray[i].ToString("X2");
}
Console.WriteLine("{0}", returnStr);
}
}
}
結果得到的是十六進位制字串,將結果轉換為字串即可。