From c98e5e3a2f3d07f0168a8acb37ae3a915597643e Mon Sep 17 00:00:00 2001
From: egibs <20933572+egibs@users.noreply.github.com>
Date: Tue, 20 May 2025 09:49:53 -0500
Subject: [PATCH 1/3] Use the include directive to centralize common private
rules
Signed-off-by: egibs <20933572+egibs@users.noreply.github.com>
---
.github/workflows/style.yaml | 2 +-
rules/anti-behavior/random_behavior.yara | 21 +-
rules/anti-static/elf/entropy.yara | 12 +-
rules/anti-static/macho/entropy.yara | 11 +-
rules/anti-static/macho/footer.yara | 9 +-
rules/anti-static/packer/aes.yara | 10 +-
rules/anti-static/unmarshal/marshal.yara | 15 +-
rules/c2/addr/ip.yara | 9 +-
rules/c2/addr/url.yara | 7 +-
rules/c2/tool_transfer/download.yara | 10 +-
rules/c2/tool_transfer/macos.yara | 12 +-
rules/c2/tool_transfer/python.yara | 70 +---
rules/data/builtin/multiple.yara | 31 +-
rules/discover/multiple.yara | 33 +-
rules/discover/user/username-get.yara | 21 +-
.../indicator_blocking/hidden_window.yara | 21 +-
.../indicator_blocking/mask_exceptions.yara | 20 +-
rules/evasion/logging/wipe.yara | 19 +-
rules/evasion/net/hide_ports.yara | 12 +-
.../evasion/self_deletion/run_and_delete.yara | 22 +-
rules/exec/program/opaque.yara | 12 +-
rules/exec/shell/relative-semicolon.yara | 8 +-
rules/exfil/discord.yara | 35 +-
rules/exfil/nodejs.yara | 29 +-
rules/exfil/npm.yara | 15 +-
rules/exfil/oauth.yara | 10 +-
rules/false_positives/py_hatch.yara | 1 +
rules/false_positives/setuptools.yara | 1 +
rules/fs/path/applications.yara | 16 +-
rules/global.yara | 320 ++++++++++++++++++
rules/impact/degrade/firewall.yara | 14 +-
rules/impact/exploit/breakout.yara | 10 +-
rules/impact/exploit/exploit.yara | 10 +-
rules/impact/remote_access/backdoor.yara | 19 +-
rules/impact/remote_access/py_setuptools.yara | 49 +--
rules/impact/wipe/crypto.yara | 9 +-
rules/malware/family/amos.yara | 20 +-
rules/malware/family/clapzok.yara | 7 +-
rules/malware/family/poseidon_stealer.yara | 16 +-
rules/net/download/fetch.yara | 14 +-
rules/sus/compiler.yara | 8 +-
rules/sus/entitlement.yara | 12 +-
.../2024.coloredtxt/base64_payload3.py.simple | 1 +
tests/python/clean/hatch/migrate.py.simple | 2 +-
.../clean/setuptools/namespaces.py.simple | 2 +-
45 files changed, 437 insertions(+), 570 deletions(-)
create mode 100644 rules/global.yara
diff --git a/.github/workflows/style.yaml b/.github/workflows/style.yaml
index 2bec77ad5..b2c3a0eed 100644
--- a/.github/workflows/style.yaml
+++ b/.github/workflows/style.yaml
@@ -38,7 +38,7 @@ jobs:
yr --version
- name: Run yr compile
run: |
- yr compile rules/
+ yr compile --path-as-namespace -w rules/
ret=$?
if [[ $ret -ne 0 ]]; then
echo "Rule compilation failed; address findings and commit the changes"
diff --git a/rules/anti-behavior/random_behavior.yara b/rules/anti-behavior/random_behavior.yara
index 6e45dbe2f..a49769f5f 100644
--- a/rules/anti-behavior/random_behavior.yara
+++ b/rules/anti-behavior/random_behavior.yara
@@ -1,21 +1,6 @@
-import "math"
-
-private rule random_behavior_pythonSetup {
- strings:
- $if_distutils = /from distutils.core import .{0,32}setup/
- $if_setuptools = /from setuptools import .{0,32}setup/
- $i_setuptools = "import setuptools"
- $setup = "setup("
-
- $not_setup_example = ">>> setup("
- $not_setup_todict = "setup(**config.todict()"
- $not_import_quoted = "\"from setuptools import setup"
- $not_setup_quoted = "\"setup(name="
- $not_distutils = "from distutils.errors import"
+include "rules/global.yara"
- condition:
- filesize < 128KB and $setup and any of ($i*) and none of ($not*)
-}
+import "math"
rule setuptools_random: critical {
meta:
@@ -27,7 +12,7 @@ rule setuptools_random: critical {
$not_easy_install = "pid = random.randint(0, sys.maxsize)"
condition:
- random_behavior_pythonSetup and $ref and none of ($not*)
+ python_setup and $ref and none of ($not*)
}
rule java_random: low {
diff --git a/rules/anti-static/elf/entropy.yara b/rules/anti-static/elf/entropy.yara
index 885270703..4e679db96 100644
--- a/rules/anti-static/elf/entropy.yara
+++ b/rules/anti-static/elf/entropy.yara
@@ -1,14 +1,6 @@
-import "math"
-
-private rule normal_elf {
- condition:
- filesize < 64MB and uint32(0) == 1179403647
-}
+include "rules/global.yara"
-private rule small_elf {
- condition:
- filesize < 400KB and uint32(0) == 1179403647
-}
+import "math"
rule higher_elf_entropy_68: medium {
meta:
diff --git a/rules/anti-static/macho/entropy.yara b/rules/anti-static/macho/entropy.yara
index 6a821c505..15956afef 100644
--- a/rules/anti-static/macho/entropy.yara
+++ b/rules/anti-static/macho/entropy.yara
@@ -1,9 +1,6 @@
-import "math"
+include "rules/global.yara"
-private rule smaller_macho {
- condition:
- filesize < 64MB and (uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962)
-}
+import "math"
rule higher_entropy_6_9: medium {
meta:
@@ -11,7 +8,7 @@ rule higher_entropy_6_9: medium {
filetypes = "macho"
condition:
- smaller_macho and math.entropy(1, filesize) >= 6.9
+ small_macho and math.entropy(1, filesize) >= 6.9
}
rule high_entropy_7_2: high {
@@ -24,5 +21,5 @@ rule high_entropy_7_2: high {
$bin_java = "bin/java"
condition:
- smaller_macho and math.entropy(1, filesize) >= 7.2 and not $bin_java
+ small_macho and math.entropy(1, filesize) >= 7.2 and not $bin_java
}
diff --git a/rules/anti-static/macho/footer.yara b/rules/anti-static/macho/footer.yara
index 5ee0acac5..37d10d3e4 100644
--- a/rules/anti-static/macho/footer.yara
+++ b/rules/anti-static/macho/footer.yara
@@ -1,9 +1,6 @@
-import "math"
+include "rules/global.yara"
-private rule anti_static_macho {
- condition:
- (uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962 or uint32(0) == 3405691583 or uint32(0) == 3216703178)
-}
+import "math"
rule high_entropy_trailer: high {
meta:
@@ -15,5 +12,5 @@ rule high_entropy_trailer: high {
$page_zero = "_PAGEZERO"
condition:
- filesize < 10MB and anti_static_macho and $page_zero and math.entropy(filesize - 1024, filesize - 1) >= 4
+ filesize < 10MB and macho and $page_zero and math.entropy(filesize - 1024, filesize - 1) >= 4
}
diff --git a/rules/anti-static/packer/aes.yara b/rules/anti-static/packer/aes.yara
index 9f6c446d3..7fc3a8dc9 100644
--- a/rules/anti-static/packer/aes.yara
+++ b/rules/anti-static/packer/aes.yara
@@ -1,10 +1,6 @@
-import "math"
+include "rules/global.yara"
-private rule smallBinary {
- condition:
- // matches ELF or machO binary
- filesize > 1MB and filesize < 8MB and (uint32(0) == 1179403647 or uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962)
-}
+import "math"
rule go_aes: high {
meta:
@@ -17,5 +13,5 @@ rule go_aes: high {
$decrypt = "NewCFBDecrypter"
condition:
- smallBinary and math.entropy(1, filesize) >= 7 and all of them
+ small_binary and math.entropy(1, filesize) >= 7 and all of them
}
diff --git a/rules/anti-static/unmarshal/marshal.yara b/rules/anti-static/unmarshal/marshal.yara
index e2da33b3d..f17c28f4c 100644
--- a/rules/anti-static/unmarshal/marshal.yara
+++ b/rules/anti-static/unmarshal/marshal.yara
@@ -1,15 +1,6 @@
-import "math"
-
-private rule pySetup {
- strings:
- $i_distutils = "from distutils.core import setup"
- $i_setuptools = "setuptools"
- $setup = "setup("
- $not_setuptools = "setuptools.command"
+include "rules/global.yara"
- condition:
- filesize < 2097152 and $setup and any of ($i*) and none of ($not*)
-}
+import "math"
rule unmarshal_py_marshal: medium {
meta:
@@ -29,5 +20,5 @@ rule setuptools_py_marshal: suspicious {
filetypes = "py"
condition:
- pySetup and unmarshal_py_marshal
+ python_setup and unmarshal_py_marshal
}
diff --git a/rules/c2/addr/ip.yara b/rules/c2/addr/ip.yara
index c51da388d..2ce46fcf0 100644
--- a/rules/c2/addr/ip.yara
+++ b/rules/c2/addr/ip.yara
@@ -1,3 +1,5 @@
+include "rules/global.yara"
+
rule hardcoded_ip: medium {
meta:
description = "hardcoded IP address"
@@ -19,11 +21,6 @@ rule hardcoded_ip: medium {
filesize < 200MB and 1 of ($sus_ip*) and none of ($not*)
}
-private rule ip_elf_or_macho {
- condition:
- uint32(0) == 1179403647 or (uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962 or uint32(0) == 3405691583 or uint32(0) == 3216703178)
-}
-
rule bin_hardcoded_ip: high {
meta:
description = "ELF with hardcoded IP address"
@@ -48,7 +45,7 @@ rule bin_hardcoded_ip: high {
$not_2345 = "23.45.67.89"
condition:
- filesize < 12MB and ip_elf_or_macho and 1 of ($sus_ip*) and none of ($not*)
+ filesize < 12MB and elf_or_macho and 1 of ($sus_ip*) and none of ($not*)
}
rule http_hardcoded_ip: high exfil {
diff --git a/rules/c2/addr/url.yara b/rules/c2/addr/url.yara
index 963e89ffc..6acbaa5cf 100644
--- a/rules/c2/addr/url.yara
+++ b/rules/c2/addr/url.yara
@@ -1,9 +1,6 @@
-import "math"
+include "rules/global.yara"
-private rule elf_or_macho {
- condition:
- uint32(0) == 1179403647 or (uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962 or uint32(0) == 3405691583 or uint32(0) == 3216703178)
-}
+import "math"
rule unusual_nodename: medium {
meta:
diff --git a/rules/c2/tool_transfer/download.yara b/rules/c2/tool_transfer/download.yara
index 13acfe6a4..696cace86 100644
--- a/rules/c2/tool_transfer/download.yara
+++ b/rules/c2/tool_transfer/download.yara
@@ -1,3 +1,5 @@
+include "rules/global.yara"
+
rule download_sites: high {
meta:
ref = "https://github.com/ditekshen/detection/blob/e6579590779f62cbe7f5e14b5be7d77b2280f516/yara/indicator_high.yar#L1001"
@@ -113,12 +115,6 @@ rule http_archive_url: medium {
any of ($ref*) and none of ($not*)
}
-private rule smallerBinary {
- condition:
- // matches ELF or machO binary
- filesize < 10MB and (uint32(0) == 1179403647 or uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962)
-}
-
rule http_archive_url_higher: high {
meta:
description = "accesses hardcoded archive file endpoint"
@@ -129,5 +125,5 @@ rule http_archive_url_higher: high {
$not_foo_bar = "http://foo/bar.tar"
condition:
- smallerBinary and any of ($ref*) and none of ($not*)
+ small_binary and any of ($ref*) and none of ($not*)
}
diff --git a/rules/c2/tool_transfer/macos.yara b/rules/c2/tool_transfer/macos.yara
index 4c82c9b22..964826d05 100644
--- a/rules/c2/tool_transfer/macos.yara
+++ b/rules/c2/tool_transfer/macos.yara
@@ -1,12 +1,4 @@
-private rule tool_transfer_macho {
- strings:
- $not_jar = "META-INF/"
- $not_dwarf = "_DWARF"
- $not_kext = "_.SYMDEF SORTED"
-
- condition:
- (uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962 or uint32(0) == 3405691583 or uint32(0) == 3216703178) and none of ($not*)
-}
+include "rules/global.yara"
rule macos_chflags_hidden: critical {
meta:
@@ -38,5 +30,5 @@ rule cocoa_bundle_dropper: critical {
$platform = "isPlatformOrVariantPlatformVersionAtLeast" fullword
condition:
- tool_transfer_macho and $shared and 5 of them
+ specific_macho and $shared and 5 of them
}
diff --git a/rules/c2/tool_transfer/python.yara b/rules/c2/tool_transfer/python.yara
index 4f30f0ec3..3108dc42d 100644
--- a/rules/c2/tool_transfer/python.yara
+++ b/rules/c2/tool_transfer/python.yara
@@ -1,46 +1,4 @@
-private rule probably_python_tt {
- strings:
- $import = "import "
- $f_common = /\s(def|if|with|else:) /
- $f_exotic = /exec\(|b64decode|bytes\(/
-
- condition:
- filesize < 10MB and $import in (1..1024) and any of ($f*)
-}
-
-private rule py_fetcher: medium {
- meta:
- description = "fetches content"
- filetypes = "py"
-
- strings:
- $http_requests = "requests.get" fullword
- $http_requests_post = "requests.post" fullword
- $http_urllib = "urllib.request" fullword
- $http_urlopen = "urlopen" fullword
- $git_git = /git.Git\(.{0,64}/
- $http_curl = "curl" fullword
- $http_wget = "wget" fullword
-
- condition:
- probably_python_tt and any of them
-}
-
-private rule py_runner {
- meta:
- description = "runs programs"
- filetypes = "py"
-
- strings:
- $os_system = /os.system\([\"\'\w\ \-\)\/]{0,64}/
- $os_startfile = /os.startfile\([\"\'\w\ \-\)\/]{0,64}/
- $os_popen = /os.spopen\([\"\'\w\ \-\)\/]{0,64}/
- $subprocess = /subprocess.\w{1,32}\([\"\'\/\w\ \-\)]{0,64}/
- $system = /system\([\"\'\w\ \-\)\/]{0,64}/
-
- condition:
- probably_python_tt and any of them
-}
+include "rules/global.yara"
rule py_dropper: medium {
meta:
@@ -122,35 +80,13 @@ rule py_dropper_chmod: high {
filesize < 1MB and py_fetcher and py_runner and $chmod and any of ($val*)
}
-private rule tool_transfer_pythonSetup {
- strings:
- $if_distutils = /from distutils.core import .{0,32}setup/
- $if_setuptools = /from setuptools import .{0,32}setup/
- $i_setuptools = "import setuptools"
- $setup = "setup("
-
- $not_setup_example = ">>> setup("
- $not_setup_todict = "setup(**config.todict()"
- $not_import_quoted = "\"from setuptools import setup"
- $not_setup_quoted = "\"setup(name="
- $not_distutils = "from distutils.errors import"
- $not_dir = "dist-packages/setuptools"
- $not_fetch = "fetch_distribution"
- $not_hopper1 = "PACKAGE_NAME = \"flashattn-hopper\""
- $not_hopper2 = "check_if_cuda_home_none(\"--fahopper\")"
- $not_hopper3 = "name=\"flashattn_hopper_cuda\","
-
- condition:
- filesize < 128KB and $setup and any of ($i*) and none of ($not*)
-}
-
rule setuptools_fetcher: suspicious {
meta:
description = "setuptools script that fetches content"
filetypes = "py"
condition:
- tool_transfer_pythonSetup and py_fetcher
+ python_setup and py_fetcher
}
rule setuptools_fetch_run: critical {
@@ -173,7 +109,7 @@ rule setuptools_dropper: critical {
filetypes = "py"
condition:
- tool_transfer_pythonSetup and py_dropper
+ python_setup and py_dropper
}
rule dropper_imports: high {
diff --git a/rules/data/builtin/multiple.yara b/rules/data/builtin/multiple.yara
index e4567dad1..fbbffedea 100644
--- a/rules/data/builtin/multiple.yara
+++ b/rules/data/builtin/multiple.yara
@@ -1,31 +1,6 @@
-import "elf"
-
-private rule _bundled_openssl: medium {
- meta:
- description = "includes bundled copy of OpenSSL"
-
- strings:
- $ref = "OpenSSL/"
- $aes_part = "AES part of OpenSSL"
- $montgomery = "Montgomery Multiplication for x86_64, CRYPTOGAMS"
- $rc4 = "RC4 for x86_64, CRYPTOGAMS"
-
- condition:
- filesize > 1024 and filesize < 150MB and elf.type == elf.ET_EXEC and uint32(0) == 1179403647 and any of them
-}
+include "rules/global.yara"
-private rule _bundled_glibc: medium {
- meta:
- description = "includes bundled copy of glibc"
-
- strings:
- $glibc_private = "GLIBC_PRIVATE"
- $glibc_tunables = "GLIBC_TUNABLES"
- $setup_vdso = "setup_vdso"
-
- condition:
- filesize > 1024 and filesize < 25MB and elf.type == elf.ET_EXEC and uint32(0) == 1179403647 and all of them
-}
+import "elf"
rule elf_with_bundled_glibc_and_openssl: high {
meta:
@@ -33,5 +8,5 @@ rule elf_with_bundled_glibc_and_openssl: high {
filetypes = "elf"
condition:
- _bundled_openssl and _bundled_glibc
+ bundled_openssl and bundled_glibc
}
diff --git a/rules/discover/multiple.yara b/rules/discover/multiple.yara
index 6862fddac..d667744ee 100644
--- a/rules/discover/multiple.yara
+++ b/rules/discover/multiple.yara
@@ -1,3 +1,5 @@
+include "rules/global.yara"
+
rule sys_net_recon: medium {
meta:
description = "collects system and network information"
@@ -62,35 +64,6 @@ rule user_sys_net_disk_recon: high {
filesize < 512KB and any of ($sys*) and any of ($net*) and any of ($user*) and any of ($disk*)
}
-private rule discover_obfuscate {
- strings:
- $b64decode = "b64decode"
- $base64 = "base64"
- $codecs = "codecs.decode"
- $x_decode = /\w{0,16}XorDecode[\w]{0,32}/
- $x_encode = /\w{0,16}XorEncode[\w]{0,32}/
- $x_file = /\w{0,16}XorFile[\w]{0,32}/
- $x_decode_ = /\w{0,16}xor_decode[\w]{0,32}/
- $x_encode_ = /\w{0,16}xor_encode[\w]{0,32}/
- $x_file_ = /\w{0,16}xor_file[\w]{0,32}/
-
- condition:
- filesize < 512KB and any of them
-}
-
-private rule discover_exfil {
- strings:
- $f_app_json = "application/json"
- $f_post = "requests.post"
- $f_nsurl = "NSURLRequest"
- $f_curl = /curl.{0,32}-X POST/
-
- $not_requests_utils = "requests.utils"
-
- condition:
- filesize < 512KB and any of ($f*) and none of ($not*)
-}
-
rule sys_net_recon_exfil: high {
meta:
description = "may exfiltrate collected system and network information"
@@ -100,5 +73,5 @@ rule sys_net_recon_exfil: high {
$not_cloudinit = "cloudinit" fullword
condition:
- sys_net_recon and discover_obfuscate and discover_exfil and none of ($not*)
+ sys_net_recon and obfuscate and exfil and none of ($not*)
}
diff --git a/rules/discover/user/username-get.yara b/rules/discover/user/username-get.yara
index 8e0dfacc9..0b930706c 100644
--- a/rules/discover/user/username-get.yara
+++ b/rules/discover/user/username-get.yara
@@ -1,3 +1,5 @@
+include "rules/global.yara"
+
rule getlogin {
meta:
syscall = "getlogin"
@@ -27,23 +29,6 @@ rule whoami: medium {
any of them
}
-private rule user_pythonSetup {
- strings:
- $if_distutils = /from distutils.core import .{0,32}setup/
- $if_setuptools = /from setuptools import .{0,32}setup/
- $i_setuptools = "import setuptools"
- $setup = "setup("
-
- $not_setup_example = ">>> setup("
- $not_setup_todict = "setup(**config.todict()"
- $not_import_quoted = "\"from setuptools import setup"
- $not_setup_quoted = "\"setup(name="
- $not_distutils = "from distutils.errors import"
-
- condition:
- filesize < 128KB and $setup and any of ($i*) and none of ($not*)
-}
-
rule pysetup_gets_login: high {
meta:
description = "Python library installer gets login information"
@@ -55,5 +40,5 @@ rule pysetup_gets_login: high {
$ref3 = "whoami" fullword
condition:
- user_pythonSetup and any of them
+ python_setup and any of them
}
diff --git a/rules/evasion/indicator_blocking/hidden_window.yara b/rules/evasion/indicator_blocking/hidden_window.yara
index 3ed227b4d..1e7702e5c 100644
--- a/rules/evasion/indicator_blocking/hidden_window.yara
+++ b/rules/evasion/indicator_blocking/hidden_window.yara
@@ -1,3 +1,5 @@
+include "rules/global.yara"
+
rule subprocess_CREATE_NO_WINDOW: medium {
meta:
description = "runs commands, hides windows"
@@ -11,23 +13,6 @@ rule subprocess_CREATE_NO_WINDOW: medium {
filesize < 32KB and all of them
}
-private rule hidden_window_pythonSetup {
- strings:
- $if_distutils = /from distutils.core import .{0,32}setup/
- $if_setuptools = /from setuptools import .{0,32}setup/
- $i_setuptools = "import setuptools"
- $setup = "setup("
-
- $not_setup_example = ">>> setup("
- $not_setup_todict = "setup(**config.todict()"
- $not_import_quoted = "\"from setuptools import setup"
- $not_setup_quoted = "\"setup(name="
- $not_distutils = "from distutils.errors import"
-
- condition:
- filesize < 128KB and $setup and any of ($i*) in (0..1024) and none of ($not*)
-}
-
rule subprocess_CREATE_NO_WINDOW_setuptools: high {
meta:
description = "runs commands, hides windows"
@@ -38,7 +23,7 @@ rule subprocess_CREATE_NO_WINDOW_setuptools: high {
$no_window = "CREATE_NO_WINDOW"
condition:
- filesize < 32KB and hidden_window_pythonSetup and all of them
+ filesize < 32KB and python_setup and all of them
}
rule subprocess_CREATE_NO_WINDOW_high: high {
diff --git a/rules/evasion/indicator_blocking/mask_exceptions.yara b/rules/evasion/indicator_blocking/mask_exceptions.yara
index 6f447a1fe..f1a3b0795 100644
--- a/rules/evasion/indicator_blocking/mask_exceptions.yara
+++ b/rules/evasion/indicator_blocking/mask_exceptions.yara
@@ -1,20 +1,6 @@
-import "math"
-
-private rule indicator_blocking_pythonSetup {
- strings:
- $if_distutils = /from distutils.core import .{0,32}setup/
- $if_setuptools = /from setuptools import .{0,32}setup/
- $i_setuptools = "import setuptools"
- $setup = "setup("
- $not_setup_example = ">>> setup("
- $not_setup_todict = "setup(**config.todict()"
- $not_import_quoted = "\"from setuptools import setup"
- $not_setup_quoted = "\"setup(name="
- $not_distutils = "from distutils.errors import"
+include "rules/global.yara"
- condition:
- filesize < 131072 and $setup and any of ($i*) and none of ($not*)
-}
+import "math"
rule py_no_fail: medium {
meta:
@@ -35,7 +21,7 @@ rule setuptools_no_fail: suspicious {
filetypes = "py"
condition:
- indicator_blocking_pythonSetup and py_no_fail
+ python_setup and py_no_fail
}
rule php_disable_errors: medium {
diff --git a/rules/evasion/logging/wipe.yara b/rules/evasion/logging/wipe.yara
index cd2afb756..38a9aa22a 100644
--- a/rules/evasion/logging/wipe.yara
+++ b/rules/evasion/logging/wipe.yara
@@ -1,21 +1,4 @@
-private rule sensitive_log_files {
- strings:
- $wtmp = "/var/log/wtmp"
- $secure = "/var/log/secure"
- $cron = "/var/log/cron"
- $iptables = "/var/log/iptables.log"
- $auth = "/var/log/auth.log"
- $cron_log = "/var/log/cron.log"
- $httpd = "/var/log/httpd"
- $syslog = "/var/log/syslog"
- $btmp = "/var/log/btmp"
- $lastlog = "/var/log/lastlog"
- $run_log = "/run/log/"
- $mail_log = "/var/spool/mail/root"
-
- condition:
- filesize < 16KB and 2 of them
-}
+include "rules/global.yara"
rule echo_log_wiper: critical {
meta:
diff --git a/rules/evasion/net/hide_ports.yara b/rules/evasion/net/hide_ports.yara
index 5dc0c9a22..1a41d51e5 100644
--- a/rules/evasion/net/hide_ports.yara
+++ b/rules/evasion/net/hide_ports.yara
@@ -1,12 +1,4 @@
-private rule net_macho {
- condition:
- uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962 or uint32(0) == 3405691583 or uint32(0) == 3216703178
-}
-
-private rule net_elf {
- condition:
- uint32(0) == 1179403647
-}
+include "rules/global.yara"
rule hides_ports: high {
meta:
@@ -22,5 +14,5 @@ rule hides_ports: high {
$hidden_port = "hidden_port"
condition:
- filesize < 2MB and (net_elf or net_macho) and any of ($bin*) and any of ($hid*)
+ filesize < 2MB and (elf_or_macho) and any of ($bin*) and any of ($hid*)
}
diff --git a/rules/evasion/self_deletion/run_and_delete.yara b/rules/evasion/self_deletion/run_and_delete.yara
index 6557dd681..d434483e5 100644
--- a/rules/evasion/self_deletion/run_and_delete.yara
+++ b/rules/evasion/self_deletion/run_and_delete.yara
@@ -1,3 +1,5 @@
+include "rules/global.yara"
+
rule tiny_copy_run_delete: critical {
meta:
description = "copy executable, run, and delete"
@@ -36,24 +38,6 @@ rule fetch_run_sleep_delete: critical {
filesize < 1KB and $url and $sleep and $rm and any of ($path*) and any of ($run*)
}
-private rule run_delete_py_fetcher: medium {
- meta:
- description = "fetches content"
- filetypes = "py"
-
- strings:
- $http_requests = "requests.get" fullword
- $http_requests_post = "requests.post" fullword
- $http_urllib = "urllib.request" fullword
- $http_urlopen = "urlopen" fullword
- $git_git = /git.Git\(.{0,64}/
- $http_curl = "curl" fullword
- $http_wget = "wget" fullword
-
- condition:
- any of them
-}
-
rule python_setsid_remove: high {
meta:
description = "fetch, run in background, delete"
@@ -65,7 +49,7 @@ rule python_setsid_remove: high {
$remove = "os.remove("
condition:
- filesize < 1MB and all of them and run_delete_py_fetcher and @remove > @subprocess and @remove - @subprocess < 256
+ filesize < 1MB and all of them and py_fetcher and @remove > @subprocess and @remove - @subprocess < 256
}
rule run_sleep_delete: critical {
diff --git a/rules/exec/program/opaque.yara b/rules/exec/program/opaque.yara
index f9dfd28ef..0e120f935 100644
--- a/rules/exec/program/opaque.yara
+++ b/rules/exec/program/opaque.yara
@@ -1,10 +1,4 @@
-private rule program_small_macho {
- strings:
- $stub_helper = "__stub_helper"
-
- condition:
- filesize < 1MB and (uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962) and $stub_helper
-}
+include "rules/global.yara"
import "math"
@@ -24,7 +18,7 @@ rule macho_opaque_binary: high {
$not_java = "java/lang"
condition:
- program_small_macho and #word_with_spaces < 8 and #libc_call < 6 and all of ($f*) and none of ($not*)
+ small_macho and #word_with_spaces < 8 and #libc_call < 6 and all of ($f*) and none of ($not*)
}
rule macho_opaque_binary_long_str: high {
@@ -45,7 +39,7 @@ rule macho_opaque_binary_long_str: high {
$long_low_str = /\x00[a-z0-9]{3000}/
condition:
- program_small_macho and #word_with_spaces < 10 and #libc_call < 15 and all of ($f*) and any of ($long*) and none of ($not*)
+ stub_macho and #word_with_spaces < 10 and #libc_call < 15 and all of ($f*) and any of ($long*) and none of ($not*)
}
rule decoded_or_encoded_cmd: medium {
diff --git a/rules/exec/shell/relative-semicolon.yara b/rules/exec/shell/relative-semicolon.yara
index e6682ccb6..6ae588774 100644
--- a/rules/exec/shell/relative-semicolon.yara
+++ b/rules/exec/shell/relative-semicolon.yara
@@ -1,10 +1,4 @@
-private rule local_cd {
- strings:
- $cd = /cd [a-z]{4,12}; \.\//
-
- condition:
- any of them
-}
+include "rules/global.yara"
rule semicolon_relative_path_cd: medium {
meta:
diff --git a/rules/exfil/discord.yara b/rules/exfil/discord.yara
index 6c15d1f9d..226ad3b0e 100644
--- a/rules/exfil/discord.yara
+++ b/rules/exfil/discord.yara
@@ -1,3 +1,5 @@
+include "rules/global.yara"
+
rule discord_bot: high {
meta:
description = "Uses the Discord webhooks API"
@@ -26,41 +28,10 @@ rule discord_bot: high {
any of them and none of ($not*)
}
-private rule iplookup_website_value_copy: high {
- meta:
- description = "public service to discover external IP address"
-
- strings:
- $ipify = "ipify.org"
- $wtfismyip = "wtfismyip"
- $iplogger = "iplogger.org"
- $getjsonip = "getjsonip"
- $ipconfig_me = "ifconfig.me"
- $icanhazip = "icanhazip"
- $ident_me = "ident.me" fullword
- $showip_net = "showip.net" fullword
- $ifconfig_io = "ifconfig.io" fullword
- $ifconfig_co = "ifconfig.co" fullword
- $ipinfo = "ipinfo.io"
- $ipify_b = "ipify.org" base64
- $wtfismyip_b = "wtfismyip" base64
- $iplogger_b = "iplogger.org" base64
- $getjsonip_b = "getjsonip" base64
- $ipinfo_b = "ipinfo.io" base64
- $ipify_x = "ipify.org" xor(1-255)
- $wtfismyip_x = "wtfismyip" xor(1-255)
- $iplogger_x = "iplogger.org" xor(1-255)
- $getjsonip_x = "getjsonip" xor(1-255)
- $ipinfo_x = "ipinfo.io" xor(1-255)
-
- condition:
- any of them
-}
-
rule discord_exfil: critical {
meta:
description = "exfiltrates data via discord webhook"
condition:
- filesize < 100MB and discord_bot and iplookup_website_value_copy
+ filesize < 100MB and discord_bot and iplookup_website
}
diff --git a/rules/exfil/nodejs.yara b/rules/exfil/nodejs.yara
index 7c3d23044..1c059f4b3 100644
--- a/rules/exfil/nodejs.yara
+++ b/rules/exfil/nodejs.yara
@@ -1,3 +1,5 @@
+include "rules/global.yara"
+
import "math"
rule nodejs_sysinfoexfil: high {
@@ -130,31 +132,6 @@ rule post_hardcoded_hardcoded_host_os: high {
filesize < 256KB and any of ($ref*) and $post and ((math.abs(@ref - @post) <= 128) or ((math.abs(@ref2 - @post) <= 128))) and $os
}
-private rule nodejs_iplookup_website: high {
- meta:
- description = "public service to discover external IP address"
-
- strings:
- $ipify = /ipify\.org{0,1}/
- $wtfismyip = "wtfismyip"
- $iplogger = "iplogger.org"
- $getjsonip = "getjsonip"
- $ipconfig_me = "ifconfig.me"
- $icanhazip = "icanhazip"
- $grabify = "grabify.link"
- $ident_me = "ident.me" fullword
- $showip_net = "showip.net" fullword
- $ifconfig_io = "ifconfig.io" fullword
- $ifconfig_co = "ifconfig.co" fullword
- $ipinfo = "ipinfo.io"
- $check_ip = "checkip.amazonaws.com"
-
- $not_pypi_index = "testpack-id-lb001"
-
- condition:
- filesize < 250MB and any of them and none of ($not*)
-}
-
rule get_hardcoded_hardcoded_host_os: critical {
meta:
description = "leaks host information to a hardcoded host"
@@ -168,5 +145,5 @@ rule get_hardcoded_hardcoded_host_os: critical {
$i_os_userinfo = "os.userInfo"
condition:
- filesize < 256KB and $ref and (any of ($i*) or nodejs_iplookup_website)
+ filesize < 256KB and $ref and (any of ($i*) or iplookup_website)
}
diff --git a/rules/exfil/npm.yara b/rules/exfil/npm.yara
index 504ddf422..09f747ca3 100644
--- a/rules/exfil/npm.yara
+++ b/rules/exfil/npm.yara
@@ -1,17 +1,4 @@
-private rule package_scripts {
- strings:
- $npm_name = /"name":/
- $npm_version = /"version":/
- $npm_description = /"description":/
- $npm_lint = /"lint":/
- $npm_test = /"test":/
- $npm_postversion = /"postversion":/
- $npm_postinstall = /"postinstall":/
- $scripts = /"scripts":/
-
- condition:
- filesize < 32KB and 3 of ($npm*) and $scripts
-}
+include "rules/global.yara"
rule npm_fetcher: high {
meta:
diff --git a/rules/exfil/oauth.yara b/rules/exfil/oauth.yara
index ac5c1f723..ff7e524dd 100644
--- a/rules/exfil/oauth.yara
+++ b/rules/exfil/oauth.yara
@@ -1,12 +1,4 @@
-private rule post_json {
- strings:
- $json = "application/json"
- $POST = "POST"
- $encode_stringify = "JSON.stringify"
-
- condition:
- $json and $POST and any of ($encode*)
-}
+include "rules/global.yara"
rule possible_oauth_stealer: high {
meta:
diff --git a/rules/false_positives/py_hatch.yara b/rules/false_positives/py_hatch.yara
index 3c0f1f9e4..6f54ea0f6 100644
--- a/rules/false_positives/py_hatch.yara
+++ b/rules/false_positives/py_hatch.yara
@@ -2,6 +2,7 @@ rule migrate_py: override {
meta:
description = "migrate.py"
setuptools_eval_high = "medium"
+ setuptools_cmd_exec = "medium"
strings:
$env = "'_HATCHLING_PORT_ADD_'"
diff --git a/rules/false_positives/setuptools.yara b/rules/false_positives/setuptools.yara
index 510c127ae..252000c5b 100644
--- a/rules/false_positives/setuptools.yara
+++ b/rules/false_positives/setuptools.yara
@@ -2,6 +2,7 @@ rule setuptools_namespaces: override {
meta:
description = "namespaces.py"
setuptools_exec_high = "low"
+ setuptools_eval_high = "low"
strings:
$func1 = "def iter_namespace_pkgs("
diff --git a/rules/fs/path/applications.yara b/rules/fs/path/applications.yara
index e9ef9ebb4..7f01fceb3 100644
--- a/rules/fs/path/applications.yara
+++ b/rules/fs/path/applications.yara
@@ -1,3 +1,5 @@
+include "rules/global.yara"
+
rule app_path: medium {
meta:
description = "references hardcoded application path"
@@ -9,16 +11,6 @@ rule app_path: medium {
any of them
}
-private rule applicatons_macho {
- strings:
- $not_jar = "META-INF/"
- $not_dwarf = "_DWARF"
- $not_kext = "_.SYMDEF SORTED"
-
- condition:
- (uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962 or uint32(0) == 3405691583 or uint32(0) == 3216703178) and none of ($not*)
-}
-
rule macho_app_path: high {
meta:
description = "references hardcoded application path"
@@ -28,7 +20,7 @@ rule macho_app_path: high {
$ref = /\/Applications\/.{0,32}\.app\/Contents\/MacOS\/[\w \.\-]{0,32}/
condition:
- applicatons_macho and any of them
+ specific_macho and any of them
}
rule mac_applications: medium {
@@ -40,5 +32,5 @@ rule mac_applications: medium {
$ref = "/Applications" fullword
condition:
- applicatons_macho and any of them
+ specific_macho and any of them
}
diff --git a/rules/global.yara b/rules/global.yara
new file mode 100644
index 000000000..25f0e238d
--- /dev/null
+++ b/rules/global.yara
@@ -0,0 +1,320 @@
+import "elf"
+
+private rule binary {
+ condition:
+ filesize < 40MB and (uint32(0) == 1179403647 or uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962)
+}
+
+private rule bundled_glibc {
+ meta:
+ description = "includes bundled copy of glibc"
+ filetypes = "elf,so"
+
+ strings:
+ $glibc_private = "GLIBC_PRIVATE"
+ $glibc_tunables = "GLIBC_TUNABLES"
+ $setup_vdso = "setup_vdso"
+
+ condition:
+ filesize > 1024 and filesize < 25MB and elf.type == elf.ET_EXEC and uint32(0) == 1179403647 and all of them
+}
+
+private rule bundled_openssl {
+ meta:
+ description = "includes bundled copy of OpenSSL"
+ filetypes = "elf,so"
+
+ strings:
+ $ref = "OpenSSL/"
+ $aes_part = "AES part of OpenSSL"
+ $montgomery = "Montgomery Multiplication for x86_64, CRYPTOGAMS"
+ $rc4 = "RC4 for x86_64, CRYPTOGAMS"
+
+ condition:
+ filesize > 1024 and filesize < 150MB and elf.type == elf.ET_EXEC and uint32(0) == 1179403647 and any of them
+}
+
+private rule container_managers {
+ strings:
+ $containerd = "github.com/containerd/containerd"
+ $systemd = "SYSTEMD_PROC_CMDLINE"
+ $snapd = "snapcore/snapd"
+
+ condition:
+ any of them
+}
+
+private rule elf_or_macho {
+ condition:
+ uint32(0) == 1179403647 or (uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962 or uint32(0) == 3405691583 or uint32(0) == 3216703178)
+}
+
+private rule exfil {
+ strings:
+ $f_app_json = "application/json"
+ $f_post = "requests.post"
+ $f_nsurl = "NSURLRequest"
+ $f_curl = /curl.{0,32}-X POST/
+
+ $not_requests_utils = "requests.utils"
+
+ condition:
+ filesize < 512KB and any of ($f*) and none of ($not*)
+}
+
+private rule iplookup_website {
+ meta:
+ description = "public service to discover external IP address"
+
+ strings:
+ $ipify = "ipify.org"
+ $wtfismyip = "wtfismyip"
+ $iplogger = "iplogger.org"
+ $getjsonip = "getjsonip"
+ $ipconfig_me = "ifconfig.me"
+ $icanhazip = "icanhazip"
+ $ident_me = "ident.me" fullword
+ $showip_net = "showip.net" fullword
+ $ifconfig_io = "ifconfig.io" fullword
+ $ifconfig_co = "ifconfig.co" fullword
+ $ipinfo = "ipinfo.io"
+ $ipify_b = "ipify.org" base64
+ $wtfismyip_b = "wtfismyip" base64
+ $iplogger_b = "iplogger.org" base64
+ $getjsonip_b = "getjsonip" base64
+ $ipinfo_b = "ipinfo.io" base64
+ $ipify_x = "ipify.org" xor(1-255)
+ $wtfismyip_x = "wtfismyip" xor(1-255)
+ $iplogger_x = "iplogger.org" xor(1-255)
+ $getjsonip_x = "getjsonip" xor(1-255)
+ $ipinfo_x = "ipinfo.io" xor(1-255)
+
+ $not_pypi_index = "testpack-id-lb001"
+
+ condition:
+ filesize < 250MB and any of them and none of ($not*)
+}
+
+private rule legal_license {
+ strings:
+ $ = "using, exploiting or modifying the Software"
+ $ = "exploit the Information commercially"
+ $ = "otherwise exploited by anyone for any purpose"
+
+ condition:
+ any of them
+}
+
+private rule local_cd {
+ strings:
+ $cd = /cd [a-z]{4,12}; \.\//
+
+ condition:
+ any of them
+}
+
+private rule macho {
+ condition:
+ (uint32(0) == 4277009102
+ or uint32(0) == 3472551422
+ or uint32(0) == 4277009103
+ or uint32(0) == 3489328638
+ or uint32(0) == 3405691582
+ or uint32(0) == 3199925962
+ or uint32(0) == 3405691583
+ or uint32(0) == 3216703178)
+}
+
+private rule normal_elf {
+ condition:
+ filesize < 64MB and uint32(0) == 1179403647
+}
+
+private rule obfuscate {
+ strings:
+ $b64decode = "b64decode"
+ $base64 = "base64"
+ $codecs = "codecs.decode"
+ $x_decode = /\w{0,16}XorDecode[\w]{0,32}/
+ $x_encode = /\w{0,16}XorEncode[\w]{0,32}/
+ $x_file = /\w{0,16}XorFile[\w]{0,32}/
+ $x_decode_ = /\w{0,16}xor_decode[\w]{0,32}/
+ $x_encode_ = /\w{0,16}xor_encode[\w]{0,32}/
+ $x_file_ = /\w{0,16}xor_file[\w]{0,32}/
+
+ condition:
+ filesize < 512KB and any of them
+}
+
+private rule package_scripts {
+ strings:
+ $npm_name = /"name":/
+ $npm_version = /"version":/
+ $npm_description = /"description":/
+ $npm_lint = /"lint":/
+ $npm_test = /"test":/
+ $npm_postversion = /"postversion":/
+ $npm_postinstall = /"postinstall":/
+ $scripts = /"scripts":/
+
+ condition:
+ filesize < 32KB and 3 of ($npm*) and $scripts
+}
+
+private rule post_json {
+ strings:
+ $json = "application/json"
+ $POST = "POST"
+ $encode_stringify = "JSON.stringify"
+
+ condition:
+ $json and $POST and any of ($encode*)
+}
+
+private rule py_fetcher {
+ meta:
+ description = "fetches content"
+ filetypes = "py"
+
+ strings:
+ $http_requests = "requests.get" fullword
+ $http_requests_post = "requests.post" fullword
+ $http_urllib = "urllib.request" fullword
+ $http_urlopen = "urlopen" fullword
+ $git_git = /git.Git\(.{0,64}/
+ $http_curl = "curl" fullword
+ $http_wget = "wget" fullword
+
+ condition:
+ any of them
+}
+
+private rule py_runner {
+ meta:
+ description = "runs programs"
+ filetypes = "py"
+
+ strings:
+ $os_system = /os.system\([\"\'\w\ \-\)\/]{0,64}/
+ $os_startfile = /os.startfile\([\"\'\w\ \-\)\/]{0,64}/
+ $os_popen = /os.spopen\([\"\'\w\ \-\)\/]{0,64}/
+ $subprocess = /subprocess.\w{1,32}\([\"\'\/\w\ \-\)]{0,64}/
+ $system = /system\([\"\'\w\ \-\)\/]{0,64}/
+
+ condition:
+ any of them
+}
+
+private rule python_setup {
+ meta:
+ filetypes = "py"
+
+ strings:
+ $if_distutils = /from distutils.core import .{0,32}setup/
+ $if_setuptools = /from setuptools import .{0,32}setup/
+ $i_setuptools = "import setuptools"
+ $setup = "setup("
+
+ $not_setup_example = ">>> setup("
+ $not_setup_todict = "setup(**config.todict()"
+ $not_import_quoted = "\"from setuptools import setup"
+ $not_setup_quoted = "\"setup(name="
+ $not_distutils = "from distutils.errors import"
+ $not_numba = "https://github.com/numba/numba"
+
+ $not_hopper1 = "PACKAGE_NAME = \"flashattn-hopper\""
+ $not_hopper2 = "check_if_cuda_home_none(\"--fahopper\")"
+ $not_hopper3 = "name=\"flashattn_hopper_cuda\","
+
+ condition:
+ filesize < 131072 and $setup and any of ($i*) and none of ($not*)
+}
+
+private rule sensitive_log_files {
+ strings:
+ $wtmp = "/var/log/wtmp"
+ $secure = "/var/log/secure"
+ $cron = "/var/log/cron"
+ $iptables = "/var/log/iptables.log"
+ $auth = "/var/log/auth.log"
+ $cron_log = "/var/log/cron.log"
+ $httpd = "/var/log/httpd"
+ $syslog = "/var/log/syslog"
+ $btmp = "/var/log/btmp"
+ $lastlog = "/var/log/lastlog"
+ $run_log = "/run/log/"
+ $mail_log = "/var/spool/mail/root"
+
+ condition:
+ filesize < 16KB and 2 of them
+}
+
+private rule small_binary {
+ condition:
+ filesize < 10MB and (uint32(0) == 1179403647 or uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962)
+}
+
+private rule small_elf {
+ condition:
+ filesize < 400KB and uint32(0) == 1179403647
+}
+
+private rule small_elf_or_macho {
+ condition:
+ filesize > 1MB and filesize < 8MB and (uint32(0) == 1179403647 or uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962)
+}
+
+private rule small_macho {
+ condition:
+ filesize < 64MB and (uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962)
+}
+
+private rule specific_macho {
+ strings:
+ $not_jar = "META-INF/"
+ $not_dwarf = "_DWARF"
+ $not_kext = "_.SYMDEF SORTED"
+
+ condition:
+ (uint32(0) == 4277009102
+ or uint32(0) == 3472551422
+ or uint32(0) == 4277009103
+ or uint32(0) == 3489328638
+ or uint32(0) == 3405691582
+ or uint32(0) == 3199925962
+ or uint32(0) == 3405691583
+ or uint32(0) == 3216703178)
+ and none of ($not*)
+}
+
+private rule stub_macho {
+ strings:
+ $stub_helper = "__stub_helper"
+
+ condition:
+ filesize < 1MB and (uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962) and $stub_helper
+}
+
+private rule ufw_tool {
+ strings:
+ $not_route = "route-insert"
+ $not_statusverbose = "statusverbose"
+ $not_enables_the = "enables the"
+ $not_enable_the = "enable the"
+ $not_enable = "ufw enable"
+
+ condition:
+ filesize < 256KB and any of them
+}
+
+private rule wordlist {
+ strings:
+ $scorpion = "scorpion"
+ $superman = "superman"
+ $porsche = "porsche"
+ $cardinal = "cardinal"
+ $wombat = "wombat"
+
+ condition:
+ filesize < 100MB and 3 of them
+}
diff --git a/rules/impact/degrade/firewall.yara b/rules/impact/degrade/firewall.yara
index f4c589a03..f9e1b7ad6 100644
--- a/rules/impact/degrade/firewall.yara
+++ b/rules/impact/degrade/firewall.yara
@@ -1,3 +1,5 @@
+include "rules/global.yara"
+
import "math"
rule selinux_firewall: high linux {
@@ -21,18 +23,6 @@ rule selinux_firewall: high linux {
filesize < 1MB and $selinux and any of ($f*) and none of ($not*)
}
-private rule ufw_tool {
- strings:
- $not_route = "route-insert"
- $not_statusverbose = "statusverbose"
- $not_enables_the = "enables the"
- $not_enable_the = "enable the"
- $not_enable = "ufw enable"
-
- condition:
- filesize < 256KB and any of them
-}
-
rule ufw_disable_word: high {
meta:
description = "disables ufw firewall"
diff --git a/rules/impact/exploit/breakout.yara b/rules/impact/exploit/breakout.yara
index 8566fd40c..26a61ec29 100644
--- a/rules/impact/exploit/breakout.yara
+++ b/rules/impact/exploit/breakout.yara
@@ -1,12 +1,4 @@
-private rule container_managers {
- strings:
- $containerd = "github.com/containerd/containerd"
- $systemd = "SYSTEMD_PROC_CMDLINE"
- $snapd = "snapcore/snapd"
-
- condition:
- any of them
-}
+include "rules/global.yara"
rule probable_container_breakout: high linux {
meta:
diff --git a/rules/impact/exploit/exploit.yara b/rules/impact/exploit/exploit.yara
index 7d86335e6..2ace17c4e 100644
--- a/rules/impact/exploit/exploit.yara
+++ b/rules/impact/exploit/exploit.yara
@@ -1,12 +1,4 @@
-private rule legal_license {
- strings:
- $ = "using, exploiting or modifying the Software"
- $ = "exploit the Information commercially"
- $ = "otherwise exploited by anyone for any purpose"
-
- condition:
- any of them
-}
+include "rules/global.yara"
rule exploitation: medium {
meta:
diff --git a/rules/impact/remote_access/backdoor.yara b/rules/impact/remote_access/backdoor.yara
index 1a765860c..965a6393a 100644
--- a/rules/impact/remote_access/backdoor.yara
+++ b/rules/impact/remote_access/backdoor.yara
@@ -1,14 +1,4 @@
-private rule wordlist {
- strings:
- $scorpion = "scorpion"
- $superman = "superman"
- $porsche = "porsche"
- $cardinal = "cardinal"
- $wombat = "wombat"
-
- condition:
- filesize < 100MB and 3 of them
-}
+include "rules/global.yara"
rule backdoor: medium {
meta:
@@ -104,11 +94,6 @@ rule commands: high {
all of them
}
-private rule backdoor_small_macho {
- condition:
- filesize < 1MB and (uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962)
-}
-
rule macho_backdoor_libc_signature: high {
meta:
description = "executes libc functions common to backdoors"
@@ -150,7 +135,7 @@ rule macho_backdoor_libc_signature: high {
$not_java = "java/lang"
condition:
- backdoor_small_macho and #word_with_spaces < 10 and #libc_call < 74 and 95 % of ($f*) and none of ($not*)
+ small_macho and #word_with_spaces < 10 and #libc_call < 74 and 95 % of ($f*) and none of ($not*)
}
rule minecraft_load_fetch_class_backdoor: critical {
diff --git a/rules/impact/remote_access/py_setuptools.yara b/rules/impact/remote_access/py_setuptools.yara
index 4e7213023..27faeab1d 100644
--- a/rules/impact/remote_access/py_setuptools.yara
+++ b/rules/impact/remote_access/py_setuptools.yara
@@ -1,25 +1,6 @@
-import "math"
-
-private rule remote_access_pythonSetup {
- strings:
- $if_distutils = /from distutils.core import .{0,32}setup/
- $if_setuptools = /from setuptools import .{0,32}setup/
- $i_setuptools = "import setuptools"
- $setup = "setup("
-
- $not_setup_example = ">>> setup("
- $not_setup_todict = "setup(**config.todict()"
- $not_import_quoted = "\"from setuptools import setup"
- $not_setup_quoted = "\"setup(name="
- $not_distutils = "from distutils.errors import"
+include "rules/global.yara"
- $not_hopper1 = "PACKAGE_NAME = \"flashattn-hopper\""
- $not_hopper2 = "check_if_cuda_home_none(\"--fahopper\")"
- $not_hopper3 = "name=\"flashattn_hopper_cuda\","
-
- condition:
- filesize < 128KB and $setup and any of ($i*) in (0..1024) and none of ($not*)
-}
+import "math"
rule setuptools_oslogin: medium {
meta:
@@ -30,7 +11,7 @@ rule setuptools_oslogin: medium {
$oslogin = "os.login()"
condition:
- remote_access_pythonSetup and any of them
+ python_setup and any of them
}
rule setuptools_homedir: high {
@@ -42,7 +23,7 @@ rule setuptools_homedir: high {
$oslogin = "C:\\Users\\.{0,64}os.login()"
condition:
- remote_access_pythonSetup and any of them
+ python_setup and any of them
}
rule setuptools_cmd_exec: high {
@@ -62,7 +43,7 @@ rule setuptools_cmd_exec: high {
$not_twine_upload = "twine upload dist/*"
condition:
- remote_access_pythonSetup and any of ($f*) and none of ($not*)
+ python_setup and any of ($f*) and none of ($not*)
}
rule setuptools_cmd_exec_start: critical {
@@ -77,7 +58,7 @@ rule setuptools_cmd_exec_start: critical {
$f_subprocess = /subprocess.\w{0,32}\([f\"\']{0,2}start[,'" ]{1,3}.{0,64}/
condition:
- remote_access_pythonSetup and any of ($f*)
+ python_setup and any of ($f*)
}
rule setuptools_eval: medium {
@@ -89,7 +70,7 @@ rule setuptools_eval: medium {
$f_eval = /eval\([\"\'\/\w\,\.\ \-\)\(]{1,64}\)/ fullword
condition:
- remote_access_pythonSetup and any of ($f*)
+ python_setup and any of ($f*)
}
rule setuptools_eval_high: high {
@@ -102,7 +83,7 @@ rule setuptools_eval_high: high {
$not_namespaced = /eval\([\w\.\(\)\"\/\']{4,16}, [a-z]{1,6}[,\)]/
condition:
- remote_access_pythonSetup and any of ($f*) and none of ($not*)
+ python_setup and any of ($f*) and none of ($not*)
}
rule setuptools_exec: medium {
@@ -116,7 +97,7 @@ rule setuptools_exec: medium {
$not_hopper = "with open(\" hopper /__version__.py\") as fp:"
condition:
- remote_access_pythonSetup and any of ($f*) and none of ($not*)
+ python_setup and any of ($f*) and none of ($not*)
}
rule setuptools_exec_high: high {
@@ -138,7 +119,7 @@ rule setuptools_exec_high: high {
$not_namespaced = /exec\([\w\.\(\)\"\/\']{4,16}, [a-z]{1,6}[,\)]/
condition:
- remote_access_pythonSetup and any of ($f*) and none of ($not*)
+ python_setup and any of ($f*) and none of ($not*)
}
rule setuptools_b64decode: suspicious {
@@ -150,7 +131,7 @@ rule setuptools_b64decode: suspicious {
$base64 = "b64decode"
condition:
- remote_access_pythonSetup and any of them
+ python_setup and any of them
}
rule setuptools_preinstall: suspicious {
@@ -165,7 +146,7 @@ rule setuptools_preinstall: suspicious {
$f_pre_install = "from pre_install"
condition:
- remote_access_pythonSetup and any of them
+ python_setup and any of them
}
rule setuptools_b64encode: suspicious {
@@ -177,7 +158,7 @@ rule setuptools_b64encode: suspicious {
$base64 = "b64encode"
condition:
- remote_access_pythonSetup and any of them
+ python_setup and any of them
}
rule setuptools_exec_powershell: critical windows {
@@ -206,7 +187,7 @@ rule setuptools_os_path_exists: medium {
$not_pyspark_ioerror = "\"Failed to load PySpark version file for packaging. You must be in Spark's python dir.\""
condition:
- remote_access_pythonSetup and $ref and none of ($not*)
+ python_setup and $ref and none of ($not*)
}
rule setuptools_excessive_bitwise_math: critical {
@@ -218,5 +199,5 @@ rule setuptools_excessive_bitwise_math: critical {
$x = /\-{0,1}\d{1,8} \<\< \-{0,1}\d{1,8}/
condition:
- remote_access_pythonSetup and #x > 20
+ python_setup and #x > 20
}
diff --git a/rules/impact/wipe/crypto.yara b/rules/impact/wipe/crypto.yara
index 71d8670db..b497f37f4 100644
--- a/rules/impact/wipe/crypto.yara
+++ b/rules/impact/wipe/crypto.yara
@@ -1,7 +1,4 @@
-private rule crypto_elf_or_macho {
- condition:
- uint32(0) == 1179403647 or (uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962 or uint32(0) == 3405691583 or uint32(0) == 3216703178)
-}
+include "rules/global.yara"
rule uname_hostname_encrypt_wipe_kill_small: high {
meta:
@@ -17,7 +14,7 @@ rule uname_hostname_encrypt_wipe_kill_small: high {
$hostname = "hostname" fullword
condition:
- filesize < 2MB and crypto_elf_or_macho and all of them
+ filesize < 2MB and elf_or_macho and all of them
}
rule uname_hostname_encrypt_wipe_kill: medium {
@@ -34,5 +31,5 @@ rule uname_hostname_encrypt_wipe_kill: medium {
$hostname = "hostname" fullword
condition:
- filesize < 20MB and crypto_elf_or_macho and all of them
+ filesize < 20MB and elf_or_macho and all of them
}
diff --git a/rules/malware/family/amos.yara b/rules/malware/family/amos.yara
index 650f1ab93..7ebe10d7a 100644
--- a/rules/malware/family/amos.yara
+++ b/rules/malware/family/amos.yara
@@ -1,14 +1,6 @@
-import "math"
-
-private rule amos_macho {
- strings:
- $not_jar = "META-INF/"
- $not_dwarf = "_DWARF"
- $not_kext = "_.SYMDEF SORTED"
+include "rules/global.yara"
- condition:
- (uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962 or uint32(0) == 3405691583 or uint32(0) == 3216703178) and none of ($not*)
-}
+import "math"
rule amos_magic_var: critical macos {
meta:
@@ -27,7 +19,7 @@ rule amos_magic_var: critical macos {
$word_with_spaces = /[a-z]{2,} [a-z]{2,}/
condition:
- filesize > 100KB and filesize < 600KB and amos_macho and $magic and $header and $main and all of ($f*) and #word_with_spaces < 3
+ filesize > 100KB and filesize < 600KB and specific_macho and $magic and $header and $main and all of ($f*) and #word_with_spaces < 3
}
rule amos_base32: critical macos {
@@ -44,7 +36,7 @@ rule amos_base32: critical macos {
$at_exit = "@___cxa_atexit"
condition:
- filesize > 40KB and filesize < 2MB and amos_macho and all of them
+ filesize > 40KB and filesize < 2MB and specific_macho and all of them
}
rule maybe_amos: high macos {
@@ -66,7 +58,7 @@ rule maybe_amos: high macos {
$not_release = "@_CFRelease" fullword
condition:
- filesize > 190KB and filesize < 400KB and amos_macho and all of them and none of ($not*) and math.entropy(1, filesize) >= 4
+ filesize > 190KB and filesize < 400KB and specific_macho and all of them and none of ($not*) and math.entropy(1, filesize) >= 4
}
rule maybe_amos_hex: high macos {
@@ -90,5 +82,5 @@ rule maybe_amos_hex: high macos {
$x = /0x[\dabcdefABCDEF]{2,8}/
condition:
- filesize > 190KB and filesize < 400KB and amos_macho and 95 % of ($f*) and math.entropy(20000, 50000) >= 4.5 and #x > 64
+ filesize > 190KB and filesize < 400KB and specific_macho and 95 % of ($f*) and math.entropy(20000, 50000) >= 4.5 and #x > 64
}
diff --git a/rules/malware/family/clapzok.yara b/rules/malware/family/clapzok.yara
index cda522a93..12e622cb0 100644
--- a/rules/malware/family/clapzok.yara
+++ b/rules/malware/family/clapzok.yara
@@ -1,7 +1,4 @@
-private rule is_macho {
- condition:
- (uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962 or uint32(0) == 3405691583 or uint32(0) == 3216703178)
-}
+include "rules/global.yara"
rule clapzok_macho: critical {
meta:
@@ -13,5 +10,5 @@ rule clapzok_macho: critical {
$ref = "SfcIsFileProtected"
condition:
- filesize < 10MB and is_macho and $ref in (filesize - 2200..filesize - 100)
+ filesize < 10MB and specific_macho and $ref in (filesize - 2200..filesize - 100)
}
diff --git a/rules/malware/family/poseidon_stealer.yara b/rules/malware/family/poseidon_stealer.yara
index 82952ffa5..1c235e913 100644
--- a/rules/malware/family/poseidon_stealer.yara
+++ b/rules/malware/family/poseidon_stealer.yara
@@ -1,14 +1,6 @@
-import "math"
-
-private rule poseidon_macho {
- strings:
- $not_jar = "META-INF/"
- $not_dwarf = "_DWARF"
- $not_kext = "_.SYMDEF SORTED"
+include "rules/global.yara"
- condition:
- (uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962 or uint32(0) == 3405691583 or uint32(0) == 3216703178) and none of ($not*)
-}
+import "math"
rule poseidon: high macos {
meta:
@@ -24,7 +16,7 @@ rule poseidon: high macos {
$ve = "vector" fullword
condition:
- filesize > 190KB and filesize < 400KB and poseidon_macho and all of them and math.entropy(20000, 50000) >= 2.5
+ filesize > 190KB and filesize < 400KB and specific_macho and all of them and math.entropy(20000, 50000) >= 2.5
}
rule poseidon_url: high macos {
@@ -37,5 +29,5 @@ rule poseidon_url: high macos {
$ref = "https://forked-project.com/check_updates"
condition:
- filesize > 190KB and filesize < 400KB and poseidon_macho and all of them
+ filesize > 190KB and filesize < 400KB and specific_macho and all of them
}
diff --git a/rules/net/download/fetch.yara b/rules/net/download/fetch.yara
index 0ffa22c31..77f37c926 100644
--- a/rules/net/download/fetch.yara
+++ b/rules/net/download/fetch.yara
@@ -1,3 +1,5 @@
+include "rules/global.yara"
+
rule curl_value: medium {
meta:
description = "Invokes curl"
@@ -76,16 +78,6 @@ rule curl_download_ip: critical {
any of them
}
-private rule fetch_macho {
- condition:
- uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962 or uint32(0) == 3405691583 or uint32(0) == 3216703178
-}
-
-private rule fetch_elf {
- condition:
- uint32(0) == 1179403647
-}
-
rule fetch_tool: medium {
meta:
description = "calls a URL fetch tool"
@@ -117,7 +109,7 @@ rule binary_calls_fetch_tool: high {
$not_tftp_err = "tftp error"
condition:
- filesize < 10MB and (fetch_elf or fetch_macho) and any of ($t*) and none of ($not*)
+ filesize < 10MB and (elf_or_macho) and any of ($t*) and none of ($not*)
}
rule curl_agent_val: high {
diff --git a/rules/sus/compiler.yara b/rules/sus/compiler.yara
index 08a18b2f7..de73884db 100644
--- a/rules/sus/compiler.yara
+++ b/rules/sus/compiler.yara
@@ -1,3 +1,5 @@
+include "rules/global.yara"
+
rule archaic_gcc: medium {
meta:
description = "built by an ancient version of GCC"
@@ -28,12 +30,6 @@ rule small_opaque_archaic_gcc: high linux {
filesize < 30KB and $gcc_v4 and $fork in (1000..3000) and none of ($not*) and #word_with_spaces < 15
}
-private rule binary {
- condition:
- // matches ELF or machO binary
- filesize < 40MB and (uint32(0) == 1179403647 or uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962)
-}
-
rule multiple_gcc: medium {
meta:
description = "built with multiple versions of GCC"
diff --git a/rules/sus/entitlement.yara b/rules/sus/entitlement.yara
index ca2e4ba68..07ed3bf04 100644
--- a/rules/sus/entitlement.yara
+++ b/rules/sus/entitlement.yara
@@ -1,12 +1,4 @@
-private rule entitlement_macho {
- strings:
- $not_jar = "META-INF/"
- $not_dwarf = "_DWARF"
- $not_kext = "_.SYMDEF SORTED"
-
- condition:
- (uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962 or uint32(0) == 3405691583 or uint32(0) == 3216703178) and none of ($not*)
-}
+include "rules/global.yara"
rule com_apple_get_task_allow: medium {
meta:
@@ -18,5 +10,5 @@ rule com_apple_get_task_allow: medium {
$true = ""
condition:
- entitlement_macho and all of them
+ specific_macho and all of them
}
diff --git a/tests/python/2024.coloredtxt/base64_payload3.py.simple b/tests/python/2024.coloredtxt/base64_payload3.py.simple
index 3a290cc7c..0c2179029 100644
--- a/tests/python/2024.coloredtxt/base64_payload3.py.simple
+++ b/tests/python/2024.coloredtxt/base64_payload3.py.simple
@@ -1,5 +1,6 @@
# python/2024.coloredtxt/base64_payload3.py: critical
c2/addr/url: high
+c2/tool_transfer/python: high
data/base64/decode: medium
data/encoding/base64: low
discover/system/platform: medium
diff --git a/tests/python/clean/hatch/migrate.py.simple b/tests/python/clean/hatch/migrate.py.simple
index 448d31422..bb81c619b 100644
--- a/tests/python/clean/hatch/migrate.py.simple
+++ b/tests/python/clean/hatch/migrate.py.simple
@@ -2,11 +2,11 @@
discover/system/environment: medium
exec/imports/python: low
exec/program: medium
-false-positives/py_hatch: low
fs/directory/list: low
fs/file/open: low
fs/symlink_resolve: low
fs/tempdir/TEMP: low
+impact/remote_access/py_setuptools: medium
net/download: medium
os/env/get: low
os/fd/read: low
diff --git a/tests/python/clean/setuptools/namespaces.py.simple b/tests/python/clean/setuptools/namespaces.py.simple
index 28aedf1ae..6f9e2b1a8 100644
--- a/tests/python/clean/setuptools/namespaces.py.simple
+++ b/tests/python/clean/setuptools/namespaces.py.simple
@@ -1,5 +1,5 @@
# python/clean/setuptools/namespaces.py: low
data/encoding/json_encode: low
exec/imports/python: low
-false-positives/setuptools: low
fs/directory/create: low
+impact/remote_access/py_setuptools: low
From 059616da7b74e470bdbd8dbe03143e047c5c0fec Mon Sep 17 00:00:00 2001
From: egibs <20933572+egibs@users.noreply.github.com>
Date: Tue, 20 May 2025 11:16:55 -0500
Subject: [PATCH 2/3] Prefix global rules; fix include statements for tests
Signed-off-by: egibs <20933572+egibs@users.noreply.github.com>
---
.github/workflows/style.yaml | 4 +-
pkg/compile/compile.go | 59 ++++++++++++++++++-
rules/anti-behavior/random_behavior.yara | 4 +-
rules/anti-static/elf/entropy.yara | 10 ++--
rules/anti-static/macho/entropy.yara | 6 +-
rules/anti-static/macho/footer.yara | 4 +-
rules/anti-static/packer/aes.yara | 4 +-
rules/anti-static/unmarshal/marshal.yara | 4 +-
rules/c2/addr/ip.yara | 4 +-
rules/c2/addr/url.yara | 6 +-
rules/c2/tool_transfer/download.yara | 4 +-
rules/c2/tool_transfer/macos.yara | 4 +-
rules/c2/tool_transfer/python.yara | 20 +++----
rules/data/builtin/multiple.yara | 4 +-
rules/discover/multiple.yara | 4 +-
rules/discover/user/username-get.yara | 4 +-
.../indicator_blocking/hidden_window.yara | 4 +-
.../indicator_blocking/mask_exceptions.yara | 4 +-
rules/evasion/logging/wipe.yara | 6 +-
rules/evasion/net/hide_ports.yara | 4 +-
.../evasion/self_deletion/run_and_delete.yara | 4 +-
rules/exec/program/opaque.yara | 6 +-
rules/exec/shell/relative-semicolon.yara | 4 +-
rules/exfil/discord.yara | 4 +-
rules/exfil/nodejs.yara | 4 +-
rules/exfil/npm.yara | 12 ++--
rules/exfil/oauth.yara | 4 +-
rules/fs/path/applications.yara | 6 +-
rules/{ => global}/global.yara | 52 ++++++++--------
rules/impact/degrade/firewall.yara | 4 +-
rules/impact/exploit/breakout.yara | 6 +-
rules/impact/exploit/exploit.yara | 10 ++--
rules/impact/remote_access/backdoor.yara | 10 ++--
rules/impact/remote_access/py_setuptools.yara | 28 ++++-----
rules/impact/wipe/crypto.yara | 6 +-
rules/malware/family/amos.yara | 10 ++--
rules/malware/family/clapzok.yara | 4 +-
rules/malware/family/poseidon_stealer.yara | 6 +-
rules/net/download/fetch.yara | 4 +-
rules/sus/compiler.yara | 6 +-
rules/sus/entitlement.yara | 4 +-
41 files changed, 206 insertions(+), 151 deletions(-)
rename rules/{ => global}/global.yara (90%)
diff --git a/.github/workflows/style.yaml b/.github/workflows/style.yaml
index b2c3a0eed..52e689c7c 100644
--- a/.github/workflows/style.yaml
+++ b/.github/workflows/style.yaml
@@ -31,8 +31,8 @@ jobs:
- name: Install yara-x
run: |
- wget https://github.com/VirusTotal/yara-x/releases/download/v0.10.0/yara-x-v0.10.0-x86_64-unknown-linux-gnu.gzip -O yara-x.gzip
- tar -xzvf yara-x.gzip && mv yr /usr/local/bin/ && rm yara-x.gzip
+ wget https://github.com/VirusTotal/yara-x/releases/download/v0.15.0/yara-x-v0.15.0-x86_64-unknown-linux-gnu.gz -O yara-x.gz
+ tar -xzvf yara-x.gz && mv yr /usr/local/bin/ && rm yara-x.gz
- name: Verify yr installation
run: |
yr --version
diff --git a/pkg/compile/compile.go b/pkg/compile/compile.go
index fcee83549..8668751f3 100644
--- a/pkg/compile/compile.go
+++ b/pkg/compile/compile.go
@@ -4,9 +4,11 @@
package compile
import (
+ "bytes"
"context"
"fmt"
"io/fs"
+ "os"
"path/filepath"
"regexp"
"strings"
@@ -17,6 +19,11 @@ import (
yarax "github.com/VirusTotal/yara-x/go"
)
+const (
+ globalInclude = `include "rules/global/global.yara"`
+ globalPath = "rules/global/global.yara"
+)
+
var FS = rules.FS
// badRules are noisy 3rd party rules to silently disable.
@@ -159,16 +166,57 @@ func removeRules(data []byte, rulesToRemove []string) []byte {
return newlinePattern.ReplaceAll(modified, []byte("\n\n"))
}
+// findRoot locates the repository root on the fly.
+func findRoot(start string) string {
+ current := start
+ for {
+ next := filepath.Join(current, "rules")
+ if _, err := os.Stat(next); err == nil {
+ return current
+ }
+
+ parent := filepath.Dir(current)
+ if parent == current {
+ return ""
+ }
+
+ current = parent
+ }
+}
+
+// replaceGlobal updates the include string to reference the absolute path of rules/global/global.yara
+// by default, the relative path is valid for local compilations and builds done from the root of the repository,
+// but this is not valid for test files located in various directories.
+func replaceGlobal(data []byte, path string) []byte {
+ modified := data
+ if bytes.Contains(data, []byte(globalInclude)) {
+ modified = bytes.Replace(data, []byte(globalInclude), []byte(fmt.Sprintf(`include "%s"`, path)), 1)
+ }
+ return modified
+}
+
func Recursive(ctx context.Context, fss []fs.FS) (*yarax.Rules, error) {
if ctx.Err() != nil {
return nil, ctx.Err()
}
- yxc, err := yarax.NewCompiler(yarax.ConditionOptimization(true))
+ yxc, err := yarax.NewCompiler(yarax.ConditionOptimization(true), yarax.EnableIncludes(true))
if err != nil {
return nil, fmt.Errorf("yarax compiler: %w", err)
}
+ // use the current working directory to determine the root path
+ // this only needs to be done once
+ cwd, err := os.Getwd()
+ if err != nil {
+ return nil, err
+ }
+ abs, err := filepath.Abs(cwd)
+ if err != nil {
+ return nil, err
+ }
+ rootPath := findRoot(abs)
+
rulesToRemove := getRulesToRemove()
for _, root := range fss {
@@ -177,7 +225,11 @@ func Recursive(ctx context.Context, fss []fs.FS) (*yarax.Rules, error) {
return err
}
- if !d.IsDir() && (filepath.Ext(path) == ".yara" || filepath.Ext(path) == ".yar") {
+ if d.IsDir() {
+ return nil
+ }
+
+ if filepath.Ext(path) == ".yara" || filepath.Ext(path) == ".yar" {
bs, err := fs.ReadFile(root, path)
if err != nil {
return fmt.Errorf("readfile: %w", err)
@@ -185,6 +237,9 @@ func Recursive(ctx context.Context, fss []fs.FS) (*yarax.Rules, error) {
bs = removeRules(bs, rulesToRemove)
+ globalAbs := filepath.Join(rootPath, globalPath)
+ bs = replaceGlobal(bs, globalAbs)
+
yxc.NewNamespace(path)
if err := yxc.AddSource(string(bs), yarax.WithOrigin(path)); err != nil {
return fmt.Errorf("failed to parse %s: %v", path, err)
diff --git a/rules/anti-behavior/random_behavior.yara b/rules/anti-behavior/random_behavior.yara
index a49769f5f..1df6de7a1 100644
--- a/rules/anti-behavior/random_behavior.yara
+++ b/rules/anti-behavior/random_behavior.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
import "math"
@@ -12,7 +12,7 @@ rule setuptools_random: critical {
$not_easy_install = "pid = random.randint(0, sys.maxsize)"
condition:
- python_setup and $ref and none of ($not*)
+ global_python_setup and $ref and none of ($not*)
}
rule java_random: low {
diff --git a/rules/anti-static/elf/entropy.yara b/rules/anti-static/elf/entropy.yara
index 4e679db96..4d183da06 100644
--- a/rules/anti-static/elf/entropy.yara
+++ b/rules/anti-static/elf/entropy.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
import "math"
@@ -8,7 +8,7 @@ rule higher_elf_entropy_68: medium {
filetypes = "elf"
condition:
- normal_elf and math.entropy(1, filesize) >= 6.95
+ global_normal_elf and math.entropy(1, filesize) >= 6.95
}
rule normal_elf_high_entropy_7_4: high {
@@ -21,7 +21,7 @@ rule normal_elf_high_entropy_7_4: high {
$not_bazel = "BazelLogHandler"
condition:
- filesize < 30MB and normal_elf and math.entropy(1, filesize) >= 7.4 and none of ($not*)
+ filesize < 30MB and global_normal_elf and math.entropy(1, filesize) >= 7.4 and none of ($not*)
}
rule normal_elf_high_entropy_footer_7_4: high {
@@ -30,7 +30,7 @@ rule normal_elf_high_entropy_footer_7_4: high {
filetypes = "elf"
condition:
- normal_elf and math.entropy(filesize - 8192, filesize) >= 7.4
+ global_normal_elf and math.entropy(filesize - 8192, filesize) >= 7.4
}
rule normal_elf_high_entropy_footer_7_4_rc4: high {
@@ -43,5 +43,5 @@ rule normal_elf_high_entropy_footer_7_4_rc4: high {
$cmp_r_x_256 = { 48 81 f? 00 01 00 00 } // cmp {rbx, rcx, …}, 256
condition:
- filesize < 25MB and normal_elf and math.entropy(filesize - 8192, filesize) >= 7.4 and any of them
+ filesize < 25MB and global_normal_elf and math.entropy(filesize - 8192, filesize) >= 7.4 and any of them
}
diff --git a/rules/anti-static/macho/entropy.yara b/rules/anti-static/macho/entropy.yara
index 15956afef..f353046f1 100644
--- a/rules/anti-static/macho/entropy.yara
+++ b/rules/anti-static/macho/entropy.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
import "math"
@@ -8,7 +8,7 @@ rule higher_entropy_6_9: medium {
filetypes = "macho"
condition:
- small_macho and math.entropy(1, filesize) >= 6.9
+ global_small_macho and math.entropy(1, filesize) >= 6.9
}
rule high_entropy_7_2: high {
@@ -21,5 +21,5 @@ rule high_entropy_7_2: high {
$bin_java = "bin/java"
condition:
- small_macho and math.entropy(1, filesize) >= 7.2 and not $bin_java
+ global_small_macho and math.entropy(1, filesize) >= 7.2 and not $bin_java
}
diff --git a/rules/anti-static/macho/footer.yara b/rules/anti-static/macho/footer.yara
index 37d10d3e4..b2a0e0c4b 100644
--- a/rules/anti-static/macho/footer.yara
+++ b/rules/anti-static/macho/footer.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
import "math"
@@ -12,5 +12,5 @@ rule high_entropy_trailer: high {
$page_zero = "_PAGEZERO"
condition:
- filesize < 10MB and macho and $page_zero and math.entropy(filesize - 1024, filesize - 1) >= 4
+ filesize < 10MB and global_macho and $page_zero and math.entropy(filesize - 1024, filesize - 1) >= 4
}
diff --git a/rules/anti-static/packer/aes.yara b/rules/anti-static/packer/aes.yara
index 7fc3a8dc9..280c20fef 100644
--- a/rules/anti-static/packer/aes.yara
+++ b/rules/anti-static/packer/aes.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
import "math"
@@ -13,5 +13,5 @@ rule go_aes: high {
$decrypt = "NewCFBDecrypter"
condition:
- small_binary and math.entropy(1, filesize) >= 7 and all of them
+ global_small_binary and math.entropy(1, filesize) >= 7 and all of them
}
diff --git a/rules/anti-static/unmarshal/marshal.yara b/rules/anti-static/unmarshal/marshal.yara
index f17c28f4c..7c90f69ae 100644
--- a/rules/anti-static/unmarshal/marshal.yara
+++ b/rules/anti-static/unmarshal/marshal.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
import "math"
@@ -20,5 +20,5 @@ rule setuptools_py_marshal: suspicious {
filetypes = "py"
condition:
- python_setup and unmarshal_py_marshal
+ global_python_setup and unmarshal_py_marshal
}
diff --git a/rules/c2/addr/ip.yara b/rules/c2/addr/ip.yara
index 2ce46fcf0..75baa9bd8 100644
--- a/rules/c2/addr/ip.yara
+++ b/rules/c2/addr/ip.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule hardcoded_ip: medium {
meta:
@@ -45,7 +45,7 @@ rule bin_hardcoded_ip: high {
$not_2345 = "23.45.67.89"
condition:
- filesize < 12MB and elf_or_macho and 1 of ($sus_ip*) and none of ($not*)
+ filesize < 12MB and global_elf_or_macho and 1 of ($sus_ip*) and none of ($not*)
}
rule http_hardcoded_ip: high exfil {
diff --git a/rules/c2/addr/url.yara b/rules/c2/addr/url.yara
index 6acbaa5cf..36f28cf5d 100644
--- a/rules/c2/addr/url.yara
+++ b/rules/c2/addr/url.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
import "math"
@@ -82,7 +82,7 @@ rule binary_with_url: low {
$ref = /https*:\/\/[\w\.\/]{8,160}[\/\w\=\&]{0,32}/
condition:
- filesize < 150MB and elf_or_macho and $ref
+ filesize < 150MB and global_elf_or_macho and $ref
}
rule binary_url_with_question: high {
@@ -99,7 +99,7 @@ rule binary_url_with_question: high {
$not_mesibo = "https://api.mesibo.com/api.php?"
condition:
- filesize < 150MB and elf_or_macho and $ref and none of ($not*)
+ filesize < 150MB and global_elf_or_macho and $ref and none of ($not*)
}
rule script_url_with_question: high {
diff --git a/rules/c2/tool_transfer/download.yara b/rules/c2/tool_transfer/download.yara
index 696cace86..ada9603c9 100644
--- a/rules/c2/tool_transfer/download.yara
+++ b/rules/c2/tool_transfer/download.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule download_sites: high {
meta:
@@ -125,5 +125,5 @@ rule http_archive_url_higher: high {
$not_foo_bar = "http://foo/bar.tar"
condition:
- small_binary and any of ($ref*) and none of ($not*)
+ global_small_binary and any of ($ref*) and none of ($not*)
}
diff --git a/rules/c2/tool_transfer/macos.yara b/rules/c2/tool_transfer/macos.yara
index 964826d05..70c70683d 100644
--- a/rules/c2/tool_transfer/macos.yara
+++ b/rules/c2/tool_transfer/macos.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule macos_chflags_hidden: critical {
meta:
@@ -30,5 +30,5 @@ rule cocoa_bundle_dropper: critical {
$platform = "isPlatformOrVariantPlatformVersionAtLeast" fullword
condition:
- specific_macho and $shared and 5 of them
+ global_specific_macho and $shared and 5 of them
}
diff --git a/rules/c2/tool_transfer/python.yara b/rules/c2/tool_transfer/python.yara
index 3108dc42d..d5a59b4c6 100644
--- a/rules/c2/tool_transfer/python.yara
+++ b/rules/c2/tool_transfer/python.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule py_dropper: medium {
meta:
@@ -10,7 +10,7 @@ rule py_dropper: medium {
$write = "write("
condition:
- filesize < 16384 and $open and $write and py_fetcher and py_runner
+ filesize < 16384 and $open and $write and global_py_fetcher and global_py_runner
}
rule py_arch_dropper: medium {
@@ -33,7 +33,7 @@ rule py_arch_dropper: medium {
$exec_run = "run" fullword
condition:
- filesize < 1MB and any of ($os*) and any of ($arch*) and any of ($download*) and (any of ($exec*) or py_runner)
+ filesize < 1MB and any of ($os*) and any of ($arch*) and any of ($download*) and (any of ($exec*) or global_py_runner)
}
rule py_dropper_obfuscated: high {
@@ -48,7 +48,7 @@ rule py_dropper_obfuscated: high {
$ob_codecs = "codecs.decode"
condition:
- filesize < 16000 and $open and $write and any of ($ob_*) and py_fetcher and py_runner
+ filesize < 16000 and $open and $write and any of ($ob_*) and global_py_fetcher and global_py_runner
}
rule py_dropper_tiny: high {
@@ -61,7 +61,7 @@ rule py_dropper_tiny: high {
$write = "write("
condition:
- filesize < 900 and $open and $write and py_fetcher and py_runner
+ filesize < 900 and $open and $write and global_py_fetcher and global_py_runner
}
rule py_dropper_chmod: high {
@@ -77,7 +77,7 @@ rule py_dropper_chmod: high {
$val_770 = "770"
condition:
- filesize < 1MB and py_fetcher and py_runner and $chmod and any of ($val*)
+ filesize < 1MB and global_py_fetcher and global_py_runner and $chmod and any of ($val*)
}
rule setuptools_fetcher: suspicious {
@@ -86,7 +86,7 @@ rule setuptools_fetcher: suspicious {
filetypes = "py"
condition:
- python_setup and py_fetcher
+ global_python_setup and global_py_fetcher
}
rule setuptools_fetch_run: critical {
@@ -100,7 +100,7 @@ rule setuptools_fetch_run: critical {
$not_hopper3 = "name=\"flashattn_hopper_cuda\","
condition:
- setuptools_fetcher and py_runner and none of ($not*)
+ setuptools_fetcher and global_py_runner and none of ($not*)
}
rule setuptools_dropper: critical {
@@ -109,7 +109,7 @@ rule setuptools_dropper: critical {
filetypes = "py"
condition:
- python_setup and py_dropper
+ global_python_setup and py_dropper
}
rule dropper_imports: high {
@@ -140,6 +140,6 @@ rule oneline: high {
$urlopen = /\.write\(.{0,8}urlopen\("http.{0,128}\"\).read\(\)/
condition:
- filesize < 512KB and any of them and py_fetcher and py_runner
+ filesize < 512KB and any of them and global_py_fetcher and global_py_runner
}
diff --git a/rules/data/builtin/multiple.yara b/rules/data/builtin/multiple.yara
index fbbffedea..9d6a2a3af 100644
--- a/rules/data/builtin/multiple.yara
+++ b/rules/data/builtin/multiple.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
import "elf"
@@ -8,5 +8,5 @@ rule elf_with_bundled_glibc_and_openssl: high {
filetypes = "elf"
condition:
- bundled_openssl and bundled_glibc
+ global_bundled_openssl and global_bundled_glibc
}
diff --git a/rules/discover/multiple.yara b/rules/discover/multiple.yara
index d667744ee..3389b4ebd 100644
--- a/rules/discover/multiple.yara
+++ b/rules/discover/multiple.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule sys_net_recon: medium {
meta:
@@ -73,5 +73,5 @@ rule sys_net_recon_exfil: high {
$not_cloudinit = "cloudinit" fullword
condition:
- sys_net_recon and obfuscate and exfil and none of ($not*)
+ sys_net_recon and global_obfuscate and global_exfil and none of ($not*)
}
diff --git a/rules/discover/user/username-get.yara b/rules/discover/user/username-get.yara
index 0b930706c..cc0ed8f3d 100644
--- a/rules/discover/user/username-get.yara
+++ b/rules/discover/user/username-get.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule getlogin {
meta:
@@ -40,5 +40,5 @@ rule pysetup_gets_login: high {
$ref3 = "whoami" fullword
condition:
- python_setup and any of them
+ global_python_setup and any of them
}
diff --git a/rules/evasion/indicator_blocking/hidden_window.yara b/rules/evasion/indicator_blocking/hidden_window.yara
index 1e7702e5c..4114e2cb8 100644
--- a/rules/evasion/indicator_blocking/hidden_window.yara
+++ b/rules/evasion/indicator_blocking/hidden_window.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule subprocess_CREATE_NO_WINDOW: medium {
meta:
@@ -23,7 +23,7 @@ rule subprocess_CREATE_NO_WINDOW_setuptools: high {
$no_window = "CREATE_NO_WINDOW"
condition:
- filesize < 32KB and python_setup and all of them
+ filesize < 32KB and global_python_setup and all of them
}
rule subprocess_CREATE_NO_WINDOW_high: high {
diff --git a/rules/evasion/indicator_blocking/mask_exceptions.yara b/rules/evasion/indicator_blocking/mask_exceptions.yara
index f1a3b0795..8266d60dc 100644
--- a/rules/evasion/indicator_blocking/mask_exceptions.yara
+++ b/rules/evasion/indicator_blocking/mask_exceptions.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
import "math"
@@ -21,7 +21,7 @@ rule setuptools_no_fail: suspicious {
filetypes = "py"
condition:
- python_setup and py_no_fail
+ global_python_setup and py_no_fail
}
rule php_disable_errors: medium {
diff --git a/rules/evasion/logging/wipe.yara b/rules/evasion/logging/wipe.yara
index 38a9aa22a..0ca99de82 100644
--- a/rules/evasion/logging/wipe.yara
+++ b/rules/evasion/logging/wipe.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule echo_log_wiper: critical {
meta:
@@ -9,7 +9,7 @@ rule echo_log_wiper: critical {
$var_log = /echo.{0,4}\> {0,2}\/var\/log\/\w{0,8}/
condition:
- filesize < 16KB and sensitive_log_files and any of them
+ filesize < 16KB and global_sensitive_log_files and any of them
}
rule log_remover: critical {
@@ -21,5 +21,5 @@ rule log_remover: critical {
$var_log = /rm {1,2}-{0,4}\/var\/log\/\w{0,8}/
condition:
- filesize < 16KB and sensitive_log_files and any of them
+ filesize < 16KB and global_sensitive_log_files and any of them
}
diff --git a/rules/evasion/net/hide_ports.yara b/rules/evasion/net/hide_ports.yara
index 1a41d51e5..8e74e2101 100644
--- a/rules/evasion/net/hide_ports.yara
+++ b/rules/evasion/net/hide_ports.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule hides_ports: high {
meta:
@@ -14,5 +14,5 @@ rule hides_ports: high {
$hidden_port = "hidden_port"
condition:
- filesize < 2MB and (elf_or_macho) and any of ($bin*) and any of ($hid*)
+ filesize < 2MB and (global_elf_or_macho) and any of ($bin*) and any of ($hid*)
}
diff --git a/rules/evasion/self_deletion/run_and_delete.yara b/rules/evasion/self_deletion/run_and_delete.yara
index d434483e5..904ff6be5 100644
--- a/rules/evasion/self_deletion/run_and_delete.yara
+++ b/rules/evasion/self_deletion/run_and_delete.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule tiny_copy_run_delete: critical {
meta:
@@ -49,7 +49,7 @@ rule python_setsid_remove: high {
$remove = "os.remove("
condition:
- filesize < 1MB and all of them and py_fetcher and @remove > @subprocess and @remove - @subprocess < 256
+ filesize < 1MB and all of them and global_py_fetcher and @remove > @subprocess and @remove - @subprocess < 256
}
rule run_sleep_delete: critical {
diff --git a/rules/exec/program/opaque.yara b/rules/exec/program/opaque.yara
index 0e120f935..f25fab6cd 100644
--- a/rules/exec/program/opaque.yara
+++ b/rules/exec/program/opaque.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
import "math"
@@ -18,7 +18,7 @@ rule macho_opaque_binary: high {
$not_java = "java/lang"
condition:
- small_macho and #word_with_spaces < 8 and #libc_call < 6 and all of ($f*) and none of ($not*)
+ global_small_macho and #word_with_spaces < 8 and #libc_call < 6 and all of ($f*) and none of ($not*)
}
rule macho_opaque_binary_long_str: high {
@@ -39,7 +39,7 @@ rule macho_opaque_binary_long_str: high {
$long_low_str = /\x00[a-z0-9]{3000}/
condition:
- stub_macho and #word_with_spaces < 10 and #libc_call < 15 and all of ($f*) and any of ($long*) and none of ($not*)
+ global_stub_macho and #word_with_spaces < 10 and #libc_call < 15 and all of ($f*) and any of ($long*) and none of ($not*)
}
rule decoded_or_encoded_cmd: medium {
diff --git a/rules/exec/shell/relative-semicolon.yara b/rules/exec/shell/relative-semicolon.yara
index 6ae588774..3698afc75 100644
--- a/rules/exec/shell/relative-semicolon.yara
+++ b/rules/exec/shell/relative-semicolon.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule semicolon_relative_path_cd: medium {
meta:
@@ -19,5 +19,5 @@ rule semicolon_relative_path_high: high {
$semi_relative = /[\/\w]{3,};[ +]{0,8}\.\/\.{0,8}\w{3,}/
condition:
- any of them and not local_cd
+ any of them and not global_local_cd
}
diff --git a/rules/exfil/discord.yara b/rules/exfil/discord.yara
index 226ad3b0e..0a64b7554 100644
--- a/rules/exfil/discord.yara
+++ b/rules/exfil/discord.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule discord_bot: high {
meta:
@@ -33,5 +33,5 @@ rule discord_exfil: critical {
description = "exfiltrates data via discord webhook"
condition:
- filesize < 100MB and discord_bot and iplookup_website
+ filesize < 100MB and discord_bot and global_iplookup_website
}
diff --git a/rules/exfil/nodejs.yara b/rules/exfil/nodejs.yara
index 1c059f4b3..6abe4779b 100644
--- a/rules/exfil/nodejs.yara
+++ b/rules/exfil/nodejs.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
import "math"
@@ -145,5 +145,5 @@ rule get_hardcoded_hardcoded_host_os: critical {
$i_os_userinfo = "os.userInfo"
condition:
- filesize < 256KB and $ref and (any of ($i*) or iplookup_website)
+ filesize < 256KB and $ref and (any of ($i*) or global_iplookup_website)
}
diff --git a/rules/exfil/npm.yara b/rules/exfil/npm.yara
index 09f747ca3..5e6eb468e 100644
--- a/rules/exfil/npm.yara
+++ b/rules/exfil/npm.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule npm_fetcher: high {
meta:
@@ -9,7 +9,7 @@ rule npm_fetcher: high {
$url = /https{0,1}:\/\/[\w][\w\.\/\-_\?=\@]{8,64}/
condition:
- package_scripts and $fetch and $url
+ global_package_scripts and $fetch and $url
}
rule npm_dev_tcp: critical {
@@ -20,7 +20,7 @@ rule npm_dev_tcp: critical {
$dev_tcp = /\/dev\/tcp\/[\w\.\/]{0,32}/
condition:
- package_scripts and $dev_tcp
+ global_package_scripts and $dev_tcp
}
rule npm_ping: critical {
@@ -31,7 +31,7 @@ rule npm_ping: critical {
$ping = /ping -\w [\w\-\. \$]{0,63}/
condition:
- package_scripts and $ping
+ global_package_scripts and $ping
}
rule npm_sensitive_files: high {
@@ -47,7 +47,7 @@ rule npm_sensitive_files: high {
$ = "/etc/passwd"
condition:
- package_scripts and any of them
+ global_package_scripts and any of them
}
rule npm_recon_commands: high {
@@ -59,5 +59,5 @@ rule npm_recon_commands: high {
$ = "cat /etc/shadow"
condition:
- package_scripts and any of them
+ global_package_scripts and any of them
}
diff --git a/rules/exfil/oauth.yara b/rules/exfil/oauth.yara
index ff7e524dd..c4320c588 100644
--- a/rules/exfil/oauth.yara
+++ b/rules/exfil/oauth.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule possible_oauth_stealer: high {
meta:
@@ -21,7 +21,7 @@ rule possible_oauth_stealer: high {
$o_microsoft5 = "code_challenge_method"
condition:
- filesize < 10MB and post_json and 5 of ($o*)
+ filesize < 10MB and global_post_json and 5 of ($o*)
}
rule oauth_stealer: critical {
diff --git a/rules/fs/path/applications.yara b/rules/fs/path/applications.yara
index 7f01fceb3..89a769c40 100644
--- a/rules/fs/path/applications.yara
+++ b/rules/fs/path/applications.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule app_path: medium {
meta:
@@ -20,7 +20,7 @@ rule macho_app_path: high {
$ref = /\/Applications\/.{0,32}\.app\/Contents\/MacOS\/[\w \.\-]{0,32}/
condition:
- specific_macho and any of them
+ global_specific_macho and any of them
}
rule mac_applications: medium {
@@ -32,5 +32,5 @@ rule mac_applications: medium {
$ref = "/Applications" fullword
condition:
- specific_macho and any of them
+ global_specific_macho and any of them
}
diff --git a/rules/global.yara b/rules/global/global.yara
similarity index 90%
rename from rules/global.yara
rename to rules/global/global.yara
index 25f0e238d..ba4f26c3d 100644
--- a/rules/global.yara
+++ b/rules/global/global.yara
@@ -1,11 +1,11 @@
import "elf"
-private rule binary {
+private rule global_binary {
condition:
filesize < 40MB and (uint32(0) == 1179403647 or uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962)
}
-private rule bundled_glibc {
+private rule global_bundled_glibc {
meta:
description = "includes bundled copy of glibc"
filetypes = "elf,so"
@@ -19,7 +19,7 @@ private rule bundled_glibc {
filesize > 1024 and filesize < 25MB and elf.type == elf.ET_EXEC and uint32(0) == 1179403647 and all of them
}
-private rule bundled_openssl {
+private rule global_bundled_openssl {
meta:
description = "includes bundled copy of OpenSSL"
filetypes = "elf,so"
@@ -34,7 +34,7 @@ private rule bundled_openssl {
filesize > 1024 and filesize < 150MB and elf.type == elf.ET_EXEC and uint32(0) == 1179403647 and any of them
}
-private rule container_managers {
+private rule global_container_managers {
strings:
$containerd = "github.com/containerd/containerd"
$systemd = "SYSTEMD_PROC_CMDLINE"
@@ -44,12 +44,12 @@ private rule container_managers {
any of them
}
-private rule elf_or_macho {
+private rule global_elf_or_macho {
condition:
uint32(0) == 1179403647 or (uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962 or uint32(0) == 3405691583 or uint32(0) == 3216703178)
}
-private rule exfil {
+private rule global_exfil {
strings:
$f_app_json = "application/json"
$f_post = "requests.post"
@@ -62,7 +62,7 @@ private rule exfil {
filesize < 512KB and any of ($f*) and none of ($not*)
}
-private rule iplookup_website {
+private rule global_iplookup_website {
meta:
description = "public service to discover external IP address"
@@ -95,7 +95,7 @@ private rule iplookup_website {
filesize < 250MB and any of them and none of ($not*)
}
-private rule legal_license {
+private rule global_legal_license {
strings:
$ = "using, exploiting or modifying the Software"
$ = "exploit the Information commercially"
@@ -105,7 +105,7 @@ private rule legal_license {
any of them
}
-private rule local_cd {
+private rule global_local_cd {
strings:
$cd = /cd [a-z]{4,12}; \.\//
@@ -113,7 +113,7 @@ private rule local_cd {
any of them
}
-private rule macho {
+private rule global_macho {
condition:
(uint32(0) == 4277009102
or uint32(0) == 3472551422
@@ -125,12 +125,12 @@ private rule macho {
or uint32(0) == 3216703178)
}
-private rule normal_elf {
+private rule global_normal_elf {
condition:
filesize < 64MB and uint32(0) == 1179403647
}
-private rule obfuscate {
+private rule global_obfuscate {
strings:
$b64decode = "b64decode"
$base64 = "base64"
@@ -146,7 +146,7 @@ private rule obfuscate {
filesize < 512KB and any of them
}
-private rule package_scripts {
+private rule global_package_scripts {
strings:
$npm_name = /"name":/
$npm_version = /"version":/
@@ -161,7 +161,7 @@ private rule package_scripts {
filesize < 32KB and 3 of ($npm*) and $scripts
}
-private rule post_json {
+private rule global_post_json {
strings:
$json = "application/json"
$POST = "POST"
@@ -171,7 +171,7 @@ private rule post_json {
$json and $POST and any of ($encode*)
}
-private rule py_fetcher {
+private rule global_py_fetcher {
meta:
description = "fetches content"
filetypes = "py"
@@ -189,7 +189,7 @@ private rule py_fetcher {
any of them
}
-private rule py_runner {
+private rule global_py_runner {
meta:
description = "runs programs"
filetypes = "py"
@@ -205,7 +205,7 @@ private rule py_runner {
any of them
}
-private rule python_setup {
+private rule global_python_setup {
meta:
filetypes = "py"
@@ -230,7 +230,7 @@ private rule python_setup {
filesize < 131072 and $setup and any of ($i*) and none of ($not*)
}
-private rule sensitive_log_files {
+private rule global_sensitive_log_files {
strings:
$wtmp = "/var/log/wtmp"
$secure = "/var/log/secure"
@@ -249,27 +249,27 @@ private rule sensitive_log_files {
filesize < 16KB and 2 of them
}
-private rule small_binary {
+private rule global_small_binary {
condition:
filesize < 10MB and (uint32(0) == 1179403647 or uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962)
}
-private rule small_elf {
+private rule global_small_elf {
condition:
filesize < 400KB and uint32(0) == 1179403647
}
-private rule small_elf_or_macho {
+private rule global_small_elf_or_macho {
condition:
filesize > 1MB and filesize < 8MB and (uint32(0) == 1179403647 or uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962)
}
-private rule small_macho {
+private rule global_small_macho {
condition:
filesize < 64MB and (uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962)
}
-private rule specific_macho {
+private rule global_specific_macho {
strings:
$not_jar = "META-INF/"
$not_dwarf = "_DWARF"
@@ -287,7 +287,7 @@ private rule specific_macho {
and none of ($not*)
}
-private rule stub_macho {
+private rule global_stub_macho {
strings:
$stub_helper = "__stub_helper"
@@ -295,7 +295,7 @@ private rule stub_macho {
filesize < 1MB and (uint32(0) == 4277009102 or uint32(0) == 3472551422 or uint32(0) == 4277009103 or uint32(0) == 3489328638 or uint32(0) == 3405691582 or uint32(0) == 3199925962) and $stub_helper
}
-private rule ufw_tool {
+private rule global_ufw_tool {
strings:
$not_route = "route-insert"
$not_statusverbose = "statusverbose"
@@ -307,7 +307,7 @@ private rule ufw_tool {
filesize < 256KB and any of them
}
-private rule wordlist {
+private rule global_word_list {
strings:
$scorpion = "scorpion"
$superman = "superman"
diff --git a/rules/impact/degrade/firewall.yara b/rules/impact/degrade/firewall.yara
index f9e1b7ad6..f97a339c6 100644
--- a/rules/impact/degrade/firewall.yara
+++ b/rules/impact/degrade/firewall.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
import "math"
@@ -31,7 +31,7 @@ rule ufw_disable_word: high {
$ref = /ufw['", ]{1,4}disable/ fullword
condition:
- filesize < 256KB and $ref and not ufw_tool
+ filesize < 256KB and $ref and not global_ufw_tool
}
rule firewall_iptables_disable: high {
diff --git a/rules/impact/exploit/breakout.yara b/rules/impact/exploit/breakout.yara
index 26a61ec29..201f58595 100644
--- a/rules/impact/exploit/breakout.yara
+++ b/rules/impact/exploit/breakout.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule probable_container_breakout: high linux {
meta:
@@ -22,7 +22,7 @@ rule probable_container_breakout: high linux {
$not_systemd = "SYSTEMD_PROC_CMDLINE"
condition:
- filesize < 1MB and 4 of ($x*) and none of ($not*) and not container_managers
+ filesize < 1MB and 4 of ($x*) and none of ($not*) and not global_container_managers
}
rule possible_container_breakout: medium linux {
@@ -45,5 +45,5 @@ rule possible_container_breakout: medium linux {
$cgroup_procs = "cgroup.procs"
condition:
- filesize < 1MB and 3 of them and not container_managers
+ filesize < 1MB and 3 of them and not global_container_managers
}
diff --git a/rules/impact/exploit/exploit.yara b/rules/impact/exploit/exploit.yara
index 2ace17c4e..12fc5d98c 100644
--- a/rules/impact/exploit/exploit.yara
+++ b/rules/impact/exploit/exploit.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule exploitation: medium {
meta:
@@ -12,7 +12,7 @@ rule exploitation: medium {
$not_ms_example = "Drive-by Compromise"
condition:
- any of ($ref*) and none of ($not*) and not legal_license
+ any of ($ref*) and none of ($not*) and not global_legal_license
}
rule install_exploit: high {
@@ -26,7 +26,7 @@ rule install_exploit: high {
$not_ms_example = "Drive-by Compromise"
condition:
- any of ($ref*) and none of ($not*) and not legal_license
+ any of ($ref*) and none of ($not*) and not global_legal_license
}
rule explot: high {
@@ -49,7 +49,7 @@ rule Exploit: medium {
$not_reduction = "Exploit reduction"
condition:
- any of ($ref*) and none of ($not*) and not legal_license
+ any of ($ref*) and none of ($not*) and not global_legal_license
}
rule exploiter: high {
@@ -65,7 +65,7 @@ rule exploiter: high {
$not_pypi_index = "testpack-id-lb001"
condition:
- any of ($ref*) and none of ($not*) and not legal_license
+ any of ($ref*) and none of ($not*) and not global_legal_license
}
rule exploit_attempt: high {
diff --git a/rules/impact/remote_access/backdoor.yara b/rules/impact/remote_access/backdoor.yara
index 965a6393a..aae54b22f 100644
--- a/rules/impact/remote_access/backdoor.yara
+++ b/rules/impact/remote_access/backdoor.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule backdoor: medium {
meta:
@@ -12,7 +12,7 @@ rule backdoor: medium {
$not_comment = "# backdoor:"
condition:
- filesize < 40MB and any of them and not wordlist and none of ($not*)
+ filesize < 40MB and any of them and not global_word_list and none of ($not*)
}
rule backdoor_shell: high {
@@ -67,7 +67,7 @@ rule backdoor_caps: high {
$ref2 = /[a-zA-Z\-_ \']{0,16}BACKDOOR[a-zA-Z\-_ ]{0,16}/ fullword
condition:
- filesize < 40MB and any of them and not wordlist
+ filesize < 40MB and any of them and not global_word_list
}
rule backdoor_leet: critical {
@@ -78,7 +78,7 @@ rule backdoor_leet: critical {
$ref4 = /[a-zA-Z\-_ \']{0,16}[bB][a4]ckd00r[a-zA-Z\-_ ]{0,16}/
condition:
- filesize < 100MB and any of them and not wordlist
+ filesize < 100MB and any of them and not global_word_list
}
rule commands: high {
@@ -135,7 +135,7 @@ rule macho_backdoor_libc_signature: high {
$not_java = "java/lang"
condition:
- small_macho and #word_with_spaces < 10 and #libc_call < 74 and 95 % of ($f*) and none of ($not*)
+ global_small_macho and #word_with_spaces < 10 and #libc_call < 74 and 95 % of ($f*) and none of ($not*)
}
rule minecraft_load_fetch_class_backdoor: critical {
diff --git a/rules/impact/remote_access/py_setuptools.yara b/rules/impact/remote_access/py_setuptools.yara
index 27faeab1d..e9ab5c620 100644
--- a/rules/impact/remote_access/py_setuptools.yara
+++ b/rules/impact/remote_access/py_setuptools.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
import "math"
@@ -11,7 +11,7 @@ rule setuptools_oslogin: medium {
$oslogin = "os.login()"
condition:
- python_setup and any of them
+ global_python_setup and any of them
}
rule setuptools_homedir: high {
@@ -23,7 +23,7 @@ rule setuptools_homedir: high {
$oslogin = "C:\\Users\\.{0,64}os.login()"
condition:
- python_setup and any of them
+ global_python_setup and any of them
}
rule setuptools_cmd_exec: high {
@@ -43,7 +43,7 @@ rule setuptools_cmd_exec: high {
$not_twine_upload = "twine upload dist/*"
condition:
- python_setup and any of ($f*) and none of ($not*)
+ global_python_setup and any of ($f*) and none of ($not*)
}
rule setuptools_cmd_exec_start: critical {
@@ -58,7 +58,7 @@ rule setuptools_cmd_exec_start: critical {
$f_subprocess = /subprocess.\w{0,32}\([f\"\']{0,2}start[,'" ]{1,3}.{0,64}/
condition:
- python_setup and any of ($f*)
+ global_python_setup and any of ($f*)
}
rule setuptools_eval: medium {
@@ -70,7 +70,7 @@ rule setuptools_eval: medium {
$f_eval = /eval\([\"\'\/\w\,\.\ \-\)\(]{1,64}\)/ fullword
condition:
- python_setup and any of ($f*)
+ global_python_setup and any of ($f*)
}
rule setuptools_eval_high: high {
@@ -83,7 +83,7 @@ rule setuptools_eval_high: high {
$not_namespaced = /eval\([\w\.\(\)\"\/\']{4,16}, [a-z]{1,6}[,\)]/
condition:
- python_setup and any of ($f*) and none of ($not*)
+ global_python_setup and any of ($f*) and none of ($not*)
}
rule setuptools_exec: medium {
@@ -97,7 +97,7 @@ rule setuptools_exec: medium {
$not_hopper = "with open(\" hopper /__version__.py\") as fp:"
condition:
- python_setup and any of ($f*) and none of ($not*)
+ global_python_setup and any of ($f*) and none of ($not*)
}
rule setuptools_exec_high: high {
@@ -119,7 +119,7 @@ rule setuptools_exec_high: high {
$not_namespaced = /exec\([\w\.\(\)\"\/\']{4,16}, [a-z]{1,6}[,\)]/
condition:
- python_setup and any of ($f*) and none of ($not*)
+ global_python_setup and any of ($f*) and none of ($not*)
}
rule setuptools_b64decode: suspicious {
@@ -131,7 +131,7 @@ rule setuptools_b64decode: suspicious {
$base64 = "b64decode"
condition:
- python_setup and any of them
+ global_python_setup and any of them
}
rule setuptools_preinstall: suspicious {
@@ -146,7 +146,7 @@ rule setuptools_preinstall: suspicious {
$f_pre_install = "from pre_install"
condition:
- python_setup and any of them
+ global_python_setup and any of them
}
rule setuptools_b64encode: suspicious {
@@ -158,7 +158,7 @@ rule setuptools_b64encode: suspicious {
$base64 = "b64encode"
condition:
- python_setup and any of them
+ global_python_setup and any of them
}
rule setuptools_exec_powershell: critical windows {
@@ -187,7 +187,7 @@ rule setuptools_os_path_exists: medium {
$not_pyspark_ioerror = "\"Failed to load PySpark version file for packaging. You must be in Spark's python dir.\""
condition:
- python_setup and $ref and none of ($not*)
+ global_python_setup and $ref and none of ($not*)
}
rule setuptools_excessive_bitwise_math: critical {
@@ -199,5 +199,5 @@ rule setuptools_excessive_bitwise_math: critical {
$x = /\-{0,1}\d{1,8} \<\< \-{0,1}\d{1,8}/
condition:
- python_setup and #x > 20
+ global_python_setup and #x > 20
}
diff --git a/rules/impact/wipe/crypto.yara b/rules/impact/wipe/crypto.yara
index b497f37f4..0bcc634ad 100644
--- a/rules/impact/wipe/crypto.yara
+++ b/rules/impact/wipe/crypto.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule uname_hostname_encrypt_wipe_kill_small: high {
meta:
@@ -14,7 +14,7 @@ rule uname_hostname_encrypt_wipe_kill_small: high {
$hostname = "hostname" fullword
condition:
- filesize < 2MB and elf_or_macho and all of them
+ filesize < 2MB and global_elf_or_macho and all of them
}
rule uname_hostname_encrypt_wipe_kill: medium {
@@ -31,5 +31,5 @@ rule uname_hostname_encrypt_wipe_kill: medium {
$hostname = "hostname" fullword
condition:
- filesize < 20MB and elf_or_macho and all of them
+ filesize < 20MB and global_elf_or_macho and all of them
}
diff --git a/rules/malware/family/amos.yara b/rules/malware/family/amos.yara
index 7ebe10d7a..b6c2aaad6 100644
--- a/rules/malware/family/amos.yara
+++ b/rules/malware/family/amos.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
import "math"
@@ -19,7 +19,7 @@ rule amos_magic_var: critical macos {
$word_with_spaces = /[a-z]{2,} [a-z]{2,}/
condition:
- filesize > 100KB and filesize < 600KB and specific_macho and $magic and $header and $main and all of ($f*) and #word_with_spaces < 3
+ filesize > 100KB and filesize < 600KB and global_specific_macho and $magic and $header and $main and all of ($f*) and #word_with_spaces < 3
}
rule amos_base32: critical macos {
@@ -36,7 +36,7 @@ rule amos_base32: critical macos {
$at_exit = "@___cxa_atexit"
condition:
- filesize > 40KB and filesize < 2MB and specific_macho and all of them
+ filesize > 40KB and filesize < 2MB and global_specific_macho and all of them
}
rule maybe_amos: high macos {
@@ -58,7 +58,7 @@ rule maybe_amos: high macos {
$not_release = "@_CFRelease" fullword
condition:
- filesize > 190KB and filesize < 400KB and specific_macho and all of them and none of ($not*) and math.entropy(1, filesize) >= 4
+ filesize > 190KB and filesize < 400KB and global_specific_macho and all of them and none of ($not*) and math.entropy(1, filesize) >= 4
}
rule maybe_amos_hex: high macos {
@@ -82,5 +82,5 @@ rule maybe_amos_hex: high macos {
$x = /0x[\dabcdefABCDEF]{2,8}/
condition:
- filesize > 190KB and filesize < 400KB and specific_macho and 95 % of ($f*) and math.entropy(20000, 50000) >= 4.5 and #x > 64
+ filesize > 190KB and filesize < 400KB and global_specific_macho and 95 % of ($f*) and math.entropy(20000, 50000) >= 4.5 and #x > 64
}
diff --git a/rules/malware/family/clapzok.yara b/rules/malware/family/clapzok.yara
index 12e622cb0..dbf5f836b 100644
--- a/rules/malware/family/clapzok.yara
+++ b/rules/malware/family/clapzok.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule clapzok_macho: critical {
meta:
@@ -10,5 +10,5 @@ rule clapzok_macho: critical {
$ref = "SfcIsFileProtected"
condition:
- filesize < 10MB and specific_macho and $ref in (filesize - 2200..filesize - 100)
+ filesize < 10MB and global_specific_macho and $ref in (filesize - 2200..filesize - 100)
}
diff --git a/rules/malware/family/poseidon_stealer.yara b/rules/malware/family/poseidon_stealer.yara
index 1c235e913..0f411dba3 100644
--- a/rules/malware/family/poseidon_stealer.yara
+++ b/rules/malware/family/poseidon_stealer.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
import "math"
@@ -16,7 +16,7 @@ rule poseidon: high macos {
$ve = "vector" fullword
condition:
- filesize > 190KB and filesize < 400KB and specific_macho and all of them and math.entropy(20000, 50000) >= 2.5
+ filesize > 190KB and filesize < 400KB and global_specific_macho and all of them and math.entropy(20000, 50000) >= 2.5
}
rule poseidon_url: high macos {
@@ -29,5 +29,5 @@ rule poseidon_url: high macos {
$ref = "https://forked-project.com/check_updates"
condition:
- filesize > 190KB and filesize < 400KB and specific_macho and all of them
+ filesize > 190KB and filesize < 400KB and global_specific_macho and all of them
}
diff --git a/rules/net/download/fetch.yara b/rules/net/download/fetch.yara
index 77f37c926..91c5788c3 100644
--- a/rules/net/download/fetch.yara
+++ b/rules/net/download/fetch.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule curl_value: medium {
meta:
@@ -109,7 +109,7 @@ rule binary_calls_fetch_tool: high {
$not_tftp_err = "tftp error"
condition:
- filesize < 10MB and (elf_or_macho) and any of ($t*) and none of ($not*)
+ filesize < 10MB and (global_elf_or_macho) and any of ($t*) and none of ($not*)
}
rule curl_agent_val: high {
diff --git a/rules/sus/compiler.yara b/rules/sus/compiler.yara
index de73884db..111053000 100644
--- a/rules/sus/compiler.yara
+++ b/rules/sus/compiler.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule archaic_gcc: medium {
meta:
@@ -39,7 +39,7 @@ rule multiple_gcc: medium {
$gcc = /GCC: \([\w \.\-\~\(\)]{8,64}/ fullword
condition:
- binary and #gcc > 1 and !gcc[1] != !gcc[2]
+ global_binary and #gcc > 1 and !gcc[1] != !gcc[2]
}
rule multiple_gcc_high: high {
@@ -54,5 +54,5 @@ rule multiple_gcc_high: high {
$not_java = "JAVA_HOME"
condition:
- binary and #gcc > 1 and !gcc[1] != !gcc[2] and none of ($not*)
+ global_binary and #gcc > 1 and !gcc[1] != !gcc[2] and none of ($not*)
}
diff --git a/rules/sus/entitlement.yara b/rules/sus/entitlement.yara
index 07ed3bf04..a491e2416 100644
--- a/rules/sus/entitlement.yara
+++ b/rules/sus/entitlement.yara
@@ -1,4 +1,4 @@
-include "rules/global.yara"
+include "rules/global/global.yara"
rule com_apple_get_task_allow: medium {
meta:
@@ -10,5 +10,5 @@ rule com_apple_get_task_allow: medium {
$true = ""
condition:
- specific_macho and all of them
+ global_specific_macho and all of them
}
From cb0a939dd04b1a3be0d630f053b5b9afdcb7b6a6 Mon Sep 17 00:00:00 2001
From: egibs <20933572+egibs@users.noreply.github.com>
Date: Tue, 20 May 2025 16:33:53 -0500
Subject: [PATCH 3/3] Import before include
Signed-off-by: egibs <20933572+egibs@users.noreply.github.com>
---
rules/anti-behavior/random_behavior.yara | 4 ++--
rules/anti-static/elf/entropy.yara | 4 ++--
rules/anti-static/macho/entropy.yara | 4 ++--
rules/anti-static/macho/footer.yara | 4 ++--
rules/anti-static/packer/aes.yara | 4 ++--
rules/anti-static/unmarshal/marshal.yara | 4 ++--
rules/c2/addr/url.yara | 4 ++--
rules/data/builtin/multiple.yara | 4 ++--
rules/evasion/indicator_blocking/mask_exceptions.yara | 4 ++--
rules/exec/program/opaque.yara | 4 ++--
rules/exfil/nodejs.yara | 4 ++--
rules/impact/degrade/firewall.yara | 4 ++--
rules/impact/remote_access/py_setuptools.yara | 4 ++--
rules/malware/family/amos.yara | 4 ++--
rules/malware/family/poseidon_stealer.yara | 4 ++--
15 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/rules/anti-behavior/random_behavior.yara b/rules/anti-behavior/random_behavior.yara
index 1df6de7a1..36cd1a7a0 100644
--- a/rules/anti-behavior/random_behavior.yara
+++ b/rules/anti-behavior/random_behavior.yara
@@ -1,7 +1,7 @@
-include "rules/global/global.yara"
-
import "math"
+include "rules/global/global.yara"
+
rule setuptools_random: critical {
meta:
description = "Python library installer that exhibits random behavior"
diff --git a/rules/anti-static/elf/entropy.yara b/rules/anti-static/elf/entropy.yara
index 4d183da06..c81189ea4 100644
--- a/rules/anti-static/elf/entropy.yara
+++ b/rules/anti-static/elf/entropy.yara
@@ -1,7 +1,7 @@
-include "rules/global/global.yara"
-
import "math"
+include "rules/global/global.yara"
+
rule higher_elf_entropy_68: medium {
meta:
description = "higher entropy ELF binary (>6.95)"
diff --git a/rules/anti-static/macho/entropy.yara b/rules/anti-static/macho/entropy.yara
index f353046f1..e8e9589f7 100644
--- a/rules/anti-static/macho/entropy.yara
+++ b/rules/anti-static/macho/entropy.yara
@@ -1,7 +1,7 @@
-include "rules/global/global.yara"
-
import "math"
+include "rules/global/global.yara"
+
rule higher_entropy_6_9: medium {
meta:
description = "higher entropy binary (>6.9)"
diff --git a/rules/anti-static/macho/footer.yara b/rules/anti-static/macho/footer.yara
index b2a0e0c4b..b806d761f 100644
--- a/rules/anti-static/macho/footer.yara
+++ b/rules/anti-static/macho/footer.yara
@@ -1,7 +1,7 @@
-include "rules/global/global.yara"
-
import "math"
+include "rules/global/global.yara"
+
rule high_entropy_trailer: high {
meta:
description = "higher-entropy machO trailer (normally NULL) - possible viral infection"
diff --git a/rules/anti-static/packer/aes.yara b/rules/anti-static/packer/aes.yara
index 280c20fef..81445e1d5 100644
--- a/rules/anti-static/packer/aes.yara
+++ b/rules/anti-static/packer/aes.yara
@@ -1,7 +1,7 @@
-include "rules/global/global.yara"
-
import "math"
+include "rules/global/global.yara"
+
rule go_aes: high {
meta:
description = "go binary packed with AES"
diff --git a/rules/anti-static/unmarshal/marshal.yara b/rules/anti-static/unmarshal/marshal.yara
index 7c90f69ae..619840366 100644
--- a/rules/anti-static/unmarshal/marshal.yara
+++ b/rules/anti-static/unmarshal/marshal.yara
@@ -1,7 +1,7 @@
-include "rules/global/global.yara"
-
import "math"
+include "rules/global/global.yara"
+
rule unmarshal_py_marshal: medium {
meta:
description = "reads python values from binary content"
diff --git a/rules/c2/addr/url.yara b/rules/c2/addr/url.yara
index 36f28cf5d..a0db1d369 100644
--- a/rules/c2/addr/url.yara
+++ b/rules/c2/addr/url.yara
@@ -1,7 +1,7 @@
-include "rules/global/global.yara"
-
import "math"
+include "rules/global/global.yara"
+
rule unusual_nodename: medium {
meta:
description = "Contains HTTP hostname with a long node name"
diff --git a/rules/data/builtin/multiple.yara b/rules/data/builtin/multiple.yara
index 9d6a2a3af..ebe682b13 100644
--- a/rules/data/builtin/multiple.yara
+++ b/rules/data/builtin/multiple.yara
@@ -1,7 +1,7 @@
-include "rules/global/global.yara"
-
import "elf"
+include "rules/global/global.yara"
+
rule elf_with_bundled_glibc_and_openssl: high {
meta:
description = "includes bundled copy of glibc and OpenSSL"
diff --git a/rules/evasion/indicator_blocking/mask_exceptions.yara b/rules/evasion/indicator_blocking/mask_exceptions.yara
index 8266d60dc..d9ad8f2c8 100644
--- a/rules/evasion/indicator_blocking/mask_exceptions.yara
+++ b/rules/evasion/indicator_blocking/mask_exceptions.yara
@@ -1,7 +1,7 @@
-include "rules/global/global.yara"
-
import "math"
+include "rules/global/global.yara"
+
rule py_no_fail: medium {
meta:
description = "Python code that hides exceptions"
diff --git a/rules/exec/program/opaque.yara b/rules/exec/program/opaque.yara
index f25fab6cd..2cef35225 100644
--- a/rules/exec/program/opaque.yara
+++ b/rules/exec/program/opaque.yara
@@ -1,7 +1,7 @@
-include "rules/global/global.yara"
-
import "math"
+include "rules/global/global.yara"
+
rule macho_opaque_binary: high {
meta:
description = "opaque binary executes mystery command-lines"
diff --git a/rules/exfil/nodejs.yara b/rules/exfil/nodejs.yara
index 6abe4779b..8bed2717a 100644
--- a/rules/exfil/nodejs.yara
+++ b/rules/exfil/nodejs.yara
@@ -1,7 +1,7 @@
-include "rules/global/global.yara"
-
import "math"
+include "rules/global/global.yara"
+
rule nodejs_sysinfoexfil: high {
meta:
description = "may gather and exfiltrate system information"
diff --git a/rules/impact/degrade/firewall.yara b/rules/impact/degrade/firewall.yara
index f97a339c6..efd10283d 100644
--- a/rules/impact/degrade/firewall.yara
+++ b/rules/impact/degrade/firewall.yara
@@ -1,7 +1,7 @@
-include "rules/global/global.yara"
-
import "math"
+include "rules/global/global.yara"
+
rule selinux_firewall: high linux {
meta:
filetypes = "elf,so"
diff --git a/rules/impact/remote_access/py_setuptools.yara b/rules/impact/remote_access/py_setuptools.yara
index e9ab5c620..5078feb2c 100644
--- a/rules/impact/remote_access/py_setuptools.yara
+++ b/rules/impact/remote_access/py_setuptools.yara
@@ -1,7 +1,7 @@
-include "rules/global/global.yara"
-
import "math"
+include "rules/global/global.yara"
+
rule setuptools_oslogin: medium {
meta:
description = "Python library installer that accesses user information"
diff --git a/rules/malware/family/amos.yara b/rules/malware/family/amos.yara
index b6c2aaad6..a407aa987 100644
--- a/rules/malware/family/amos.yara
+++ b/rules/malware/family/amos.yara
@@ -1,7 +1,7 @@
-include "rules/global/global.yara"
-
import "math"
+include "rules/global/global.yara"
+
rule amos_magic_var: critical macos {
meta:
description = "AMOS infostealer variant"
diff --git a/rules/malware/family/poseidon_stealer.yara b/rules/malware/family/poseidon_stealer.yara
index 0f411dba3..59261c32d 100644
--- a/rules/malware/family/poseidon_stealer.yara
+++ b/rules/malware/family/poseidon_stealer.yara
@@ -1,7 +1,7 @@
-include "rules/global/global.yara"
-
import "math"
+include "rules/global/global.yara"
+
rule poseidon: high macos {
meta:
description = "Possible Poseidon infostealer"