TekStream Security Bulletin: Use Splunk to Swat StripedFly
By Bryan Bollou, Team Lead, Cybersecurity Engineering
Purpose of TekStream Security Bulletins
With the TekStream Security Bulletin, we are presenting some specific detection use cases using everyone’s favorite SIEM, Splunk. We’ve cherry-picked vulnerabilities that are not only intriguing but also directly impactful for our valued clients. These vulnerabilities were chosen based on a multitude of factors, ranging from the technology in the crosshairs to the specific sectors being targeted. This is not a blog post to fully explain or give recommendations on remediating the vulnerability – this has been discussed at length by various resources. The goal here is to aggregate the detections to maximize your chances of detecting an attempt to exploit these vulnerabilities. A part of that is gathering the list of IOCs scattered in multiple locations on the internet and looking at activity that could point to the vulnerability being exploited. Here at TekStream, we have an amazing team of cybersecurity engineers armed with a deep knowledge of logs and the secrets they hold, ready to fortify your cyber resiliency.
Introduction
StripedFly has been a consistent threat since first discovered by Kaspersky in 2016. It is associated with APT malware and is estimated to have infected over 1 million systems – both Windows and Linux. This malware is known to infect machines by exploiting the following:
- The initial infection is by piggybacking off a custom EternalBlue SMBv1 exploit.
- A lightweight TOR client is then used to communicate with a C2 server and download additional malware – though the main purpose (crypt mining, espionage, etc.) is not fully known.
- This additional malware can then engage in a variety of malicious activities including credential harvesting, crypto mining, adware, etc.
- The malware disables the SMBv1 protocol and uses SSH along with processes similar EternalBlue to spread.
Threat Overview
The vulnerability has been acknowledged by Kaspersky and they have suggested various mitigation steps to prevent its exploitation. Due to the flexibility of the malware and the way its APT uses it, the recommendations are quite generic.
These steps include:
- Training and mitigations for phishing attacks – the most common way victims are exposed to this malware.
- Exercising good credential hygiene including the use of a secure password manager
- Ensuring all devices on a network have an updated endpoint security system.
- Disabling SMBv1 if it is not necessary for critical business processes.
So far, we have seen many good options and would like to present a few more specific cases using Splunk. The goal here is to aggregate the detections to maximize your chances of detecting this critical attack. A part of that is gathering the list of IOCs scattered in multiple locations on the internet and looking at activity that could point to a StripedFly malware infection. Recommendations on remediating the vulnerability are discussed at length by various resources including Secure List.
In this security bulletin, we go through the various ways StripedFly exploits a victim system and how to detect it. With this format, we are providing a more generic data model “tstats” command. This is taking advantage of the data model to quickly find data that may match our IOC list. We then provide examples of a more specific search that will add context to the first find. There will be a wide variety of specific searches as each client has their own specific technologies. To get help building detection for your specific client, fill in the form below and get access to our Splunk/security expertise.
Note: Analyzing trends in your environment to detect anomalies relating to processes normally run and regular access to online code repositories would be ideal. This requires massaging to a specific environment and detecting this part is not covered in this blog post. Reach out to TekStream by filling out the form below if you’d like specific guidance on that aspect.
The following detection steps mirror the stages and TTP-related indicators used in the attack:
- Detect malicious PowerShell scripts indicating initial infection.
- Detect disabling of SMBv1.
- Detect requests to malicious code repositories.
- Detect beaconing to a command-and-control server in the TOR network.
- Detect the existence of files associated with StripedFly malware modules
Threat Implication
StripedFly primarily exploits the weakness of SMBv1 on internet-facing systems. The initial infection is dropped on the machine and this malware self-propagates once on a network. It sets up an encrypted channel using TOR to hide communications with a C2 server. As part of its activities, it downloads updates and additional malware by connecting to malicious code repositories.
The fact the malware has support and pluggable modules to update its functionality points to APT malware. It has been associated with the Shadow Brokers, but the true origin of the malware is still unclear. It has also been associated with the ThunderCrypt ransomware, which may suggest a monetary incentive for the malware’s authors.
Threat Detection
Step 1
If a victim machine is infected with the original malware from StripedFly, PowerShell scripts are run if the tool is available. This is done to set up persistence for the malware. Here we are looking to detect any PowerShell commands that are run and contain more than 50 trailing or leading spaces – not typical for a normal user or process running scripts. The spaces are used to obfuscate the code and avoid detection by an EDR system.
Actions Detect
Using Regex to find a PowerShell command with more than 50 leading or trailing spaces.
SPL – Using Windows Data Source
index=windows sourcetype=WinEventLog EventCode=4104
| where match(ScriptBlockText, "(?i)[ ]{50,}\w+") OR match(ScriptBlockText, "(?i)\w+[ ]{50,}")
| table _time EventCode name action service UserData_Xml Message Subject_Account_Name ComputerName EventCode cmd ScriptBlockText
Step 2
A mark of the StripedFly infection the disabling of the SMBv1 protocol after infection. This is done once the malware payload is executed and a lightweight TOR client is installed. This step is done to “seal the gates” on the victim’s machine. Here we are detecting the disabling of these protocols.
Actions Detect
We are looking to detect the following activity and parameter set in the appropriate registry entry:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
Copy
Registry entry: SMB1
REG_DWORD: 0 = Disabled
REG_DWORD: 1 = Enabled
Default: 1 = Enabled (No registry key is created)
SPL 1 – Using the Windows Data Source
index=windows sourcetype=wineventlog EventCode=4657 Object_Name="*HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters*" New_Value_Type = "REG_DWORD" Old_Value_Type = "REG_DWORD" Old_Value = 1 New_Value = 0 Object_Value_Name = "SMB1"
SPL 2 – Using the Endpoint Datamodel
| tstats allow_old_summaries=true count, values("Registry.registry_key_name") AS registry_key_name, values("Registry.registry_path") AS registry_path, min(_time) AS firstTime, max(_time) AS lastTime FROM datamodel=Endpoint.Registry WHERE ("Registry.registry_hive" = "HKEY_LOCAL_MACHINE\SYSTEM" AND "Registry.registry_path" = "*HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters*" AND "Registry.registry_value_type" = "REG_DWORD" AND "Registry.registry_value_name" = "SMB1" AND ("Registry.registry_value_data" = "0" OR "Registry.registry_value_text" = "0" )) BY "Registry.dest", "Registry.user"
Step 3
As a way to reduce the footprint of the initial exploit, the StripedFly malware has most of its elements offloaded and stored in legitimate websites. Once persistence is set up, the malware will then request these elements to carry out malicious activities on the victim machine. The sophistication of these pluggable, customizable and version control malware modules point to an APT developing this malware. Multiple repositories have been identified to contain code requested by malware.
Actions Detect
Attempts to hit the URL’s associated with the malicious code repositories from within the victim’s environment.
URLs
This is a selection of URL’s to watch for:
ghtyqipha6mcwxiz[.]onion:1111
bitbucket[.]org/JulieHeilman/m100-firmware-mirror/downloads/
bitbucket[.]org/upgrades/um/downloads/
bitbucket[.]org/legit-updates/flash-player/downloads
gitlab[.]com/JulieHeilman/m100-firmware-mirror/raw/master/
gitlab[.]com/saev3aeg/ugee8zee/raw/master/
github[.]com/amf9esiabnb/documents/releases/download/
tcp://pool.minexmr[.]com:4444
tcp://mine.aeon-pool[.]com:5555
tcp://5.255.86[.]125:8080
tcp://45.9.148[.]21:80
tcp://45.9.148[.]36:80tcp://45.9.148[.]132:8080
This CSV file includes all the listed URLS, along with other Indicators of Compromise (IOCs), conveniently consolidated for streamlined export into a lookup for notable detections.
SPL – Using the Web Datamodel
Detect URLs
| tstats `summariesonly` sum("Web.bytes") as bytes,values("Web.http_content_type") as http_content_type,values("Web.http_method") as http_method,values("Web.http_user_agent") as http_user_agent,values("Web.status") as status from datamodel="Web"."Web" where Web.url IN (" ghtyqipha6mcwxiz[.]onion:1111", "bitbucket[.]org/JulieHeilman/m100-firmware-mirror/downloads/","bitbucket[.]org/upgrades/um/downloads/","bitbucket[.]org/legit-updates/flash-player/downloads","gitlab[.]com/JulieHeilman/m100-firmware-mirror/raw/master/","gitlab[.]com/saev3aeg/ugee8zee/raw/master/","github[.]com/amf9esiabnb/documents/releases/download/","tcp://pool.minexmr[.]com:4444","tcp://mine.aeon-pool[.]com:5555","tcp://5.255.86[.]125:8080","tcp://45.9.148[.]21:80","tcp://45.9.148[.]36:80","tcp://45.9.148[.]132:808") by "Web.src", "Web.dest", "Web.user", "Web.http_referrer", "Web.url", _time | `drop_dm_object_name("Web")` | fields _time src, dest, user, http_referrer, url, http_content_type, http_method, http_user_agent, status, bytes | eval ip_pair = src . " - " . dest | stats values(_time) as Time values(ip_pair) AS src_dest, values(user) as user, values(http_referrer) as http_referrer, values(http_user_agent) as http_user_agent, values(http_method) as http_method, values(status) as status, values(bytes) as bytes count by url| fieldformat Time = strftime(Time,"%m/%d/%Y %T")
Note: The malicious URLs have been kept sanitized using “[.]” for the periods, please remove these when running the SPL. Please be careful not to navigate to them outside a sandbox.
Step 4
The StripedFly malware has a few known Command-and-Control servers hosted in the TOR network. The malware uses a lightweight TOR client to connect to the C2 server through TCP connections – often sending a unique ID for the victim machine, requesting malware modules/updates and beaconing. Finding any attempts to communicate with these known C2 servers would be a smoking gun for this malware being present in a victim’s environment.
Actions Detect
Any connection attempts with the following domains and/or IP addresses.
C2 Domains
gpiekd65jgshwp2p53igifv43aug2adacdebmuuri34hduvijr5pfjad[.]onion
ghtyqipha6mcwxiz[.]onion
ajiumbl2p2mjzx3l[.]onion
C2 IPv4 Addresses
45.9.148[.]21
45.9.148[.]36
45.9.148[.]132
5.255.86[.]125
This CSV file includes all the listed URLS, along with other Indicators of Compromise (IOCs), conveniently consolidated for streamlined export into a lookup for notable detections.
SPL 1 – Using the Web Datamodel for Domains
Detect Domains
| tstats `summariesonly` sum("Web.bytes") as bytes,values("Web.http_content_type") as http_content_type,values("Web.http_method") as http_method,values("Web.http_user_agent") as http_user_agent,values("Web.status") as status from datamodel="Web"."Web" by "Web.src", "Web.dest", "Web.user", "Web.http_referrer", "Web.url", _time | `drop_dm_object_name("Web")` | where match(url, "(?i)(gpiekd65jgshwp2p53igifv43aug2adacdebmuuri34hduvijr5pfjad[.]onion)|(ghtyqipha6mcwxiz[.]onion)|(ajiumbl2p2mjzx3l[.]onion)") | fields _time src, dest, user, http_referrer, url, http_content_type, http_method, http_user_agent, status, bytes | eval ip_pair = src . " - " . dest | stats values(_time) as Time values(ip_pair) AS src_dest, values(user) as user, values(http_referrer) as http_referrer, values(http_user_agent) as http_user_agent, values(http_method) as http_method, values(status) as status, values(bytes) as bytes count by url | fieldformat Time = strftime(Time,"%m/%d/%Y %T")
Note: The malicious URLs have been kept sanitized using “[.]” for the periods, please remove these when running the SPL. Please be careful not to navigate to them outside a sandbox.
SPL 2 – Using the Network Datamodel for IPs
Detect IPs
| tstats `summariesonly` latest(_time) as _time, sum("All_Traffic.bytes") as bytes, values("All_Traffic.src_port") as src_port, values("All_Traffic.transport") as transport, values("All_Traffic.dest_port") as dest_port from datamodel="Network_Traffic"."All_Traffic" where All_Traffic.src IN ("45.9.148[.]21","45.9.148[.]36","45.9.148[.]132","5.255.86[.]125") OR All_Traffic.dest IN ("45.9.148[.]21","45.9.148[.]36","45.9.148[.]132","5.255.86[.]125") by "All_Traffic.action", "All_Traffic.src", "All_Traffic.dest", "All_Traffic.user" | head 10000 | `drop_dm_object_name("All_Traffic")`| eval earliest_time = IF(isnum("$earliest_time$"),"$earliest_time$",strftime(relative_time(now(),"$earliest_time$"),"%s")) | eval latest_time = CASE(isnum("$latest_time$"),"$latest_time$","$latest_time$"="now",now(),1=1,strftime(relative_time(now(),"$latest_time$"),"%s")) | where _time >= earliest_time AND _time <= latest_time | head 10000 | table action, src, src_port, dest, transport, dest_port, user, bytes
Note: The malicious IPs have been kept sanitized using “[.]” for the periods, please remove these when running the SPL. Please be careful not to navigate to them outside a sandbox.
Step 5
Since the malicious code repositories are known, the files are often requested are known. The filenames and hashes have been taken from malware repos. Evidence of these files in a victim’s environment would point to malware modules requested/downloaded and this malware present. Looking for these known IOCs would also be a smoking gun for StripedFly presence.
Actions Detect
The presence of any of these known bad hashes in the victim’s environment:
SPL
| tstats `summariesonly` latest(_time) as _time, latest(Filesystem.file_create_time) as file_create_time, latest(Filesystem.file_modify_time) as file_modify_time, latest(Filesystem.file_access_time) as file_access_time from datamodel="Endpoint"."Filesystem", values(Filesystem.dest) as dest, values(Filesystem.action) as action, values(Filesystem.file_name) as file_name, values(Filesystem.file_hash) as file_hash, values(Filesystem.file_path) as file_path, values(Filesystem.file_size) as file_size | search Filesystem.file_name IN ("system.img", "delta.dat", "delta.img", "ota.dat", "ota.img ") OR Filesystem.file_hash IN ( "b28c6d00855be3b60e220c32bfad2535", "18f5ccdd9efb9c41aa63efbe0c65d3db", "2cdc600185901cf045af027289c4429c", "54dd5c70f67df5dc8d750f19ececd797", "d32fa257cd6fb1b0c6df80f673865581", "c04868dabd6b9ce132a790fdc02acc14", "c7e3df6455738fb080d741dcbb620b89", "d684de2c5cfb38917c5d99c04c21769a", "a5d3abe7feb56f49fa33dc49fea11f85", "35fadceca0bae2cdcfdaac0f188ba7e0", "00c9fd9371791e9160a3adaade0b4aa2", "41b326df0d21d0a8fad6ed01fec1389f", "506599fe3aecdfb1acc846ea52adc09f", "6ace7d5115a1c63b674b736ae760423b", "2e2ef6e074bd683b477a2a2e581386f0", "04df1280798594965d6fdfeb4c257f6c", "abe845285510079229d83bb117ab8ed6", "090059c1786075591dec7ddc6f9ee3eb", "120f62e78b97cd748170b2779d8c0c67", "d64361802515cf32bd34f98312dfd40d") | fields _time, dest, action, file_name, file_hash, file_path, file_size, file_create_time, file_modify_time, file_access_time
| fieldformat Time = strftime(_time,"%m/%d/%Y %T")
IOC List
This file is an aggregate of IOCs found related to StripedFly exploitation. It has been presented here for you to have it consolidated in one spot and made easier to export to a lookup for notable detections.
Conclusion
Ideally, you could make scheduled searches like what is shown above with lookup tables for matching more specific and new detections. These can be set to run on a continuous schedule to ensure the monitoring of your assets from new vulnerabilities. Old vulnerabilities that have been patched (and applied) can also be aged out of this lookup table to ensure it is timely and efficient. For questions on how to build such a process that is dynamic and customizable for your environment, ask one of our consultants by filling in the form below. Also, subscribe to the TekStream blog to catch the next monthly security bulletin and apply the latest detections to protect your systems. Happy Splunking!
References
Bleeping Computer: StripedFly Malware Framework Infects 1 Million Windows Linux Hosts
Securelist.com: StripedFly Perennially Flying Under the Radar
OTX.Alienvault.com StripedFly Securelist
OTX.Alienvault.com StripedFly: Perennially flying under the radar
Disclaimer
The approaches recommended herein have not been tested broadly across the TekStream customer base. They are preliminary in nature and come without any certification of efficacy.