ReVaLaTioN, a .NET Keylogger
Continuing with the “theme” of the last post, I decided to analyse one more .NET sample for a bit of practice. This time, rather than ransomware, I’m analyzing what seems to be quite an old keylogger titled ReVaLaTioN, which looks to be of Turkish origin. I have not been able to find any blog posts about analyzing this keylogger, unless it goes by a different name – although it isn’t really APT level malware so it is understandable. You can find several different samples of ReVaLaTioN on VirusBay uploaded by Jacob Soo, dating back to December 2017, and just recently, June 30th. I believe the builder for the keylogger is free for download on several Turkish forums, so script kiddies are able to configure it to suit themselves, and their targets.
As always, I ran strings on the sample, which returned a large amount of interesting strings and possible function names. Based on the returned result, it was clear to me the sample was not obfuscated or packed, meaning the analysis would be relatively easy. As you’ll notice in the image, it seems the program is able to stop multiple AntiVirus programs from running, as well as Analysis tools such as Wireshark and KeyScrambler (an Anti Keylogging tool). Furthermore, it looks like the logger is able to steal NoIP, FileZilla and possibly Steam credentials and information – so it isn’t just a keylogger.
I skimmed over the rest of the list, and noticed strings containing Clipboard, so that hints towards the keylogger possibly being able to steal any data in the clipboard. I also found the string DownloadFile – not only does the keylogger kill certain programs, not only does it steal information, it is also possible that it can download remote files. I decided to transfer the file to my virtual machine to perform some further analysis. I opened the file up in PEStudio and skimmed over the strings output from that, to see if there was anything I missed when I first looked. I noticed a string pointing to a .PDB file – a file used by the compiler and gives information on the executable. Based on the file path, we can take an extremely wild guess that the keylogger is version 3.0 of the (not) widely known ReVaLaTioN keylogger. But the path isn’t the only interesting string in the image – strings such as smtp.live.com hint towards which SMTP server is used to exfiltrate data, and the other file path: C:\KFJD947DHC.exe could be the location as to where the file will be copied to, or even the location where a downloaded file could be. Finally, there is a string containing the path to the hosts file, which helps to resolve hostnames – although as far as I am aware it is not as necessary nowadays, as DNS is responsible for that.
I finished going through the strings and opened the file up in dnSpy. Examining Form1, the first function that appeared was a persistence method used by the logger – AddStartup(). This function creates a registry key at CurrentUser\\Software\\Microsoft\\Windows\\CurrentVersion\\Run and sets the value using the two arguments passed to it. From looking through the file, it doesn’t seem like there are any other persistence methods – and even though the program requests admin privileges to run, it doesn’t modify the HKLM registry surprisingly.
Remember the Anti- strings seen in the strings output? Those are all function names, nearly all of which do exactly the same things (except for the Anti-Sandboxie). They get a list of running processes, and the name of each running process is compared to the name of the process to be killed – such as mbam for MalwareBytes. The process is then killed using Processes[i].Kill().
I located a DecryptMe() function which takes one argument – the data to be decrypted AKA decoded as the function just Base64 decodes the data, and converts it to an ASCII string.
What I did find quite peculiar with this keylogger is that it has the ability to locate the file signon in the Firefox Profiles folder and delete it – I believe that Firefox used to store any saved details for automatically logging into sites inside this file. I was quite confused as to why it was deleting this file, but then it suddenly came to me. Why bother trying to use Mozilla Developer DLLs and low level code to crack stored Firefox passwords when you can just delete the saved logons and then log the keystrokes of the user who is trying to log back in to those sites? The logger also deletes any Firefox cookies, as well as Internet Explorer cookies, meaning the user will have to manually log back into sites. I did not see any attempts to do this to Google Chrome, so it seems like either there is an option to select the targeted Web Browsers, or there was no support for it.
The function DoThisShit() is responsible for downloading and executing a remote file, which is stored in the C:\\ directory, under the name KFJD947DHC.exe, the string which we saw in the strings output. The URL is passed to DoThisShit(), although I was unable to find any calls to this function which hints that the builder offers several customization options to the user.
The logger also seems to target an application called IMVU, which looks like it stores user data in the registry and so the logger takes advantage of this and steals the stored credentials. I was quite interested in the function name itself – DoToVU(), so I ran a quick Google Search and located this interesting post on HackForums, dating back to 2011, which contains the exact code (except for variable names) used to steal the IMVU credentials in the keylogger. What is surprising is the fact that the title of this post is C++ Stealers, when it is .NET instead. The author of the post could have written the stealer – but I highly doubt it due to the I’m not 100% sure that these are correct. But I do believe they will work. at the beginning of the post – therefore it is most likely a copy and paste from somewhere else.
Another hint that this keylogger is quite old is the USB spreading mechanism. The function SpreadBGWusb_DoWork() is responsible for this. It first monitors the system for attached drives, and then deletes two files off of each drive; Sys.exe and Autorun.inf. This is to prevent several copies of the malware being transferred. Once the two files have been deleted, the malware copies itself onto the attached drive under the name Sys.exe, and creates the file Autorun.inf. This string is then written to the INF file:
If this keylogger was used before April 2011, and had infected USB drives, when those USB drives were plugged in to another system, Autorun.inf would have been executed, which would have executed Sys.exe (the copy of the keylogger). Since then, Microsoft has disabled the AutoRun functionality, due to the Conficker Worm using it as a method of spreading. Therefore, the spreading mechanism of this keylogger is quite useless nowadays, meaning this could have been written sometime before 2011 – or the author didn’t keep up with the news.
Whilst analyzing the sample, I had an idea that the malware exfiltrated data via SMTP, however I wanted to be 100% sure, and if that was the case, I wanted to find the credentials used for said SMTP server. The answers to all of these questions were stored in the function logcuk(), which takes a string argument. As you can see in the image below, there is not 1, but 2 mentions to SMTP servers; Gmail and Outlook (Live). First, the value stored in yontem is compared to several strings, such as log and ss. If the value in yontem matches the string log, the program converts the integer stored in hangisi to a Double format, and checks if it matches 0.0, 1.0 or 2.0. This value is used to determine the exfiltration method. 0.0 corresponds to Gmail, 1.0 corresponds to Outlook, and 2.0 uploads the data to a remote server.
As you can also see, the program is copying the values from array and array to smtpClient.Credentials. Therefore, we can take a guess that array contains the information we need about the email and password. Just above this, the value hihaho is split by a #, and the values are stored in array. So hihaho contains both the email and password. As you can see in the image below, hihaho is initialized in Form1, and is used to store the value in options, which is then Base64 decoded. So now we need to figure out what is stored in the options array. Above the line where hihaho is initialized, the data in text1 is split by this string:
Something seemed familiar about this string – I noticed it appear a few times in the PEStudio output. I opened PEStudio again, and had a look at the Overlay section. The first bytes shown look exactly like the string that splits the data in text1, except for the spaces.
I dumped the overlay, and to my surprise, there was a lot of data, some of which was encoded with Base64. This couldn’t be the configuration file, could it?
I copied the data, opened up Python, and split it using the ReVaLaTioN string. For some reason, the author of the keylogger thought it would be a good idea to store the configuration file in the overlay of the executable, and only encode the credentials in Base64, rather than securely encrypt it. To check this, I decoded some of the encoded values to see what they were. Sure enough, the SMTP email and password of the user were stored in the config – not once, but twice. In addition, the True‘s and False‘s correspond to the capabilities of the specific keylogger – due to this, we will be able to write a simple script to automate analysis of this type of keylogger.
I decided to examine Form1_Load() in more depth, rather than skimming over it, to figure out what exactly the True’s and False’s meant in the configuration. As I mentioned before, they correspond to the capabilities. For example, in the image below, the value stored in options, which in this case is True, is converted to a Boolean and put in an if statement. If the boolean value is True, the code in the if statement will run – otherwise, the program will ignore it and continue on. As options is True, the program will copy itself to C:\\Program Files\\Internet Explorer\\ and create two registry keys:
The first registry key is linked to the file copied to C:\\Program Files\\Internet Explorer\\, and the second contains whatever is stored in rasgele (this contains options, which in this case is 1,785915E+11)
The malware uses Timer functions to constantly run code such as Screenshotting or logging Clipboard data. Time intervals are also stored in the configuration, as you’ll notice in the image below. Timer6.Interval is taken from options, which in this case is 180000. Timer6() is then executed, which executes Timer6_Tick(), a function which is responsible for calling logcuk(“clipboard”). You can also see just underneath, if options is true, the logger is able to overwrite the Hosts file.
A couple of Disable functions are available in the logger – once again based on the users choice. There is the ability to disable the Task Manager, System Restore, Registry Tools, and the Command Prompt.
There are a few other capabilities that the keylogger has, but rather than get too deep into anything else, I decided to write an automation script to extract the configuration file from the executable, get the useful information, parse said information, and output it. Some sections are missing from the parsing as the fields were blank in the sample I had, but it only really focuses on the important data, for example the attackers email, password, the remote URL to download and execute from and the exfiltration method.
Firstly, we need to extract the overlay. To do this, we can use a Python module called pefile which allows us to interact with several different types of executable files. We will be using the get_overlay_data_start_offset() function to get the offset of where the overlay data begins. This will allow us to read the data after the start offset, giving us the entire config.
However, instead of printing the data, we want to parse it first. Pass it to the Parse function, and then split the data by the ReVaLaTioN string we saw the malware using.
Now lets format that data into a list so we can access it easier. In order to do this, I used a Class. This will allow us to simply input all of the data into the list automatically, rather than manually. As you can see, some of the information is labelled Unk or Blank – this is because based off of the sample I had there were no clues whatsoever on what that data was useful for. I have gone through the logger in dnSpy and figured out which True and False was for what, and added some text to signify what the logger could and could not do. I have also made sure the Base64 encoded data is decoded when passed to the Class.
So now we need to put the data into the list and then display it, so lets go back to the Parse() function. In order to put the data into the list, we need to call Format(), passing the overlay as an argument. We can then store that in the variable Data, which will enable us to access information using Data.IP for example. Placing all of the important information in a list, we can use a simple for loop to quickly display everything we need. So now we can print the data, but what if another sample of this keylogger has some blank sections? And what if, when the Exfiltration method is being displayed, the user doesn’t understand what 2.0 means? To fix this, we can use the enumerate() function that Python has – before we pass the data to the Class object. We first check if the length of each item in the list is less than or equal to 0, and if it is, we overwrite that value with NULL. We can also check for whether or not the the value of an item is equal to 0, 1 or 2 in order to display the correct exfiltration information. Finally, I decided to overwrite the True‘s and False‘s with Activated and Deactivated.
The output of the script should look something like the image below. It is customizable, so if you want to view other pieces of information then you can simply add it to the list. As the keylogger is very old, it is quite unlikely you’ll come across active samples, however this was just an example of how to automate configuration analysis – this can be applied to several different strains of malware that utilize configurations, allowing for quick and easy analysis. You can find the script here.
That was the last .NET static analysis post for a bit – I have a few other samples which I plan to analyse in the mean time, and will hopefully have a post up soon about one of them. Whilst .NET malware is extremely easy to reverse engineer, a lot only requires static analysis, and I personally enjoy learning and interpreting Assembly and performing dynamic analysis a lot more, so I’ll probably stick to non .NET Malware until some brand new .NET nation state level stuff gets discovered (although highly unlikely!).
- MD5 of Sample: 92386496961c04faeffbda99be573520
- Email Address: firstname.lastname@example.org