Reverse Challenge .NET (are you sure ?)

I would like to write about mini challenge about reversing the .NET application. There is nothing new here but I just want to create it at my blog.

I created an application myself with some simple AES encryption implementation provided in C#. So this application will encrypt an information that we dont know with IV and Key and print the output.

In order to do the reverse, I need to identify the compiled code. Let use PEStudio to get the overview of the PE.

So based on the above higlighted information, we know that this application was developed using .NET Framework.

There is a great tool that we can use to reverse .NET application called dnSpy. This tool works amazingly that can decompile into its original code almost 100%.

Lets download and run dnSpy application from https://github.com/0xd4d/dnSpy/releases

Open dnSpy and open the file

Lets start browse the application and check for the main function as the begining of all application

In the right panel we can find the code of main function. (Amazing right? compared to decompiling using IDA) I will tell you later why it is possible to be decompile into this detail.

// RioReverse.Program
// Token: 0x06000002 RID: 2 RVA: 0x00002090 File Offset: 0x00000290
private static void Main(string[] args)
{
	Dns.GetHostEntry(Dns.GetHostName());
	string encryptedData = Convert.ToBase64String(Program.EncryptStringToBytes_Aes(Program.LocalIPAddress().ToString(), Encoding.ASCII.GetBytes("MbQeThWmZq4t7w!z"), Encoding.ASCII.GetBytes("B?E(H+MbQeThWmZq")));
	Console.WriteLine("Encrypted data : " + encryptedData);
}
// RioReverse.Program
// Token: 0x06000001 RID: 1 RVA: 0x00002050 File Offset: 0x00000250
private static IPAddress LocalIPAddress()
{
	if (!NetworkInterface.GetIsNetworkAvailable())
	{
		return null;
	}
	return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault((IPAddress ip) => ip.AddressFamily == AddressFamily.InterNetwork);
}
// RioReverse.Program
// Token: 0x06000003 RID: 3 RVA: 0x000020EC File Offset: 0x000002EC
private static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
{
	if (plainText == null || plainText.Length <= 0)
	{
		throw new ArgumentNullException("plainText");
	}
	if (Key == null || Key.Length == 0)
	{
		throw new ArgumentNullException("Key");
	}
	if (IV == null || IV.Length == 0)
	{
		throw new ArgumentNullException("IV");
	}
	byte[] encrypted;
	using (Aes aesAlg = Aes.Create())
	{
		aesAlg.Key = Key;
		aesAlg.IV = IV;
		ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
		using (MemoryStream msEncrypt = new MemoryStream())
		{
			using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
			{
				using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
				{
					swEncrypt.Write(plainText);
				}
				encrypted = msEncrypt.ToArray();
			}
		}
	}
	return encrypted;
}

So basically we can see that the application workflow are below
1. Application will get the default network IP of the computer
2. Pass it to the AES Encryption and Get the return result encrypted text

Next we need to find what is the Key and IV being used in this AES encryption

We can see that from the function signature above, EncrypStringToBytes_Aes accept 3 paramenters
1. string PlainText
2. byte [] Key
3. byte [] IV

So basically we can identify those 3 parameters above from the main function which calls the EncyptStringToBytes_Aes as below map

Now we can get the value of Key and IV as below
1. Key = MbQeThWmZq4t7w!z
2. IV = B?E(H+MbQeThWmZq

So based on this information we can now reverse the encrypted message (“QGhHhWevg0aOD4BNtP/H3g==”) to the original text with the information we have gathered

Lets decrypt it

Go to website https://www.devglan.com/online-tools/aes-encryption-decryption

1. Put the encrypted text which is base64 encoded
2. Select input text is Base64
3. Select Mode to CBC

4. Put the IV we have got
5. Select the Key size in bit (Size = Key Length * 8 so 16 * 8 = 128)
6. Enter the secret Key we have got

7. Press decrypt
8. You will get the result but still encoded in base64
9. Press decode to plain text
10. You can get the result of the original text

I would also like to discuss in this case that with dnSpy you can change the code and recompile it. Let me show you how to do it.

For example you want to put additional Console.WriteLine(); so that you can see what is the actual string before it is pushed to encryption function.

Go to the main function and right click on the code and select edit method

There will be new windows poped up

using System;
using System.Net;
using System.Text;

namespace RioReverse
{
	// Token: 0x02000002 RID: 2
	internal partial class Program
	{
		// Token: 0x06000002 RID: 2 RVA: 0x00002090 File Offset: 0x00000290
		private static void Main(string[] args)
		{
			Dns.GetHostEntry(Dns.GetHostName());
			Console.WriteLine("Data before Encrypted : " + Program.LocalIPAddress().ToString());
			string encryptedData = Convert.ToBase64String(Program.EncryptStringToBytes_Aes(Program.LocalIPAddress().ToString(), Encoding.ASCII.GetBytes("MbQeThWmZq4t7w!z"), Encoding.ASCII.GetBytes("B?E(H+MbQeThWmZq")));
			Console.WriteLine("Encrypted data : " + encryptedData);
		}
	}
}

I added the code like this to write the data before it is encrypted

Press Compile

Press Save All

We can see the different as below where the Original PE and Patched PE with additional code that we added to show the data before get encrypted

You can download my application at https://github.com/rioasmara/wordpress/blob/master/netcoreapp3.1.7z

One comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s