The contests of this post were originally from this github repository.


The contestant is given a Windows executable file named Calculator.exe, which is a modified version of an open source calculator and is an obfuscated .NET program.

The obfuscation made it a very confusing challenge, but thankfully I managed to follow an online guide but someone else had already beat me in getting first blood fo the challenge.

An image of the calculator

Reconaissance

  • IlSpy
    • The Github repository the program was based on was in C#, and I knew that C# programs were easy to decompile.
    • I knew from my experience messing with Unity games that I had to use a program like IlSpy or DnSpy to view the program’s decompiled source code.
    • I tried using the IlSpy extension for Visual Studio Code but I soon realised that the program had pretty serious deobfuscation. Even the class names were invisible Unicode characters.
  • Virtual Machine
    • Running the program in a Windows virtual machine gave me a popup stating that it was deobfuscated with SmartAssembly.
  • Hybrid Analysis
    • Uploading the program to Hybrid Analysis revealed that the program had base64 decoding and cryptographic capabilities, although the program was probably stuck at the SmartAssembly popup the whole time.

What didn’t work

  • I tried following this guide on SimpleAssembly Editor but it crashed when I tried to load the program.
  • I tried using de4dot to deobfuscate the program. I had to track down an installer for de4dot, but the deobfuscated code was too low level for me to really understand what was going on.
    • I saw classes that did nothing but generate byte arrays and called cryptographic functions, so that gave me the false impression that the flag was decrypted during runtime.
    • Worse is that the clean program generated by de4dot wouldn’t run.
  • Reading the program’s memory with Cheat Engine di not give me the flag either.

What worked

You know how insanity is doing the same thing over and over and expecting a different result? Well I tried following the guide on Simpleasssembly Editor again and I spotted this in the program’s code:

internal void m000007(object p0, EventArgs p1)
		{
			string text = this.f000003;
			string text2 = text;
			if (!(text2 == "+"))
			{
				if (!(text2 == "-"))
				{
					if (!(text2 == "*"))
					{
						if (text2 == "/")
						{
							this.f000019.Text = (this.f000002 / double.Parse(this.f000019.Text)).ToString();
						}
					}
					else
					{
						this.f000019.Text = (this.f000002 * double.Parse(this.f000019.Text)).ToString();
					}
				}
				else
				{
					this.f000019.Text = (this.f000002 - double.Parse(this.f000019.Text)).ToString();
				}
			}
			else
			{
				bool flag = this.f000019.Text == "289372" && this.f000002.ToString() == "93829";
				if (flag)
				{
					string text3 = "eW91IHdpbiA7KSBm";
					string text4 = "cnMgeW91IHVzZWQgaW4gdGhlIGZvcm";
					byte[] array = Convert.FromBase64String(text3 + this.f000001 + text4 + this.f000004);
					this.f000019.Text = Encoding.UTF8.GetString(array);
				}
				else
				{
					this.f000019.Text = (this.f000002 + double.Parse(this.f000019.Text)).ToString();
				}
			}
			this.f000002 = double.Parse(this.f000019.Text);
			this.f00001a.Text = " ";
		}

It had somehow deobfuscated all the references to some string table that made this very hard to begin with. f000019 and f000002 seem to correlate with the caluclator’s input text and result text.

I also found the folllowing base64 strings:

  • eW91IHdpbiA7KSBm you win ;) f
  • bGFnIGlzIHRoZSAyIG51bWJl lag is the 2 numbe
  • cnMgeW91IHVzZWQgaW4gdGhlIGZvcm rs you used in the for

From this I deduce that the flag must be IRS{289372_93829}