India - Reverse Me & Extract Flag from Packets (rev/network)

Inspecting the wireshark PCAP, there only seems to be one TCP stream. Right click any packet and follow TCP Stream to see the following:

type c:\tmp\flag.txt
1KeGOcMvvKpPbxrNRdyqJmSGh3j+ZCvIT5RKk6lTBkSGBYSYrX7dy3Q/E8wVuQAXNFMs978T1A4qyx7EeX9fvg==

We can guess that this is probably some ciphertext we need to decrypt.

Let's look at the DMP we are given:

elijah@soyabean:/mnt/c/Users/chiae/Downloads/cyberseagames/csg_reversing_network_forensic_challenge/csg_reversing_network_forensic_challenge$ file ./csg_reversing_network_forensic_challenge.DMP
./csg_reversing_network_forensic_challenge.DMP: Mini DuMP crash report, 16 streams, Sun Sep  7 06:03:02 2025, 0x421826 type

I found that volatility was unable to work with this file, but WinDbg worked fine. On loading it into WinDbg we can list all modules using lm:

0:000> lm
start             end                 module name
0000015c`f4e80000 0000015c`f4e88000   Microsoft_Win32_Primitives   (pdb symbols)          C:\ProgramData\Dbg\sym\Microsoft.Win32.Primitives.pdb\CE3B39E6FAD8F5EC8C3AA743CDF400641\Microsoft.Win32.Primitives.pdb
0000015c`f67b0000 0000015c`f67b8000   ajccbc_reversing_challenge   (deferred)             
0000015c`f67c0000 0000015c`f67ce000   System_Runtime   (deferred)             
0000015c`f67d0000 0000015c`f67d8000   System_Runtime_Intrinsics   (deferred)             
0000015c`f67e0000 0000015c`f67e8000   System_Diagnostics_Tracing   (deferred)             
00007ff7`97ce0000 00007ff7`98638000   csg_reversing_network_forensic_challenge   (deferred)             
00007ffc`893e0000 00007ffc`8a06d000   System_Private_CoreLib   (deferred)             
00007ffc`93a40000 00007ffc`93c6e000   icu        (deferred)             
00007ffc`a82f0000 00007ffc`a8373000   System_Net_Sockets   (deferred)             
00007ffc`a8500000 00007ffc`a8524000   System_Memory   (deferred)             
00007ffc`a8580000 00007ffc`a85a8000   System_Console   (deferred)             
00007ffc`a8660000 00007ffc`a8696000   System_Net_Primitives   (deferred)             
00007ffc`af430000 00007ffc`af445000   System_Runtime_InteropServices   (deferred)             
00007ffc`b2180000 00007ffc`b2214000   apphelp    (deferred)             
00007ffc`b2420000 00007ffc`b2427000   wshunix    (deferred)             
00007ffc`b2ca0000 00007ffc`b2cb2000   kernel_appcore   (deferred)             
00007ffc`b44b0000 00007ffc`b451a000   mswsock    (pdb symbols)          C:\ProgramData\Dbg\sym\mswsock.pdb\E366E96F199A74D8B7651617AF8408431\mswsock.pdb
00007ffc`b4e00000 00007ffc`b4e27000   bcrypt     (deferred)             
00007ffc`b4f90000 00007ffc`b528d000   KERNELBASE   (deferred)             
00007ffc`b5290000 00007ffc`b53a7000   gdi32full   (deferred)             
00007ffc`b53b0000 00007ffc`b53d2000   win32u     (deferred)             
00007ffc`b5500000 00007ffc`b5582000   bcryptPrimitives   (deferred)             
00007ffc`b55e0000 00007ffc`b56e0000   ucrtbase   (deferred)             
00007ffc`b56e0000 00007ffc`b577d000   msvcp_win   (deferred)             
00007ffc`b5780000 00007ffc`b58a3000   rpcrt4     (deferred)             
00007ffc`b58b0000 00007ffc`b601f000   shell32    (deferred)             
00007ffc`b6600000 00007ffc`b6953000   combase    (deferred)             
00007ffc`b6a70000 00007ffc`b6b10000   sechost    (deferred)             
00007ffc`b6bc0000 00007ffc`b6d5d000   user32     (deferred)             
00007ffc`b6d60000 00007ffc`b6e21000   kernel32   (deferred)             
00007ffc`b6f30000 00007ffc`b6f9b000   ws2_32     (pdb symbols)          C:\ProgramData\Dbg\sym\ws2_32.pdb\C4AF2923BB8706346F027C3A7631E89F1\ws2_32.pdb
00007ffc`b6fa0000 00007ffc`b706d000   oleaut32   (deferred)             
00007ffc`b7070000 00007ffc`b709b000   gdi32      (deferred)             
00007ffc`b7100000 00007ffc`b719e000   msvcrt     (deferred)             
00007ffc`b71a0000 00007ffc`b72cb000   ole32      (deferred)             
00007ffc`b72d0000 00007ffc`b72ff000   imm32      (deferred)             
00007ffc`b7300000 00007ffc`b73b0000   advapi32   (deferred)             
00007ffc`b7750000 00007ffc`b7948000   ntdll      (pdb symbols)          C:\ProgramData\Dbg\sym\ntdll.pdb\4C328D42D0B9A2B218FB85860DECF27C1\ntdll.pdb

We can guess that the module of interest is probably csg_reversing_network_forensic_challenge or ajccbc_reversing_challenge. Unfortunately the WinDbg .writemem command didn't work successfully. This is because ajccbc_reversing_challenge.dll was not stored contiguously in memory, as we can see using !address -f:MEM_COMMIT to filter by committed virtual memory:

     15c`f67b0000      15c`f67b1000        0`00001000 MEM_IMAGE   MEM_COMMIT  PAGE_READONLY                      Image      [ajccbc_reversing_challenge; "C:\Users\tsshimizu\Desktop\share\win-x64\ajccbc_reversing_challenge.dll"]
     15c`f67b2000      15c`f67b5000        0`00003000 MEM_IMAGE   MEM_COMMIT  PAGE_READONLY                      Image      [ajccbc_reversing_challenge; "C:\Users\tsshimizu\Desktop\share\win-x64\ajccbc_reversing_challenge.dll"]
     15c`f67b6000      15c`f67b7000        0`00001000 MEM_IMAGE   MEM_COMMIT  PAGE_READONLY                      Image      [ajccbc_reversing_challenge; "C:\Users\tsshimizu\Desktop\share\win-x64\ajccbc_reversing_challenge.dll"]

What worked was using the MEX Debugging Extension for WinDbg, and using it to write modules. You can use the following command to dump all DLLs/EXEs:

!mex.writemodule -a -p "C:\Users\chiae\Downloads\cyberseagames\csg_reversing_network_forensic_challenge\csg_reversing_network_forensic_challenge"

Apparently the exe was generated as a result of JIT compilation when the dll is run.

Let's analyse the dll using dnspy:

Let's look at the important C# functions:

private static void <Main>$(string[] args)
{
	arc_server.RemoteShell();
}

internal class arc_server
{
	// Token: 0x06000008 RID: 8 RVA: 0x00002160 File Offset: 0x00000360
	public static void RemoteShell()
	{
		TcpListener tcpListener = new TcpListener(IPAddress.Any, 8553);
		tcpListener.Start();
		bool flag = true;
		arc_crypto arc_crypto = new arc_crypto();
		while (flag)
		{
			using (TcpClient tcpClient = tcpListener.AcceptTcpClient())
			{
				using (NetworkStream stream = tcpClient.GetStream())
				{
					using (StreamReader streamReader = new StreamReader(stream))
					{
						using (StreamWriter streamWriter = new StreamWriter(stream)
						{
							AutoFlush = true
						})
						{
							string text;
							while ((text = streamReader.ReadLine()) != null)
							{
								string text2 = text.ToLower().Trim();
								if (text2 == "quit" || text2 == "q" || (text2 != null && text2.Length == 0))
								{
									flag = false;
								}
								else
								{
									Console.WriteLine("Received command: " + text);
									string text3 = arc_server.ExecuteCommand(text);
									arc_communicator.postBlog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ": " + arc_crypto.obfuscate(text), arc_crypto.obfuscate(text3));
									streamWriter.WriteLine(arc_crypto.obfuscate(text3));
								}
							}
						}
					}
				}
			}
		}
	}

As we can see from this snippet:

string text;
while ((text = streamReader.ReadLine()) != null)
{
	string text2 = text.ToLower().Trim();
	if (text2 == "quit" || text2 == "q" || (text2 != null && text2.Length == 0))
	{
		flag = false;
	}
	else
	{
		Console.WriteLine("Received command: " + text);
		string text3 = arc_server.ExecuteCommand(text);
		arc_communicator.postBlog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ": " + arc_crypto.obfuscate(text), arc_crypto.obfuscate(text3));
		streamWriter.WriteLine(arc_crypto.obfuscate(text3));
	}
}

What wireshark captured was the command executed, and the following line was the obfuscated result of executing that command.

Let's look at all the obfuscation:

public class arc_crypto
	{
		// Token: 0x0600000B RID: 11 RVA: 0x000023B4 File Offset: 0x000005B4
		public arc_crypto()
		{
			string text = "2a5b05310e08081f2b3405031134372a073c1f1c371a2e1c09303b4308393219";
			string text2 = "252e0a0a3a1f291c1b343b39212b3c11013d312f08315158";
			this.key = Encoding.UTF8.GetBytes(arc_crypto.AdvancedDecode(text));
			this.iv = Encoding.UTF8.GetBytes(arc_crypto.AdvancedDecode(text2));
		}

		// Token: 0x0600000C RID: 12 RVA: 0x00002400 File Offset: 0x00000600
		public string obfuscate(string plainText)
		{
			string text;
			using (Aes aes = Aes.Create())
			{
				aes.Key = this.key;
				aes.IV = this.iv;
				ICryptoTransform cryptoTransform = aes.CreateEncryptor(aes.Key, aes.IV);
				using (MemoryStream memoryStream = new MemoryStream())
				{
					using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, 1))
					{
						using (StreamWriter streamWriter = new StreamWriter(cryptoStream))
						{
							streamWriter.Write(plainText);
						}
						text = Convert.ToBase64String(memoryStream.ToArray());
					}
				}
			}
			return text;
		}

		// Token: 0x0600000D RID: 13 RVA: 0x000024D0 File Offset: 0x000006D0
		public static string AdvancedEncode(string input)
		{
			string text = Convert.ToBase64String(Encoding.UTF8.GetBytes(input));
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < text.Length; i++)
			{
				stringBuilder.Append(text[i] ^ arc_crypto.xorKey[i % arc_crypto.xorKey.Length]);
			}
			string text2 = stringBuilder.ToString();
			StringBuilder stringBuilder2 = new StringBuilder();
			foreach (char c in text2)
			{
				StringBuilder stringBuilder3 = stringBuilder2;
				int num = (int)c;
				stringBuilder3.Append(num.ToString("x2"));
			}
			return stringBuilder2.ToString();
		}

		// Token: 0x0600000E RID: 14 RVA: 0x00002578 File Offset: 0x00000778
		public static string AdvancedDecode(string input)
		{
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < input.Length; i += 2)
			{
				stringBuilder.Append((char)Convert.ToInt32(input.Substring(i, 2), 16));
			}
			string text = stringBuilder.ToString();
			StringBuilder stringBuilder2 = new StringBuilder();
			for (int j = 0; j < text.Length; j++)
			{
				stringBuilder2.Append(text[j] ^ arc_crypto.xorKey[j % arc_crypto.xorKey.Length]);
			}
			string text2 = stringBuilder2.ToString();
			string text3;
			try
			{
				byte[] array = Convert.FromBase64String(text2);
				text3 = Encoding.UTF8.GetString(array);
			}
			catch (Exception)
			{
				text3 = null;
			}
			return text3;
		}

		// Token: 0x04000001 RID: 1
		private readonly byte[] key;

		// Token: 0x04000002 RID: 2
		private readonly byte[] iv;

		// Token: 0x04000003 RID: 3
		private static readonly string xorKey = "simplekey";

		// Token: 0x04000004 RID: 4
		private static readonly string orKeyx = "complekey";
	}
}

key: AdvancedDecode("2a5b05310e08081f2b3405031134372a073c1f1c371a2e1c09303b4308393219")

iv: AdvancedDecode("252e0a0a3a1f291c1b343b39212b3c11013d312f08315158")

Upon decoding the key and iv using the xorKey which is simplekey, we can use AES CBC to decrypt the flag:

from base64 import b64decode
from pwn import *
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad

key = "2a5b05310e08081f2b3405031134372a073c1f1c371a2e1c09303b4308393219"
iv = "252e0a0a3a1f291c1b343b39212b3c11013d312f08315158"
ct = "1KeGOcMvvKpPbxrNRdyqJmSGh3j+ZCvIT5RKk6lTBkSGBYSYrX7dy3Q/E8wVuQAXNFMs978T1A4qyx7EeX9fvg=="
xorKey = b'simplekey'

key = bytes.fromhex(key)
iv = bytes.fromhex(iv)
key = xor(key, xorKey)
iv = xor(iv, xorKey)
key = b64decode(key.decode())
iv = b64decode(iv.decode())
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
ct = b64decode(ct)
pt = cipher.decrypt(ct)
pt = unpad(pt, AES.block_size).decode()
print(f"plaintext: {pt}") 
# plaintext: R3v3rsing_@nd_N3tw0rk_F0r3nsic_Ch@ll3ng3_S0lv3d!!

Last updated