By Ruben Santamarta
When I was reading the CrySyS report on Flame (sKyWIper)[1], one paragraph in
particular caught my attention:
In case of sKyWIper, the code injection
mechanism is stealthier such that the presence of the code injection cannot be
determined by conventional methods such as listing the modules of the corresponding
system processes (winlogon, services, explorer). The only trace we found at the
first sight is that certain memory regions are mapped with the suspicious READ,
WRITE and EXECUTE protection flags, and they can only be grasped via the
Virtual Address Descriptor (VAD) kernel data structure
So I decided to take a look and see what kind of methods
Flame was using.
Flame is conceived to gather as much information as
possible within heterogeneous environments that can be protected by different
solutions, isolated at certain levels, and operated upon by different profiles.
Which means that, from the developers point of view, you can't assume anything
and should be prepared for everything.
Some of the tricks implemented in Flame seem to focus on
bypass just as much AV products, specifically in terms of heuristics. A
distributed "setup" functionality through three different processes
(winlogon, explorer, and services ) is way more confusing than letting a
unique, trusted process do the job; i.e. it's less suspicious to detect
Internet Explorer coming from
explorer.exe than winlogon.
In essence, the injection method seems to pivot around the
following three key features:
·
Disguise the malicious module as a legitimate
one;
Shell32.dll
in this case.
·
Bypass common registration methods supplied by
the operating system, such as
LoadLibrary, to avoid being detected as an active module.
·
Achieve the same functionality as a correctly-registered
module.
So, let's see how Flame implements it.
During the initial infection when
DDEnumCallback is
called, Flame injects a blob and creates a remote thread in Services.exe. The blob
has the following structure:
The loader stub is a function that performs the functionality
previously described: basically a custom PE loader that's similar to the
CryptoPP
dllloader.cpp[2] with some
additional tricks.Injection Context: Blob + 0x710
esi OpenMutexW
esi+4
VirtualAlloc
esi+8 VirtualFree
esi+0Ch VirtualProtect
esi+10h LoadLibraryA
esi+14h LoadLibraryW
esi+18h GetModuleHandleA
esi+1Ch GetProcAddress
esi+20h memcpy
esi+24h memset
esi+28h CreateFileMappingW
esi+2Ch OpenFileMappingW
|
esi+30h MapViewOfFile
esi+34h UnmapViewOfFile
esi+38h ReleaseMutex
esi+3Ch NtQueryInformationProcess
esi+40h GetLastError
esi+44h CreateMutexW
esi+48h WaitForSingleObject
esi+4Ch CloseHandle
esi+50h CreateFileW
esi+54h FreeLibrary
esi+58h Sleep
esi+5Ch LocalFree
|
The
loader stub also contains some interesting tricks.
Shell32.dll: A matter of VAD
To conceal its own module, Flame hides itself behind
Shell32.dll, which is
one of the largest DLLs you can find on any Windows system, meaning it's large
enough to hold Flame across different versions.
Once
shell32.dll
has been mapped, a VAD node is created that contains a reference to the FILE_OBJECT, which
points to Shell32.dll.
Flame then zeroes that memory and loads its malicious module through the custom
PE loader, copying sections, adjusting permissions, and fixing relocations.
As a result, those forensics/AntiMalware/AV engines
walking the VAD tree to discover hidden DLLs (and not checking images) would be
bypassed since they assume that memory belongs to
Shell32.dll, a trusted module, when it's
actually mssecmgr.ocx.
The stub then calls to
DllEntryPoint, passing in DLL_PROCESS_ATTACH to
initialize the DLL.
The malicious DLL currently has been initialized, but
remember it isn't registered properly, so cannot receive remaining events such
as
DLL_THREAD_ATTACH,
DLL_THREAD_DETACH,
and DLL_PROCESS_DETACH.
And here comes the
final trick:
The
msvcrt.dll
is loaded up to five times, which is a little bit weird, no?
Then the PEB
InLoadOrder structure is traversed to find the
entry that corresponds to msvcrt.dll
by comparing the DLL base addresses:
Once found, Flame hooks this entry point:
InjectedBlock1
(0x101C36A1) is a small piece of code that basically dispatches
the events received to both the malicious DLL and the original module.
The system uses this entry point to dispatch events to all
the DLLs loaded in the process; as a result, by hooking into it Flame's main
module achieves the goal of receiving all the events other DLLs receive.
Therefore, it can complete synchronization tasks and behaves as any other DLL.
Neat.
I assume that Flame loads
msvcrt.dll several times to increase its
reference count to prevent msvcrt.dll from being unloaded, since this hook would then become
useless.








Hey Ruben well done! The technique used by Flamer is really sophisticated for my simple mind but you did explain that very well. There's still a question I have: What about that "magic" value \xba \xba \x0d \xf0?
ReplyDeleteMHL used it to determine other entered memory pages (see http://mnin.blogspot.de/2012/06/quickpost-flame-volatility.html).
But what do this "magic" bytes mean? I have found them in all processes expected to be infected by flamer:
C:\Micha\Forensics\Volatility-2.1a>python vol.py yarascan -Y "{ba ba 0d f0}" -f D:\X-Ways-Images\flame.mem | egrep -i "(owner)" -A 1
Volatile Systems Volatility Framework 2.1_alpha
Owner: Process services.exe Pid 912
0x00e40000 ba ba 0d f0 00 00 e3 00 30 25 80 7c
--
Owner: Process services.exe Pid 912
0x00e40038 ba ba 0d f0 75 f1 8d 70 04 8b 0e 6a
--
Owner: Process services.exe Pid 912
0x041aa6c5 ba ba 0d f0 75 f1 8d 70 04 8b 0e 6a
--
Owner: Process services.exe Pid 912
0x041aacd8 ba ba 0d f0 89 48 04 ff b6 18 09 00
--
Owner: Process services.exe Pid 912
0x7cb836c5 ba ba 0d f0 75 f1 8d 70 04 8b 0e 6a
--
Owner: Process services.exe Pid 912
0x7cb83cd8 ba ba 0d f0 89 48 04 ff b6 18 09 00
--
Owner: Process svchost.exe Pid 1244
0x00f90000 ba ba 0d f0 00 00 f8 00 30 25 80 7c
--
Owner: Process svchost.exe Pid 1244
0x00f90038 ba ba 0d f0 75 f1 8d 70 04 8b 0e 6a
--
Owner: Process explorer.exe Pid 1604
0x02af0000 ba ba 0d f0 00 00 93 01 30 25 80 7c
--
Owner: Process explorer.exe Pid 1604
0x02af0038 ba ba 0d f0 75 f1 8d 70 04 8b 0e 6a
I also could not explain why most of the infected pages have the PAGE_EXECUTE_WRITECOPY-protection which is not supported by VirtualAlloc, is it? How could this pages have been allocated?
Regards
Michael
Hi Michael,
ReplyDeleteThat magic is used as a marker. Some snippets have the following structure [magic][data][code] Thus, [code] scans the memory backward till finding the magic, then it can access data.
PAGE_EXECUTE_WRITECOPY is used to perform the shell32->VAD trick. It's used by VirtualProtect not VirtualAlloc.
Regards,
Ruben.