📜 ⬆️ ⬇️

Mal, yes Blessed: Trojan-Downloader.Win32.Tiny

Good day to all.
There are a lot of technical details in today's release. So excuse me if there are too many of them :)

Letter


So here we go. At the entrance we have a letter with the text “Journalist shot in Georgia! See attached video. Password is 123 "and with the attached file" Georgia.zip ".

For more or less complete analysis, we will need:
- The Best Disassembler in the IDA World
- Nice Windbg Debugger
- python 2.5 (strictly speaking, any will suit, simply at me 2.5)
- Visual Studio some and Microsoft SDK to build a small program on with ++.
- packer software upx
- well, something else on the little things.
')
We unpack the file sent to us, and we see that our suspicions are justified: the video did not sleep there at night.
 connected.exe (md5: 607af96b03addadf28cf9280701df191)
 Dr.Web: Trojan.Packed.151
 Kaspersky: Trojan-Downloader.Win32.Agent.abqe


Unpacking


First attack. We save the file to a safe place, remove the right to execute it, upload it to ida. Immediately, ida swears at the IAT in a non-standard section and warns that not all imported functions will be visible, agree to continue. After that, ida thinks a little, doing the disassembling and analysis of our file, and, having finished, goes into Entry Point itself.



We see some large and complex calculations in the “Navigation” window, and by pressing Ctrl-S, in the opened list of segments we see two entries: “UPX0” and “UPX1”. And this is clearly given to us in the mogz: “packaged upx”. More precisely, there is a possibility that upx is packaged, and we are going to check this opportunity.

 D: \ programs \ upx> upx -t D: \ prog \ virus \ 0001.Georgia-2008-08-25 \ joined.exe

 testing D: \ prog \ virus \ 0001.Georgia-2008-08-25 \ joined.exe [OK]

 That is, upx recognized its file.  We pack:
 D: \ programs \ upx> upx -d D: \ prog \ virus \ 0001.Georgia-2008-08-25 \ joined.exe
         File size Ratio Format Name
    -------------------- ------ ----------- ----------
      10240 <- 7680 75.00% win32 / pe joined.exe

 Unpacked 1 file.

After that, open the unpacked file in ida and skim through it.



The main function looks quite simple: first, some adjustment is made using LoadLibrary and GetProcAddress, so as not to shine the functions used in the import. Then comes the call to EnumResourceNames, which lists all the resource names. Well, resources, this is interesting, let's see what is in the resources of our file.

Open the resource editor (I have an old ResourceExplorer), and we see, among other things, an excellent binary resource called "LOADER.19B099.EXE". Executable file inside the resource! Well, it is very similar that the main virus exports the nested one and starts it in some way. I propose for the time being to postpone the first file and pick this binary resource.



Trojan in Trojans



We export the resource to the file, see what the antiviruses say.

 resource-loader.19b099.exe (md5: ca843aed6a7910fcb36bd0146af990ca)
 Dr.Web: Trojan.Packed.151
 Kaspersky: Trojan-Downloader.Win32.Tiny.bvi

(Note, by the way, that doctorWeb marks this file as well as joined.exe).

Well, first, the size. 1.6 kilobytes It means that we worked thoroughly with a file, forced the compiler to optimize and generally tried our best. Secondly, such code can be easily injected into some other process - if this code is, of course, correctly written. Thirdly, no imports at all - another plus to the shell code hypothesis. Well and, fourthly, the body is “encrypted”. Here's what's going on at the entry point:



We see that the code calculates where it is located (gets EIP using fnstenv), runs from this place back to the beginning of the current page, that is, roughly speaking, until the last three characters of the address become zero. This is done because the code starts with an offset of 00001000h relative to the beginning of the image of the file in memory. The unpacking algorithm is as follows:

 byte * data = [EIP], obtained by tricky manipulations.
 x = 0A9h;
 while (data & 0xFFF)
 {
	 * data = * data ^ x;
	 x--;
	 data--;
 } 

After that, control is transferred somewhere in the middle of the unpacked code.

Unpacking-2


Well, since the file unpacks itself, let it do it itself. We will only need to stop at the right place to see the unpacked code. Run Windbg, press Ctrl-E (Open executable file), then the debugger stops. This is not the entry point, but only the beginning of the process. Finding out the entry point (if we suddenly forgot it when we looked at the disassembled code):

 0: 001>! Dh 00400000 
 File Type: EXECUTABLE IMAGE
 ...
 OPTIONAL HEADER VALUES
      10B magic #
     7.10 linker version
      400 size of code
      200 size of initialized data
        0 size of uninitialized data
     132F address of entry point		
     1000 base of code 


Go to her:
 0: 000> g 40132F 


We are interested in the final stage of decryption: the transition to the decrypted code that occurs in the string:
 .text: 0040135D push offset dword_401135

Go here:
 0: 000> bp 0040135D

We press "g" (Go), and do not have time to blink an eye, as the program stops. By the way, we can see right from here how this code looks now. At the address where the transition is planned, is this:

 0: 000> uf 00401135
 image00400000 + 0x1135:
 00401135 55 push ebp
 00401136 8bec mov ebp, esp
 00401138 81ec98060000 sub esp, 698h
 0040113e 53 push ebx


Well, that's fine. We start some LordPE, make a dump of the file, and the code in the disassembler now looks more readable. The file size has not changed, it is still tiny. It has only three functions. Let's study them.

Basic functionality



That's what's at the entry point.



Of particular interest is a bunch of this type:
 mov ecx, 0D82AFA6Fh
 call my_get_proc_address
 ...
 call eax             


Through ECX, the parameter is passed to the my_get_proc_address function (I called it that. In the original, it was called sub_00401135 :), and what it returns is nothing more than the address of a certain function to which control of the call instruction is transferred.

What does the function my_get_proc_address do?

(There are quite a lot of code; those who are not too lazy will see for themselves, see below). In short:

1. Receives a pointer to PEB:
  mov eax, large fs: 30h 


By the way, we can also see what is there:
 0: 000> dt nt! _PEB
 ntdll! _PEB
    + 0x000 InheritedAddressSpace: UChar
    + 0x001 ReadImageFileExecOptions: UChar
    + 0x002 BeingDebugged: UChar
    + 0x003 SpareBool: UChar
    + 0x004 Mutant: Ptr32 Void
    + 0x008 ImageBaseAddress: Ptr32 Void
    + 0x00c Ldr: Ptr32 _PEB_LDR_DATA
    + 0x010 ProcessParameters: Ptr32 _RTL_USER_PROCESS_PARAMETERS
    + 0x014 SubSystemData: Ptr32 Void
 ...


2. Receives from PEB a list of loaded modules and passes through it. We also know where this list lies:

 0: 000> dt -r1 nt! _PEB
 ntdll! _PEB
 ...
    + 0x00c Ldr: Ptr32 _PEB_LDR_DATA
       + 0x000 Length: Uint4B
       + 0x004 Initialized: UChar
       + 0x008 SsHandle: Ptr32 Void
       + 0x00c InLoadOrderModuleList: _LIST_ENTRY
       + 0x014 InMemoryOrderModuleList: _LIST_ENTRY
       + 0x01c InInitializationOrderModuleList: _LIST_ENTRY
 ...


3. For each of these modules, the function finds the export table, “gets a list” of the exported functions. For each exported function, a certain hash is calculated, which is compared with the same strange number that is passed to the function as an argument.



By the way, this is a classic of the silk code genre. Yes, it works a little slower than the usual import procedure, but the names of the functions used hide well. How do we find the functions that are actually used? In principle, there is an option to put a breakpoint where necessary and wait. But since progress does not stand still, and we cannot be left behind, we will briefly digress from the analysis and start programming.



That means this very function is pretty simple. We will program it. Like what, on python! He is now everywhere, and in Google, they say, they love him.

 #! bin / python
 def rotl (x, n):
     return ((x << n) | (x >> (32-n)))% 2 ** 32

 def hash (s):
     x = 0
     for i in s:
         x = (rotl (x, 5) ^ ord (i))% 2 ** 32
     return x


Python with its support for large numbers hinders us, so we emulate 32-bit arithmetic, taking a module of 2 32 each .

So we recall what we said earlier: “for all exported functions of all modules”. But wait a minute, attentive readers will say. After all, the silkcode does not import anything! Gotcha! and rather rubbing their hands :) But there is such eternal Russian sadness in executable windows: creating a new win32 process from a PE file, the loader always loads two standard libraries into it: ntdll and kernel32. Here we already have a list of two modules.

The good news is that we can also get the names of the functions that these libraries export! The old-aged utility dumpbin. And cygwin, of course, will be nice to have on hand.

 dumpbin / exports C: \ WINDOWS \ system32 \ kernel32.dll> krnl-exp 
 gawk '{print $ 4}' krnl-exp> krnl-exp1 


Well, the same for ntdll. Then in the editor we remove the remnants of the header and the total generated by dumpbin, getting the list as a result. We set our python script on these files, we get that for example “0xd82afa6f” means “LdrLoadDll” - o-very poorly documented function used by the loader itself. However, its name speaks for itself - it loads the library into the address space of the process. As we have seen before, the disassembled code contains the string “ole32.dll”, yes, exactly, this is what the malware loads with the LdrLoadDll function.

We make passes with a dump and over ol32.dll, we find to our homegrown brute force all the “secret” functions (in the order of the call).

0xd82afa6f - "LdrLoadDll"
0x872b8a64 - "GetTempPathW"
0x4b99cb08 - "CoInitializeEx"
0x938ed88c - "CoInitializeSecurity"
0x7279d017 - "CoCreateInstance"
0xbde95c09 - "GetTempFileNameW"
0x050798d0 - "Sleep"
0x4b09a52a - "CreateProcessW"
0x0f12e6f0 - “CoUninitialize”
0xe3db70a7 - "ExitProcess"

We make a small description of this process in our mind: “Load ole32 (LdrLoadDll), initialize COM (CoInitialize *), create a COM object (CoCreateInstance), get the name of the temporary file (GetTemp *), wait for the weather by the sea (Sleep), create a process ( CreateProcessW), exit (everything else). Brr, already cold on the skin, how methodically and evenly we are going to infect with some kind of filth.

In general, the biggest trouble is CoCreateInstance and the subsequent CreateProcess. Because the calls to the com-object methods are done dynamically, and these methods are not named at all. That is, we, of course, can find out what is caused there, but it will be hemorrhoids ... And what to do.

What kind of object creates this reptile? In CoCreateInstance two Guid'a are transmitted - in the code they look like this:
 .text: 00401000 rclsid dd 4991D34Bh, 429180A1h, 2833B683h, 97906B36h
 .text: 00401010 riid dd 5CE34C0Dh, 4C1F0DC9h, 0A1DA7C89h, 7CEE8CB7h


Due to the nature of data storage, the “user-friendly” guid looks “mixed”, for example, if the array in memory is {5CE34C0Dh, 4C1F0DC9h, 0A1DA7C89h, 7CEE8CB7h}, means {5CE34C0D-0DC9-4C1F-897C-DAA1B78CEE7C}. Well, already something. The author of the shellcode included a hard-core guid, which means he is confident that this will work on most machines. We look for identifiers in our registry and get:

  {5CE34C0D-0DC9-4C1F-897C-DAA1B78CEE7C} 
 InProcServer32 = C: \ WINDOWS \ system32 \ qmgrprxy.dll = Background Intelligent Transfer Service Proxy
 {4991d34b-80a1-4291-83b6-3328366b9097}
 Background Intelligent Transfer Control Class 1.0


The ominous shadow of a "reasonable" file upload service looms behind these identifiers. Background Intelligent Transfer Service, or in common parlance, BITS, is, by the way, the very thing that downloads updates for windows from the Internet. In short, there is a suspicion that in this way a com-object is created which, using BITS, pumps another, more dangerous virus onto our machine. But this is only a guess, and we go to the MSND for BITS documentation.

Having rummaged a little, we find a small code sample in Connecting to the BITS Service .

  hr = CoCreateInstance (__ uuidof (BackgroundCopyManager), NULL,
                         CLSCTX_LOCAL_SERVER,
                         __uuidof (IBackgroundCopyManager),
                         (void **) & g_pbcm);


Compile, disassemble, watch what happened in our demo program:

 lea eax, [ebp + ppv]
 push eax;  ppv
 push offset dword_408140;  riid
 push 4;  dwClsContext
 push 0;  pUnkOuter
 push offset dword_408130;  rclsid
 call ds: CoCreateInstance
 ...
 .rdata: 00408130;  CLSID dword_408130
 .rdata: 00408130 dword_408130 dd 4991D34Bh, 429180A1h, 2833B683h, 97906B36h;  0
 .rdata: 00408140;  IID dword_408140
 .rdata: 00408140 dword_408140 dd 5CE34C0Dh, 4C1F0DC9h, 0A1DA7C89h, 7CEE8CB7h;  0


Actually, what was required to prove. Those same Guid's! Trying to find out what name is being downloaded using BITS, we see that the file name is “encrypted”.


Again we quickly write a python script that decrypts this line to us:
 def xor (enc, key):
     res = ""
     for x in enc:
         y = (x ^ key)% 255
         if y == 0:
             break
         key = (key + 1)% 2 ** 32;
         res = res + (chr (y))
     return res


... and get the result, stunning us to the depths of the soul !!!

 
  http://reddii.org/traffic/all/files/filebyaka.exe  
 

(Attention! At the specified address there is still a virus. Attempting to open this file can be fatal for you and your car).

The name speaks for itself. This is bjaka, and even what!

 filebyaka.exe (md5: fc85dab5849416f8796b799fc209395a)
 Dr.Web: Trojan.Packed.619
 Kaspersky: Backdoor.Win32.Agent.ajd


Actually, the analysis of this bjaki you can find on the link xanalysis.blogspot.com , which was suggested in the comments .

Everything that happens next, we can predict, even without returning to the debager. There is a job (Job) for BITS, the download starts. Then every 10 milliseconds the task status is checked. When the download is complete, the downloaded file is launched. Fuh, poyra kilobyte, and so much fuss!

Total


The “big” trojan horse inside itself as a resource contains the “little” trojan foal. This virus, only one and a half kilobytes in size (these are two pages of text in my editor), can download and launch another, more dangerous virus. It is made in the style of a silk code, right "according to the textbook." Most of the techniques used are described in detail in the Evolving Shell Code article. Troyan makes a little feint with his ears, and instead of implementing network connections, http protocol, and so on, he simply uses a windows service called Background intelligent transfer service (this is what allows reducing the size of the code). System functions are not called by direct addresses, but functions that are used to work with files, such as CreateFile, are not called at all. There is a big doubt that any of the existing antiviruses can identify such malicious functionality with heuristic analysis alone. This tiny file is downloading with a graceful name filebyaka.exe, which means that you yourself know what roots.

Files used in the analysis can be found at this address.

On this optimistic note, I say goodbye to you. Do not run unfamiliar files. Take care of yourself!

Source: https://habr.com/ru/post/39419/


All Articles