HACKvent 2015: Day 14
Challenge
pull out the Nugget out of this binary.
The following Windows binary was also provided: hv15-day14-_ZM0qfjSu8Tf3OZDqjS74.exe
Solution
I download the binary and run it and am presented with the following program:
It turns out that this program will tell you (via a messagebox) if you enter in the correct daily nugget or not!
So all we have to do is check the binary to see what causes the successful message box to appear.
Note: You can do this challenge using IDA or a .NET disassembler like ILSpy (link).
If using IDA, its useful to be familiar with CIL instructions.
ILSpy Approach
I decided to use ILSpy as it is apparently a very good .NET disassembler. I open the program and load the binary and it disassembles it into various classes as you would expect.
We are mainly interested in the hv15 class. By searching for strings like yes, that is the key!
we realise the only important functions we need to look at are Button1_Click
and Encrypt
.
This is the code for both:
Button1_Click
// hv15.Form1
private void Button1_Click(object sender, EventArgs e)
{
string text = this.TextBox1.Text;
string left = this.Encrypt(text, Form1.GlobalVariables.assembly);
if (Operators.CompareString(left, "zV5/UFU8PUD3N2T49IBuCwvGzCLYz39tkMZts7rfBU4=", false) == 0)
{
Interaction.MsgBox("yes, that is the key!", MsgBoxStyle.Information, "HACKVent 2015");
}
else
{
Interaction.MsgBox("nope, that is NOT the key!", MsgBoxStyle.Critical, "HACKVent 2015");
}
}
Encrypt
// hv15.Form1
public string Encrypt(string input, string pass)
{
RijndaelManaged rijndaelManaged = new RijndaelManaged();
MD5CryptoServiceProvider mD5CryptoServiceProvider = new MD5CryptoServiceProvider();
string result;
try
{
byte[] array = new byte[32];
byte[] sourceArray = mD5CryptoServiceProvider.ComputeHash(Encoding.ASCII.GetBytes(pass));
Array.Copy(sourceArray, 0, array, 0, 16);
Array.Copy(sourceArray, 0, array, 15, 16);
rijndaelManaged.Key = array;
rijndaelManaged.Mode = CipherMode.ECB;
ICryptoTransform cryptoTransform = rijndaelManaged.CreateEncryptor();
byte[] bytes = Encoding.ASCII.GetBytes(input);
result = Convert.ToBase64String(cryptoTransform.TransformFinalBlock(bytes, 0, bytes.Length));
}
catch (Exception expr_7B)
{
ProjectData.SetProjectError(expr_7B);
Exception ex = expr_7B;
Interaction.MsgBox(ex.Message, MsgBoxStyle.OkOnly, null);
result = "";
ProjectData.ClearProjectError();
}
return result;
}
It becomes super simple to solve this challenge at this stage. The input parameter is just the text we enter into the textbox and the pass parameter is Form1.GlobalVariables.assembly
which is defined to be the string __ERROR_HANDLER
. All we have to do is reverse the encryption starting with an input that equals zV5/UFU8PUD3N2T49IBuCwvGzCLYz39tkMZts7rfBU4=
. We first decode the base64 string into a byte array and then run the program again but with rijndaelManaged.CreateEncryptor()
changed to rijndaelManaged.CreateDecryptor()
.
I wrote a small C# program that accomplishes what we want to do:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//Undo Encrypt function!
string input = "zV5/UFU8PUD3N2T49IBuCwvGzCLYz39tkMZts7rfBU4=";
string pass = "__ERROR_HANDLER";
//Decode base64
byte[] unb64 = Convert.FromBase64String(input);
//Set up the Rijndael keys in same way as before
byte[] result;
RijndaelManaged rijndaelManaged = new RijndaelManaged();
MD5CryptoServiceProvider mD5CryptoServiceProvider = new MD5CryptoServiceProvider();
byte[] array = new byte[32];
byte[] sourceArray = mD5CryptoServiceProvider.ComputeHash(Encoding.ASCII.GetBytes(pass));
Array.Copy(sourceArray, 0, array, 0, 16);
Array.Copy(sourceArray, 0, array, 15, 16);
rijndaelManaged.Key = array;
rijndaelManaged.Mode = CipherMode.ECB;
ICryptoTransform cryptoTransform = rijndaelManaged.CreateDecryptor(); //This time we make a decryptor
//Transform final block
result = cryptoTransform.TransformFinalBlock(unb64, 0, unb64.Length);
//Print result as ASCII
Console.WriteLine(Encoding.ASCII.GetString(result));
}
}
}
We run the above program and get our flag!
Flag:
HV15-uQEJ-4HPX-Qcau-Xvt7-NAlP