In depth analysis of malware obfuscations

09 Aug, 2015 12:42
I've started this article with the idea to throw some light on the latest malware obfuscation trends.

Therefore, I'll try to be less technical about the malicious payload, and give more details about the used obfuscations instead.
When I started wandering through the exciting world of malware analysis, things were simple. There was only few AV vendors at the time, they were betting on fingerprinting, and of course, that was plenty enough to fight with the latest threads.
Because at that time, the malware niche was still small and the AV vendors were few, obfuscation techniques were rarely (if none at all) used.

Now days however, things are more complicated.
Instead on blindly fingerprinting the threads, AV vendors are using combination of fingerprinting, heuristic analysis, sandboxing, and more.

On the other hand, the malware authors are also up to date, so instead of recompiling the malicious payload and change the workhorse code, they are using obfuscations that can fool the AV detection schemes.

Usually, the payload is something developed long time ago, but wrapped by multiple type of "obfuscations" - encryption, code randomization, bundling with a well known clean application, and so on.

It's often when I spend a week to beat the obfuscations, and when I finally start working on the payload itself, it turns out to be a malware from 2-3 years ago...
And since the malware is mostly static through the time, the interesting part becomes the obfuscation wrapping it and not the actual malicious code.

In this article I was able to catch in the wild this sample.

Some of the vendors detect it as "Downloader", other as "Ransom", third call it "Kryptik" - and technically, they are all correct.

Because the obfuscation of the thread has many layers, I decided to split each of them in stages.

So, buckle up and enjoy the ride!

Stage 1: Raw sample

Filename: societe_generale_sa.scr
Size: 53 248b
MD5: 2D0775DD7718EEDD1104BEE38633E58B
Timestamp: 05/08/2010 20:16:32 (probably forged)

There are small obfuscations of some code parts, like this one here, where HeapCreate parameters are calculated, instead of just being static:
Assembly.text:004010C9		mov     edx, 28982F6Ch
.text:004010CE		sub     edx, 2898289Ch  ; 0x28982F6C - 0x2898289C = 0x6D0
.text:004010D4		push    edx             ; dwMaximumSize = 0x6D0
.text:004010D5		mov     edx, 28982F6Ch
.text:004010DA		sub     edx, 2898289Ch  ; 0x28982F6C - 0x2898289C = 0x6D0
.text:004010E0		push    edx             ; dwInitialSize = 0x6D0
.text:004010E1		mov     eax, 289C289Ch
.text:004010E6		sub     eax, 2898289Ch  ; 0x289C289C - 0x2898289C = 0x00040000
.text:004010EB		push    eax             ; flOptions = HEAP_CREATE_ENABLE_EXECUTE
.text:004010EC		lea     eax, ds:663C1FAAh
.text:004010F2		sub     eax, 65FC0F72h
.text:004010F7		call    dword ptr [eax] ; kernel32.HeapCreate

Here, the first encryption is encountered, but it turns out it's rather simple one:
MinGW Cvoid decrypt(byte* data_buffer, int data_size) {
   DWORD key = 0x6F7A34AD;
   DWORD t;
   int   i;

   for(i = 0; i < data_size; i += 4) {
      t = ~((*(DWORD*)&data_buffer[i] & 0xFFFFFFFF) - 0x08) - key + 1;
      key = rol((t & 0xFFFFFFFF), 0x08);
      *(DWORD*)&data_buffer[i] = t;

The produced result is a shellcode that is executed at Stage 2.

Stage 2: The "loader" shellcode

The API function used here are obtained by a checksum calculated from the API name, instead of using the API name itself.
This technique is well known, and its goal is to hide the plaintext ASCII strings from the curious eyes of people like me.

Implementation of the checksum calculator in C, looks like this:
MinGW CDWORD encode(char* input_data) {
   DWORD crc = 0;
   DWORD t = 0;
   int   i;

   for(i = 0; i < strlen(input_data)+1; i++) {
      t = ror(t, 0x07);
      crc = rol(crc, 0x0D) + t;
      t = (t & 0xFFFFFF00) + *(char*)&input_data[i];
   return crc;

Something interesting that catches my eye is this code:
Assembly0088002B   8B45 2C          MOV EAX,DWORD PTR SS:[EBP+2C]	; kernel32.ReadFile
0088002E   8038 8B          CMP BYTE PTR DS:[EAX],8B
00880031   75 01            JNZ SHORT 00880034
00880033   C3               RETN				; exit
00880034   E8 B0010000      CALL 008801E9

It basically check if the entry point of kernel32.ReadFile starts with MOV (opcode 0x8B).
Originally, ReadFile starts with PUSH, so this verification appears to be an API hook protection or something, although I'm more of a JMP guy and MOV wouldn't be my weapon of choice if I was about to hook anything.

Another encryption is used here, to decrypt a payload data:
MinGW Cvoid decrypt(byte *data_buffer, int data_size) {
   DWORD key = 0x173FDE3C;
   DWORD t;
   int   i;

   key ^= 0x7845EA91;
   for(i = 0; i < data_size; i += 4) {
      t = *(DWORD*)&data_buffer[i] ^ 0x01;
      __asm__("bswap %0" : "+r" (t));
      t ^= key;
      key = *(DWORD*)&data_buffer[i];
      *(DWORD*)&data_buffer[i] = t;

This algorithm is decrypting a fully functional MZ-PE file. However, instead of dropping it on the disk, it gets self injected into the current process.
Again, a well known and widespread technique of keeping the code away from the antivirus.

Stage 3: The cake is a lie!

Since the decrypted by Stage 2 data is a MZ-PE, I can fetch some interesting statistics information:

File size: 10 752b
MD5: 1AC0CB549C277F8825AB6B140BAFB90C
Timestamp: 22/04/2015 10:31:26 (matches the time of the catch)

This file has two goals:

  1. Drop a .rtf "decoy" file (stored as a .cab, inside the data section of the executable), that should mislead the user by showing him some boring text file.

  2. Download the sneaky payload from a set of attack/CnC websites and infect the machine.

But first things first.

In this executable, the important ASCII strings are all encrypted, using a simple dynamic key-XOR encryption:
MinGW Cvoid decrypt(char* data, int data_size) {
   char key[] = "\x6A\x08\x2D\xB4\x69\xD7\x96\x31\x0B\xEA\xBD\xE6\xB3\xDF\x4E\x1C";
   int  i;

   for(i = 0; i < data_size; i++) {
      *(byte*)&data[i] = *(byte*)&data[i] ^ *(byte*)&key[i%0x10];
      *(byte*)&key[i%0x10] ^= *(byte*)&data[i];
//* This encryption algorithm is used for both wide char and multibyte strings.

A sophisticated random file name generator is also used:
MinGW Cint genRandom(int strLengthLimit, int seed) {
   DWORD t;
   SystemFunction036(&t, 4);
   return (t % ((strLengthLimit - seed) + 1)) + seed;

void genRndStr(char *result, int strLengthLimit, int fileExt) {
   char charset1[] = "aeoiuy.";
   char charset2[] = "qwrtpsdfghjklzxcvbnm";
   char extList[] = "txtrtfdocchmhlpttfpdffb2xlscabmdbcdawavwmamp3avimpgmdvflvswfwmvvobbmpgifjpgpngisomdfmdsbindatnrg3gpoggvobexedll";
   //all these charset1, charset2 and extList are decrypted using the previously mentioned key-XOR crypto.
   int i, strLength;

   strLength = genRandom(strLengthLimit, 3);
   if (strLength > 0) {
      for(i = 0; i < strLength; i++) {
         if (i&0x80000001) {
            result[i] = *(byte*)&charset1[genRandom(0x05, 0)];
         } else {
            result[i] = *(byte*)&charset2[genRandom(0x13, 0)];
   result[i] = *(byte*)&charset1[6];
   if (fileExt == 1) {
      fileExt = 0x69;	// points to "exe"
   } else if (fileExt == 3) {
      fileExt = 0x1B;	// points to "cab"
   } else {
      fileExt = genRandom(0x22, 0) * 3; // get random extension
   *(DWORD*)&result[i+1] = *(DWORD*)&extList[fileExt];
   *(byte*)&result[i+4] = 0;	// terminate the string

The file name for the .cab archive, holding the decoy .rtf file is generated by this function.
However, using this random string generator, the attacker can generate file names with many different extensions (see extList for reference).

Since I already mention this file is a downloader, it holds an URL list, where the actual malicious part is located:

Again, the URLs are encrypted by the key-XOR encryption, and every time one of them is used, it gets encrypted back to its original state, to (probably) hide it from potential memory analysis.

The downloaded file "image.jpg" is structured like a very simple file system:
C Structurestruc malFS_raw {
   DWORD crc32;
   DWORD data_size;
   byte* data_encrypted;

This "data_encrypted" buffer is encrypted by the same string encryption used before, and the crc32 parameter is (obviously) the CRC32 checksum of the decrypted data, that is used as verification after the decryption.

The produced data is again structured:
C Structurestruc malFS_decrypted {
   DWORD data_size_0;
   byte* data_0;
   DWORD data_size_N;
   byte* data_N;

According to the structure above, the decrypted data can contain many entries. However, in the current sample, the entries are two MZ-PE files, that are executed in reverse order.

Because the execution process splits in two here, I will also split the article as Stage 3.1 (second entry of the downloaded payload) and Stage 4 (first entry).

The executable I will analyze next at stage 3.1 is <SPOILER ALERT> only credential gatherer, and it doesn't make any HTTP requests.
All of the information that it gathers is sent to the CnC server by the current code here in stage 3.

Speaking of the CnC, the exact URL is not present as-is, but it is dynamically created on the run, from the payload URLs.
The algorithm is quite simple:
- Lets say we use "" as a payload server.
- From that address, we take the file name - "image.jpg", calculate its CRC32 checksum, convert it from HEX to decimal number and we get 3447786819.
- Finally the CnC URL is constructed back, to produce the URL ""

After sending the stolen data, depending on the server response, leads to either process termination (if the server doesn't response with "Confirmed") or to execution of the first payload (see stage 4).

But first thing first, lets see the "credential stealer" payload first, at Stage 3.1

Stage 3.1: All of your _pass_ are belong to me

I already mentioned that this one is a stand-alone MZ-PE, but it is actually a DLL file.

File size: 91 648b
MD5: C6F1A88592BE4C9BB2390E8ED57B8831
Timestamp: 20/05/2014 13:19:19 (probably legit compile time stamp)

The DLL has only one export function - "Grab_Psw", that quite obviously shows what the code actually do - grabs passwords.

Stolen credentials can be put in five categories: FTP, E-Mail, Web Browser, e-currency and misc credentials, plus user certificates.

Follows a complete list of the affected programs.

FTP Clients and alike:
Far Manager, Total Commander / Windows Commander, ipswitch, CuteFTP, FlashFXP, FileZilla, FTP Navigator / FTP Commander, Bullet Proof FTP, SmartFTP, TurboFTP, FFFTP, Direct FTP, Core FTP, FTP Explorer, Frigate, SecureFX, UltraFXP, FTP Rush, Web Site Publisher, BitKinex, ExpanDrive, Classic FTP, Fling, SoftX FTP Client, Directory Opus, LeapFTP, WinSCP, 32bit FTP, NetDrive, WebDrive, FTP Control, WISE-FTP, FTP Voyager, FireFTP, LeechFTP, Odin Secure FTP Expert, WinFTP, FTP Surfer, FTPGetter, ALFTP, DeluxeFTP, Staff-FTP, AceFTP, Global Downloader, FreshFTP, BlazeFtp, FTP++, GoFTP, 3D-FTP, EasyFTP, NetSarang Xftp, FTPNow, Robo-FTP, LinasFTP, Cyberduck, Notepad++ NppFTP plugin, FTPShell, FTPInfo, NexusFile, WinZip FTP plugin, My FTP, NovaFTP, FastTrack FTP,

E-Mail clients:
Windows Live Mail, Windows Mail, Becky! Internet Mail, Pocomail, IncrediMail, BatMail/The Bat!, Outlook, Thunderbird

E-currency clients:
Bitcoin, Electrum, MultiBit, FTP Disk, Litecoin, Namecoin, Terracoin, Armory, PPCoin, Primecoin, Feathercoin, NovaCoin, Freicoin, Devcoin, Franko, ProtoShares, Megacoin, Quarkcoin, Worldcoin, Infinitecoin, Ixcoin, Anoncoin, BBQcoin, Digitalcoin, Mincoin, GoldCoin, Yacoin, Zetacoin, Fastcoin, I0coin, Tagcoin, Bytecoin, Florincoin, Phoenixcoin, Luckycoin, Craftcoin, Junkcoin

Web browsers:
FastStone 4in1 Browser, ChromePlus, Yandex Browser, Epic privacy browser, K-Meleon, RockMelt, Comodo, Nichrome, Bromium, Chrome, Chromium, Flock, SeaMonkey, Firefox, Opera,

PuTTY saved sessions, valid certificates, Remote Desktop, Internet Explorer proxy settings, Dreamweaver stored passwords, CoffeeCup shared accounts, Unknown GUID {74FF1730-B1F2-4D88-926B-1568FAE61DB7}

Most of the strings are plaintext but few are encrypted with XOR 0x01:
MinGW Cvoid decrypt(char *input_data) {
   int i;

   for(i = 0; i < strlen(input_data); i++) {
      *(char*)&input_data[i] = *(char*)&input_data[i]^0x01;

The stolen information is formatted as "PKDFILE" package and compressed using aPLib 1.01.
Then, the compressed data gets RC4 encrypted twice, using "Ukulele" as encryption key.
A slightly modified CRC32 checksums are added between the RC4 encryption stages, probably for future verification by the CnC:
Assembly.text:10001580                 push    [ebp+var_8]
.text:10001583                 push    eax
.text:10001584                 push    0
.text:10001586                 call    _CRC32
.text:1000158B                 mov     [ebp+var_C], eax
.text:1000159E                 mov     eax, [ebp+var_C]
.text:100015A1                 bswap   eax		; < Modification 1
.text:100015A3                 not     eax		; < Modification 2

Stage 4: The drop

Again, I got a MZ-PE, so here are the details:

File size: 1 096 704b
MD5: 723E2B1B686A62BF564DD45E97E5F3EE
Timestamp: 23/04/2015 02:47:28 (probably legit compile time stamp)

Something that might be considered as a flaw is the fact that this payload is physically dropped on the victim's machine, then executed.
This makes the obfuscations and encryption used so far kind of useless, but never mind.

At first glance, this executable appears to be "Frankensteined" from many different legit programs, to hide its malicious core in between them.
Some of the artifacts I've found, lead to Calibre, others to a unknown Russian software.

Even though the encryption used here appeared to be a bit complicated, it turns out that the final algorithm is XOR-0x24:
MinGW Cvoid decrypt(byte *data_buffer, int data_size) {
   int i;
   for(i = 0; i < data_size; i++) {
      *(byte*)&data_buffer[i] ^= 0x24;

Obviously, the attackers intentionally obfuscated the encryption algorithm, by using bulk code and pointless calculations:
Assembly* commented lines are just "filler" code.
 00402210  |> 8B0D 148B4F00  MOV ECX,DWORD PTR DS:[4F8B14]		; key = 0x0817
 00402216  |> 8B5424 10      MOV EDX,DWORD PTR SS:[ESP+10]		; encrypted_data
 0040221A  |. 8B4424 14      MOV EAX,DWORD PTR SS:[ESP+14]		; i
 0040221E  |. 8A1402         MOV DL,BYTE PTR DS:[EDX+EAX]		; encrypted_data[i]
;00402221  |. 884C24 3B      MOV BYTE PTR SS:[ESP+3B],CL		; temp_key, but it's not used!
 00402225  |. 885424 47      MOV BYTE PTR SS:[ESP+47],DL		; temp_encrypted_data[i]
;00402229  |. 85C9           TEST ECX,ECX				;/ probably will never jump
;0040222B  |. 74 0E          JE SHORT cepyg.0040223B			;\
 0040222D  |. 8BF7           MOV ESI,EDI				; EDI = 0xFA
 0040222F  |. 2B7424 3C      SUB ESI,DWORD PTR SS:[ESP+3C]		; ESP+3C = var1 = 0, zeroed
;00402233  |. 0335 108B4F00  ADD ESI,DWORD PTR DS:[4F8B10]		; 004F8B10 = 0, we can ignore it
 00402239  |. 03F6           ADD ESI,ESI
;0040223B  |> 8B0D 088B4F00  MOV ECX,DWORD PTR DS:[4F8B08]
;00402241  |. 8B15 188B4F00  MOV EDX,DWORD PTR DS:[4F8B18]		; 004F8B18 = 0, we can ignore it
;00402247  |. 8D8424 2803000>LEA EAX,DWORD PTR SS:[ESP+328]
;0040224E  |. 50             PUSH EAX                                 	; /lParam
;0040224F  |. 6A 02          PUSH 2                                   	; |wParam = 2
;00402251  |. 68 01040000    PUSH 401                                 	; |Message = WM_USER+1
;00402256  |. 51             PUSH ECX                                 	; |ControlID => FFED0BD4
;00402257  |. 52             PUSH EDX                                 	; |hWnd => NULL
;00402258  |. FF15 10124100  CALL DWORD PTR DS:[<&USER32.SendDlgItemM>	; \SendDlgItemMessageA
;0040225E  |. 8B0D 188B4F00  MOV ECX,DWORD PTR DS:[4F8B18]		; 004F8B18 = 0, we can ignore it

Something that puzzled me is that little piece at the end, after the decryption routine:
Assembly0040235A  |. 8B4424 10      MOV EAX,DWORD PTR SS:[ESP+10] ; decrypted shellcode
0040235E  |. 8D5424 34      LEA EDX,DWORD PTR SS:[ESP+34] ; hInstance of the current process (00400000)
00402362  |. 8950 01        MOV DWORD PTR DS:[EAX+1],EDX  ; places the hInstance pointer, one byte after the beginning of the shellcode

There are two potential problems I see here.
First is the shellcode itself:
Assembly00B80688  24 B8 AF BE AD DE E9 76 14 00 00 CC CC CC CC CC

00B80688   24 B8            AND AL,0B8
00B8068A   AF               SCAS DWORD PTR ES:[EDI]
00B8068B   BE ADDEE976      MOV ESI,76E9DEAD
00B80690   14 00            ADC AL,0
00B80692   00CC             ADD AH,CL
00B80694   CC               INT3

That doesn't make sense, unless I replace the first byte (0x24) with NOP:
Assembly00B80688  90 B8 AF BE AD DE E9 76 14 00 00 CC CC CC CC CC

00B80688   90               NOP
00B8068E   E9 76140000      JMP 00B81B09
00B80693   CC               INT3

Now, that looks way better.

However, the hInstance will be set on the wrong place, so instead of:
Assembly00402362     8950 01        MOV DWORD PTR DS:[EAX+1],EDX

I've changed it to:
Assembly00402362     8950 02        MOV DWORD PTR DS:[EAX+2],EDX

I have no idea why the code starts with opcode 0x24. Bug? Maybe. RE protection? Could be...

Since now I know how the shellcode "should" look, I have another problem, this time with the code that sets the hInstance value.
Assembly0040235A     8B4424 10      MOV EAX,DWORD PTR SS:[ESP+10]	; decrypted shellcode
0040235E     8D5424 34      LEA EDX,DWORD PTR SS:[ESP+34]	; hInstance of the current process (00400000)
00402362     8950 02        MOV DWORD PTR DS:[EAX+2],EDX	; now pointing to the right place

For some reason, the hInstance is not taken by value, but it's stack pointer (LEA).

This renders the code invalid, because every time that hInstnce is needed, it will take the stack pointer, and not the value.
Fixing this is easy:
Assembly0040235A     8B4424 10      MOV EAX,DWORD PTR SS:[ESP+10]	; decrypted shellcode
0040235E     8B5424 34      MOV EDX,DWORD PTR SS:[ESP+34]	; LEA goes to MOV
00402362     8950 02        MOV DWORD PTR DS:[EAX+2],EDX	; now pointing to the right place

The shellcode is now fixed, so let's go to the next stage - the shellcode itself.

Stage 5: Just a simple shellcode. Really?

Even that Stage 5 has a simple job, yet it holds quite complicated code.
The shellcode egghunts for some data inside the executable. This egghunt is quite complicated actually.
It fetches small pieces of data and applies different decryption, decompression and decoding routines over them.

Basically, the egghunted data is split into small chunks inside the executable, and not only the size of these chunks vary, they may use different encryption, compression or encoding.

I was able to reverse engineer most of the algorithm for eggunting and building the shellcode, but since my code became one giant meatballs and spaghetti beast, it's also incomplete (yet it can drop the correct result) I'll not publish it in this article. Trust me, for the sake of humanity.

It's good to mention that the result shellcode get "patched", the same way it was with the current one, but this time, the value is not hInstance, but forced to 0.
Assembly00B81BA2   8B55 FC          MOV EDX,DWORD PTR SS:[EBP-4] ; decrypted shellcode
00B81BA5   C742 01 00000000 MOV DWORD PTR DS:[EDX+1],0	 ; set the value to 0
00B836BD   B8 AFBEADDE      MOV EAX,DEADBEAF		 ; this one is set by the MOV EAX,0 above
00B836C2   E9 26220000      JMP 00B858ED
00B836C7   CC               INT3

Stage 6: Almost the last shellcode

This shellcode has two ways of execution, depending on the hInstance parameter mentioned before.
If the first value assigned to EAX was hInstance for example, the current code continues by eghunting plain (not encrypted) payload from its memory and executes it.

In my case however, the hInstance is set to NULL, so it continues by eghunting for encrypted payload.
That encrypted payload is again built using the same decrypt/decompress/decode method as the one used in Stage 5.
So, here we can see classic "reusing" of the same code.

The obtained payload is executed directly as all shellcodes were so far (no physical dropping of the payload).

Stage 7: Simple obfuscation and another shellcode decrypt

File size: 669 696b
MD5: 45D3CBEEF8B792D4470355B5764BE88F
Timestamp: NULL

Stage 7 is a short one. It uses a simple JMP oriented obfuscation, that is easy to beat and hard to fingerprint:
Assembly.text:00401FA3                 push    ebp
.text:00401FA4                 jmp     loc_440E0C
... bulk data ...
.text:00440E0C                 mov     ebp, esp
.text:00440E0E                 jmp     sub_456CF9
... bulk data ...
.text:00456CF9                 sub     esp, 20h
.text:00456CFC                 jmp     loc_40BE41
... bulk data ...

The obfuscated code is a encryption routine, that decrypts the shellcode for the next stage:
MinGW Cbyte* decrypt(byte* data_buffer, DWORD* data_size) {
   int		i, j;
   DWORD	key;
   byte	t;
   byte*	data;
   byte*	result_data;

   key = 0x0C78E5EC3;
   data = data_buffer + 0x2B0;

   result_data = (byte*)VirtualAlloc(NULL, *data_size, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);

   *data_size = 0;
   while(1) {
      t = *(byte*)&data[0] ^ LOBYTE(key);
      if (t == 0) { break; }
      key = rol(key, 3) * 0xDB0CCE3F;
      if (t >= 0xE0) {
         data = data + t - 0xE0;
      } else {
         for(j = 0; j < t; j++) {
            *(byte*)&result_data[*data_size] = *(byte*)&data[0] ^ LOBYTE(key);
            key = rol(key, 3) * 0x0DB0CCE3F;
   return result_data;

Stage 8: Final decryption

At stage 8 the final payload is decrypted by unknown (to me) encryption that I didn't even bother reverse engineering it.

The result payload is a headless MZ-PE that is built in the memory during its decryption, and executed from there.

Stage 9: The twist

Stage 9 is the final payload.
It didn't take me too long to figure out that the payload is actually CTB-Locker.

<screentext>%a1%%f3%%c3%Your personal files are encrypted by CTB-Locker.%f0%%c0%

Your documents, photos, databases and other important files have been encrypted with strongest encryption and unique key, generated for this computer.

Private decryption key is stored on a secret Internet server and nobody can decrypt your files until you pay and obtain the private key.

If you see the main locker window, follow the instructions on the locker. Overwise, it's seems that you or your antivirus deleted the locker program. Now you have the last chance to decrypt your files.

Open %c1%http://%gatea%%c0% or %c1%http://%gateb%%c0% in your browser. They are public gates to the secret server.

If you have problems with gates, use direct connection:

1. Download Tor Browser from %c1%

2. In the Tor Browser open the %c1%http://%onion%/%c0%
Note that this server is available via Tor Browser only. Retry in 1 hour if site is not reachable.

Write in the following public key in the input form on server. Avoid missprints.

Follow the instructions on the server.

These instructions are also saved to file named Decrypt-All-Files.txt in Documents folder. You can open it and use copy-paste for address and key.</screentext>

Overall, the whole thread can be represented as the following block diagram:

That concludes this article.
As you can see the malware of tomorrow is build as onion, and pealing the scales most of the time reveals something well known, like CTB-Locker.
During the time of the analysis i was able to catch different versions of the same thread.
Currently the URLs of the CnC are long gone, as expected, but the thread is probably still present in the wild.

So, watch out, and I hope I'll see you in the next article!


* You have an opinion? Let us all hear it!

Guest 21 May, 2017 14:06
Guest 19 May, 2017 15:19
were so proud of you.
cheap FFXIV Gil for sale
Guest 18 May, 2017 09:09
© 2011-2017 | legal | terms & rules | contacts