Post

Windows Of Opportunity

Today I will tell you about how I solved ‘WindowsOfOpportunity’ challenge from HTB Uni CTF 2023. The difficulty level of challenge is easy.

A file named ‘windows’ was given. First, I checked the type of given file:

file type check

It was a Linux executable file. Then, I checked the strings present in the file using ‘strings filename’ command but found nothing interesting.

As it was an executable file, I decided to view its source code by decompiling it using a website: Decompiler Explorer

decompiling

Dogblot website allows you to decompile executable files using various decompilers. I go through the source codes generated by various decompilers, but the source code of ‘Hex-Rays’ was easy to understand for me. So, I decided to analyze it thoroughly.

I started analyzing the main function. It asks user for a password and then it loops through the first 37 characters of the user’s input. In program, 0x24 is a hex value which is equal to 36. In for loop, it is adding two characters of user’s input, one at current iteration index and one next to this. Afterwards, it compares the resulting value with value of an array ‘arr’ at current iteration index. If the condition is true, loop stops and it will print ‘The window slams shut…”. Otherwise, loop will continue. If condition is false every time, loop will complete and print “The window opens to allow you passage…”.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int __fastcall main(int argc, const char **argv, const char **envp)
{
  char s[43]; // [rsp+0h] [rbp-30h] BYREF
  char v5; // [rsp+2Bh] [rbp-5h]
  unsigned int i; // [rsp+2Ch] [rbp-4h]

  puts("A voice comes from the window... 'Password?'");
  fgets(s, 42, stdin);
  for ( i = 0; i <= 0x24; ++i )
  {
    v5 = s[i] + s[i + 1];
    if ( v5 != arr[i] )
    {
      puts("The window slams shut...");
      return -1;
    }
  }
  puts("The window opens to allow you passage...");
  return 0;
}

Following is the snippet of array used for comparison in main function.

1
2
3
4
5
6
7
8
9
_BYTE arr[37] =
{
  -100,
  -106,
  -67,
  .
  .
  .
}

This array contains 37 char values (char data type ranges from -127 to 127).

Now, I understood how program works. Next step was to create a program which will reverse the whole process and give us our flag.

In source program, the main function was comparing the sum of two consecutive characters from input with values of array, it means while reversing one character will be found on the basis of its next character.

Let’s suppose we have an array like [-100,-106]. The sum of character ‘H’ and ‘T’ will result in -100 char value because of overflow (as range of char value is -127 to 127). The sum of both characters is equal to first value of array. Here we cannot say that ‘H’ and ‘T’ are correct characters because there can be other combinations of characters, like l and 0, which can lead to -100 char value. In order to verify whether ‘H’ and ‘T’ are correct characters, we need to check sum of character ‘T’ and other possible character is equal to -106 char value of array. If we found any combination whose value is equal to -106 value of array, then it means both characters are correct otherwise not. In this case, sum of ‘T’ and ‘B’ equals to -106. So, our correct characters will be HTB.

I created a C program which reverses the whole process of given ‘windows’ executable file. In my C program, I created a rev function which contains two loops which are iterating through 32–125 which is range of printable ascii characters. Both loops are doing the same things as I explained in the above example. First loop finds a combination which equals to value of array at an index and second loop verifies whether combination is correct or not. It will print any correct character found and that’s how we will get our flag.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
int rev(char i, int arr_index){

	for(char j=32;j<=125;j++){
			
		char t = i + j;
		
		if (t == arr[arr_index]){
					
			if(arr_index == 36){
        	
				printf("%c%c",i,j,arr_index);
				
				return -1;
			}

			for(char l=32;l<=125;l++){
					
				char v = j + l;
					
				if(v == arr[arr_index+1]){
					
					printf("%c",i);
			
					return rev(j,arr_index+1);		

				}
					
			}
					

		}
			
	}
		
}
1
2
3
4
5
6
int main(){

		rev(72,0);
		
	return 0;
}

The rev function takes two parameters, a character and integer (used for tracking index). I knew that the format of HTB flags is like this HTB{.*}. So, I gave the character value of H which is 72 as argument and 0 as starting index while calling the rev function inside main function. When I ran the program, It gave me the flag.

1
HTB{4_d00r_cl0s35_bu7_4_w1nd0w_0p3n5!}
This post is licensed under CC BY 4.0 by the author.

Trending Tags