Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new detection: suspicious systemd units #383

Merged
merged 3 commits into from
Aug 27, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
268 changes: 268 additions & 0 deletions detection/persistence/suspicious-systemd-unit.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
-- Funky systemd units, may be evidence of persistence
--
-- references:
-- * https://attack.mitre.org/techniques/T1543/002/ (Create or Modify System Process: Systemd Service)
-- * https://www.cadosecurity.com/blog/spinning-yarn-a-new-linux-malware-campaign-targets-docker-apache-hadoop-redis-and-confluence
-- * https://sandflysecurity.com/blog/log4j-kinsing-linux-malware-in-the-wild/
--
-- false positives:
-- * home-made systemd files
--
-- tags: persistent filesystem systemd
-- platform: linux
SELECT
file.path,
file.size,
file.btime,
file.ctime,
file.mtime,
hash.sha256,
yara.*
FROM file
JOIN yara ON file.path = yara.path
JOIN hash ON file.path = hash.path
WHERE
file.path IN (
SELECT DISTINCT(fragment_path) FROM systemd_units
WHERE fragment_path LIKE "%.service"
AND NOT fragment_path LIKE "/run/systemd/generator.late/%"
)
AND yara.sigrule = '
rule systemd_execstart_danger_path_val : high {
meta:
ref = "https://sandflysecurity.com/blog/log4j-kinsing-linux-malware-in-the-wild/"
description = "Starts from a dangerous-looking path"
strings:
$awkward = /ExecStart=\/(boot|var|tmp|dev|root)\/[\.\w\-\/]{0,32}/
condition:
filesize < 102400 and $awkward
}

rule systemd_execstart_elsewhere : medium {
meta:
description = "Starts from an unusual path"
ref = "https://sandflysecurity.com/blog/log4j-kinsing-linux-malware-in-the-wild/"
hash_2023_Downloads_kinsing = "05d02411668f4ebd576a24ac61cc84e617bdb66aa819581daa670c65f1a876f0"
hash_2023_articles_https_pberba_github_io_security_2022_02_07_linux_threat_hunting_for_persistence_systemd_generators = "8c227f67a16162ffd5b453a478ced2950eba4cbe3b004c5cc935fb9551dc2289"
hash_2024_2024_Spinning_YARN_yarn_fragments = "723326f8551f2a92ccceeec93859f58df380a3212e7510bc64181f2a0743231c"
strings:
$execstart = /ExecStart=\/[\w\/]{1,128}/
$not_bin = "ExecStart=/bin/"
$not_bin_true = "ExecStart=/bin/true"
$not_etc_rcd = "ExecStart=/etc/rc.d/rc.local"
$not_etc_rc_local = "ExecStart=/etc/rc.local"
$not_init_d = "ExecStart=/etc/init.d/"
$not_lib = "ExecStart=/lib/"
$not_motd = "ExecStart=/etc/update-motd.d/"
$not_opt = "ExecStart=/opt/"
$not_sbin = "ExecStart=/sbin/"
$not_usr_bin = "ExecStart=/usr/bin/"
$not_usr_libexec = "ExecStart=/usr/libexec/"
$not_usr_lib = "ExecStart=/usr/lib/"
$not_usr_local = "ExecStart=/usr/local/"
$not_usr_sbin = "ExecStart=/usr/sbin/"
$not_usr_share = "ExecStart=/usr/share/"
condition:
filesize < 102400 and $execstart and none of ($not_*)
}

rule systemd_execstop_elsewhere : medium {
meta:
ref = "https://www.trendmicro.com/en_us/research/23/c/iron-tiger-sysupdate-adds-linux-targeting.html"
description = "Runs program from unexpected directory at stop"
strings:
$execstop = /ExecStop=\/[\w\.\_\-]{2,64}/
$not_lib = "ExecStop=/lib/"
$not_opt = "ExecStart=/opt/"
$not_sbin = "ExecStop=/sbin/"
$not_usr_libexec = "ExecStop=/usr/libexec/"
$not_usr_lib = "ExecStop=/usr/lib/"
$not_usr_local = "ExecStop=/usr/local/"
$not_usr_sbin = "ExecStop=/usr/sbin/"
$not_usr_share = "ExecStop=/usr/share/"
condition:
filesize < 384 and $execstop and none of ($not*)
}

rule systemd_small_no_blank_lines : high {
meta:
ref = "https://sandflysecurity.com/blog/log4j-kinsing-linux-malware-in-the-wild/"
hash_2023_Downloads_kinsing = "05d02411668f4ebd576a24ac61cc84e617bdb66aa819581daa670c65f1a876f0"
strings:
$execstart = "ExecStart"
$blank = "\n\n"
$not_dbus = "Type=dbus"
$not_after = /After=\w/
$not_before = /Before=\w{1,128}/
$not_notify = "Type=notify"
condition:
filesize < 512 and $execstart and not $blank and none of ($not*)
}

rule systemd_small_multiuser_no_comments_or_documentation : high {
meta:
ref = "https://sandflysecurity.com/blog/log4j-kinsing-linux-malware-in-the-wild/"
description = "systemd unit is undocumented"
strings:
$execstart = "ExecStart="
$multiuser = "multi-user.target"
$not_comment = "# "
$not_documentation = "Documentation="
$not_requires_socket = /Requires=.{0,64}socket/
$not_condition_path = "Condition"
$not_after = "After="
$not_systemd = "ExecStart=systemd-"
$not_output = "StandardOutput="
$not_part_of = "PartOf="
$not_dbus = "Type=dbus"
$not_oneshot = "Type=oneshot"
$not_lima = "Description=lima-guestagent"
condition:
filesize < 384 and $execstart and $multiuser and none of ($not_*)
}
rule systemd_small_no_output : high {
meta:
description = "Discards all logging output"
strings:
$output_null = "StandardOutput=null"
$error_null = "StandardError=null"
$not_input_null = "StandardInput=null"
$not_syslog = "syslog"
$not_before = "Before="
$not_display = "WantedBy=display-manager.service"
condition:
filesize < 384 and ($output_null and $error_null) and none of ($not*)
}

rule systemd_small_multiuser_not_in_dependency_tree : high {
meta:
description = "Relies on nothing, nothing relies on it"
hash_2023_Downloads_kinsing = "05d02411668f4ebd576a24ac61cc84e617bdb66aa819581daa670c65f1a876f0"
strings:
$execstart = "ExecStart="
$multiuser = "multi-user.target"
$not_after = /After=\w/
$not_before = /Before=\w{1,128}/
$not_requires = /Requires=\w/
$not_condition = "Condition"
$not_oneshot = "Type=oneshot"
$not_default = "DefaultDependencies=no"
$not_env = "EnvironmentFile="
$not_bus = "BusName="
$not_idle = "Type=idle"
$not_systemd = "ExecStart=systemd-"
$not_lima = "Description=lima-guestagent"
condition:
filesize < 384 and $execstart and $multiuser and none of ($not_*)
}

rule sytemd_small_type_forking_not_in_dep_tree : high {
meta:
hash_2023_Txt_Malware_Sustes_0e77 = "0e77291955664d2c25d5bfe617cec12a388e5389f82dee5ae4fd5c5d1f1bdefe"
hash_2023_Unix_Malware_Kaiji_3e68 = "3e68118ad46b9eb64063b259fca5f6682c5c2cb18fd9a4e7d97969226b2e6fb4"
hash_2023_Unix_Malware_Kaiji_f4a6 = "f4a64ab3ffc0b4a94fd07a55565f24915b7a1aaec58454df5e47d8f8a2eec22a"
strings:
$forking = "Type=forking"
$not_after = /After=\w/
$not_before = /Before=\w{1,128}/
$not_condition = "ConditionPath"
$not_oneshot = "Type=oneshot"
$not_default_deps = "DefaultDependencies=no"
$not_env = "EnvironmentFile="
$not_bus = "BusName="
$not_idle = "Type=idle"
$not_systemd = "ExecStart=systemd-"
$not_default_target = "WantedBy=default.target"
condition:
filesize < 384 and $forking and none of ($not_*)
}

rule systemd_small_restart_always : medium {
meta:
description = "service restarts no matter how many times it crashes"
hash_2023_Downloads_kinsing = "05d02411668f4ebd576a24ac61cc84e617bdb66aa819581daa670c65f1a876f0"
strings:
$restart = "Restart=always"
$not_syslog = "SyslogLevel="
$not_gpl = "GPL-2.0-only"
$not_after = /After=\w/
$not_before = /Before=\w{1,128}/
$not_notify = "Type=notify"
condition:
filesize < 384 and $restart and none of ($not*)
}

rule systemd_small_short_description {
meta:
description = "Short or no description"
strings:
$execstart = "ExecStart="
$short_desc = /Description=\n/
condition:
filesize < 384 and all of them
}

rule systemd_nice_execstart_restart_no_comment {
meta:
description = "Sets nice value and restarts always without comments, possible miner"
strings:
$has_execstart = "ExecStart="
$has_restart = "Restart=always"
$has_nice = "Nice="
$not_comment = "#"
condition:
filesize < 4096 and all of ($has*) and none of ($not*)
}

rule usr_bin_execstop_shell : medium {
meta:
ref = "https://www.trendmicro.com/en_us/research/23/c/iron-tiger-sysupdate-adds-linux-targeting.html"
description = "Runs shell script at stop"
strings:
$execstop = /ExecStop=\/bin\/sh .{0,64}/
$not_podman_logging = "/usr/bin/podman $LOGGING"
condition:
filesize < 4096 and $execstop and none of ($not*)
}

rule systemd_hidden_execstart : critical {
meta:
description = "ExecStart references hidden file"
strings:
$path_top_bin = /ExecStart=\/\.[\w\/]+/
$path_sub_bin = /ExecStart=\/\w[\w\/]*\/\.\w+/
$path_arg_sub = /ExecStart=.* \/\w[\w\/]*\/\.\w+/
$path_arg_top = /ExecStart=.* \/\.[\w\/]+/
$not_autorelabel = "/.autorelabel"
$not_exists = "ConditionPathExists"
$not_ksysguard = "/.ksysguard/ksgrd_network_helper"
condition:
any of ($path*) and none of ($not*)
}

rule systemd_hidden_execstop : critical {
meta:
description = "ExecStop references hidden file"
strings:
$path_top_bin = /ExecStart=\/\.[\w\/]+/
$path_sub_bin = /ExecStart=\/\w[\w\/]*\/\.\w+/
$path_arg_sub = /ExecStart=.* \/\w[\w\/]*\/\.\w+/
$path_arg_top = /ExecStart=.* \/\.[\w\/]+/

$not_autorelabel = "/.autorelabel"
$not_exists = "ConditionPathExists"
condition:
any of ($path*) and none of ($not*)
}

rule systemd_hidden_working_directory : critical {
meta:
description = "WorkingDirectory is a hidden"
strings:
$ref = /WorkingDirectory=.*\/\..*/
condition:
any of them
}
'

AND yara.count > 0
Loading