I didn’t get to spend a lot of time on the FLARE-On challenges this year, but I worked through the first 2 and used it as an opportunity to learn Radare2 a little better.

Here’s my solution to challenge 1.

$ md5 challenge1.exe
MD5 (challenge1.exe) = 2caaa4aa5923d026b17d7b38ee410918

I ran strings on the file to see if there was anything interesting. The ones below stood out.

$ gstrings -n 48 challenge1.exe

Enter password:
Wrong password


It looks like the program prompts for a password and will output whether it was correct. The first string looks like some encoded data. We might first guess it’s base64 encoded, but, not so much:

$ echo "x2dtJEOmyjacxDemx2eczT5cVS9fVUGvWTuZWjuexjRqy24rV29q" | base64 -D

However, that last string is interesting. It looks like all the characters in a typical base64 alphabet, but it starts with XYZ instead of ABC, so it looks like this may be base64 using a custom alphabet.

Before testing that, I did take a look at the file in radare2, since like I mentioned in the summary, I wanted to use these challenges as a way to learn radare. There may be better ways to do what I was doing, and I’m definitely open to suggestions.

$ r2 challenge1.exe
[0x0040170d]> aaaa
[0x0040170d]> s sym.main
[0x00000000]> pdf
Cannot find function at 0x00000000

Typically, after analyzing, I run “s sym.main” but it wasn’t found with the analysis. I knew the output strings would be near the important code, so I ran:

$ r2 challenge1.exe
[0x0040170d]> aaaa
[0x0000bfac]> s/ Correct
Searching 7 bytes from 0x0000bfad to 0x00417e64: 43 6f 72 72 65 63 74
Searching 7 bytes in [0xbfad-0x417e64]
hits: 1  hit1_0 .. hit1_0
0x0040d1ac hit1_0 .r password:Correct!Wrong passw.
[0x0040d1ac]> pd 20
;-- str.Correct__r_n:
; DATA XREF from 0x004014ae (sub.KERNEL32.dll_GetStdHandle_420)
0x0040d1ac     .string "Correct!\\r\\n" ; len=11

[0x0040d1ac]> s 0x4014ae
[0x004014ae]> pd 10
│           0x004014ae      68acd14000     push str.Correct__r_n ; str.Correct__r_n ; "Correct!.." @ 0x40d1ac
│           0x004014b3      8b4df8         mov ecx, dword [ebp - local_8h]
│           0x004014b6      51             push ecx
│           0x004014b7      ff15a0d04000   call dword [sym.imp.KERNEL32.dll_WriteFile] ; sym.imp.KERNEL32.dll_WriteFile
│       ┌─< 0x004014bd      eb17           jmp 0x4014d6
│       │   0x004014bf      6a00           push 0
│       │   0x004014c1      8d55fc         lea edx, [ebp - local_4h]
│       │   0x004014c4      52             push edx
│       │   0x004014c5      6a11           push 0x11
│       │   0x004014c7      68b8d14000     push str.Wrong_password_r_n ; str.Wrong_password_r_n ; "Wrong password.." @ 0x40d1b8
[0x004014ae]> s sub.KERNEL32.dll_GetStdHandle_420
[0x00401420]> pdf
╒ (fcn) sub.KERNEL32.dll_GetStdHandle_420 188
│   sub.KERNEL32.dll_GetStdHandle_420 ();
│           ; var int local_94h @ ebp-0x94
│           ; var int local_14h @ ebp-0x14
│           ; var int local_10h @ ebp-0x10
│           ; var int local_ch @ ebp-0xc
│           ; var int local_8h @ ebp-0x8
│           ; var int local_4h @ ebp-0x4
│           ; CALL XREF from 0x0040168b (entry0)
│           0x00401420      55             push ebp
│           0x00401421      8bec           mov ebp, esp
│           0x00401423      81ec94000000   sub esp, 0x94
│           0x00401429      6af5           push -0xb
│           0x0040142b      ff1510d14000   call dword [sym.imp.KERNEL32.dll_GetStdHandle] ; sym.imp.KERNEL32.dll_GetStdHandle
│           0x00401431      8945f8         mov dword [ebp - local_8h], eax

So this looks like the function we want. I switched over to visual mode to get a look at the control flow by entering “VV” on the console and hitting enter, then hitting “p” until I got to the BB-SUMM screen:

[0x00401420]> VV @ sub.KERNEL32.dll_GetStdHandle_420 (nodes 4 edges 4 zoom 100%) BB-SUMM mouse:canvas-y movements-speed:5

                             | [0x401420]                                                 |
                             | 0x0040142b call dword [sym.imp.KERNEL32.dll_GetStdHandle]  |
                             | 0x00401436 call dword [sym.imp.KERNEL32.dll_GetStdHandle]  |
                             | 0x0040144e str.Enter_password:_r_n                         |
                             | 0x00401457 call dword [sym.imp.KERNEL32.dll_WriteFile]     |
                             | 0x00401473 call dword [sym.imp.KERNEL32.dll_ReadFile]      |
                             | 0x00401487 call fcn.00401260                               |
                             | 0x0040149a call fcn.00402c30                               |
                                   t f
     .-----------------------------' '---------------------------------.
     |                                                                 |
     |                                                                 |
---------------------------------------------------------=     =---------------------------------------------------------=
  0x4014bf                                               |     |  0x4014a6                                               |
 0x004014c7 str.Wrong_password_r_n                       |     | 0x004014ae str.Correct__r_n                             |
 0x004014d0 call dword [sym.imp.KERNEL32.dll_WriteFile]  |     | 0x004014b7 call dword [sym.imp.KERNEL32.dll_WriteFile]  |
---------------------------------------------------------=     =---------------------------------------------------------=
   v                                                               v
                                                 |  0x4014d6          |

It looks like handles to STDIN and STDOUT are created, the prompt is printed, input is read, and then processed in the two calls to determine if it was successful or not.

I looked over the code and determined the argument passed in (arg_ch) was the password length, which was divided by 3 and multiplied by 4 (because every 3 ASCII characters turn into 4 characters in the base64 output). The base64 alphabet from the strings output is also referenced a lot in this function, so that pretty much confirmed what was going on.

[0x00401420]> s 0x401260
[0x00401260]> pdf
╒ (fcn) fcn.00401260 448
│   fcn.00401260 (int arg_8h, int arg_ch);
│           ; CALL XREF from 0x00401487 (sub.KERNEL32.dll_GetStdHandle_420)
│           0x00401260      55             push ebp
│           0x00401261      8bec           mov ebp, esp
│           0x00401263      83ec30         sub esp, 0x30               ; '0'
│           0x00401266      8b450c         mov eax, dword [ebp + arg_ch] ; [0xc:4]=0xffff
│           0x00401269      83c002         add eax, 2
│           0x0040126c      33d2           xor edx, edx
│           0x0040126e      b903000000     mov ecx, 3
│           0x00401273      f7f1           div ecx
│           0x00401275      8d1485010000.  lea edx, [eax*4 + 1]        ; 0x1 ; "Z."
│           0x0040127c      8955e8         mov dword [ebp - local_18h], edx
│           0x0040127f      8b45e8         mov eax, dword [ebp - local_18h]
│           0x00401282      50             push eax
│           0x00401283      e8341a0000     call sub.KERNEL32.dll_HeapAlloc_cbc

I found a website that allowed you to enter a custom base64 alphabet, and got the resulting key for challenge1: sh00ting_phish_in_a_barrel@flare-on.com.

Base64 Decode with custom alphabet