Flare-On 8 – Task 7
2021-10-23 09:05:00 Author: hshrzd.wordpress.com(查看原文) 阅读量:34 收藏

Intro:

The task is a Windows executable, 32-bit.

When we run the application, the following window pops up:

At the beginning I wasn’t sure if the task runs correctly on my system. But I decided to trace it with Tiny Tracer to see what happens.

I noticed that when I closed the window, something got unpacked it the memory and executed. Relevant fragment of the trace log:

18c049;user32.IsWindow
19a9d4;ntdll.RtlEnterCriticalSection
19a9e5;kernel32.TlsGetValue
19aa05;ntdll.RtlLeaveCriticalSection
19a9d4;ntdll.RtlEnterCriticalSection
19a9e5;kernel32.TlsGetValue
19aa05;ntdll.RtlLeaveCriticalSection
19a9d4;ntdll.RtlEnterCriticalSection
19a9e5;kernel32.TlsGetValue
19aa05;ntdll.RtlLeaveCriticalSection
18fec6;user32.GetActiveWindow
19a9d4;ntdll.RtlEnterCriticalSection
19a9e5;kernel32.TlsGetValue
19aa05;ntdll.RtlLeaveCriticalSection
19a9d4;ntdll.RtlEnterCriticalSection
19a9e5;kernel32.TlsGetValue
19aa05;ntdll.RtlLeaveCriticalSection
18bac6;kernel32.FreeResource
2d30;kernel32.GetModuleHandleExA
2d61;kernel32.GetProcAddress
	Arg[0] = ptr 0x00007ffa8a8f0000
	Arg[1] = ptr 0x00007ff7094dc0b0 -> "VirtualAllocExNuma"

2d6c;kernel32.GetCurrentProcess
17970b;kernel32.VirtualAllocExNuma
17972f;called: ?? [1747b490000+0]
> 1747b490000+1cd;ntdll.LdrLoadDll
> 1747b490000+1f2;ntdll.LdrGetProcedureAddress
> 1747b490000+218;ntdll.LdrGetProcedureAddress
> 1747b490000+23d;ntdll.LdrGetProcedureAddress
> 1747b490000+263;ntdll.LdrGetProcedureAddress
> 1747b490000+289;ntdll.LdrGetProcedureAddress
> 1747b490000+2ae;ntdll.LdrGetProcedureAddress
> 1747b490000+2d4;ntdll.LdrGetProcedureAddress
> 1747b490000+377;kernel32.GetNativeSystemInfo
> 1747b490000+3c0;kernel32.VirtualAlloc
> 1747b490000+648;kernel32.LoadLibraryA
	Arg[0] = ptr 0x00000001800152b6 -> "KERNEL32.dll"

> 1747b490000+6ad;ntdll.LdrGetProcedureAddress
> 1747b490000+6ad;ntdll.LdrGetProcedureAddress
> 1747b490000+6ad;ntdll.LdrGetProcedureAddress
> 1747b490000+6ad;ntdll.LdrGetProcedureAddress
> 1747b490000+6ad;ntdll.LdrGetProcedureAddress
> 1747b490000+6ad;ntdll.LdrGetProcedureAddress

We can see that it uses a function VirtualAllocExNuma to allocate memory. Then, something (probably a shellcode) is loaded into this memory and executed. By seeing the functions inside the shellcode we can understand that this is yet another loader, which loads imports of something that seems to be the next stage payload.

Unpacking

The previous experiment showed that the executable is packed. So, I decided to unpack it with the help of mal_unpack (one of the tools from PE-sieve family). Since manual closing of the window is required in order to trigger payload unpacking, I run mal_unpack with the following commandline (infinite timeout):

mal_unpack.exe /timeout 0 /exe spel.exe

And then I closed the window.

Some DLLs got dumped.

Shellcode, as well as one of the DLLs seems to be nothing but the next stage loaders.

However, I noticed among them an interesting DLL with one function exported:

Unfortunately, the relocation table of this DLL was removed:

Data Directory view shows that the Relocation Table is cut out

Due to this fact, it could not be used as a standalone DLL.

Manual reconstruction of a relocation table is difficult, and sometimes even impossible. But I got an idea that maybe I can still find a raw copy of this DLL, with the relocation table intact. So I scanned it again, this time with an option /data 3 to dump also PEs from non-executable memory.

mal_unpack.exe /timeout 0 /exe spel.exe /data 3

This time more DLLs were dumped.

One of them was indeed a valid copy of the DLL I was looking for – this time with a valid relocation table.

Now, all I needed to do was to remove padding of the dumped file. I did it with PE-bear. And the DLL is ready to be run.

Tracing the DLL and writing a loader

I decided to trace it also with TinyTracer. The DLL exports a function Start so I suspected this will be the function that should be called.

I set it in Tiny Tracer and run.

In the trace log, I noticed the DLL tries to load some resource. The resource is supposed to be fetched from the main application. I added to the TinyTracer tracking of related parameters, and I saw what exactly is being loaded. It was a PNG resource.

1b4d;kernel32.GetModuleFileNameA
1b63;kernel32.GetModuleHandleA
1ba8;kernel32.FindResourceA
	Arg[0] = ptr 0x00007ff72e9e0000
	Arg[1] = 0x0000000000000080 = 128
	Arg[2] = ptr 0x0000005628ebf5e4 -> "PNG"

The relevant PNG is in the resources of the main application:

Interestingly, PE-bear fails to display it. It turns out other tools have the same problem. The content of the PNG is just invalid. I suspected that it will contain some encrypted data, possibly the flag.

The content of the PNG: possibly an encrypted buffer

Now we know that this PNG needs to be passed to the DLL. In order to do so, saved the resources by PE-bear. Then, I created my own loader, that includes this PNG as a resource with identical name as the DLL requires.

Static analysis

I opened the DLL in IDA in order to analyze it statically. Most of the API functions are resolved by hashes, so the TAG file generated by TinyTracer came handy. I just applied tags on the IDA view (using IFL plugin), and the code became much more understandable.

However, this way of resolving API calls have some limitations: since the tags are generated during tracing, only the calls that were actually executed will be resolved. So, still we are left with some hashes that are not mapped. Fortunately, a quick google lookup shows that the hashing algorithm is well known, and there are already lists of common API functions with their corresponding hashes. This helped to find some more functions.

Decompiled code available here.

There are more condition that the DLL checks, for example, the executable must be named Spell.EXE – so I renamed my loader to this name.

The DLL tries to communicate with some server: it queries two addresses: invalid.flare-on.com and invalid2.flare-on.com , trying to connect to port 888. None of those addresses is active, so we have to somehow emulate this communication.

Once it connects to the C2, it sends a beacon “@” and is waiting for a command. There are 3 commands available: “exe”, “run”, “flare.com”.

First two commands are used for running some received shellcode, or a PE file. Third of them leads to a function that seems to decrypt something…

Emulating the C2

One of the possible ways of emulating the communication, is to start a server locally, for example using netcat.

netcat -l -p 888

Then we can redirect the domain to it by editing the following file:

%windir%\system32\drivers\etc\hosts

We need to create the entry that will cause the the domain to be resolved as our localhost:

127.0.0.1 inactive.flare-on.com

Running the commands

As mentioned earlier, the third command (“flare.com”) looks interesting, because it leads to some decryption. We can run the prepared loader again, via TinyTracer, and watch the APIs called during the communication with the fake C2. First, the BCrypt library is loaded, and it is set to decrypt using AES, CBC mode. The following string got decrypted:

The string didn’t make much sense, but at least it is ASCII, so I thought it may be a flag. However, it turned out invalid. So I had to dig deeper.

I noticed this string is being XORed, scrambled, and the result is written into Windows Registry.

I decided to clear the buffers with which it is XORed. And as the result the valid flag was saved in the registry:

[email protected]

文章来源: https://hshrzd.wordpress.com/2021/10/23/flare-on-8-task-7/
如有侵权请联系:admin#unsafe.sh