I had loaned one of my USB drives out to someone and as it usually happens, it came back with a nice little malware infection. At this point sticking your USB drive into a very public computer (e.g. One they use at a photo booth/kiosk to print stuff) is very much like visiting certain members of the oldest profession. I opened up the drive folder and was pleasantly surprised to see an unwanted executable instead of a folder containing my data.
Further investigation revealed that my data was still there, albeit hidden.
I assumed this was one the 'ransomware' type of malware which extracted some payment from the victim in exchange for restoring data access. Never having seen one live, I wondered if I could poke around and see what it was all about. Seeing a bunch of MSVBVM60.DLL imports and the call to ThunRTMain made it almost certain that this was a VB executable. Now, as you might or might not be aware, in 1983, long before the JVM or the .NET CLR existed Microsoft had another VM based tech called P-Code. P-Code which was based on UCSD Pascal, was an intermediate language that Applications, DLLs, ActiveX objects could be compiled into. Upon execution, an interpreter translated the P-Code to the underlying processor's object code. However unlike the CLR, the primary reason for the existence of this tech is the reduced code size, not portability. Experienced readers will immediately realize why I'm mentioning this. Yes, its the dreaded virual machine ! If you want to live-debug any code, you have to execute it, but if you execute interpreted code you end up debugging the virtual machine itself. Now certainly, there are ways around this ofcource. For e.g. you could create a disassembly of the p-code by hooking into the VB VM and check what each individual opcode does. Maybe you could even automate this and create a disassembler. But the point is - this is a real PITA.
So, The first order of business was to determine whether this was a native or a p-code executable. Luckily this turned out to be a regular native executable. Note that BOTH kinds use MSVBVM60.DLL. As I was browsing the the disassembly, I started running into some interesting stuff.
..... .text:004A4004 unicode 0, <(>,0 .text:004A4008 a****2_no_0: ; DATA XREF: .text:004AC587o .text:004A4008 ; .text:004AC696o ... .text:004A4008 unicode 0, <****.no-ip.info>,0 .text:004A4032 align 4 .text:004A4034 unicode 0, <&>,0 .text:004A4038 a****2_no_1: ; DATA XREF: .text:004AC7A5o .text:004A4038 ; .text:004AC8B4o ... .text:004A4038 unicode 0, <****.no-ip.org>,0 .text:004A4060 unicode 0, <&>,0 .text:004A4064 a****3_noIp: ; DATA XREF: .text:004AC9C3o .text:004A4064 ; .text:004ACAD2o ... .text:004A4064 unicode 0, <****.no-ip.biz>,0 .text:004A408C unicode 0, <(>,0 .text:004A4090 a****3_no_0: ; DATA XREF: .text:004ACBE1o .text:004A4090 ; .text:004ACCF0o ... .text:004A4090 unicode 0, <****.no-ip.info>,0 .text:004A40BA align 4 .text:004A40BC unicode 0, <&>,0 .text:004A40C0 a****3_no_1: ; DATA XREF: .text:004ACDFFo .text:004A40C0 ; .text:004ACF0Eo ... .text:004A40C0 unicode 0, <****.no-ip.org>,0 .text:004A40E8 dd 2 .text:004A40EC dword_4A40EC dd 47h, 0C0h ; DATA XREF: .text:004AECB8o .text:004A40F4 aCmd_exeCRegAdd: ; DATA XREF: .text:004AE27Eo .text:004A40F4 ; .text:004B016Bo .text:004A40F4 unicode 0, <cmd.exe /c REG ADD HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\> .text:004A40F4 unicode 0, <Windows\CurrentVersion\Run /v microsoft>,0 .text:004A41B6 align 4 .text:004A41B8 aV_0: .text:004A41B8 unicode 0, <V>,0 ... .. ..
I spent a whole bunch of time trying to understand what it was doing. Here's some of the things this malware does.
Sets up 6 timers with intervals (1, 1, 60000, 60000, 1, 100). Here's what their functions do.
Timer2 - Disabled
Timer3 - Unused
Timer4 - Disabled
Timer5 - Adds itself to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run for autorun. Changes explorer.exe registry settings to hide file extensions, and disable showing hidden files.
Timer6 - Calls GetForegroundWindow and subsequently GetWindowText and saves the values.
It also has a bunch of helper functions
HelperFunction1 - Takes a url as an argument, opens it using ShellExecute
HelperFunction2 - Takes an argument. executes the WINMGMT Query "Select Name from Win32_Process Where Name = {argument}". And then calls terminate on the returned Win32_Process objects
HelperFunction3 - Takes a screenshot using Gdi+ functions and saves it to a jpg file.
HelperFunction4 - Downloads data from a given URL with a GET request using MSXML2.XMLHTTP. The data is probably binary as ADODB.Stream is used to write it out.
HelperFunction5 - Collects a bunch of information about the PC using environment variables - COMPUTERNAME, OS, USERPROFILE, USERNAME and PROCESSOR_IDENTIFIER. It uses all the collected information to construct a url of the form http://address/bot.php?id=COMPUTERNAME+some calculated number&compname=..... and so on. It then issues a function call that I haven't been able to understand yet. Its through some virtual table which means the only way to get the actual function is to live debug this, which is not really what I want to do on my dev box :P. If I had to make an educated guess it would have to be HelperFunction1
HelperFunction6 - Identifies and saves the default browser using HKEY_CLASSES_ROOT\HTTP\shell\open\command\. Probably used by HelperFunction1.
HelperFunction7 - This function will execute commands like 'exe', 'download', 'password' , 'run', 'folderlist', 'visitpage', 'email'. They are polled from the command server.
Form_Load - Calls Form.Hide , Sets App.TaskVisible=0, checks if its being run from the %WINDIR%, if not copies itself to %WINDIR%. Next it uses some weird logic to determine which command center to contact. All of the command center URLs are in the [fixed_string+number].no-ip.[info,biz,org] kind of format. Havent been able to understand what it does next.
Now for the fun part. As Form_Load indicates, this executable contained a VB Form for the GUI. Also the 'email' command in HelperFunction7 referenced a lot of its components' properties. I needed a way to decompile the binary form into readable text. The state of VB Decompilers is horrible, but 'good enough'. I decompiled the form and was pleasantly surprised to see how simple it all was. (Though at this point I also immediately suspected that this was created using some kind of malware kit) You see, the 'email' command in HelperFunction7 was implemented just as you would expect a newbie programmer to do so. Yes, it had plain-text strings for the smtp server, username and password ! I decided to check if the mailbox was still active. It was.
A sampling of what the email attachments contained.
The fun continues. As the author was testing his code one of the emails contained an attachment showing a screenshot of his own machine.
And also his own passwords.
Apparently, CSI was right, you can write a VB6 GUI to do most things. Seeing this screenshot made me lose all interest in poking through the code any further. I mean, sure, it was fun turning the tables on the malware writer, but seeing the total lack of sophistication with my own eyes made me kind of feel sorry for the dude.
This mailbox has no recent emails which could mean that the malware has stopped infecting PCs or that they had switched email addresses. Hopefully I'll have a more challenging task the next time I reverse engineer something.
}