Win32.Parite.B Unpacking and Anatomy Reversing and Network Analysis
Long time not blogging due to real life issues. Today we are going to inspect Win32.Parite.B a trojan that modifies System Files and Enstablishes a Network Activity with an Irc Server and Downloads other potential threats. We can consider Parite.B an IrcBot Client.
Let's perform a first basilar inspection of the malicious binary. The executable is delivered under the name of Protesto_Serasa.exe
Application presents an interesting Section Directory
Apparently appears to be a classical UPX packed application, but if we go to inspect deeply the .wtq section we can suddenly see that the EntryPoint is located at 00096000 that belogs exactly to .wtq. This means that
at loading time, UPX presence is quite useless because the first code that will be execute comes out from .wtq that as we will see contains layer of decryption for the rest of the code.
Pay attention that exists also a TLS Directory, so in debugging phase we have to set TLS Awareness (Break on TLS) to be sure that we are able to follow the potentially hidden to debugger code.
After disassembling Parite we can jump suddenly to the binary entry point by selecting the address that comes out from ctrl+E, as you can see we land into .wtq_ section:
.wtq_:00496000 public start
.wtq_:00496002 mov ecx, 55B4CDBh
.wtq_:00496002 mov ecx, 55B4CDBh
.wtq_:00496007 push (offset loc_496025+1)
.wtq_:0049600C pop edx
.wtq_:0049600E mov esi, 598h
.wtq_:00496015 push dword ptr [edx+esi]
.wtq_:00496018 xor [esp], ecx
.wtq_:0049601B pop dword ptr [edx+esi]
.wtq_:0049601F sub esi, 2
.wtq_:00496022 sub esi, 2
.wtq_:00496025 jnz short loc_496015
This piece of code is a layer of decryption that decodes the code starting from 496026, if you are in a situation like this and don't want to risk that a breakpoint disrupts the genuinity of decrypted code, just place a conditional breakpoint on jump. After that this routine is executed, here how changes the code:
0049602A CALL 004961AC
0049602F ADD BYTE PTR DS:[EAX],AL
00496031 ADD BYTE PTR DS:[EAX],AL
Inside Call 004961ac we can see that there is a big portion of unassembled code, to remove this issue just select Analysis -> Remove Analysis and the code will appear. Inside this call we can see that in ESI we will have the "Kernel32.dll" string and successively we will enter into a second call where we can see this
00496270 57 PUSH EDI ;EDI Points to Kernel32.dll string
00496271 FF13 CALL DWORD PTR DS:[EBX] ;EBX points to LoadLibrary
00496273 8BF0 MOV ESI,EAX
00496275 85F6 TEST ESI,ESI
00496277 0F84 8C000000 JE 00496309 ;Jump if LoadLibrary fails
004962A7 50 PUSH EAX ;points to 'GetTempPath
004962A8 56 PUSH ESI ; kernel32.dll
004962A9 FF53 04 CALL DWORD PTR DS:[EBX+4] ;EBX+4 is GetProcAddress
In this way is builded an ImportTable, here some function retrived via GetProcAddress:
GetTempFileName, CreateFile, ReadFile, WriteFile, SetFilePointer, CloseHandle, GetTickCount,
at this last imported function ends the first round, here how continues the importing function:
0049630D 8D97 85000000 LEA EDX,[EDI+85]
00496313 52 PUSH EDX ; ASCII "ADVAPI32.dll"
00496314 FF13 CALL DWORD PTR DS:[EBX]
00496316 8BF0 MOV ESI,EAX
00496318 85F6 TEST ESI,ESI
0049631A 74 2C JE SHORT 00496348 ;go out
The imported functions are the classical one used for Registry Keys basilar operations. Here ends the function of this call, flow comes back to the main call and after some instruction we land into another call that makes compromise System Registry Keys, let's see how..
00496373 50 PUSH EAX
00496374 68 19000200 PUSH 20019
00496379 8D97 BD000000 LEA EDX,[EDI+0BD]
0049637F 6A 00 PUSH 0
00496381 52 PUSH EDX
00496382 68 01000080 PUSH 80000001
00496387 FF56 2C CALL DWORD PTR DS:[ESI+2C] ;RegOpenKeyExA
This is the Registry Key: Software\M*cro$oft\Wi ndows\CurrentVersion\Explorer and successively via RegQueryValue is taken the PINF value. Successively is performed a verification based on PINF's value but this does not affect the process of Parite Anatomy definition, so we can move on and reach the successive call, where is builded a new file, let's see how is done this:
00496428 50 PUSH EAX
00496429 6A 00 PUSH 0
0049642B FF53 28 CALL DWORD PTR DS:[EBX+28] ;GetModuleFileNameA
0049642E 6A 00 PUSH 0
00496430 6A 01 PUSH 1
00496432 6A 03 PUSH 3
00496434 6A 00 PUSH 0
00496436 6A 01 PUSH 1
00496438 8D95 ECFEFFFF LEA EDX,[EBP-114]
0049643E 68 00000080 PUSH 80000000
00496443 52 PUSH EDX
00496444 FF53 10 CALL DWORD PTR DS:[EBX+10] ;CreateFileA
00496458 50 PUSH EAX
00496459 68 04010000 PUSH 104
0049645E FF53 08 CALL DWORD PTR DS:[EBX+8] ;GetTempPath
00496461 FF53 24 CALL DWORD PTR DS:[EBX+24] ;GetTickCount
00496464 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX
00496467 33C9 XOR ECX,ECX
00496469 33C0 XOR EAX,EAX
0049646B 8A440D F8 MOV AL,BYTE PTR SS:[ECX+EBP-8]
0049646F 51 PUSH ECX
00496470 B9 0A000000 MOV ECX,0A
00496475 99 CDQ
00496476 F7F9 IDIV ECX
00496478 59 POP ECX
00496479 04 61 ADD AL,61
0049647B 88440D F8 MOV BYTE PTR SS:[ECX+EBP-8],AL
0049647F 41 INC ECX
00496480 83F9 02 CMP ECX,2
00496483 ^ 7E E4 JLE SHORT 00496469
This piece of code locates Get Temp files path and via GetTickCount and a conversion routine build a string that is random because depends directly from GetTickCount.
0049649A 6A 00 PUSH 0
0049649C 68 80000000 PUSH 80
004964A1 6A 02 PUSH 2
004964A3 6A 00 PUSH 0
004964A5 6A 01 PUSH 1
004964A7 68 000000C0 PUSH C0000000
004964AC 56 PUSH ESI
004964AD FF53 10 CALL DWORD PTR DS:[EBX+10] ; CreateFileA
creates a file with a random file name (*.tmp)
004964CE FF53 1C CALL DWORD PTR DS:[EBX+1C] ;SetFilePointer
004964D1 81FE 00280000 CMP ESI,2800
004964D7 76 56 JBE SHORT 0049652F
00496527 81FE 00280000 CMP ESI,2800
0049652D ^ 77 AA JA SHORT 004964D9
Now starts a process of decryption and *.tmp byte filling. Parite by using ReadFile and WriteFile, takes blocks of code from itself, decrypts it and dump in the *.tmp file. After finishing this operation we land here
00496229 E8 CA010000 CALL 004963F8 ;*.tmp builder
0049622E 84C0 TEST AL,AL
00496230 74 12 JE SHORT 00496244 ;if building is ok prosecute, else jump
00496238 8D85 C2FEFFFF LEA EAX,[EBP-13E]
0049623E 50 PUSH EAX ; ASCII "C:\DOCUME~1\xxxx\IMPOST~1\Temp\dyj1.tmp"
0049623F E8 7C010000 CALL 004963C0
Inside call 004963c0 we can suddely discover that *.tmp is a DLL, this is easy to understand due to the usage of LoadLibrary with dyj1.tmp name.
004963E2 FF75 10 PUSH DWORD PTR SS:[EBP+10]
004963E5 FFD0 CALL EAX ;This is a truly interesting call
004963E7 84C0 TEST AL,AL
004963E9 74 04 JE SHORT 004963EF
Call EAX is our gateway to dyj1.tmp dll, indeed this function belongs to dyj1.tmp.Initiate function.
Before starting the direct debugging of this dll, let's see how is builded which function exports etc.
When IDA finishes to disassemble it, just press ctrl+E, a list of exported functions appear, let's see the most interesting:
We can essentially isolate four categories of functions:
* AttachHook, Initiate, Debug ; Devoted to hooking and system component Subversion
* Functionsunit ;General processing unit for hook management
* Lifeunit ;Infection management
* Numudp ;Networking Functionalities
* xp; Event Handler
In the second piece of this paper we will investigate deeply this issue
In the previous post we discovered that Parite.B makes use of a self generated dll, this dynamic library offers a collection of support functionalities. This dll presents big blocks of encrypted code plus a malformed IAT (Import Address Table).
With a bit of research on Exported functions, like for example @Nmudp@TNMUDP@SetLocalPort$qqri
we can Demangle it on fly.
Unit Name: NMUDP
TNMUDP = class(TComponent)
By using google we suddenly can discover that Nmudp is an old delphi UDP component, that offers streaming and udp packets management functionalities. This allow us to jump the entire reversing of Nmudp component because we already know what does and with 30 secs of google research also how functions are declared and which parameters are used.
Parite.B accesses to this dll via this piece of code
004963E2 FF75 10 PUSH DWORD PTR SS:[EBP+10]
004963E5 FFD0 CALL EAX ;dll gateway
004963E7 84C0 TEST AL,AL
004963E9 74 04 JE SHORT 004963EF
At this point we should decide how to prosecute analysis, we have the following possible paths to follow
* Enter into Initialize import and follow the entire dll
* Enter into Inizialize, jump the Nmudp components and focus on AttachHook
* Do not enter into Initialize and prosecute with main binary analysis
We will follow the third approach due to the fact that entire dll analysis is long and decentrates from the objective of this post.
When Initialize function is completed, execution comes back to the main executable:
00496217 8BD8 MOV EBX,EAX
00496219 84DB TEST BL,BL
0049621B 75 27 JNE SHORT 00496244 ;Jump out if Initialize failed
00494660 60 PUSHAD
00494661 BE 00104600 MOV ESI,Protesto_Serasa.00461000 ;Base Address Block
00494666 8DBE 0000FAFF LEA EDI,[ESI+FFFA0000]
0049467A EB 0E JMP SHORT 0049468A
00494680 /8A06 MOV AL,BYTE PTR DS:[ESI]
00494682 |46 INC ESI
00494683 |8807 MOV BYTE PTR DS:[EDI],AL ;EDI starts from 00401000
00494685 |47 INC EDI
00494686 |01DB ADD EBX,EBX
00494688 |75 07 JNE SHORT 00494691
0049468A |8B1E MOV EBX,DWORD PTR DS:[ESI]
0049468C |83EE FC SUB ESI,-4
0049468F |11DB ADC EBX,EBX
00494691 ^\72 ED JB SHORT 00494680
This routine united with another considerable piece of code that i did not reported here decrypts data from 00461000 and places it into 00401000. Suddenly after the block decoding, with the already seen method (LoadLibrary + GetProcAddress) Parite obtains some other Import's address.
004947E2 BB 00100000 MOV EBX,1000
004947E7 50 PUSH EAX
004947E8 54 PUSH ESP
004947E9 6A 04 PUSH 4
004947EB 53 PUSH EBX
004947EC 57 PUSH EDI
004947ED FFD5 CALL EBP ;VirtualProtect
Changes Page Privileges into READWRITE
004947EF 8D87 1F020000 LEA EAX,[EDI+21F]
004947F5 8020 7F AND BYTE PTR DS:[EAX],7F
004947F8 8060 28 7F AND BYTE PTR DS:[EAX+28],7F
these two instructions make an AND byte operation to the first byte before UPX1 and RSRC name section
004947FC 58 POP EAX
004947FD 50 PUSH EAX
004947FE 54 PUSH ESP
004947FF 50 PUSH EAX
00494800 53 PUSH EBX
00494801 57 PUSH EDI
00494802 FFD5 CALL EBP ;VirtualProtect
Restore old privileges (READONLY Access)
Finally we land here:
004762CF A1 D08A4700 MOV EAX,DWORD PTR DS:[478AD0] ; ASCII "49B49D908E5EE57DB779401B035381939876BE55AB6BB2358DCD"
004762D4 E8 8FDAFFFF CALL 00473D68 ;Decrypt String
004762D9 8B45 EC MOV EAX,DWORD PTR SS:[EBP-14] ; ASCII "C:\Arquivos de Programas\" ;this is the decoded string after CALL 00473D68
004762DC E8 F72FF9FF CALL 004092D8
004762E1 84C0 TEST AL,AL
004762E3 75 1A JNE SHORT 004762FF
The meaning of this piece of code should be easy to understand, we have and encrypted string that is decoded by CALL 00473D68 and successively the decoded one is used by another function ( CALL 004092D8 )
"C:\Arquivos de Programas\"
"C:\Arquivos de programas\Internet Explorer\"
"C:\Arquivos de programas\Internet Explorer\PLUGINS\"
finally after some string operation we can directly sniff from memory, the following path
004763BD A1 38BC4700 MOV EAX,DWORD PTR DS:[47BC38] ; ASCII "C:\Arquivos de programas\Internet Explorer\PLUGINS\iewd.exe"
When finished with these operations, devoted to build this new executable called iewd.exe, Parite.B moves to another operation releated to System Services.
004753EF 6A 01 PUSH 1
004753F1 68 3C544700 PUSH Protesto_Serasa.0047543C ; ASCII "ServicesActive"
004753F6 6A 00 PUSH 0
004753F8 E8 A3FFFFFF CALL ; Jump to advapi32.OpenSCManagerA
0047541A 6A 01 PUSH 1
0047541C A1 84BB4700 MOV EAX,DWORD PTR DS:[47BB84]
00475421 50 PUSH EAX
00475422 E8 71FFFFFF CALL ; Jump to advapi32.ControlService
Sends a ControlCode to a specified service, in our case sends a SERVICE_CONTROL_STOP. Immediately after ControlService is called, system will notice that Firewall is Disabled, not a stealth approach to disable system firewall =)
At this point, execution have a little derailment, in other work Parite.B performs an Unhandled Exception, to bypass this issue, simply add Exception bypass on Olly Options, plus add Illegal Instruction bypass and press Run, Parite will crash, now just accept the classical Crash Window and you will be automatically prompted again on malicious code.
0040458B E8 C4CCFFFF CALL ; Jump to kernel32.UnhandledExceptionFilter
00404590 83F8 00 CMP EAX,0
00404593 74 71 JE SHORT 00404606
00404595 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]
00404599 FC CLD
In the following post we will see how Parite works from a networking point of view, and successively we will analyze deeply the involved dll.
This time we will move our point of view at the immediate post infection instant, the point where Parite.B attempts to enstablish a networked communication with an IRC Server and two Websites.
The best approach to discover and define network features is to use a packet capture system, like Wireshark, into a well controlled environement, Vmware or VirtualBox is perfect, just remember if you are not sure of the capilities that your malware have, to correctly protect transactions between Host and Guest Systems.
When environement is ready, run Wireshark and watch the traffic dumped when the system is at rest, what is dumped at this point is a further annoyance into the Malware Activity PCAP, so be smart enough to build the appropriate packet filtering rules.
Now you can run Parite.B, just wait some moment and wireshark will do his work. Just a note, if you dissect today network activity of this Parite variant, many informations are lost, because malicious server has changed.
Here some Evidence of Parite Network Activity:
As you can see here we have two DNS Queries (type DNS_TYPE_A ) about two domains, that are correctly resolved. Successively we can see some Http Request performed on the first domain:
Our malicious binary requests a malicious file called imag1.gif and successively mais1.php
This confirm the Download functionality of Parite, now we are also able to build a Blocking Rule for this malicious Domain. By inspecting further activities we can carve the following truly interesting informations:
Parite.B attemps to connect to:
Plus, by watching traffic produced to reach an Irc Server, we can isolate the following Credential:
From port 21 traffic, we can carve the following password:
Another important thing to not forgot is to watch the HOST file, usually this king of malware adds URL to IP mappings. Obviously you need to know the HOST file, BEFORE and AFTER infection, with a basilar differentiation between these two events, suddenly we detect two domains that are certainly inserted by Parite:
These domains came from Brasil and belongs to Brasilian Banking Services.
In the next post we will see how works the malicious dll previously encountered.
Giuseppe 'Evilcry' Bonfa'