Soraya Malware Analysis - Dropper
Today I got some free time to take a look at recent Soraya malware. You can read more about this malware here.
In this post, I'll be analyzing dropper part of this malware.
CRC32: 5AB00BD2 MD5: A95DACBA360E45FC03769EA55C546A7B SHA-1: 0BE287EEFE96EE1519A37A0F6C6A547EF043E80E
This app does have some resource entries with language ID: 10249 (0x2809) which is for Belize.
Here is screenshot from application's properties:
It seems malware authors have some sort of humor.
Also here is some strange texts in application's .xdata resource section:
By doing so, malware will use critical section objects for mutual exclusion synchronization in the thread of a single process.
After initializing critical sections, it uses several "PUSH and RET"s to jump to next stage:
Also it uses basic XOR operations to deobfuscate parts of string for API names. For instance, it does have:
0x56 0x40 0x2B 0x53 0xB7 0x61 0x6C 0x41 0x6C 0x6C 0x6F 0x63 somehow: V@+S·alAlloc
Then Soraya XORes it with 0xC2 0x27 0x59 0x29
and end result becomes VirtualAlloc
It then allocated a memory page with size of 8kb (0x2000) with read, write and execute permission. It then starts a long decryption process. It reads from it's own binary file, decrypts it and writes to allocated location. After decryption of 8kb, using JMP instruction, it jumps to beginning of 8kb page.
In decrypted code, after intializations, it uses ADD and MOV instructions to put "C:\myapp.exe" string into memory:
Afterward, it calls CreateFileA with "C:\myapp.exe" as filename parameter to open this file. If API call returns correct handle, eventually it will terminate. So computers with myapp.exe in C:\ folder will never be infected as Soraya simply exists when it detect C:\myapp.exe. I think this function written by developers to prevent infecting malware developers own computers, specially during development process.
Anyway, If there is no myapp.exe, it proceeds to next stage. In next stage, again it allocates another memory page with read, write and execute permission, this time 48kb in size. Another decryption takes place and newly allocated 48kb receives decrypted data. In initial call, 24336 bytes of data written on this page, then next 24336, which makes it totally 47kb written on 48kb allocated page.
Later it allocated two more pages, one with size of 24kb and another one with size of 48kb, both of them does have read, write and execute permission. 24kb page is written with an executable file packed with UPX, but modified to prevent easy decompression. We'll talk about this one later. Here, Soraya also calls VirtualProtect with address and size of it's own binary mapped in memory to set access of these mapped pages to read, write, execute and copy on write, it's documented as PAGE_EXECUTE_WRITECOPY
Soraya now loops through all processes using CreateToolhelp32Snapshot, then ProcessFirst and looping with Process32Next calls. It then tries to open each process using OpenProcess API.
If it successfully opens a process (which usually through looping, first process successfully it will open will be smss.exe), it resolves ZwCreateSection, DbgPrintEx, RtlMoveMemory, ZwCreateThreadEx API addresses from ntdll.
Then it calls ZwCreateSection API, if fails, it will move on and try on next process. After opening a process it calls ZwMapViewOfSection to allocate a memory page in remote process. Again if this call fails, it keeps looping through remaining processes. Then, it calls RtlMoveMemory several times to copy entire binary into mapped section. Finally, it calls ZwCreateThreadEx to run it's injected thread into remote processes. In my case, using Windows 7, after injecting it's module into csrss.exe, my system just gets BSOD.
If you want to jump right here of debugging this malware, just use APIFinder plugin for Olly, then set breakpoint on RtlMoveMemory, then go to call stack, find address of caller, go to that address, put breakpoint to next line after RtlMoveMemory call, step into some lines and some small loops, you'll see a call to ZwCreateThreadEx, set this to NOP (to prevent infection spread to other processes which is not in control of debugger) and continue debugging.
After these injections, it resolves ExitProcess API address and simply calls it with 0 as exit code argument.
In next post, I'll analyze the file it tried to inject all processes and what it does.