Flare-On 7 2020 Challenge #6: codeit

Eviatar Gerzi
5 min readOct 29, 2020

--

I noticed the file is packed with UPX:

I unpacked it with with upx.exe:

I noticed that it has AuotIt script in the resources:

I opened it in Resource Hacker:

And saved it using Action > Save Resource to a *.bin file... as a a3x file (because of its header A3 48 4B).

This is a compiled version of AutoiIt script so I needed to use the program Exe2Auth program in order to view it as AutoIt script which is more readable.

The problem is that Exe2Auth support only 32 bit files:

So I needed to convert my file from 64 bit to 32. Luckily hexacorn already wrote article on how to convert it together with a video someone did to based on the article.

I followed the instructions by hexacorn:

  1. Download 32-bit AuotIt and unpack it
  2. Copy autoit-v3.2.8.1.zip\Aut2Exe\AutoItSC.bin to the folder where the 64-bit compiled AutoIt resides
  3. Installed Strawberry perl for windows and saved hexacorn perl script:
use strict;
use warnings;
my $f=shift || die ("Gimme a file name!");print STDERR "Processing '$f':\n";
print STDERR "- Reading 'AutoItSC.bin'\n";
open F,"<AutoItSC.bin";
binmode F;
read F,my $a, -s 'AutoItSC.bin';
close F;
print STDERR "- Reading '$f'\n";
open F,"<$f";
binmode F;
read F,my $d, -s $f;
close F;
print STDERR "- Looking for the script\n";
if ($d=~/\xA3\x48\x4B\xBE\x98\x6C\x4A\xA9\x99\x4C\x53\x0A\x86\xD6\x48\x7D/sg)
{
my $pd=(pos $d)-16;
print STDERR "- Script found @ ".sprintf("%08lX",$pd)."\n";
print STDERR "- Creating 32-bit version '$f.a32.exe'\n";
open F,">$f.a32.exe";
binmode F;
print F $a.substr($d,$pd,length($d)-$pd);
close F;
}
else
{
print STDERR "- Script not found !\n";
}

run it:

Drop the new extracted 32 bit AutoIt script file to Exe2Auth:

extract_resource.a3x.a32_.au3

De-obfuscating the script

When I opened the script I noticed it is obfuscated. I started to de-obfuscate it and I wrote a script the does it and you can find the full de-obfuscated version here. After that I had a clear version of it and it was time to start and understand it.

Analyzing

I renamed the obfuscated function areyzotafnf to cryptoFunc because it had number of crypto function in the bottom but the interesting part of this function is actually in the beginning where it call GetComputerNameAFunc() to retrieve the computer name of the computer the program is running on and later to the function aregtfdcyni, which I renamed to modifyComputerNameStruct, that receives the computer name in hexadecimal.

But why there is a call to GetComputerNameAFunc(), it doesn’t make sense. This crack me will be run on different computer with different names, something is weird and I needed to figure it out.

Understanding the modifyComputerNameStruct function

The function starts by creating (installRandomFileName()) BMP file named sprite.bmp:

It then opens the file, and reads it content to a struct that build from two section. One is 54 bytes and the second is the rest of the file (file size minus 54).

There is a loop that runs over the computer name characters and on each character it read byte from the second section of the BMP struct. Let’s check the BMP file:

Notice to the marked area (the area after the 54 index). Some bytes are 0xFF or 0xFE. The difference is in the LSB bit:

0xFF: 1111 1111
0xFE: 1111 1110

<understanding_the_code_in_progress>

Convert the code to Python

To find the correct computer name, we converted the AutoIt function to Python:

import osbmpFile = r'C:\tmp\flare2020\6\sprite.bmp'
bmpSize = os.path.getsize(bmpFile)

with open(bmpFile, 'rb') as f:
bmpContent = f.read()

count = 0

computerArray = []

for i in range(0,20):
computerArray.append(0x00)


newComputerName = ''
newComputerNameArray = []
bmpContent = bmpContent[54:]

numStr = ''
for i in range(0,len(computerArray)):
num = computerArray[i]

for j in range(6,0,-1):
num += (bmpContent[count] & 1) << j
count += 1

num += (bmpContent[count] & 1) << 0
count += 1
numStr += chr(num)
result = (num >> 1) + ((num & 1) << 7)
newComputerName += chr((num >> 1) + ((num & 1) << 7))
newComputerNameArray.append((num >> 1) + ((num & 1) << 7))

print('Result: ', numStr)
>>> Result: aut01tfan1999

The hidden computer name is aut01tfan1999.

I was lazy so I changed the VMware computer name to aut01tfan1999:

Which after decode it with QR I got:

flag: L00ks_L1k3_Y0u_D1dnt_Run_Aut0_Tim3_0n_Th1s_0ne!@flare-on.com

--

--

Eviatar Gerzi

Security researcher interested in reversing, solving CTFs, malware analysis, penetration testing and DevOps security (docker and Kubernetes)