.NET CrackMe ์ด๋ค.
dnspy์ ๋ฃ์์ ๋ ์๋์ค๊ธธ๋ self-contained ์ต์
์ผ๋ก .NET ๋ฐ์ด๋๋ฆฌ ํ๋ ๋ง๋ค์ด์ ํ์ธํด ๋ดค๋ค.


section , binary ๊ตฌ์กฐ ๋ชจ๋ ์ผ์น ํ๊ธฐ ๋๋ฌธ์ dnspy์์ ์ง์์ ์ํ๋ ๊ฑธ๋ก ์๊ฐํ๊ณ ๋ค๋ฅธ ๋์ปดํ์ผ๋ฌ ๋๊ตฌ์ ์ต์ ๋ฒ์ ์ ์ฌ์ฉํ๋ค.
{
TUI.Initialize();
Console.CancelKeyPress += delegate
{
Environment.Exit(0);
};
while (true)
{
if (Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape)
{
Environment.Exit(0);
}
TUI.DrawBox(5, 2, Console.WindowWidth - 10, Console.WindowHeight - 4, ConsoleColor.Cyan);
TUI.WriteCenter("Welcome to the Toxic Crackme", 4, ConsoleColor.Yellow);
TUI.WriteCenter("Enter the password to win:", 6);
string text = TUI.ReadInput(Console.WindowWidth / 2 - 10, 9);
if (text.Length > 0 && text[0] == '\u001b')
{
Environment.Exit(0);
}
TUI.Clear();
TUI.DrawBox(5, 2, Console.WindowWidth - 10, Console.WindowHeight - 4, ConsoleColor.Cyan);
if (cr4ck.VK(text))
{
break;
}
TUI.WriteCenter("Sorry, that's not the correct password.", 6, ConsoleColor.Red);
TUI.WriteCenter("Press any key to try again...", 8, ConsoleColor.DarkGray);
if (Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape)
{
Environment.Exit(0);
}
Console.ReadKey();
TUI.Clear();
}
TUI.WriteCenter("\ud83c\udf89 Congratulations! You found the correct password! \ud83c\udf89", 6, ConsoleColor.Green);
TUI.WriteCenter("Press any key to exit...", 8, ConsoleColor.DarkGray);
if (Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape)
{
Environment.Exit(0);
}
Console.ReadKey();
if (cr4ck.VK(text))
{
break;
}
cr4ck.VK์์ ๋น๋ฐ๋ฒํธ๋ฅผ ๊ฒ์ฆํ๋ค.
private static string BTS(byte[] P_0)
{
if (P_0 == null || P_0.Length == 0)
{
return string.Empty;
}
char[] array = new char[P_0.Length];
int num = 0;
for (int i = 0; i < P_0.Length; i++)
{
if (P_0[i] <= 127)
{
array[num++] = (char)P_0[i];
continue;
}
int num2;
uint num3;
if ((P_0[i] & 0xE0) == 192)
{
if (i + 1 >= P_0.Length)
{
break;
}
num2 = 2;
num3 = (uint)(((P_0[i] & 0x1F) << 6) | (P_0[i + 1] & 0x3F));
}
else if ((P_0[i] & 0xF0) == 224)
{
if (i + 2 >= P_0.Length)
{
break;
}
num2 = 3;
num3 = (uint)(((P_0[i] & 0xF) << 12) | ((P_0[i + 1] & 0x3F) << 6) | (P_0[i + 2] & 0x3F));
}
else
{
if ((P_0[i] & 0xF8) != 240)
{
continue;
}
if (i + 3 >= P_0.Length)
{
break;
}
num2 = 4;
num3 = (uint)(((P_0[i] & 7) << 18) | ((P_0[i + 1] & 0x3F) << 12) | ((P_0[i + 2] & 0x3F) << 6) | (P_0[i + 3] & 0x3F));
}
if (num3 <= 65535)
{
array[num++] = (char)num3;
}
else
{
num3 -= 65536;
array[num++] = (char)((num3 >> 10) + 55296);
array[num++] = (char)((num3 & 0x3FF) + 56320);
}
i += num2 - 1;
}
return new string(array, 0, num);
}
public static bool VK(string P_0)
{
try
{
byte[] array = Convert.FromBase64String(BTS(_secretBytes));
string text = BTS(array);
if (_resBytes.SequenceEqual(array))
{
return false;
}
return string.Equals(P_0, text, StringComparison.Ordinal);
}
catch
{
return false;
}
}
VK ํจ์์์ secretBytes๋ก๋ถํฐ ๋ฌธ์์ด์ ๋ง๋ ๋ค ์
๋ ฅ๊ณผ ๋น๊ตํ๋ค.
secretBytes๋ ๋ค์๊ณผ ๊ฐ๋ค.
private static readonly byte[] _secretBytes = new byte[20]
{
84, 106, 66, 48, 88, 51, 77, 119, 88, 51,
81, 119, 101, 68, 70, 106, 73, 81, 61, 61
};
BTS ํจ์๋ ๋งค๊ฐ๋ณ์๋ฅผ ๋ฌธ์์ด๋ก ๋ณํํด์ฃผ๋ ์ญํ ์ ํ๋ค.
(BytesToString)
for (int i = 0; i < P_0.Length; i++)
{
if (P_0[i] <= 127)
{
array[num++] = (char)P_0[i];
continue;
}
๋ฌธ์์ด๋ก ๋ณํํ base64 decode ํด์ฃผ๋ฉด password๊ฐ ๋์จ๋ค.
local t = { 84, 106, 66, 48, 88, 51, 77, 119, 88, 51,
81, 119, 101, 68, 70, 106, 73, 81, 61, 61}
return byteTableToString(t)
>>> TjB0X3MwX3QweDFjIQ==

์ถ๊ฐ๋ก Vkํจ์ ๋ด์์ ๋ณ ์๋ฏธ ์๊ฒ resBytes๋ผ๋ ๊ฒ๋ ์ฐ์ด๋๋ฐ
private static readonly byte[] _resBytes = new byte[16]
{
68, 101, 118, 105, 111, 117, 115, 32, 68, 101,
99, 111, 121, 32, 58, 41
};
ํ์ธํด๋ณด๋ฉด ์ด๋ฐ ๋ด์ฉ์ด ์๋ค.
local t = { 68, 101, 118, 105, 111, 117, 115, 32, 68, 101,
99, 111, 121, 32, 58, 41}
return byteTableToString(t)
>>> Devious Decoy :)
๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํ๋ฉด ๋๋๋ค.
