Skip to content

Commit

Permalink
Tune HIGH/CRITICAL findings + disallow "clean" samples from matching (#…
Browse files Browse the repository at this point in the history
…712)

* Tune HIGH/CRITICAL findings based on Wolfi review

* refresh testdata

* refresh testdata

* update tests

* update testdata

* further rule tuning

* further rule tuning

* further rule tuning

* run yara-x-fmt
  • Loading branch information
tstromberg authored Dec 17, 2024
1 parent ca24a67 commit 368f804
Show file tree
Hide file tree
Showing 96 changed files with 1,000 additions and 245 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@


SAMPLES_REPO ?= chainguard-dev/malcontent-samples
SAMPLES_COMMIT ?= dd5e3099092d965b83ac31f803769ab04bc18d7d
SAMPLES_COMMIT ?= 38d8faef6bcbd63f7cc02bb243b12aaa3e1ba70c

# BEGIN: lint-install ../malcontent
# http://github.com/tinkerbell/lint-install
Expand Down
1 change: 1 addition & 0 deletions pkg/compile/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ var badRules = map[string]bool{
"mimikatz_offensive_tool_keyword": true,
// Inquest
"Microsoft_Excel_Hidden_Macrosheet": true,
"Adobe_Type_1_Font": true,
// YARA VT
"Base64_Encoded_URL": true,
"Windows_API_Function": true,
Expand Down
6 changes: 5 additions & 1 deletion rules/anti-behavior/process-check.yara
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ rule linux_monitors: high linux {
$x_vmstat = "vmstat" fullword
$x_ps = "ps" fullword
$not_renice = "renice" fullword
$not_ddrescue = "ddrescue" fullword
$not_traceroute = "traceroute" fullword
condition:
filesize < 100KB and any of ($p*) and 3 of ($x*)
filesize < 100KB and any of ($p*) and 3 of ($x*) and none of ($not*)
}

rule anti_rootkit_hunter: high linux {
Expand Down
54 changes: 21 additions & 33 deletions rules/anti-static/base64/exec.yara
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,27 @@ rule base64_commands: high {
description = "commands in base64 form"

strings:
$b_chmod = "chmod" base64
$b_curl = "curl -" base64
$b_bin_sh = "/bin/sh" base64
$b_bin_bash = "/bin/bash" base64
$b_openssl = "openssl" base64
$b_dev_null = "/dev/null" base64
$b_usr_bin = "/usr/bin" base64
$b_usr_sbin = "/usr/sbin" base64
$b_var_tmp = "/var/tmp" base64
$b_var_run = "/var/run" base64
$b_screen_dm = "screen -" base64
$b_zmodload = "zmodload" base64
$b_dev_tcp = "/dev/tcp" base64
$b_bash_i = "bash -i" base64
$b_tar_c = "tar -c" base64
$b_tar_x = "tar -x" base64
$b_bash_c = "bash -c" base64
$not_kandji = "kandji-parameter-agent"
$not_mdmprofile = "mdmprofile"
$not_example = "commands are encoded"
$b_chmod = "chmod" base64
$b_curl = "curl -" base64
$b_bin_sh = "/bin/sh" base64
$b_bin_bash = "/bin/bash" base64
$b_openssl = "openssl" base64
$b_dev_null = "/dev/null" base64
$b_usr_bin = "/usr/bin" base64
$b_usr_sbin = "/usr/sbin" base64
$b_var_tmp = "/var/tmp" base64
$b_var_run = "/var/run" base64
$b_screen_dm = "screen -" base64
$b_zmodload = "zmodload" base64
$b_dev_tcp = "/dev/tcp" base64
$b_bash_i = "bash -i" base64
$b_tar_c = "tar -c" base64
$b_tar_x = "tar -x" base64
$b_bash_c = "bash -c" base64
$not_kandji = "kandji-parameter-agent"
$not_mdmprofile = "mdmprofile"
$not_example = "commands are encoded"
$not_sourcemappingURL = "sourceMappingURL=data:application/json;charset=utf-8;base64"
condition:
any of ($b_*) and none of ($not_*)
Expand Down Expand Up @@ -82,19 +83,6 @@ rule echo_decode_bash_probable: high {
filesize < 256KB and any of them and (@shell[#shell] - @decode[#decode]) < 32 and (@shell[#shell] - @decode[#decode]) > 0
}

rule acme_sh: override {
meta:
description = "acme.sh"
echo_decode_bash_probable = "medium"
iplookup_website = "medium"

strings:
$ref = "https://github.com/acmesh-official"
condition:
$ref
}

rule ruby_system_near_enough: critical {
meta:
description = "Executes commands from base64 content"
Expand Down
14 changes: 8 additions & 6 deletions rules/anti-static/base64/http_agent.yara
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ rule base64_http_val: high {
description = "base64 HTTP protocol references"

strings:
$user_agent = "User-Agent" base64
$mozilla_5_0 = "Mozilla/5.0" base64
$referer = "Referer" base64
$http_1_0 = "HTTP/1.0" base64
$http_1_1 = "HTTP/1.1" base64
$b_user_agent = "User-Agent" base64
$b_mozilla_5_0 = "Mozilla/5.0" base64
$b_referer = "Referer" base64
$b_http_1_0 = "HTTP/1.0" base64
$b_http_1_1 = "HTTP/1.1" base64
$not_sourcemappingURL = "sourceMappingURL=data:application/json;charset=utf-8;base64"
condition:
any of them
any of ($b*) and none of ($not*)
}
3 changes: 2 additions & 1 deletion rules/anti-static/elf/entropy.yara
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ rule normal_elf_high_entropy_7_4: high {

strings:
$not_whirlpool = "libgcrypt-grub/cipher/whirlpool.c"
$not_bazel = "BazelLogHandler"
condition:
normal_elf and math.entropy(1, filesize) >= 7.4 and none of ($not*)
filesize < 30MB and normal_elf and math.entropy(1, filesize) >= 7.4 and none of ($not*)
}

rule normal_elf_high_entropy_footer_7_4: high {
Expand Down
5 changes: 4 additions & 1 deletion rules/anti-static/obfuscation/bitwise.yara
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ rule excessive_bitwise_math: high {
$not_effective_bits = "effective bits"
$not_bit_offsets = "bit offsets"
$not_uuid = "uuid" fullword
$not_webpack = "webpack-api-runtime.js" fullword
condition:
filesize < 192KB and #x > 64 and none of ($not*)
Expand Down Expand Up @@ -132,8 +133,10 @@ rule unsigned_bitwise_math_excess: high {
$left = /[a-z]\>\>\>\d{1,3}/
$right = /[a-z]\>\>\>\d{1,3}/
$not_webpack = "webpack-api-runtime.js" fullword
condition:
filesize < 5MB and $function and $charAt and (#left > 50 or #right > 50)
filesize < 5MB and $function and $charAt and (#left > 50 or #right > 50) and none of ($not*)
}

rule charAtBitwise: high {
Expand Down
18 changes: 8 additions & 10 deletions rules/anti-static/obfuscation/python.yara
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
private rule probably_python {
strings:
$f_function = "import" fullword
$f_for = "for x in" fullword
$f_return = "return self."
$f_def = "def _"
$f_ord = " ord("
$import = "import "
$f_common = /\s(def|if|with|else:) /
$f_exotic = /exec\(|b64decode|bytes\(/
condition:
filesize < 10MB and any of ($f*)
filesize < 10MB and $import in (1..1024) and any of ($f*)
}

rule py_indirect_builtins: suspicious {
Expand Down Expand Up @@ -282,7 +280,7 @@ rule multi_decode_3: high {
$decode_or_b64decode = /\.[b64]{0,3}decode\(.{0,256}\.[b64]{0,3}decode\(.{0,256}\.[b64]{0,3}decode/
condition:
filesize < 10MB and all of them
probably_python and filesize < 10MB and all of them
}

rule multi_decode: medium {
Expand Down Expand Up @@ -311,13 +309,13 @@ rule rename_requests: medium {

rule rename_requests_2char: high {
meta:
description = "imports 'requests' library and gives it a two-letter name"
description = "imports 'requests' library and gives it a shorter name"

strings:
$ref = /import requests as \w{2}/
$ref = /import requests as \w{1,2}/ fullword
condition:
filesize < 65535 and all of them
filesize < 32KB and all of them
}

rule rename_os: high {
Expand Down
53 changes: 25 additions & 28 deletions rules/anti-static/xor/xor-commands.yara
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,31 @@ rule xor_commands: high {
description = "commands obfuscated using xor"

strings:
$b_chmod = "chmod " xor(1-31)
$b_curl = "curl -" xor(1-31)
$b_bin_sh = "/bin/sh" xor(1-31)
$b_bin_bash = "/bin/bash" xor(1-31)
$b_openssl = "openssl" xor(1-31)
$b_screen_dm = "screen -" xor(1-31)
$b_zmodload = "zmodload" xor(1-31)
$b_dev_tcp = "/dev/tcp" xor(1-31)
$b_bash_i = "bash -i" xor(1-31)
$b_bash_c = "bash -c" xor(1-31)
$b_base64 = "base64" xor(1-31)
$b_eval = "eval(" xor(1-31)
$b_chmod2 = "chmod " xor(33-255)
$b_curl2 = "curl -" xor(33-255)
$b_bin_sh2 = "/bin/sh" xor(33-255)
$b_bin_bash2 = "/bin/bash" xor(33-255)
$b_openssl2 = "openssl" xor(33-255)
$b_screen_dm2 = "screen -" xor(33-255)
$b_zmodload2 = "zmodload" xor(33-255)
$b_dev_tcp2 = "/dev/tcp" xor(33-255)
$b_bash_i2 = "bash -i" xor(33-255)
$b_bash_c2 = "bash -c" xor(33-255)
$b_base642 = "base64" xor(33-255)
$b_eval2 = "eval(" xor(33-255)
$b_xterm = "TERM=xterm" xor(1-31)
$b_xterm2 = "TERM=xterm" xor(33-255)
$not_password_list = "qwer1234"
$b_chmod = "chmod " xor(1-31)
$b_curl = "curl -" xor(1-31)
$b_bin_sh = "/bin/sh" xor(1-31)
$b_bin_bash = "/bin/bash" xor(1-31)
$b_openssl = "openssl" xor(1-31)
$b_screen_dm = "screen -" xor(1-31)
$b_zmodload = "zmodload" xor(1-31)
$b_dev_tcp = "/dev/tcp" xor(1-31)
$b_bash_i = "bash -i" xor(1-31)
$b_bash_c = "bash -c" xor(1-31)
$b_base64 = "base64" xor(1-31)
$b_chmod2 = "chmod " xor(33-255)
$b_curl2 = "curl -" xor(33-255)
$b_bin_sh2 = "/bin/sh" xor(33-255)
$b_bin_bash2 = "/bin/bash" xor(33-255)
$b_openssl2 = "openssl" xor(33-255)
$b_screen_dm2 = "screen -" xor(33-255)
$b_zmodload2 = "zmodload" xor(33-255)
$b_dev_tcp2 = "/dev/tcp" xor(33-255)
$b_bash_i2 = "bash -i" xor(33-255)
$b_bash_c2 = "bash -c" xor(33-255)
$b_base642 = "base64" xor(33-255)
$b_xterm = "TERM=xterm" xor(1-31)
$b_xterm2 = "TERM=xterm" xor(33-255)
condition:
any of ($b_*) and not ($b_eval and $not_password_list)
any of them
}
11 changes: 11 additions & 0 deletions rules/anti-static/xor/xor-functions.yara
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
rule xor_eval: medium {
meta:
description = "eval( xor'd"

strings:
$b_eval = "eval(" xor(1-31)
$b_eval2 = "eval(" xor(33-255)
condition:
any of ($b_*)
}
2 changes: 2 additions & 0 deletions rules/c2/addr/ip.yara
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ rule bin_hardcoded_ip: high {
$not_10_11_12_13 = "10.11.12.13"
$not_libebt_among_init = "libebt_among_init"
$not_send_att = "3.2.5.7"
$not_192_168 = "192.168."
$not_2345 = "23.45.67.89"
condition:
filesize < 12MB and ip_elf_or_macho and 1 of ($sus_ip*) and none of ($not*)
Expand Down
1 change: 1 addition & 0 deletions rules/c2/addr/url.yara
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ rule binary_url_with_question: high {
$not_msdn = "msdn.microsoft.com/"
$not_codeproject = "www.codeproject.com/"
$not_wiki = "index.php?title="
$not_mesibo = "https://api.mesibo.com/api.php?"
condition:
filesize < 150MB and elf_or_macho and $ref and none of ($not*)
Expand Down
11 changes: 6 additions & 5 deletions rules/c2/tool_transfer/exe_url.yara
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@ rule http_url_with_exe: high {
description = "accesses hardcoded executable endpoint"

strings:
$exe_url = /https*:\/\/[\w\.]{0,160}[:\/\w\_\-\?\@=]{6,160}\.exe/ fullword
$exe_url = /https*:\/\/[\w\.]{0,160}[:\/\w\_\-\?\@=]{6,160}\.exe/
$not_mongodb_404 = "https://docs.mongodb.com/manual/reference/method/Bulk.exe"
condition:
any of ($exe*)
any of ($exe*) and none of ($not*)
}

rule http_ip_url_with_exe: critical {
meta:
description = "accesses hardcoded executable endpoint via IP"

strings:
$exe_url = /https*:\/\/[\d\.\:\[\]]{8,64}[:\/\w\_\-\?\@=]{6,160}\.exe/ fullword
$exe_url = /https*:\/\/[\d\.\:\[\]]{8,64}[:\/\w\_\-\?\@=]{6,160}\.exe/
condition:
any of ($exe*)
Expand All @@ -25,7 +26,7 @@ rule http_url_with_msi: high {
description = "accesses hardcoded install file endpoint"

strings:
$exe_url = /https*:\/\/[\w\.]{0,160}[:\/\w\_\-\?\@=]{6,160}\.(msi|pkg)/ fullword
$exe_url = /https*:\/\/[\w\.]{0,160}[:\/\w\_\-\?\@=]{6,160}\.msi/
condition:
any of ($exe*)
Expand All @@ -36,7 +37,7 @@ rule http_ip_url_with_msi: critical {
description = "accesses hardcoded install file endpoint via IP"

strings:
$exe_url = /https*:\/\/[\d\.\:\[\]]{8,64}[:\/\w\_\-\?\@=]{6,160}\.(msi|pkg)/ fullword
$exe_url = /https*:\/\/[\d\.\:\[\]]{8,64}[:\/\w\_\-\?\@=]{6,160}\.msi/
condition:
any of ($exe*)
Expand Down
1 change: 0 additions & 1 deletion rules/c2/tool_transfer/grayware.yara
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ rule grayware_sites: high {
$ = "packetstormsecurity"
$ = "pentestmonkey.net"
$ = "phpjiami.com"
$ = "shodan.io"
$ = "github.com/b374k/b374k"
$ = "mumaasp.com"
Expand Down
14 changes: 12 additions & 2 deletions rules/c2/tool_transfer/python.yara
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
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"
Expand All @@ -12,7 +22,7 @@ private rule py_fetcher: medium {
$http_wget = "wget" fullword
condition:
any of them
probably_python_tt and any of them
}

private rule py_runner {
Expand All @@ -27,7 +37,7 @@ private rule py_runner {
$system = /system\([\"\'\w\ \-\)\/]{0,64}/
condition:
any of them
probably_python_tt and any of them
}

rule py_dropper: medium {
Expand Down
18 changes: 10 additions & 8 deletions rules/credential/shell/bash_history.yara
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
rule bash_history: high {
rule bash_history: medium {
meta:
description = "accesses bash shell history"

strings:
$ref = ".bash_history" fullword
$ref = ".bash_history"
condition:
all of them
}

rule bash: override {
rule bash_history_high: high {
meta:
description = "bash"
bash_history = "medium"
description = "accesses bash shell history"

strings:
$posix = "POSIXLY_CORRECT"
$source = "BASH_SOURCE"
$ref = ".bash_history"
$not_posix = "POSIXLY_CORRECT"
$not_source = "BASH_SOURCE"
$not_cshrc = ".cshrc"
condition:
filesize > 100KB and filesize < 2MB and all of them
$ref and none of ($not*)
}

Loading

0 comments on commit 368f804

Please sign in to comment.