Norman Blog

insight, opinion & information

 
 

Flamer string decoder

TL;DR: IDAPython Flamer string decoder script available from here:

http://download01.norman.no/blog/flamedec.py

Modify as you see fit.

When analyzing complex malwares like Flamer it is necessary to find the strings used by the malware, as they contain essential information about what the malware is trying to do. In the Flamer case, these strings are in most cases encrypted (or, as any true numberhead would say, encoded). Decoding these is easy enough to do if there are but a handful. However, Flamer contains many strings. Too many.

Sergei Shevchenko over at Stratsec has published some excellent articles on the algorithms used for some of the components already, but since I needed to make my own decoder I figured to share the results.

It initially seemed that there were two main decoding algorithms, the one used by SOAPR32.OCX and a few others, and the one used by most other components like NTEPS32.OCX and MSSECMGR.OCX. IDA Pro’s HexRays decompiler produced pseudo-C similar to the ones below.

//MSSECMGR, NTEPS32 a.o. decoder
int __usercall NTEPS_decode<eax>(char* encodedptr<eax>, int stringsize<edx>)
{
 int v2; // esi@1
 int v3; // edi@2

 v2 = encodedptr;
 if ( stringsize )
 {
   v3 = 5 - encodedptr;
   do {
      encodedptr = (v3 + v2) * (v3 + v2 + 0x15);
      *(_BYTE *)v2 -= encodedptr ^ (((v3 + v2) * 
                                     (v3 + v2 + 0x15)) >> 8) ^
                                    ((v3 + v2) * (v3 + v2 + 0x15) >> 16) ^
                                    ((v3 + v2) * (v3 + v2 + 0x15) >> 24);
      ++v2;
      --stringsize;
   } while ( stringsize );
 }
return encodedptr;
}

 

//SOAPR32 a.o. key generator
unsigned int __usercall SOAPR_key<eax>(int index<eax>)
{
 return (index + 11) * (index + 17) ^ ((((index + 11) * (index + 17)) >> 8) ^
      (((index + 11) * (index + 17) ^ ((((index + 11) * (index + 17)) >> 8)) >> 16);
}

//SOAPR32 a.o. decoder
void __cdecl <strong>SOAPR_decode</strong>(int encodedptr, unsigned int stringsize)
{
 int index; // edi@1
 index = 0;
 if ( stringsize ) {
    do {
       *(_BYTE *)(index + encodedptr) -= SOAPR_key(index);
       ++index;
    } while ( index < stringsize );
 }
}

Looking harder at the code, it becomes apparent that these algorithms are the same. The only real variation in the algorithms are the hardcoded constant parameters (shown as k, aval and bval in the pseudocode snippet below).

decode(encodedstring, strsize):
index = 0
while index < strsize :
   i0 = k + (index + aval) * (index + bval)
   i1 = i0 >> 24
   i2 = i0 >> 16
   i3 = i0 >> 8
   key = (i0^ i1 ^ i2 ^ i3)
   decodedstring[index] = encodedstring[index]-key
   index += 1
return decodedstring

Also, in most of these files there are two decoders, one for ANSI 8-byte strings and one for widechar/unicode. The actual decoding algorithm is the same in the two, but where the input data is stored differs.

I’ve made a small Python script for decoding the strings found in Flamer executables. The script is directly loadable into IDA with a working IDAPython, and does not require any additional tinkering – it uses some simple autorecognition of the decoding algorithm. It will patch your IDB file, and attempt to rename all string references to something useful. This general approach can be adapted to a lot of other malwares.
It produces output like this:

flamedec: IDAPython Flamer decryption tool.
flamedec: (C) 2012 Snorre Fagerland, Norman ASA.
------------------------------------------------
flamedec: ANSI string decoder found at 1000a84c
flamedec: UNICODE string decoder found at 1000a877
flamedec: Found decoding algorithm type 0
flamedec: New decryption loop. Using decryption function at 1000a84c
flamedec: ------------------------------------------------------------

explorer.exe
FORM
csrsrv.dll
CsrCreateRemoteThread
default

flamedec: New decryption loop. Using decryption function at 1000a877
flamedec: ------------------------------------------------------------

%_SYSTEMDIR%kernel32.dll
HKLMSOFTWAREKasperskyLab
password
Global
ZwQueryInformationThread
_WINDIR
_CURRENTDIR
_SYSTEMDIR
_TEMPDIR
WriteProcessMemory
...etc

Note that some Flamer’s are UPX-packed, and need to be unpacked before attempting any decoding.

Script link on top.

Tags: , , ,

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

 
 
Snorre Fagerland

The Author:

Snorre Fagerland is a Principal Security Researcher in the Malware Detection Team (MDT) at Norman.

Norman Blog Archive