這個題目同樣是一道.NET的逆向題,.NET的逆向方法在之前的博文中已經介紹過,這里不做重復的說明。本題的源程序可以在我的github上下載:https://github.com/gsharpsh00ter/reverse
0x01 逆向
flagfinder為.NET編譯的PE文件,用dnSpy反編譯后,得到如下源碼:
1 using System; 2 using System.IO; 3 using System.Linq; 4 using System.Security.Cryptography; 5 using System.Threading; 6 using Microsoft.VisualBasic.CompilerServices; 7 8 namespace flagfinder 9 { 10 // Token: 0x02000007 RID: 7 11 [StandardModule] 12 internal sealed class Module1 13 { 14 // Token: 0x06000012 RID: 18 RVA: 0x000020D4 File Offset: 0x000002D4 15 [STAThread] 16 //遍歷所有驅動器上的所有文件 17 public static void Main() 18 { 19 DriveInfo[] drives = DriveInfo.GetDrives(); 20 checked 21 { 22 for (int i = 0; i < drives.Length; i++) 23 { 24 DriveInfo driveInfo = drives[i]; 25 if (driveInfo.IsReady) 26 { 27 Module1.SearchDir(driveInfo.RootDirectory); 28 } 29 } 30 } 31 } 32 33 // Token: 0x06000013 RID: 19 RVA: 0x0000210C File Offset: 0x0000030C 34 public static void SearchDir(DirectoryInfo dir) 35 { 36 checked 37 { 38 try 39 { 40 FileInfo[] files = dir.GetFiles(); 41 for (int i = 0; i < files.Length; i++) 42 { 43 FileInfo file = files[i]; 44 //對于每一個文件,會進行檢查,找到符合條件的文件會打印flag 45 Module1.CheckFile(file); 46 } 47 DirectoryInfo[] directories = dir.GetDirectories(); 48 for (int j = 0; j < directories.Length; j++) 49 { 50 dir = directories[j]; 51 Module1.SearchDir(dir); 52 } 53 } 54 catch (Exception expr_49) 55 { 56 ProjectData.SetProjectError(expr_49); 57 Console.WriteLine("Unable to search: " + dir.FullName); 58 ProjectData.ClearProjectError(); 59 } 60 } 61 } 62 63 // Token: 0x06000014 RID: 20 RVA: 0x00002198 File Offset: 0x00000398 64 public static void CheckFile(FileInfo file) 65 { 66 try 67 { 68 Console.WriteLine("Analyzing " + file.FullName + " ..."); 69 //此處為判斷條件,文件內容的MD5為指定值后會計算sha256哈希值,并打印flag 70 MD5CryptoServiceProvider mD5CryptoServiceProvider = new MD5CryptoServiceProvider(); 71 if (mD5CryptoServiceProvider.ComputeHash(file.OpenRead()).SequenceEqual(Module1.target)) 72 { 73 SHA256CryptoServiceProvider sHA256CryptoServiceProvider = new SHA256CryptoServiceProvider(); 74 Console.WriteLine("We've found the flag on your hard drive:"); 75 Console.WriteLine("ISG{" + BitConverter.ToString(sHA256CryptoServiceProvider.ComputeHash(file.OpenRead())).ToLower() + "}"); 76 Environment.Exit(0); 77 } 78 Thread.Sleep(100); 79 } 80 catch (Exception expr_81) 81 { 82 ProjectData.SetProjectError(expr_81); 83 Console.WriteLine("Unable to read: " + file.FullName); 84 ProjectData.ClearProjectError(); 85 } 86 } 87 88 // Token: 0x04000006 RID: 6 89 private static byte[] target = new byte[] 90 { 91 108, 92 203, 93 97, 94 69, 95 90, 96 216, 97 146, 98 25, 99 144, 100 43, 101 58, 102 246, 103 10, 104 154, 105 45, 106 28 107 }; 108 } 109 }
0x02 分析
程序邏輯比較簡單,運行后會遍歷驅動器上的所有文件,并對每一個文件進行檢查。如果某個文件的內容經過MD5哈希后是指定的值(target),則該文件為flag文件,此時會計算器sha256的哈希值,并打印flag。
顯然我們不太可能根據已有的MD5值去逆向破解出文件的內容。可以用google查一下對應的MD5值。在http://www.herdprotect.com/a2cmd.exe-12fc1578b371d0847bf158eefb36f85f42cb9fb3.aspx這個頁面,我們發現相關的信息:
MD5: 6ccb61455ad89219902b3af60a9a2d1c
Sha256: 4cbce92e74fc64dba2b0c5194dd54bf7d694d37fc758572f46bd5b3b8a0c1a80
這應該是一個惡意文件的MD5值,雖然我們沒有該文件,但是沒關系,我們已經得到了sha256的哈希值,根據程序邏輯,我們已經可以自己打印flag了。
打印flag的python代碼如下:
1 #!/usr/bin/python2 2 3 #targets = [108, 203, 97, 69, 90, 216, 146, 25, 144, 43, 58, 246, 10, 154, 45, 28] 4 md5="6ccb61455ad89219902b3af60a9a2d1c" 5 sha256="4cbce92e74fc64dba2b0c5194dd54bf7d694d37fc758572f46bd5b3b8a0c1a80" 6 flag="ISG{" 7 8 for i in range(0, len(sha256), 2): 9 flag = flag + sha256[i:i+2] + "-" 10 flag += "}" 11 flag = flag.replace("-}", "}") 12 print flag
運行結果如下:
Flag為:
ISG{4c-bc-e9-2e-74-fc-64-db-a2-b0-c5-19-4d-d5-4b-f7-d6-94-d3-7f-c7-58-57-2f-46-bd-5b-3b-8a-0c-1a-80}