Flareon challenge 10

Couple of challenge notes I wrote for this year's Flareon10 ; Unfortunately, my laptop broke and I didn't have a ton of time to spare so I didn't get super far. Wanted to document this as I used PONCE on challenge 3 and haven't seen many write-ups that leverage symbolic/concolic execution plugins in IDA.



Challenge1

We unzip the folder, find a 64 bit exe; The pdb is in the folder which will probably make things easier.

We open it in Ida because the challeng points us to the .exe:

This package contains many files and, I can’t believe i’m saying this, click the one with the “.exe” file extension to launch the program. Maybe focus your “reverse engineering” efforts on that one too.

We quickly realize this is running apphost the .net launcher. The launcher is actually launching x.dll a mono game.

I was initially using the old archived version of dnspy and had never looked at async methods in it.

This is what the method looked like and initially I thought this was expected.

After mucking around for a bit, I thought I'd try Cheat-Engine's mono dissector instead. CE didn't pick up on Mono (probably because I was using an old version) but did show the .NET button. This highlighted the BackGround.Success method:

I xrefd it in dnspy and found it was used by MoveNext in the async function for which I couldn't get the decompiled code.

A quick StackOverflow post suggested I should use dnspyEx https://stackoverflow.com/questions/65110369/dnspy-showing-strange-disassembly-code-for-async-methods

DnspyEx clearly shows we should try 42

We try that and get the flag:

glorified_captcha@flare-on.com

Challenge2

We get an android apk file.

Dumping it in jadx, we get a ton of methods to look at.



Usually, the juicy stuff is under com.<appname>:

The Post Method under PostByWeb seemed interesting

We Xref it to the following onNewToken:

What is that c2 string? We can find that string under res/values/strings.xml:

It calls to https://flare-on.com/evilc2server/report_token/report_token.php?token=

Turns out this string is used under X but that's a red herring;

However, it's also used in the below that looks like it grabs substrings from c2 and w1 (mapping to "wednesday") and calls the a method on the UTF8 bytes.

I mucked around a bit with these; basically d builds the secret key, c reads the IV from the iv string in resources and b is an AES decrypt call to iv.png which is written to a file.

I commented the relevant stuff below:

I wrote a little script to run the d function and make sure I got the right CRC (initially I was getting the first value which I left in the comments; second value is the right one).

import java.util.zip.CRC32;

public class MyClass {
    

    public static void main(String args[]) {
      int x=10;
      int y=25;
      int z=x+y;

      System.out.println("Sum of x+y = " + z);
      
        String slice;
        String string = "https://flare-on.com/evilc2server/report_token/report_token.php?token=";
        String string2 = "wednesday";
        StringBuilder sb = new StringBuilder();
        sb.append(string.subSequence(4, 10));
        sb.append(string2.subSequence(2, 5));
        String sb2 = sb.toString();
                System.out.println(sb2);

        byte[] bytes;
         try {
         bytes = sb2.getBytes("UTF-8");
         CRC32 crc32 = new CRC32();
        crc32.update(bytes);
        long crc32res = crc32.getValue();
        StringBuilder sb3 = new StringBuilder();
        sb3.append(crc32res);
        sb3.append(crc32res);
        String sb4 = sb3.toString();
        System.out.println(sb4);
         } catch(Exception e) {
                   System.out.println("Sum of x+y = " + z);
      
}
                 
      
    }
}

Once I had the key and the IV, I just used cyberchef to get my png decrypted:

Challenge 3

We find the main (watch OALabs to learn how to identify it):

And quickly see we need a command line argument and that argument goes through a bunch of checks (if we fail the checks, we get signed out of windows...):

The first constraint is the cmp ecx,2 (which just checks that we have a command line arg);

The second check looks at the first character and comapres it to '0'

I used the Ponce plugin to solve some of these checks; RDX contains our argument so we browse that memory region and symbolize the memory/our argument.
I assumed this argument would be Ascii so we add the ASCII only constraint.


We can then step through and every time we hit a new constrain, right-click and "Negate-and-inject".

One of the checks was a VirtualAlloc for prepping some memory region and then running shellcode; In order to run shellcode, you need flProtect argument to be PAGE_EXECUTE_READWRITE ; That's 0x40 ; I wasn't quite sure which part of my command line arg was ending up in there so I incremented the characters (similar to what we do for shellcoding to find a BOF offset getting written to RIP/EIP).
Here we see r8d is 0x43 which means the C in my command line argument is supposed to be 0x40. I changed that to 0x40

At this point our argument is now 05SAAR@AAAAAAAAAAAAAAA where "A" is unknown. We also don't really know the length.

Our VirtualAlloc gets shellcode copied into it from xmm0 registers and a call rdi jumps into it:

Our shellcode breaks at the very bottom of the above screenshot and crashed ida in my case.
Showing opcodes in our screenshot, (But also visible in the dump), we see the disassembly instructions are all mov byte ptr [rbp-xh],yh

Which in hex is C6 45 XX XX ; However, we have a C6 49 here. In our command line, 49 is the I so we can now replace that with 0x45 -> E. After the xmm stuff is loaded, one byte is overwritten with a mov instruction. Fixing it,
We now get:

05SAAR@AAAAAEAAAAAAAAA where "A" is unknown;

As we debug the shellcode, we find some cocde that forks our symbolic execution meaning it's checking our input argument against specific constraints.


Shellcode check 1

This shellcode loads a constant into ecx and another into edx, substracts both and checks if the result is 0. It does that in a loop. We can find these constants at the rax address:

Our cli argument now becomes:

05SAAR@brUc3EAAAAAAAAA

We see we're importing user32 ordinal 2624 and wsprintfW

We can grab that ordinal using dependency walker

05SAAR@brUc3EAAAAAAAAA//////////////////////////////////////////////////////////////////////////////

Unfortunately, my laptop broke and I didn't have time to get it fixed before the challenge ended.

warsang

Security funny doing cloud stuff and Game related things. Trying to learn something new every day.