In the first part of this series, we saw how you can use Osquery to analyze and extract valuable information about malware’s behavior. In that post, we followed the activity of the known Emotet loader, popular for distributing banking trojans. Using Osquery, we were able to discover how it infects a system using a malicious Microsoft Office document and how it extracts and executes the payload.
In this post, we are going to see another common technique that malware uses, persistence. To do so, we will continue using Osquery to explore the registry and startup_items tables.
Registry Persistence
In this case, we will analyze a piece of malware built using the .NET framework, in particular a sample of Shrug ransomware. This malware encrypts users’ personal documents and requests an amount of Bitcoins to get all files restored back.
Opening the sample with a .NET debugger, we can see that it first creates a new file in the user temp directory and writes a new value in the “CurrentVersionRun” registry key for the user space pointing to that file. The malware will be executed every time the user logs on. This is a common persistence mechanism that malware droppers use in order to stay in the system.
If we run the sample in our Osquery environment, we can easily detect this activity using a couple of queries. For example, if you remember the query we used to log files written on disk in Part 1 of this blog series, we can also use it here to detect the file planted on user temp directory. We are just searching for files written on Users directories in the last 100 seconds.
Additionally, we can search for the new entry created in the registry hive. For that, we can use the ‘registry’ Osquery table, which allows us to query all the registry entries in the system. We can also use the ‘startup_items’ table. This second table contains a set of predefined paths that the system uses to run programs automatically at startup. Running the following query, we can see how the malware has written a new entry, pointing to the ‘shrug.exe’ file discovered with the first query.
The file shrug.exe is also written on .NET framework, so we can open it again with the debugger and see some interesting parts. This file first checks if the system is already infected. If not, it creates a new registry key with the same name to write the installation parameters.
This time we can use the registry table to see if any new entry has been created in the registry. By running a query to search for any new keys created in the HKEY_USERS hive in the last 100 seconds, as we did previously for files, we can see the new “Shrug” key.
To see if any values have been added into that key, we can use the key path to search the registry table. Querying the previous key path, we obtain the installation parameters used by the ransomware to store data like installation date, victim identifier, and also the key and the Initialization Vector (IV) used for encrypting files.
After the registry installation, Shrug ransomware sends some data to the domain stored in the address variable. This connection can be discovered by running a query similar to that one used in the Part 1 blog post to see the communication to the Command and Control server.
Finally, as ransomware usually does, it tries to encrypt all of the user’s personal documents. In this case, we can see in the previous image how it starts encrypting the whole “C:\” directory. Fortunately, this activity causes the files to change their modification timestamp, allowing us to query all files that have been modified recently. The query will return all files modified by the ransomware, and as we can see, they all have a new file extension “.SHRUG”.
Scheduled tasks and services
Another common way to gain persistence on Windows systems is to create scheduled tasks or install new services. These actions are often performed by malware, and Osquery has tables to query them.
Here is an example of OilRig malware. As you can see in the table below, two new scheduled tasks have been created after running the sample. Osquery can give us this information by querying the scheduled_tasks table.
The services table allows us to see which services have been installed in the system. After running a malware sample that installs a malicious service to gain persistence, we can build a query to return these results and see all details about the new service. As you can see we have detected the service “Check for updates” executing a malicious PowerShell script.
How AlienVault uses Osquery
By using Osquery we can detect a lot of mechanisms and techniques frequently used by malware threats. In the previous blog post, we saw how to analyze a malware infection, stage by stage. In this post, we have seen how it is possible to catch persistence tricks. This can be extremely helpful during the investigation of.
Appendix
Osquery searches
select path, size from file where path like 'C:Users%%' and mtime > (select local_time from time) - 100 and filename != '.';
select source, name, path from startup_items;
select path, name, type, data from registry where path like 'HKEY_USERS%%%' and mtime > (select local_time from time) - 100;
select path, name, type, data from registry where key like 'HKEY_USERS%Shrug';
select name, action, path, enabled, next_run_time from scheduled_tasks;
select name, display_name, start_type, path, user_account from services;
Sample IOCs
Connections[.]com/marthas_stuff/uploadhash.php
145.14.145.119
Files
ShrugInstaller.exe
a554b92036fbbc1c5d1a7d8a4049b01c5b6b7b30f06843fcdccf1f2420dfd707
Dropped executable file
C:UsersadminAppDataLocalTempshrug.exe
b14a57ad391d9ba5b2714dad4773118f118ed8d64b523466bb60f3b18336efc1
Yara
import "dotnet"
rule ShrugRansomware {
meta:
author = "AlienVault Labs"
strings:
$bitcoin_address = "1Hr1grgH9ViEgUx73iRRJLVKH3PFjUteNx"
$s1 = "upoldhash.php"
$s2 = "HarmedFiles"
$s3 = "ShrugDecryptor"
$s4 = "SHRUG2"
$pdb1 = "\Debug\ShrugTwo.pdb"
$pdb2 = "\Debug\Shrug.pdb"
condition:
uint16(0) == 0x5A4D and dotnet.number_of_guids > 0 and
((dotnet.typelib == "a6ab6b1f-b144-4920-be42-bb90ec6fc22e")
or ($bitcoin_address)
or (2 of ($s*))
or (any of ($pdb*)))
}
read original article here