𝖌𝖕𝖆.𝖗𝖎𝖕 𝖇𝖑𝖔𝖌

CSIT's Easter 2023 Challenge Walkthrough

Published 10 April 20235 min read
image
Image Credit: CSIT

The CSIT Easter 2023 Mini Challenge lasted from 7 April 2023 to 23 April 2023, and was first announced on CSIT's LinkedIn.
The link for the challenge download and submission can be found here: Link

Difficulty and Requirements

Challenge Difficulty: 1/5 (Beginner)

Theme: Reverse Engineering

Estimated Time with Walkthrough: 5-10 Mins

Requirements:

Given Files

RabbitHole.zip

Hash Calculation

You can calculate the Hash of the EXE and compare it with the following SHA256 Hash to make sure the EXE is as intended.

SHA256 Hash: 13d604a0bda615114681781b93ce7f0226c5faa28e4eba19c12791d9a95d7232

CMD Command: certutil -hashfile "C:\fileDirectory\RabbitHole.exe" SHA256

Terminal Command: sha256sum ./RabbitHole.exe

Solution Walkthrough

Open up RabbitHole.exe with dnSpy 32-bit and navigate to the RabbitHole.exe Module, RabbitHole Namespace, MainWindow Type, Image_MouseLeftButtonUp Method.

This method contains the code we need to look at to find the flag.

image
Class and Method Structure

The code should look something like this:

					
// RabbitHole.MainWindow
// Token: 0x06000007 RID: 7 RVA: 0x00002134 File Offset: 0x00000334
private void Image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
	Random random = new Random();
	Assembly executingAssembly = Assembly.GetExecutingAssembly();
	string text = "RabbitHole.Resources.aa.txt";
	string text2 = "RabbitHole.Resources.a.txt";
	string text3 = "RabbitHole.Resources.aaa.txt";
	string[] array = new StreamReader(executingAssembly.GetManifestResourceStream(text2)).ReadToEnd().Split(new char[] { ',' });
	string[] array2 = new StreamReader(executingAssembly.GetManifestResourceStream(text3)).ReadToEnd().Split(new char[] { ',' });
	Point position = Mouse.GetPosition(this);
	Point point = new Point(position.X, position.Y);
	Point point2 = new Point(Convert.ToDouble(array[random.Next(1, 15) % array.Length]), Convert.ToDouble(array2[random.Next(1, 21) % array2.Length]));
	string text4 = new c().cc();
	if (point == point2)
	{
		byte[] array3 = Convert.FromBase64String(new StreamReader(executingAssembly.GetManifestResourceStream(text)).ReadToEnd());
		MemoryStream memoryStream = new MemoryStream(this.bbb(array3, text4));
		BitmapImage bitmapImage = new BitmapImage();
		bitmapImage.BeginInit();
		bitmapImage.StreamSource = memoryStream;
		bitmapImage.EndInit();
		this.myImg.Source = bitmapImage;
		return;
	}
	MessageBox.Show("The egg is not here and has moved to a new location! Please try again.", string.Format("X={0}, Y={1}", point.X, point.Y), MessageBoxButton.OK, MessageBoxImage.Hand);
}

					
				    

The Method generates a new set of x and y co-ordinates every time a location on the image in the exe is clicked.

The generator takes from the file "RabbitHole.Resources.a.txt" for the x co-ordinate and from the file "RabbitHole.Resources.aaa.txt" for the y co-ordinate, meaning there are only a limited amount of possibilities for generated co-ordinates.

The Method then compares the generated co-ordinates to the user's clicked co-ordinates and gives you the flag if they are the same.

Since the generation and comparison of co-ordinates only happens after the user clicks on a certain co-ordinate:

  • It would not be possible to know what co-ordinates will be selected by the generator untill after the user has clicked.
  • Given the pre-defined co-ordinates, it would be possible to keep clicking on an answer co-ordinate untill the flag is given, however that would take a long time and alot of effort.
  • 						
    // Possible answer x co-ordinates ("RabbitHole.Resources.a.txt")
    
    958,487,1054,100,54,770,98
    
    // Possible answer y co-ordinates ("RabbitHole.Resources.aaa.txt")
    
    10,910,789,507,200
    
    // Possible generated answer co-ordinates
    
    {958,10},{487,10},{1054,10},{100,10},{54,10},{770,10},{98,10},{958,910}......
    
    // With the 35 different possible answer co-ordinates, as long as you keep clicking 
    // on any one of them, with luck on your side, you will eventually be able to get the flag 
    // (With alot of effort and a 2.86% success chance)
    				    

    To make it easier, we can simply edit the comparison co-ordinates to our selected co-ordinates, or vice versa during debugging.

    Set a breakpoint right before the comparison operation so that the pointers can be modified.

    image
    Place Breakpoint

    Start the debugger by clicking the start button at the navigation bar.

    image
    Start Debugging

    If the Debug Program prompt appears, simply click on "Ok".

    image
    Debug Program

    Click on any co-ordinate during the debugging process and make sure that the program reaches the breakpoint.

    After the breakpoint has been reached, click on the dropdown for the "point" variable {1} and change the x and y values {2} to match those of the "point2" variable {3}.

    image
    Change Values
    image
    Values After Changing

    Resume the Program.

    image
    Resume Button

    After resuming the program, the screen will be changed to an image with a golden egg and the details of the flag.

    image
    Resume Button

    Entering the flag on the answer page on CSIT will result in a congratulation page with the following Reward Badge:

    image
    Reward Badge

    Remarks

    Thank you for reading my blog! If it helped you out with learning reverse engineering, feel free to show your support by connecting with me on LinkedIn! (Leave a message telling me that you came from here!)