Skip to main content
Splunk Lantern

Detecting WhisperGate malware

WhisperGate is a destructive malware operation that targets multiple organizations in Ukraine. These searches detect and investigate unusual activities that might relate to WhisperGate malware, including looking for suspicious process execution, command-line activity, downloads, and DNS queries.

How to use Splunk software for this use case

Searches using the endpoint data model

To run these searches, ensure that you should also ensure you are ingesting normalized endpoint data, populating the Endpoint data model in the Common Information Model (CIM).  For information on installing and using the CIM, see the Common Information Model documentation. In addition, if you are using Sysmon, you must have at least version 6.0.4.

► Add or set Windows Defender exclusion

 

To complete this process, your deployment needs to ingest information on process that includes the name of the process responsible for the changes from your endpoints. 

This search detects a suspicious process command line related to Windows Defender. This command is abused by attackers to bypass Windows Defender antivirus products by excluding folder paths, file paths, processes, and extensions from its scans.

| tstats summariesonly=false allow_old_summaries=true count, min(_time) AS firstTime, max(_time) AS lastTime FROM datamodel=Endpoint.Processes WHERE (("Processes.process"="*Add-MpPreference *" OR "Processes.process"="*Set-MpPreference *") "Processes.process"="*-exclusion*") BY "Processes.dest", "Processes.user", "Processes.parent_process", "Processes.parent_process_name", "Processes.process_name", "Processes.original_file_name", "Processes.process", "Processes.process_id", "Processes.parent_process_id" 
| rename "Processes.*" AS "*" 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(firstTime) 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(lastTime)
► Cmd.exe carry out string command parameter

To complete this process, your deployment needs to ingest information on process that includes the name of the process responsible for the changes from your endpoints. 

This search identifies command-line arguments where cmd.exe /c is used to run a program. cmd /c is used to run commands in MS-DOS and terminates after the command or process completion. This technique is used by attackers to run batch commands using a different shell like PowerShell or processes other than cmd.exe.

False positives from this search might be high, based on legitimate scripted code in any environment. Tune and filter as necessary.

| tstats summariesonly=false allow_old_summaries=true min(_time) AS firstTime, max(_time) AS lastTime FROM datamodel=Endpoint.Processes WHERE (("Processes.process_name"=cmd.exe OR "Processes.original_file_name"=Cmd.Exe) "Processes.process"="* /c *") BY "Processes.dest", "Processes.user", "Processes.parent_process", "Processes.process_name", "Processes.original_file_name", "Processes.process", "Processes.process_id", "Processes.parent_process_id" 
| rename "Processes.*" AS "*" 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(firstTime) 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(lastTime)
► Executables or script creation in suspicious file path

To complete this process, your deployment needs to ingest information on process that includes the name of the Filesystem responsible for the changes from your endpoints. 

This search identifies suspicious executables or scripts (known file extensions) in a list of suspicious file paths in Windows. This technique is used by attackers to evade detection. The suspicious file paths used in this search are known paths and don't commonly have executables or scripts.

| tstats summariesonly=false allow_old_summaries=true values("Filesystem.file_path") AS file_path, count, min(_time) AS firstTime, max(_time) AS lastTime FROM datamodel=Endpoint.Filesystem WHERE (("Filesystem.file_name"=*.exe OR "Filesystem.file_name"=*.dll OR "Filesystem.file_name"=*.sys OR "Filesystem.file_name"=*.com OR "Filesystem.file_name"=*.vbs OR "Filesystem.file_name"=*.vbe OR "Filesystem.file_name"=*.js OR "Filesystem.file_name"=*.ps1 OR "Filesystem.file_name"=*.bat OR "Filesystem.file_name"=*.cmd OR "Filesystem.file_name"=*.pif) ("Filesystem.file_path"=*\\windows\\fonts\\* OR "Filesystem.file_path"=*\\windows\\temp\\* OR "Filesystem.file_path"=*\\users\\public\\* OR "Filesystem.file_path"=*\\windows\\debug\\* OR "Filesystem.file_path"=*\\Users\\Administrator\\Music\\* OR "Filesystem.file_path"=*\\Windows\\servicing\\* OR "Filesystem.file_path"=*\\Users\\Default\\* OR "Filesystem.file_path"=*Recycle.bin* OR "Filesystem.file_path"=*\\Windows\\Media\\* OR "Filesystem.file_path"=*\\Windows\\repair\\* OR "Filesystem.file_path"=*\\AppData\\Local\\Temp* OR "Filesystem.file_path"=*\\PerfLogs\\*)) BY "Filesystem.file_create_time", "Filesystem.process_id", "Filesystem.file_name", "Filesystem.user" 
| rename "Processes.*" AS "*" 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(firstTime) 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(lastTime)
► Suspicious process file path

To complete this process, your deployment needs to ingest information on process that includes the name of the process responsible for the changes from your endpoints. 

This search detects a suspicious process running in a file path where a process is not commonly seen. This behavior is used by attackers where they drop and run an .exe file in a path that is accessible without admin privileges.

| tstats summariesonly=false allow_old_summaries=true count, values("Processes.process_name") AS process_name, values("Processes.process") AS process, min(_time) AS firstTime, max(_time) AS lastTime FROM datamodel=Endpoint.Processes WHERE ("Processes.process_path"="*\\windows\\fonts\\*" OR "Processes.process_path"="*\\windows\\temp\\*" OR "Processes.process_path"="*\\users\\public\\*" OR "Processes.process_path"="*\\windows\\debug\\*" OR "Processes.process_path.file_path"="*\\Users\\Administrator\\Music\\*" OR "Processes.process_path.file_path"="*\\Windows\\servicing\\*" OR "Processes.process_path.file_path"="*\\Users\\Default\\*" OR "Processes.process_path.file_path"="*Recycle.bin*" OR "Processes.process_path"="*\\Windows\\Media\\*" OR "Processes.process_path"="\\Windows\\repair\\*" OR "Processes.process_path"="*\\temp\\*" OR "Processes.process_path"="*\\PerfLogs\\*") BY "Processes.parent_process_name", "Processes.parent_process", "Processes.process_path", "Processes.dest", "Processes.user" 
| rename "Processes.*" AS "*" 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(firstTime) 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(lastTime)
► Windows InstallUtil.exe running from non-standard path

To complete this process, your deployment needs to ingest information on process that includes the name of the process responsible for the changes from your endpoints.

This search identifies the Windows binary InstallUtil.exe running from a non-standard location.

False positives from this search might occur since certain utilities can run from non-standard paths based on the third-party application in use. Tune and filter as necessary.

| tstats summariesonly=false allow_old_summaries=true count, min(_time) AS firstTime, max(_time) AS lastTime FROM datamodel=Endpoint.Processes WHERE (("Processes.process_name"=installutil.exe OR "Processes.original_file_name"=InstallUtil.exe) NOT "Processes.process_path"="*\\Windows\\ADWS\\*" NOT "Processes.process_path"="*\\Windows\\SysWOW64*" NOT "Processes.process_path"="*\\Windows\\system32*" NOT "Processes.process_path"="*\\Windows\\NetworkController\\*" NOT "Processes.process_path"="*\\Windows\\SystemApps\\*" NOT "Processes.process_path"="*\\WinSxS\\*" NOT "Processes.process_path"="*\\Windows\\Microsoft.NET\\*") BY "Processes.dest", "Processes.user", "Processes.parent_process", "Processes.process_name", "Processes.process", "Processes.original_file_name", "Processes.process_id", "Processes.parent_process_id", "Processes.process_hash" 
| rename "Processes.*" AS "*" 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(firstTime) 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(lastTime)
► Ping sleep batch command

To complete this process, your deployment needs to ingest logs with the process name, parent process, and command-line executions from your endpoints. I

This search identifies the possible execution of ping sleep batch commands. This technique is used by attackers to trigger sleep times without explicitly calling sleep functions or commandlets, with the goal of delaying the execution of malicious code and bypassing detection or sandbox analysis.

False positives from this search might occur as administrators or network operators might run this command. Tune and filter as necessary.

| tstats summariesonly=false allow_old_summaries=true count, min(_time) AS firstTime, max(_time) AS lastTime FROM datamodel=Endpoint.Processes WHERE (("Processes.process_name"=ping.exe OR "Processes.original_file_name"=ping.exe) (("Processes.parent_process"="*ping*" "Processes.parent_process"=*-n* "Processes.parent_process"="* Nul*" "Processes.parent_process"="*>*") OR ("Processes.process"="*ping*" "Processes.process"=*-n* "Processes.process"="* Nul*" "Processes.process"="*>*"))) BY "Processes.parent_process_name", "Processes.parent_process", "Processes.process_name", "Processes.original_file_name", "Processes.process", "Processes.process_id", "Processes.process_guid", "Processes.user", "Processes.dest" 
| rename "Processes.*" AS "*" 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(firstTime) 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(lastTime)
► Impacket lateral movement command line

To complete this process, your deployment needs to ingest logs with the process name, parent process, and command-line executions from your endpoints. 

This search looks for the presence of suspicious command line parameters when using Impacket tools. Impacket is a collection of Python classes meant to be used with Microsoft network protocols. There are multiple scripts that use impacket libraries like wmiexec.py, smbexec.py, dcomexec.py and atexec.py, used to execute commands on remote endpoints.

These scripts use administrative shares and hardcoded parameters that can be used as a signature to detect their usage. Attackers use Impacket tools for lateral movement and remote code execution.

| tstats summariesonly=false allow_old_summaries=true count, min(_time) AS firstTime, max(_time) AS lastTime FROM datamodel=Endpoint.Processes WHERE ("Processes.process"="*/c* \\\\127.0.0.1\\*" OR "Processes.process"="*/c* 2>&1") BY "Processes.dest", "Processes.user", "Processes.parent_process_name", "Processes.process_name", "Processes.process", "Processes.process_id", "Processes.parent_process_id" 
| rename "Processes.*" AS "*" 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(firstTime) 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(lastTime)
► Windows NirSoft AdvancedRun.exe

To complete this process, your deployment needs to ingest information on process that includes the name of the process responsible for the changes from your endpoints.

This search identifies the use of AdvancedRun.exe. AdvancedRun.exe has similar capabilities to other remote programs like psexec. AdvancedRun might also ingest a configuration file with all settings defined and perform its activity. The search identifies a renamed binary and also common command-line arguments.

False positives from this search should be limited the search is specific to AdvancedRun. Filter as needed based on legitimate usage.

| tstats summariesonly=false allow_old_summaries=true count, min(_time) AS firstTime, max(_time) AS lastTime FROM datamodel=Endpoint.Processes WHERE (("Processes.process_name"=advancedrun.exe OR "Processes.original_file_name"=advancedrun.exe) ("Processes.process"="*EXEFilename*" OR "Processes.process"="*/cfg*" OR "Processes.process"="*RunAs*" OR "Processes.process"="*WindowState*")) BY "Processes.dest", "Processes.user", "Processes.parent_process_name", "Processes.process_name", "Processes.process", "Processes.original_file_name", "Processes.process_id", "Processes.parent_process_id" 
| rename "Processes.*" AS "*" 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(firstTime) 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(lastTime)
► WScript or CScript suspicious child process

To complete this process, your deployment needs to ingest logs with the process name, parent process, and command-line executions from your endpoints. 

This search identifies a suspicious spawned process by WScript or CScript. This technique is a commonly used by malware to run different LOLBin, other scripts like PowerShell, or to spawn a suspended process to inject its code as a defense evasion.

False positives from this search might occur since the search can detect some normal script that uses several application tools that are in the list of the child process it detects. Administrators might also create VBScript or JS script that uses several tools as part of its execution. Filter as needed.

| tstats summariesonly=false allow_old_summaries=true count, min(_time) AS firstTime, max(_time) AS lastTime FROM datamodel=Endpoint.Processes WHERE ("Processes.original_file_name"=rclone.exe "Processes.process_name"!=rclone.exe) BY "Processes.dest", "Processes.user", "Processes.parent_process_name", "Processes.process_name", "Processes.process", "Processes.process_id", "Processes.parent_process_id", "Processes.original_file_name" 
| rename "Processes.*" AS "*" 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(firstTime) 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(lastTime)
► EncodedCommand parameter in malicious PowerShell process

To complete this process, your deployment needs to ingest data that records process activity from your hosts. 

This search identifies the use of the EncodedCommand PowerShell parameter. This is typically used by administrators to run complex scripts but can be used by attackers to hide their code.

The search looks for all variations of EncodedCommand, as PowerShell allows the ability to shorten the parameter, e.g. enc, enco, encod. PowerShell also interprets different command switch types beyond the hyphen, so the search also looks for endash, emdash, horizontal bar, and forward slash.

If your search returns potentially suspicious results, review parallel events to determine legitimacy and tune as needed based on administrator scripts in use.

| tstats summariesonly=false allow_old_summaries=true count, min(_time) AS firstTime, max(_time) AS lastTime FROM datamodel=Endpoint.Processes WHERE ("Processes.process_name"=pwsh.exe OR "Processes.process_name"=sqlps.exe OR "Processes.process_name"=sqltoolsps.exe OR "Processes.process_name"=powershell.exe OR "Processes.process_name"=powershell_ise.exe OR "Processes.original_file_name"=pwsh.dll OR "Processes.original_file_name"=PowerShell.EXE OR "Processes.original_file_name"=powershell_ise.EXE) BY "Processes.user", "Processes.process_name", "Processes.process", "Processes.parent_process_name", "Processes.original_file_name", "Processes.dest", "Processes.process_id" 
| rename "Processes.*" AS "*" 
| where match(process,"(?i)[\\-|\\/|–|—|―]e(nc*o*d*e*d*c*o*m*m*a*n*d*)*\\s+[^-]") 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(firstTime) 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(lastTime)

Additional searches

Some commands, parameters, and field names in the searches below might need to be adjusted to match your environment. In addition, to optimize the searches shown below, you should specify an index and a time range when appropriate. If you are using Sysmon, you must have at least version 6.0.4.

► Excessive file deletion in Windows Defender folder

To complete this process, your deployment needs to ingest logs with the process name, TargetFilename, and ProcessID executions from your endpoints.

This search identifies excessive file deletion events in the Windows Defender folder. This technique is used in the WhisperGate malware campaign where attackers abuse Nirsoft's advancedrun.exe to gain administrative privileges, then run PowerShell commands to delete files within the Windows Defender application folder. This behavior is a good indicator that the offending process is trying to corrupt a Windows Defender installation.

False positives from this search might occur since Windows Defender antivirus updates might exhibit this behavior. Tune and filter where necessary.

| search (EventCode=23 TargetFilename="*\\ProgramData\\Microsoft\\Windows Defender*" (source=Syslog:Linux-Sysmon/Operational OR source=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational OR sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational)) 
| stats values(TargetFilename) AS deleted_files min(_time) AS firstTime max(_time) AS lastTime count BY user EventCode Image ProcessID Computer 
| where (count >= 50) 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(firstTime) 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(lastTime)
► Powershell removing Windows Defender folder

To complete this process, your deployment needs to enable PowerShell Script Block Logging on some or all endpoints.

This search looks for a suspicious PowerShell command used to delete the Windows Defender folder. This technique is used in the WhisperGate malware campaign where Nirsoft's advancedrun.exe is used to gain administrative privileges, then a PowerShell command is run to delete the Windows Defender folder.

Positive results from this search are a good indicator the offending process is trying to corrupt a Windows Defender installation.

| search (EventCode=4104 Message="* rmdir *" Message="*\\Microsoft\\Windows Defender*" (source=WinEventLog:Microsoft-Windows-PowerShell/Operational OR source="XmlWinEventLog:Microsoft-Windows-PowerShell/Operational")) 
| stats count min(_time) AS firstTime max(_time) AS lastTime BY EventCode Message ComputerName User 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(firstTime) 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(lastTime)
► PowerShell Windows Defender exclusion commands

This search looks for a suspicious process command line related to Windows Defender's exclusion feature. This command is abused by attackers to bypass Windows Defender's antivirus scans by excluding specific folder paths, file paths, processes, or extensions from real-time or scheduled scans.

Positive results from this search are a a good indicator of defense evasion and you should look further for events after this behavior.

| search (EventCode=4104 Message="*-exclusion*" (Message="*Add-MpPreference *" OR Message="*Set-MpPreference *") (source=WinEventLog:Microsoft-Windows-PowerShell/Operational OR source="XmlWinEventLog:Microsoft-Windows-PowerShell/Operational")) 
| stats count min(_time) AS firstTime max(_time) AS lastTime BY EventCode Message ComputerName User 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(firstTime) 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(lastTime)
► Process deleting its process file path

This search looks for a suspicious process that tries to delete the process file path related to its process, a defense evasion technique. This technique is used by attackers who use a .bat command if the keyboard layout is not the layout it tries to infect.

| search (EventCode=1 Image="*\\cmd.exe" cmdline="*/c del*" (source=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational OR sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational)) 
| eval result=if(like(process,(("%" . parent_process) . "%")),"Found","Not Found")
| search result=CASE("Found") 
| stats min(_time) AS firstTime max(_time) AS lastTime count BY Computer user ParentImage ParentCommandLine Image cmdline EventCode ProcessID result 
| where (result == "Found") 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(firstTime) 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(lastTime)
► High file deletion frequency

 

To complete this process, your deployment needs to ingest logs with the deleted target file name, process name, and process ID from your endpoints. 

This search looks for a high frequency of file deletion relative to process name and process ID. These events usually happen when ransomware tries to encrypt files with ransomware file extensions and Sysmon treats the original files to be deleted, as soon they are replaced, as encrypted data.

False positives from this search can occur as legitimate users might delete a lot of pictures or files in a folder at once.

| search (EventCode=23 (source=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational OR sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational) (TargetFilename="*\.7z" OR TargetFilename="*\.bmp" OR TargetFilename="*\.chm" OR TargetFilename="*\.cmd" OR TargetFilename="*\.db" OR TargetFilename="*\.doc*" OR TargetFilename="*\.gif" OR TargetFilename="*\.ini" OR TargetFilename="*\.jpeg" OR TargetFilename="*\.jpg" OR TargetFilename="*\.js" OR TargetFilename="*\.log" OR TargetFilename="*\.png" OR TargetFilename="*\.ppt*" OR TargetFilename="*\.ps1" OR TargetFilename="*\.rar" OR TargetFilename="*\.vbs" OR TargetFilename="*\.xls*" OR TargetFilename="*\.zip"))
| stats values(TargetFilename) AS deleted_files min(_time) AS firstTime max(_time) AS lastTime count BY Computer user EventCode Image ProcessID
| where (count >= 100)
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(firstTime)
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(lastTime)

Need more help with this search? Click here.

► Web services making suspicious DNS queries

To complete this process, your deployment needs to ingest Sysmon logs with event ID 22, DNS query.

This search detects a suspicious process making a DNS query via known, abused web services, such as text-paste services, VoIP, instant messaging, and digital distribution platforms used to download external files. This technique is abused by adversaries, malware actors, and red teams to download a malicious file on the target host. This is a good Tactics, Techniques, and Procedures (TTP) indicator for possible initial access techniques.

This search uses suggested web services Discord, Pastebin, t.me and Telegram which you can modify as appropriate.

sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational OR source=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational OR source=Syslog:Linux-Sysmon/Operational
EventCode=22
(QueryName="*discord*" OR QueryName="*pastebin*" OR QueryName="*t.me*" OR QueryName="*telegram*") 
(process_name="*powershell*" OR process_name="cmd.exe" OR process_name="cscript.exe" OR process_name="pwsh.exe" OR process_name="wscript.exe")
| stats count min(_time) AS firstTime max(_time) AS lastTime BY Image QueryName QueryStatus process_name QueryResults Computer
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(firstTime)
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(lastTime)

Need more help with this search? Click here.

► Suspicious process with Discord DNS query

To complete this process, your deployment needs to ingest Sysmon logs with event ID 22, DNS query.

This search detects a process making a DNS query to Discord, a well-known instant messaging and digital distribution platform. Discord can be abused by attackers, as seen in the WhisperGate campaign, to host and download malicious external files.

A process resolving a Discord DNS name might be an indicator of malware trying to download files from Discord for further execution.

Noise and false positives from this search might occur if instant messaging is allowed within your corporate network. Tune and filter as necessary.

| search (process_name!="discord.exe" process_path!="*\\AppData\\Local\\Discord\\*" process_path!="*\\Program Files*" EventCode=22 QueryName="*discord*" (source=Syslog:Linux-Sysmon/Operational OR source=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational OR sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational)) 
| stats count min(_time) AS firstTime max(_time) AS lastTime BY Image QueryName QueryStatus process_name QueryResults Computer process_path 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(firstTime) 
| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(lastTime)

Next steps

The content in this article comes from Splunk Enterprise Security (ES). As a Splunk premium security solution, ES solves a wide range of security analytics and operations use cases including continuous security monitoring, advanced threat detection, compliance, incident investigation, forensics and incident response. Splunk ES delivers an end-to-end view of an organization's security posture with flexible investigations, unmatched performance, and the most flexible deployment options offered in the cloud, on-premises, or hybrid deployment models. If you have questions about this use case, see the Security Research team's support options on GitHub.

In addition, these Splunk resources might help you understand and implement this use case:

Still need help with this use case? Most customers have OnDemand Services per their license support plan. Engage the ODS team at OnDemand-Inquires@splunk.com if you require assistance.