Obscene trojan.
In general, everything was clear with this trojan from the very beginning: it is downloading something from the network. But for some reason (one of them is Casper detection as P2P-Worm.Win32.Socks.s), I decided to “disassemble” it. Under the cut - technical details of the opening of the trojan. Attention, there are not quite censored words and a lot of technical details!
Today on the table is the services.exe file, a little less than 20,000 bytes. Not packaged, written on VC one of the versions.
IDA after processing the file stops at WinMain. And in WinMain we immediately see:
.text: 00403444 push ebp
.text: 00403445 mov ebp, esp
.text: 00403447 push 0FFFFFFFFh
.text: 00403449 push offset unk_404140
.text: 0040344E push offset loc_403540
.text: 00403453 mov eax, large fs: 0
.text: 00403459 push eax
.text: 0040345A mov large fs: 0, esp
.text: 00403461 push ecx
.text: 00403462 push ecx
.text: 00403463 sub esp, 10h
.text: 00403466 push ebx
.text: 00403467 push esi
.text: 00403468 push edi
.text: 00403469 mov [ebp + var_18], esp
.text: 0040346C and [ebp + var_4], 0
.text: 00403470 and dword ptr [ebp + Time + 4], 0
.text: 00403474 mov eax, dword ptr [ebp + Time + 4]
.text: 00403477 mov dword ptr [eax], 0DFADBABEh
.text: 0040347D or [ebp + var_4], 0FFFFFFFFh
.text: 00403481 jmp loc_40352B
...
.text: 0040352B loc_40352B :; CODE XREF: WinMain (x, x, x, x) + 3D
.text: 0040352B mov ecx, [ebp + var_10]
.text: 0040352E mov large fs: 0, ecx
.text: 00403535 pop edi
.text: 00403536 pop esi
.text: 00403537 pop ebx
.text: 00403538 leave
.text: 00403539 retn 10h
.text: 00403539 _WinMain @ 16 endp
But let's pay attention to the code starting with the address 0x403470 - an explicit attempt to access the address 0x000000! At this point, the SEH handler is called, and as a result, control is still transferred to where it should be. A similar trick is used at least once more in WinMain. But WinMain prepared a couple more surprises, for example, control is transferred to the following code:
.text: 00401EA3 loc_401EA3 :; CODE XREF: WinMain (x, x, x, x): loc_4034C9
.text: 00401EA3 push ebp
.text: 00401EA4 mov ebp, esp
.text: 00401EA6 push 0FFFFFFFFh
.text: 00401EA8 push offset unk_404120
.text: 00401EAD push offset loc_4035
. text: 00401EB2 mov eax, large fs: 0
.text: 00401EB8 push eax
.text: 00401EB9 mov large fs: 0, esp
.text: 00401EC0 push ecx
.text: 00401EC1 push ecx
.text: 00401EC2 push ecx
.text: 00401EC3 push ebx
.text: 00401EC4 push esi
.text: 00401EC5 push edi
.text: 00401EC6 mov [ebp-18h], esp
.text: 00401EC9 and dword ptr [ ebp-4], 0
.text: 00401ECD mov eax, 1
.text: 00401ECD; - .text: 00401ED2 dw 3F0Fh
.text: 00401ED4 dd 45C70B07h, 0FFFFFFFCh, 0FC4D83FFh, 6A14EBFFh, 8BC35801h
.text: 00401ED4 dd
6580E865h, 4D8300E7h0B01D00HBD00DB0100E7H0B0100E7B0H00B0F01F0HB0FB01F0FB01FB01
Invalid opcode. Olly, at this point, refuses to move to the next instruction. That is, we have a kind of anti-debugging technique. And the last trick is VMWare detection, which is quickly and easily recognized by the following instructions:
.text: 00401F34 mov eax, 'VMXh'
.text: 00401F39 mov ebx, 8685D465h
.text: 00401F3E mov ecx, 0Ah
.text: 00401F43 mov dx, 5658h
. text: 00401F47 in eax, dx
In fact, WinMain performs two functions: it complicates the life of the researcher and transfers (if everything is as it should) control to the payload. I did not go through WinMain, and at the very beginning I moved EIP directly to PayLoad. At first, as usual, the trojan prepares data for its dirty deeds: it decrypts all the lines and finds out the addresses of the necessary API functions (LoadLibrary + GetProcAddress, and not in a loop). String encryption - XOR with one byte, though the key is different everywhere. The algorithm is easily recognized:
.text: 0040100E loc_40100E :; CODE XREF: decryptXor + 37 j
.text: 0040100E mov eax, [ebp + pos]
.text: 00401011 inc eax
.text: 00401012 mov [ebp + pos], eax
.text: 00401015
.text: 00401015 loc_401015 :; CODE XREF: decryptXor + C j
.text: 00401015 push [ebp + lpString]; lpString
.text: 00401018 call ds: lstrlenA
.text: 0040101E cmp [ebp + pos], eax
.text: 00401021 jge short loc_401039
.text: 00401023 mov eax, [ebp + lpString]
.text: 00401026 add eax, [ebp + pos ]
.text: 00401029 movsx eax, byte ptr [eax]
.text: 0040102C xor eax, [ebp + key]
.text: 0040102F mov ecx, [ebp + lpString]
.text: 00401032 add ecx, [ebp + pos]
. text: 00401035 mov [ecx], al
.text: 00401037 jmp short loc_40100E
On Delphi, by the way, such a decryption function would take two pages. For what I Delphi and do not like.
Then comes the WSAStartup call - preparation for working with Windows Sockets, an attempt to delete the c: \ stop file (the Trojan is uniquely identified by the name of this file), and preparing lines containing the necessary paths. The following point is interesting: the trojan opens its file for reading, moves the reading position to 0x43 bytes and reads 8 bytes from there. I look at HIEW at this place ... Oppa! Yes, we have a MANUAL modified header here! 0x43 is just the beginning of the line “This program ...”, and here we have load \ 0. The next number of our program is the calculation of a unique line based on the path to the Windows system catalog and the serial number of the disk. Now the trojan will check for the presence of two files in the system:% Windows% \ system32 \ drivers \ services.exe and svchost.exe in the current user's directory. When the trojan is not installed in the system, it switches to a very interesting code. First, from the string (!), Through the own implementation of the atoi function, a number is obtained, which is then multiplied by 1000, and the result is passed to the Sleep function, that is, an adjustable delay is performed. The delay before the Trojan receives command line arguments, collects them all together, and passes them to WinExec. Suggests suspicion that the trojan may be registered as a default program for opening files! Missing arguments are handled correctly. Before performing destructive actions, the trojan checks for the presence of the mutex in the system, and if the mutex already exists, it completes its work. If there are no brothers, it creates two threads, one of which checks the c: \ stop file in the loop (if it exists, terminates the process), and the second performs work with the network. The final touch is extracting the ftp34 file from your body. dll (XOR encryption, key - 1 byte) to the user directory and system directory with its subsequent download. To complicate the user's life, the creation date of these files will be the same as the system ones.
Network activity.
All work with the network is concentrated in one of the Trojan streams. In the same stream, the trojan copies itself to% Windows% \ system32 \ drivers \ services.exe, the svchost.exe file in the current user directory and the userinit.exe file in “Startup” in the Windows main menu (and the date also corrects). (At this point, I foolishly released the Trojan out of control and had to restore the system from the image). It is registered in the register in at least 5 places. And, as I expected, it is registered as a default program for opening EXE files. I won’t put the threadblock at the beginning of ThreadProc, again stupidly and cynically I will change EIP to its beginning :-)
So what about the network? An attempt is made to request a URL of the form site.com/shl/?&v=load&lid=1033. Whois reports that the contact soap for this site is on mail.ru, and the IP address belongs to the Russian hoster. What is passed in the URL? “Load” is just that piece that was extracted from the site header, and 1033 is the identifier of the system language. If you go to site.com/shl/ with your browser, there will be a picture and a login form.
Here is such a logo!
I put shttpd on the vendor, registered 127.0.0.1 for site.com in etc / hosts. But there is a problem: shttpd is bad with urls containing "?" coping. The problem is solved simply: download the desired file from the server with wget, rename it to shl.txt, and before calling InternetReadFile from the trojan, patch the URL in memory so that it becomes site.com/shl.txt. Now the server will give the file and the trojan will receive it. At first I thought that the Trojan needed this page to somehow send a username and password. But everything turned out to be simpler: the trojan is looking for the string “form method” and if it is, it continues to download. This time, the file is downloaded from the site.com/shl/manda.php?ns=1&id=1212312124 URL, where id is a unique number (see receipt above). But for some reason this file didn’t download for me :-( Perhaps there is an IP blocking on the server, who knows ... But the file downloaded at work. There is a list of URLs in plain text. The code is quite simple, and it becomes clear that files are downloaded from the indicated URLs and launched for execution, this is done from a separate stream.
The results.
Caspers made a mistake with the name, and once again I was convinced that such files are at least Downloaders. The authors of the Trojan are Russian-speaking comrades who sell the Trojan ... Less than 20% of the code is not parsed in detail, but judging by the description on the authors website and also by text lines, the Trojan is able to collect email addresses for spam mailings. The ftp34.dll library is most likely used to intercept passwords for FTP access. I think at work I can pick out the rest of it in detail. Here it is, the trojan is “silly” :-)
UPDATE Continuation of vilgeforce.habrahabr.ru/blog/44145.html
Today on the table is the services.exe file, a little less than 20,000 bytes. Not packaged, written on VC one of the versions.
IDA after processing the file stops at WinMain. And in WinMain we immediately see:
.text: 00403444 push ebp
.text: 00403445 mov ebp, esp
.text: 00403447 push 0FFFFFFFFh
.text: 00403449 push offset unk_404140
.text: 0040344E push offset loc_403540
.text: 00403453 mov eax, large fs: 0
.text: 00403459 push eax
.text: 0040345A mov large fs: 0, esp
.text: 00403461 push ecx
.text: 00403462 push ecx
.text: 00403463 sub esp, 10h
.text: 00403466 push ebx
.text: 00403467 push esi
.text: 00403468 push edi
.text: 00403469 mov [ebp + var_18], esp
.text: 0040346C and [ebp + var_4], 0
.text: 00403470 and dword ptr [ebp + Time + 4], 0
.text: 00403474 mov eax, dword ptr [ebp + Time + 4]
.text: 00403477 mov dword ptr [eax], 0DFADBABEh
.text: 0040347D or [ebp + var_4], 0FFFFFFFFh
.text: 00403481 jmp loc_40352B
...
.text: 0040352B loc_40352B :; CODE XREF: WinMain (x, x, x, x) + 3D
.text: 0040352B mov ecx, [ebp + var_10]
.text: 0040352E mov large fs: 0, ecx
.text: 00403535 pop edi
.text: 00403536 pop esi
.text: 00403537 pop ebx
.text: 00403538 leave
.text: 00403539 retn 10h
.text: 00403539 _WinMain @ 16 endp
But let's pay attention to the code starting with the address 0x403470 - an explicit attempt to access the address 0x000000! At this point, the SEH handler is called, and as a result, control is still transferred to where it should be. A similar trick is used at least once more in WinMain. But WinMain prepared a couple more surprises, for example, control is transferred to the following code:
.text: 00401EA3 loc_401EA3 :; CODE XREF: WinMain (x, x, x, x): loc_4034C9
.text: 00401EA3 push ebp
.text: 00401EA4 mov ebp, esp
.text: 00401EA6 push 0FFFFFFFFh
.text: 00401EA8 push offset unk_404120
.text: 00401EAD push offset loc_4035
. text: 00401EB2 mov eax, large fs: 0
.text: 00401EB8 push eax
.text: 00401EB9 mov large fs: 0, esp
.text: 00401EC0 push ecx
.text: 00401EC1 push ecx
.text: 00401EC2 push ecx
.text: 00401EC3 push ebx
.text: 00401EC4 push esi
.text: 00401EC5 push edi
.text: 00401EC6 mov [ebp-18h], esp
.text: 00401EC9 and dword ptr [ ebp-4], 0
.text: 00401ECD mov eax, 1
.text: 00401ECD; - .text: 00401ED2 dw 3F0Fh
.text: 00401ED4 dd 45C70B07h, 0FFFFFFFCh, 0FC4D83FFh, 6A14EBFFh, 8BC35801h
.text: 00401ED4 dd
6580E865h, 4D8300E7h0B01D00HBD00DB0100E7H0B0100E7B0H00B0F01F0HB0FB01F0FB01FB01
Invalid opcode. Olly, at this point, refuses to move to the next instruction. That is, we have a kind of anti-debugging technique. And the last trick is VMWare detection, which is quickly and easily recognized by the following instructions:
.text: 00401F34 mov eax, 'VMXh'
.text: 00401F39 mov ebx, 8685D465h
.text: 00401F3E mov ecx, 0Ah
.text: 00401F43 mov dx, 5658h
. text: 00401F47 in eax, dx
In fact, WinMain performs two functions: it complicates the life of the researcher and transfers (if everything is as it should) control to the payload. I did not go through WinMain, and at the very beginning I moved EIP directly to PayLoad. At first, as usual, the trojan prepares data for its dirty deeds: it decrypts all the lines and finds out the addresses of the necessary API functions (LoadLibrary + GetProcAddress, and not in a loop). String encryption - XOR with one byte, though the key is different everywhere. The algorithm is easily recognized:
.text: 0040100E loc_40100E :; CODE XREF: decryptXor + 37 j
.text: 0040100E mov eax, [ebp + pos]
.text: 00401011 inc eax
.text: 00401012 mov [ebp + pos], eax
.text: 00401015
.text: 00401015 loc_401015 :; CODE XREF: decryptXor + C j
.text: 00401015 push [ebp + lpString]; lpString
.text: 00401018 call ds: lstrlenA
.text: 0040101E cmp [ebp + pos], eax
.text: 00401021 jge short loc_401039
.text: 00401023 mov eax, [ebp + lpString]
.text: 00401026 add eax, [ebp + pos ]
.text: 00401029 movsx eax, byte ptr [eax]
.text: 0040102C xor eax, [ebp + key]
.text: 0040102F mov ecx, [ebp + lpString]
.text: 00401032 add ecx, [ebp + pos]
. text: 00401035 mov [ecx], al
.text: 00401037 jmp short loc_40100E
On Delphi, by the way, such a decryption function would take two pages. For what I Delphi and do not like.
Then comes the WSAStartup call - preparation for working with Windows Sockets, an attempt to delete the c: \ stop file (the Trojan is uniquely identified by the name of this file), and preparing lines containing the necessary paths. The following point is interesting: the trojan opens its file for reading, moves the reading position to 0x43 bytes and reads 8 bytes from there. I look at HIEW at this place ... Oppa! Yes, we have a MANUAL modified header here! 0x43 is just the beginning of the line “This program ...”, and here we have load \ 0. The next number of our program is the calculation of a unique line based on the path to the Windows system catalog and the serial number of the disk. Now the trojan will check for the presence of two files in the system:% Windows% \ system32 \ drivers \ services.exe and svchost.exe in the current user's directory. When the trojan is not installed in the system, it switches to a very interesting code. First, from the string (!), Through the own implementation of the atoi function, a number is obtained, which is then multiplied by 1000, and the result is passed to the Sleep function, that is, an adjustable delay is performed. The delay before the Trojan receives command line arguments, collects them all together, and passes them to WinExec. Suggests suspicion that the trojan may be registered as a default program for opening files! Missing arguments are handled correctly. Before performing destructive actions, the trojan checks for the presence of the mutex in the system, and if the mutex already exists, it completes its work. If there are no brothers, it creates two threads, one of which checks the c: \ stop file in the loop (if it exists, terminates the process), and the second performs work with the network. The final touch is extracting the ftp34 file from your body. dll (XOR encryption, key - 1 byte) to the user directory and system directory with its subsequent download. To complicate the user's life, the creation date of these files will be the same as the system ones.
Network activity.
All work with the network is concentrated in one of the Trojan streams. In the same stream, the trojan copies itself to% Windows% \ system32 \ drivers \ services.exe, the svchost.exe file in the current user directory and the userinit.exe file in “Startup” in the Windows main menu (and the date also corrects). (At this point, I foolishly released the Trojan out of control and had to restore the system from the image). It is registered in the register in at least 5 places. And, as I expected, it is registered as a default program for opening EXE files. I won’t put the threadblock at the beginning of ThreadProc, again stupidly and cynically I will change EIP to its beginning :-)
So what about the network? An attempt is made to request a URL of the form site.com/shl/?&v=load&lid=1033. Whois reports that the contact soap for this site is on mail.ru, and the IP address belongs to the Russian hoster. What is passed in the URL? “Load” is just that piece that was extracted from the site header, and 1033 is the identifier of the system language. If you go to site.com/shl/ with your browser, there will be a picture and a login form.
Here is such a logo!
I put shttpd on the vendor, registered 127.0.0.1 for site.com in etc / hosts. But there is a problem: shttpd is bad with urls containing "?" coping. The problem is solved simply: download the desired file from the server with wget, rename it to shl.txt, and before calling InternetReadFile from the trojan, patch the URL in memory so that it becomes site.com/shl.txt. Now the server will give the file and the trojan will receive it. At first I thought that the Trojan needed this page to somehow send a username and password. But everything turned out to be simpler: the trojan is looking for the string “form method” and if it is, it continues to download. This time, the file is downloaded from the site.com/shl/manda.php?ns=1&id=1212312124 URL, where id is a unique number (see receipt above). But for some reason this file didn’t download for me :-( Perhaps there is an IP blocking on the server, who knows ... But the file downloaded at work. There is a list of URLs in plain text. The code is quite simple, and it becomes clear that files are downloaded from the indicated URLs and launched for execution, this is done from a separate stream.
The results.
Caspers made a mistake with the name, and once again I was convinced that such files are at least Downloaders. The authors of the Trojan are Russian-speaking comrades who sell the Trojan ... Less than 20% of the code is not parsed in detail, but judging by the description on the authors website and also by text lines, the Trojan is able to collect email addresses for spam mailings. The ftp34.dll library is most likely used to intercept passwords for FTP access. I think at work I can pick out the rest of it in detail. Here it is, the trojan is “silly” :-)
UPDATE Continuation of vilgeforce.habrahabr.ru/blog/44145.html