Unfortunately tasks currently are unavailable, so I cannot copy task and its name.
We are given a .NET application (You can verify this using file utility.) which checks password. You can try to guess it, but this won't help you anyhow.
Let's decompile it. This application is quite simple and straightforward. The most intersting part of code is password check.
1) Gets the value of environment variable "USERNAME" .
2) Left and right pads it with "_P4d11n9_" strings
3) Computes MD5 hash from result string and compares couple of bytes with needed values. (Quite nice technique to check MD5 I suppose. Full hash is not exposed)
4) Then it compares your input to the resource string "6sZh2HZCx3DI66Xs". (Available after decompilation too)
5) And finally a MD5 hash is taken from "<environment_variable>:6sZh2HZCx3DI66Xs:JH34ZqIx5AOzN34sA4xJzA22AsS". The last part is another string from resources.
6) Flag is printed
The main difficulty is to break a MD5 hash just by couple of bytes. There was a hint that this value matches regular expression [A-Z]{3}, however I saw this hint after the flag has been already submitted. In this case you would need to bruteforce this hash. I will use C# in order to get the same results for UTF8.GetBytes calls. Firstly I used one loop to brute one character, then two and finally three loops which uncovered environment variable value. The whole code:
So the flag is: dbb4b8dda3198d9b77c5dedaa816d873
We are given a .NET application (You can verify this using file utility.) which checks password. You can try to guess it, but this won't help you anyhow.
Let's decompile it. This application is quite simple and straightforward. The most intersting part of code is password check.
public void check_password(string password) { string environmentVariable = MyProject.Application.GetEnvironmentVariable("USERNAME"); string s = "_P4d11n9_" + environmentVariable + "_P4d11n9_"; MD5CryptoServiceProvider cryptoServiceProvider = new MD5CryptoServiceProvider(); byte[] hash1 = cryptoServiceProvider.ComputeHash(Encoding.UTF8.GetBytes(s)); int[] numArray = new int[6] { 1310, 1450, 1435, 1316, 1302, 1439 }; int index1 = 0; int num1 = 0; int num2 = hash1.Length - 1; int index2 = num1; while (index2 <= num2 && ((int) hash1[index2] ^ 1337) == numArray[index1]) { ++index1; index2 += 3; } if (index1 == 6) { if (Operators.CompareString(password, crackme1.My.Resources.Resources.ResourceManager.GetString("password"), false) == 0) { byte[] hash2 = cryptoServiceProvider.ComputeHash(Encoding.UTF8.GetBytes(environmentVariable + ":" + password + ":" + crackme1.My.Resources.Resources.ResourceManager.GetString("flag"))); StringBuilder stringBuilder = new StringBuilder(); foreach (byte num3 in hash2) stringBuilder.Append(num3.ToString("x2").ToUpper()); this.Label2.Text = "Hello " + environmentVariable + ", The Flag is: " + stringBuilder.ToString().ToLower(); } else { this.Label2.Text = "Invalid Password!"; this.checks = this.checks + 1; Interaction.Beep(); } } else { this.Label2.Text = "You are not allowed to use this application!"; this.checks = this.checks + 1; Interaction.Beep(); } }The check does the following:
1) Gets the value of environment variable "USERNAME" .
2) Left and right pads it with "_P4d11n9_" strings
3) Computes MD5 hash from result string and compares couple of bytes with needed values. (Quite nice technique to check MD5 I suppose. Full hash is not exposed)
4) Then it compares your input to the resource string "6sZh2HZCx3DI66Xs". (Available after decompilation too)
5) And finally a MD5 hash is taken from "<environment_variable>:6sZh2HZCx3DI66Xs:JH34ZqIx5AOzN34sA4xJzA22AsS". The last part is another string from resources.
6) Flag is printed
The main difficulty is to break a MD5 hash just by couple of bytes. There was a hint that this value matches regular expression [A-Z]{3}, however I saw this hint after the flag has been already submitted. In this case you would need to bruteforce this hash. I will use C# in order to get the same results for UTF8.GetBytes calls. Firstly I used one loop to brute one character, then two and finally three loops which uncovered environment variable value. The whole code:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Security.Cryptography; namespace Bruter { class Class1 { public static void Main() { string bruted = ""; StringBuilder builder = new StringBuilder(); char[] dict = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; for (int i3 = 0; i3 < dict.Length; ++i3) { for (int j = 0; j < dict.Length; ++j) { for (int i = 0; i < dict.Length; ++i) { builder.Clear(); builder.Append(dict[i]); builder.Append(dict[j]); builder.Append(dict[i3]); bruted = builder.ToString(); string s = "_P4d11n9_" + bruted + "_P4d11n9_"; MD5CryptoServiceProvider cryptoServiceProvider = new MD5CryptoServiceProvider(); byte[] hash1 = cryptoServiceProvider.ComputeHash(Encoding.UTF8.GetBytes(s)); int[] numArray = new int[6] { 1310, 1450, 1435, 1316, 1302, 1439 }; int index1 = 0; int num1 = 0; int num2 = hash1.Length - 1; int index2 = num1; while (index2 <= num2 && ((int)hash1[index2] ^ 1337) == numArray[index1]) { ++index1; index2 += 3; } if (index1 == 6) { Console.WriteLine("Found!"); Console.WriteLine(bruted); byte[] hash2 = cryptoServiceProvider.ComputeHash(Encoding.UTF8.GetBytes(bruted + ":" + "6sZh2HZCx3DI66Xs" + ":" + "JH34ZqIx5AOzN34sA4xJzA22AsS")); StringBuilder stringBuilder = new StringBuilder(); foreach (byte num3 in hash2) stringBuilder.Append(num3.ToString("x2").ToUpper()); Console.WriteLine("Hello " + bruted + ", The Flag is: " + stringBuilder.ToString().ToLower()); } } } } } } }Let's execute it:
So the flag is: dbb4b8dda3198d9b77c5dedaa816d873
Great, Thanks !
ReplyDelete