Analysis of Win32.Symmi : Find the key and decrypt the files
Recently on Malekal.com forum, I came across a challenge.
Some people got infected by a brand new ransomware having the particularity to encrypt documents (based on extension, .jpg, .doc, and so on). Having a dropper, I decided to have a look into it and find a way to decrypt those files (if possible)…
The dropper is detected as Win32.Symmi on Virus Total:
Static analysis – What has changed on files?
After launched the dropper, I looked at the modified files. After a little wait, the infection showed up a window saying lots of documents where compromised. The infection is self restarted by a registry key (RUN).
It looked like the very first 100 bytes where overwritten, with no kind of logical (the null bytes where randomly overwritten). No basic encryption here then. I’ll have to go further.
Dropping the Paypload
The dropper uses basic tricks to avoid debugging. It’s not packed nor protected, but does massive usage of GetProcAddress to make the routine detection more difficult. I found nothing useful by first looking at the dropper in OllyDbg, so I went to APIMonitor.
What APIMonitor showed is fun 🙂
The dropper was indeed trying to escape of debugging by also create threads and new processes:
Let’s see this in OllyDB!
In fact, the process is created using the flag CREATE_SUSPENDED (see the “PUSH 4” before the call), and later we will see a WriteProcessMemory, and then a ResumeThread.
The WriteProcessMemory routine is indeed writing a whole new PE at StartAddress (0x400000) of our new process, completely overwriting itself. I’ve made a dump of this code section, it’s a standalone PE (our Payload). We will analyse it right after.
The Paypload is detected as Generic (quite bad) in Virus Total :
Analysing the Payload
Once the payload dumped, and loaded into OllyDbg, we can have a quick overview by looking into the strings and intermodular calls. And this is indeed our encrypter 🙂
What is remarkable is the calls to the APIs : FindFirstFile, FindNextFile (files enumeration), CreateFile (file opening), and WriteFile (file overwriting).
After loading it into API Monitor, we have a dynamic overview of the scheme of file overwriting. This will be useful to understand where to search for a way to decrypt them. We can see the scheme: SetFileAttributes, CreateFile, ReadFile, and then WriteFile (with 100 bytes)
Let’s find the key!
In my tale to find the key, I ran into the fact that the malware was calling an API called GetVolumeInformation right before the call to the routine to XOR the file. My little finger told me it was important in order to get the key, so I put a breakpoint on the return buffer of this API.
Indeed, it was important. Once the routine responsible for key’s computing found, I saw that the Volume serial number was the only thing able to change the key’s content.In the main loop, the “Push EDI” was pushing the volume serial number onto the stack for later use.
Let’s restore the files!
I’ve made a little program able to retrieve the key corresponding to a hard drive (the program must be on the same drive than the file to restore), and apply a XOR with this key on the 100 first bytes of a given file (it does the same as the malware, but as XOR is reversible, it restores the file).
Here’s the routine to get the key. It’s a basic algorithm, but not trivial to reverse…
void GetKey(char* & key)
DWORD volumeSerial = 0, modifiedSerial = 0;
DWORD initial = 0, tmp = 0, tmp2 = 0, result = 0;
DWORD operand = 0x0A;
int count = 0;
// Volume info
GetVolumeInformation(L"\\", NULL, 0, &volumeSerial, NULL, NULL, NULL, NULL);
modifiedSerial = -volumeSerial;
memset(keytmp, '\0', 1024);
initial = modifiedSerial;
while(initial != 0)
tmp = initial / operand;
tmp2 = tmp * operand;
result = - (tmp2 - initial);
result += 0x30; //go to ACSII
initial = tmp;
keytmp[count] = (char)result;
// Invert buffer, add -
key = (char*)malloc(count + 1 + 1); //1 for -, 1 for null byte
memset(key, '\0', count + 1 + 1);
key = 0x2D; // - char
for (u_int i = 0 ; i < count ; i++)
key[count - i] = keytmp[i];
The program to restore your files is available here :
To use it, simply move a file to restore on the program’s icon, it will trigger the program with its path on parameter, and restore the file. It works also by selecting multiple files at once.