TekStream Security Bulletin: Splunk Takes Out SysJoker Variant Written in Rust

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

SysJoker is a backdoor malware that was first discovered in December 2021 by Intezer. This malware is a backdoor that targets multiple operating systems. It was initially discovered on a Linux-based web server belonging to a large educational institution. Recently, there has been a resurgence of its use, specifically a variant written in Rust, which suggests the malware code was completely rewritten. The use of this variant has been associated with some APTs (Advanced Persistent Threats) known to operate regions involved in the current geopolitical climate in the Middle East. Indicators of compromise (IOCs) associated with the malware have been identified in the infrastructure of companies located in countries involved in the conflict.

Threat Overview

Due to the flexibility of the malware and the way its APT uses it, the recommendations are generic.

These steps include:

  • Training and mitigations for phishing attacks – the most common way victims are exposed to this malware on workstations versions
  • Good security practice to ensure software updates and downloads only come from trusted vendors as it is believed this RAT is also spread via malicious NPM packages for server versions.
  • Ensure all devices on a network have an updated endpoint security system
  • Ensure the principle of least privilege has been used when setting up the production servers in an environment
  • At the proxy level, block unwanted connections to non-enterprise file-sharing domains 

So far, we have seen many good options and would like to present a few more specific cases using everyone’s favorite SIEM, Splunk.

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 such as VMWare SysJoker Analysis.

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 the presence of the SysJoker malware. Here at TekStream, we have several security engineers that are intimate with cybersecurity knowledge and especially the logs of our clients.

In this blog post, we go through the various steps used by the SysJoker RAT in its exploitation and detection. 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: The SysJoker RAT may masquerade and gather victim information in various ways not covered in this blog. An anomaly analysis tailored to your environment would be needed to discover this. 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:

  1. Detect persistence attempt of the malware [Windows]
  2. Detect persistence attempt of the malware [Linux]
  3. Detect persistence attempt of the malware [MacOs]
  4. Detect the connection to a malicious Cloud Storage Link
  5. Detect connection attempts to the C2 Server IOCs (domains and IP addresses)

Threat Implication

Step 1

Once the SysJoker malware is present on a victim machine, it first sets up persistence. The methods vary based on operating system, so let’s go through them – starting with Windows. In the Windows version, a dropper is masqueraded as a system update by making a registry object. The malware runs generic commands using common tools (eg; dnslookup, ping, etc) to get MAC address, username, physical media serial number, and IP address of victim machine.

Actions Detect

Creation of a Windows Registry Key

Name: igfxCUIService 
Type: REG_SZ 
Data: “C:\ProgramData\SystemData\igfxCUIService.exe”

Detect the presence of Known Hashes Related to SysJoker RAT

61df74731fbe1eafb2eb987f20e5226962eeceef010164e41ea6c4494a4010fc
d476ca89674c987ca399a97f2d635fe30a6ba81c95f93e8320a5f979a0563517
d1d5158660cdc9e05ed0207ceba2033aa7736ed1
888226b749b3fa93dadf5d7c2acf32c71e3a0918
d71e1a6ee83221f1ac7ed870bc272f01
293f116c2c51473ae2bf7f4e787d3ec3
1ffd6559d21470c40dcf9236da51e5823d7ad58c93502279871c3fe7718c901c
36fed8ab1bf473714d6886b8dcfbcaa200a72997d50ea0225a90c28306b7670e

Note: This CSV file includes all the listed hashes, along with other Indicators of Compromise (IOCs), conveniently consolidated for streamlined export into a lookup for notable detections.

SPL 1 – Using the Windows Data Source for Registry Key Creation
index=windows sourcetype=wineventlog EventCode=4657 Object_Name="*HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionRun*" New_Value_Type = "REG_SZ"  Object_Value_Name = "igfxCUIService"
SPL 2 – Using the Endpoint Datamodel for Registry Key Creation
| 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_CURRENT_USERS*" AND "Registry.registry_path" = "*HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionRun*" AND "Registry.registry_value_type" = "REG_SZ" AND "Registry.registry_value_name" = "igfxCUIService" BY "Registry.dest", "Registry.user"
SPL 3 – Using the Endpoint Datamodel for Hashes
| 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 | Filesystem.file_hash IN ( "61df74731fbe1eafb2eb987f20e5226962eeceef010164e41ea6c4494a4010fc","d476ca89674c987ca399a97f2d635fe30a6ba81c95f93e8320a5f979a0563517","d1d5158660cdc9e05ed0207ceba2033aa7736ed1","888226b749b3fa93dadf5d7c2acf32c71e3a0918","d71e1a6ee83221f1ac7ed870bc272f01","293f116c2c51473ae2bf7f4e787d3ec3","1ffd6559d21470c40dcf9236da51e5823d7ad58c93502279871c3fe7718c901c","36fed8ab1bf473714d6886b8dcfbcaa200a72997d50ea0225a90c28306b7670e") | 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")

Step 2

For the Linux version of the SysJoker malware, persistence is made by creating a cron job. The RAT creates or replaces a process called “updateSystem”.

Actions Detect

Detect the Creation of the “Update System” cron job

@reboot (/.Library/SystemServices/updateSystem) 

Detect the presence of Known Hashes Related to SysJoker RAT

1a9a5c797777f37463b44de2b49a7f95abca786db3977dcdac0f79da739c08ac
fe99db3268e058e1204aff679e0726dc77fd45d06757a5fda9eafc6a28cfb8df
d0febda3a3d2d68b0374c26784198dc4309dbe4a8978e44bb7584fd832c325f0
554aef8bf44e7fa941e1190e41c8770e90f07254
f5149543014e5b1bd7030711fd5c7d2a4bef0c2f
01d06375cf4042f4e36467078530c776a28cec05
e06e06752509f9cd8bc85aa1aa24dba2
6fb483e7ec55f8c56849d8f4f31bfd7b
85dbbaa8c4d37ebb9829464f0510787b

Note: This CSV file includes all the listed hashes, along with other Indicators of Compromise (IOCs), conveniently consolidated for streamlined export into a lookup for notable detections.

SPL 1: Detect the Creation of a Cron Job
| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime FROM datamodel=Endpoint.Filesystem where Filesystem.action=created Filesystem.file_path="/etc/cron.*" OR Filesystem.file_path ="* /.Library/SystemServices/updateSystem *" by _time
SPL 2: Detect the presence of Known Hashes Related to SysJoker RAT
| 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 | Filesystem.file_hash IN ("1a9a5c797777f37463b44de2b49a7f95abca786db3977dcdac0f79da739c08ac","fe99db3268e058e1204aff679e0726dc77fd45d06757a5fda9eafc6a28cfb8df","d0febda3a3d2d68b0374c26784198dc4309dbe4a8978e44bb7584fd832c325f0","554aef8bf44e7fa941e1190e41c8770e90f07254","f5149543014e5b1bd7030711fd5c7d2a4bef0c2f","01d06375cf4042f4e36467078530c776a28cec05","e06e06752509f9cd8bc85aa1aa24dba2","6fb483e7ec55f8c56849d8f4f31bfd7b","85dbbaa8c4d37ebb9829464f0510787b") | 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")

Step 3

For the MacOS version of the SysJoker malware, persistence is made by creating a service. The RAT uses a service called launchAgents named “Apple launch service” targeting “/Library/MacOsServices/updateMacOs”.

Actions Detect

Detect the Creation of a service with LaunchAgent. Creates persistence via LaunchAgent under the path “/Library/LaunchAgents/com.apple.update.plist.”

Detect the presence of Known Hashes Related to SysJoker RAT

36fed8ab1bf473714d6886b8dcfbcaa200a72997d50ea0225a90c28306b7670e
1ffd6559d21470c40dcf9236da51e5823d7ad58c93502279871c3fe7718c901c
bd0141e88a0d56b508bc52db4dab68a49b6027a486e4d9514ec0db006fe71eed
d028e64bf4ec97dfd655ccd1157a5b96515d461a710231ac8a529d7bdb936ff3
1e894ddc237b033b5b1dcf9b05d281ff0a053532
fad66bdf5c5dc2c050cbc574832c6995dba086a0
23c56da0cdddc664980705c4d14cb2579a970eed
b21ba8da278b75e1cc515b6e2c84b91be6611800
9a7f0b64007cedfa9ae20dd212892d73
d90d0f4d6dad402b5d025987030cc87c
5e11432c30783b184dc2bf27aa1728b4
C805649d6909bf1d7e220f144801044b

Note: This CSV file includes all the listed hashes, along with other Indicators of Compromise (IOCs), conveniently consolidated for streamlined export into a lookup for notable detections.

SPL 1: Service Creation Through LaunchAgent
| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime FROM datamodel=Endpoint.Filesystem where Filesystem.action=created Filesystem.file_path="*/Library/LaunchAgents/com.apple.update.plist*" by _time
SPL 2: Detect the presence of Known Hashes Related to SysJoker RAT
| 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 | Filesystem.file_hash IN ("36fed8ab1bf473714d6886b8dcfbcaa200a72997d50ea0225a90c28306b7670e","1ffd6559d21470c40dcf9236da51e5823d7ad58c93502279871c3fe7718c901c","bd0141e88a0d56b508bc52db4dab68a49b6027a486e4d9514ec0db006fe71eed","d028e64bf4ec97dfd655ccd1157a5b96515d461a710231ac8a529d7bdb936ff3","1e894ddc237b033b5b1dcf9b05d281ff0a053532","fad66bdf5c5dc2c050cbc574832c6995dba086a0","23c56da0cdddc664980705c4d14cb2579a970eed","b21ba8da278b75e1cc515b6e2c84b91be6611800","9a7f0b64007cedfa9ae20dd212892d73","d90d0f4d6dad402b5d025987030cc87c","5e11432c30783b184dc2bf27aa1728b4","c805649d6909bf1d7e220f144801044b") | 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")

Step 4

Once persistence is established, the SysJoker malware grabs an encoded Google Drive (sometimes, OneDrive) link from within its package. This link is decoded, and it is requested to pull down a text file. This text file contains another encoded link – the Command-and-Control URL for the malware that is constantly updated.

Actions Detect

Navigating to the Known Malicious Google Drive URLs

https[://]drive[.]google[.]com/uc?export=download&id=1-NVty4YX0dPHdxkgMrbdCldQCpCaE-Hn
https[://]drive[.]google[.]com/uc?export=download&id=1W64PQQxrwY3XjBnv_QAeBQu-ePr537eu

Note: 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: Detect Known Malicious Google Drive 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 ("https[://]drive[.]google[.]com/uc?export=download&id=1-NVty4YX0dPHdxkgMrbdCldQCpCaE-Hn", "https[://]drive[.]google[.]com/uc?export=download&id=1W64PQQxrwY3XjBnv_QAeBQu-ePr537eu") 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 5

Once the command-and-control link is acquired, a connection attempt to the various known SysJoker infrastructure is attempted. This C2 connection can be used by an attacker to control the malware to execute remote commands, execute scripts, change registry entries and exit/hide. The malware makes GET requests to the C2 API endpoints and the C2 server responds in JSON with parameters/instructions.

Actions Detect

Connection Attempts to Known C2 Domains

bookitlab[.]tech
graphic-updater[.]com
office360-update[.]com
winaudio-tools[.]com
github.url-mini[.]com
graphic-updater[.]com
sharing-u-file[.]com
filestorage-short[.]org
audiosound-visual[.]com

Connection Attempts to Known C2 IP Addresses

85.31.231[.]49
62.108.40[.]129
SPL 1 – Detect C2 Domains using Network Resolution Data Model
| tstats `summariesonly` latest(_time) as _time  values("DNS.dest") as dest, values("DNS.query") as query, values("DNS.query_count") as query_count, values("DNS.message_type") as message_type, values("DNS.answer") as answer, values("DNS.reply_code") as reply_code from datamodel="Network_Resolution"."DNS" where DNS.query IN ("bookitlab[.]tech","graphic-updater[.]com","office360-update[.]com","winaudio-tools[.]com","github.url-mini[.]com","graphic-updater[.]com","sharing-u-file[.]com","filestorage-short[.]org","audiosound-visual[.]com"
) | table _time, dest, query, query_count, message_type, answer, reply_code | fieldformat Time = strftime(_time,"%m/%d/%Y %T")
SPL 2 – Detect C2 Domains using Web Data Model
| 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, "(bookitlab[.]tech)|(graphic-updater[.]com)|(office360-update[.]com)|(winaudio-tools[.]com)|(github.url-mini[.]com)|(graphic-updater[.]com)|(sharing-u-file[.]com)|(filestorage-short[.]org)|(audiosound-visual[.]com)
") | 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 domains 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 3 – Detect C2 IP Address Using Network Traffic Data Model
| 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 ("85.31.231[.]49","62.108.40[.]129") OR All_Traffic.dest IN ("85.31.231[.]49","62.108.40[.]129") 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.

IOC List

The file link below is an aggregate of IOCs found related to the SysJoker RAT malware. 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.

TekStream SysJoker IOC List

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 and/or malware. 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

Articles referenced and used for this blog post include:

OTX.Alien Vault: SysJoker IOC’s

OTX.Alien Vault: SysJoker Backdoor: Propagation, Exploitation, and Indicators of Compromise

Bleeping Computer: New Rust-based SysJoker backdoor linked to Hamas hackers

Intezer: New SysJoker Backdoor Targets Windows, Linux, and macOS

VMware: SysJoker – An Analysis of a Multi-OS RAT

Check Point Research: Israle-Hamas War Spotlight: Shaking The Rust Off SysJoker

Disclaimer

The approaches recommended herein have not been tested broadly across the TekStream customer base. They are preliminary and come without certification of efficacy.