Skip to content

Commit

Permalink
ELF malware detection improvements based on Wolfsbane analysis (chain…
Browse files Browse the repository at this point in the history
…guard-dev#680)

* libselinux.so tuning

* Finish libselinux.so analysis

* Finish libselinux.so analysis

* add missing files

* Finish dbus analysis

* Finish dbus analysis

* Finish dbus analysis

* add rules

* fix yara compile errors (duplicated rule names)

* Update testdata

---------

Signed-off-by: Evan Gibler <[email protected]>
Co-authored-by: Evan Gibler <[email protected]>
  • Loading branch information
tstromberg and egibs authored Dec 16, 2024
1 parent 3903332 commit c234760
Show file tree
Hide file tree
Showing 111 changed files with 758 additions and 163 deletions.
9 changes: 5 additions & 4 deletions pkg/action/testdata/scan_archive
Original file line number Diff line number Diff line change
Expand Up @@ -1626,15 +1626,16 @@
"RuleName": "temp"
},
{
"Description": "Uses mktemp to create temporary files",
"Description": "creates temporary files",
"MatchStrings": [
"mktemp",
"temp file"
"temp file",
"tmpfile"
],
"RiskScore": 1,
"RiskLevel": "LOW",
"RuleURL": "https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/tempdir/tempfile-create.yara#mktemp",
"ID": "fs/tempdir/tempfile_create",
"RuleURL": "https://github.com/chainguard-dev/malcontent/blob/main/rules/fs/tempfile.yara#mktemp",
"ID": "fs/tempfile",
"RuleName": "mktemp"
},
{
Expand Down
12 changes: 12 additions & 0 deletions rules/anti-static/elf/multiple.yara
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import "elf"

rule multiple_elf: medium {
meta:
description = "multiple ELF binaries within an ELF binary"

strings:
$elf_head = "\x7fELF"
condition:
uint32(0) == 1179403647 and #elf_head > 1
}
10 changes: 10 additions & 0 deletions rules/anti-static/obfuscation/hidden_literals.yara
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
rule hidden_literals: medium {
meta:
description = "references hidden literals"

strings:
$ref = "hidden_literals"
condition:
filesize < 10MB and $ref
}
61 changes: 26 additions & 35 deletions rules/anti-static/xor/xor-commands.yara
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,32 @@ 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_dev_null = "/dev/null" xor(1-31)
$b_usr_bin = "/usr/bin" xor(1-31)
$b_usr_sbin = "/usr/sbin" xor(1-31)
$b_var_tmp = "/var/tmp" xor(1-31)
$b_var_run = "/var/run" 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_dev_null2 = "/dev/null" xor(33-255)
$b_usr_bin2 = "/usr/bin" xor(33-255)
$b_usr_sbin2 = "/usr/sbin" xor(33-255)
$b_var_tmp2 = "/var/tmp" xor(33-255)
$b_var_run2 = "/var/run" 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_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"
condition:
Expand Down
32 changes: 32 additions & 0 deletions rules/anti-static/xor/xor-paths.yara
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
rule xor_paths: high {
meta:
description = "paths obfuscated using xor"

strings:
$dev_shm = "/dev/shm" xor(1-31)
$dev_shm2 = "/dev/shm" xor(33-255)
$dev_null = "/dev/null" xor(1-31)
$dev_null2 = "/dev/null" xor(33-255)
$dev_stdin = "/dev/stdin" xor(1-31)
$dev_stdin2 = "/dev/stdin" xor(33-255)
$dev_stderr = "/dev/stderr" xor(1-31)
$dev_stderr2 = "/dev/stderr" xor(33-255)
$proc_net_tcp = "/proc/net/tcp" xor(1-31)
$proc_net_tcp2 = "/proc/net/tcp" xor(33-255)
$var_log_wtmp = "/var/log/wtmp" xor(1-31)
$var_log_wtmp2 = "/var/log/wtmp" xor(33-255)
$var_run_utmp = "/var/run/utmp" xor(1-31)
$var_run_utmp2 = "/var/run/utmp" xor(33-255)
$usr_bin = "/usr/bin" xor(1-31)
$usr_sbin = "/usr/sbin" xor(1-31)
$var_tmp = "/var/tmp" xor(1-31)
$var_run = "/var/run" xor(1-31)
$usr_bin2 = "/usr/bin" xor(33-255)
$usr_sbin2 = "/usr/sbin" xor(33-255)
$var_tmp2 = "/var/tmp" xor(33-255)
$var_run2 = "/var/run" xor(33-255)
condition:
filesize < 10MB and any of them
}

26 changes: 26 additions & 0 deletions rules/anti-static/xor/xor-terms.yara
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
rule xor_terms: high {
meta:
description = "terms obfuscated using xor"

strings:
$LIBRARY = "LIBRARY" xor(1-31)
$LIBRARY2 = "LIBRARY" xor(33-255)
$INFECT = "INFECT" xor(1-31)
$INFECT2 = "INFECT" xor(33-255)
$MAGIC = "MAGIC" xor(1-31)
$MAGIC2 = "MAGIC" xor(33-255)
$plugin = "plugin" xor(1-31)
$plugin2 = "plugin2" xor(33-255)
$debug = "debug" xor(1-31)
$debug2 = "debug2" xor(33-255)
$evil = " evil " xor(1-31)
$evil2 = " evil " xor(33-255)
$environ = "environ" xor(1-31)
$environ2 = "environ" xor(33-255)
$xterm = "xterm" xor(1-31)
$xterm2 = "xterm" xor(33-255)
condition:
filesize < 5MB and any of them
}
38 changes: 36 additions & 2 deletions rules/discover/multiple.yara
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ rule sys_net_recon: medium {
$net_ipconfig = "ipconfig" fullword
$net_ipaddr = "ipaddr" fullword
$sys_getpass = "getpass.getuser"
$sys_whoami = "whoami" fullword
$sys_platform_node = "platform.node()" fullword
$sys_platform_platform = "platform.platform()" fullword
$sys_platform_system = "platform.system()" fullword
Expand All @@ -19,15 +20,48 @@ rule sys_net_recon: medium {
$sys_id = "id" fullword
$sys_lspi = "lspci"
$sys_sudo = /sudo.{0,4}-l/
$sys_uname = "uname -a"
$sys_whoami = "whoami" fullword
$sys_uname_a = "uname -a"
$sys_uname_r = "uname -r"
$sys_macos = "isPlatformOrVariant"
$sys_systeminfo = "systeminfo" fullword
condition:
filesize < 512KB and any of ($sys*) and any of ($net*)
}

rule user_sys_net_disk_recon: high {
meta:
description = "collects user, system, disk, and network information"

strings:
$net_ipconfig = "ipconfig"
$net_ipaddr = "ipaddr" fullword
$user_getpass = "getpass.getuser"
$user_whoami = "whoami"
$sys_platform_node = "platform.node()" fullword
$sys_platform_platform = "platform.platform()" fullword
$sys_platform_system = "platform.system()" fullword
$sys_tasklist = /tasklist.{0,4}\/svc/ fullword
$net_ifconfig = "ifconfig" fullword
$net_ip_addr = /ip.{0,4}addr/ fullword
$net_ip_route = /ip.{0,4}route/
$net_netstat = /netstat.{0,4}-[arn]/
$net_ufw = /ufw.{0,4}status/
$sys_hostname = "hostname" fullword
$sys_id = "id" fullword
$sys_lspi = "lspci"
$sys_sudo = /sudo.{0,4}-l/
$sys_uname_a = "uname -a"
$sys_uname_r = "uname -r"
$sys_macos = "isPlatformOrVariant"
$sys_systeminfo = "systeminfo" fullword
$disk_df_h = "df -h"
$disk_space = "Disk space"
condition:
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"
Expand Down
2 changes: 1 addition & 1 deletion rules/evasion/file/location/multiple.yara
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
rule multiple_elf: high linux {
rule multiple_elf_system_paths: high linux {
meta:
description = "references multiple system paths, may be trying to hide content"

Expand Down
12 changes: 12 additions & 0 deletions rules/evasion/file/prefix/prefix.yara
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ rule static_hidden_path: medium {
$ref
}

rule known_hidden_path: critical {
meta:
description = "known hidden file path"

strings:
$xl1 = /[a-z\/]{0,24}\/(var|usr|tmp|lib)\/[a-z\/]{0,24}\/\.Xl1[\w\_\-\.]{0,16}/
$kde_root = /[a-z\/]{0,24}\/(var|usr|tmp|lib)\/[a-z\/]{0,24}\/\.kde-root[\w\_\-\.]{0,16}/
condition:
any of them
}

rule hidden_path: medium {
meta:
description = "hidden path in a system directory"
Expand Down
12 changes: 12 additions & 0 deletions rules/evasion/logging/hide_shell_history.yara
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ rule hide_shell_history: high {
any of ($h*) and none of ($not*)
}

rule histfile_xor: high {
meta:
description = "commands obfuscated using xor"

strings:
$HISTFILE = "HISTFILE" xor(1-31)
$HISTFILE2 = "HISTFILE" xor(33-255)
condition:
filesize < 10MB and any of them
}

rule histfile_savehist_ld: high {
meta:
description = "likely hides shell command history"
Expand Down
16 changes: 16 additions & 0 deletions rules/evasion/rootkit/userspace.yara
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@ rule readdir_intercept: high {
filesize < 2MB and uint32(0) == 1179403647 and all of ($r*) and none of ($not*)
}

rule readdir_dlsym_interceptor: high {
meta:
description = "userland rootkit designed to hide files (readdir)"

filetypes = "so,c"

strings:
$dlsym = "dlsym" fullword
$readdir64 = "readdir64" fullword
$readlink_maybe_not_needed = "readlink"
$proc = "/proc"
condition:
filesize < 1MB and uint32(0) == 1179403647 and all of them
}

rule readdir_tcp_wrapper_intercept: high {
meta:
description = "userland rootkit designed to hide files and bypass tcp-wrappers"
Expand Down
3 changes: 2 additions & 1 deletion rules/exec/dylib/symbol-address.yara
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ rule dlsym: medium {
description = "get the address of a symbol"

strings:
$ref = "dlsym" fullword
$ref = "dlsym" fullword
$ref2 = "dlvsym" fullword
condition:
any of them
Expand Down
22 changes: 22 additions & 0 deletions rules/exec/program/program.yara
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,25 @@ rule npm_exec: medium {
condition:
all of them
}

rule hash_bang_bash_exec: high {
meta:
description = "starts program from a hash-bang line"

strings:
$bin_bash = /#!\/bin\/bash\s{1,256}\/[\w\/\.\-]{2,64}/
condition:
all of them and $bin_bash at 0
}

rule hash_bang_sh_exec: high {
meta:
description = "starts program from a hash-bang line"

strings:
$bin_sh = /#!\/bin\/sh\s{1,256}\/[\w\/\.\-]{2,64}/
condition:
all of them and $bin_sh at 0
}
1 change: 1 addition & 0 deletions rules/exec/shell/arbitrary_command-dev_null.yara
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ rule cmd_dev_null_quoted: high {
strings:
$ref = /"%s" {0,2}[12&]{0,1}> {0,1}\/dev\/null/
$ref2 = "\"%s\" >/dev/null"
$ref3 = /.{0,64} %s 2\>\/dev\/null/
condition:
any of them
Expand Down
15 changes: 15 additions & 0 deletions rules/fs/proc/pid-cmdline.yara
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import "math"

rule proc_s_cmdline: high {
meta:
description = "access command-line of other processes"
Expand Down Expand Up @@ -45,3 +47,16 @@ rule proc_py_cmdline: high {
condition:
any of them
}

rule proc_cmdline_near: high {
meta:
description = "access command-line for other processes"

strings:
$proc = "/proc" fullword
$fmt = "cmdline" fullword
$fmt_d = "%d" fullword
condition:
all of them and math.abs(@proc - @fmt) < 64 and math.abs(@fmt - @fmt_d) < 64
}
12 changes: 12 additions & 0 deletions rules/fs/proc/pid-fd.yara
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,15 @@ rule proc_fd_high: medium {
condition:
$ref and none of ($not*)
}

rule inspects_opened_sockets: high {
meta:
description = "inspects open file descriptors, looking for sockets"

strings:
$ref = "socket:[" fullword
$ref2 = /\/proc\/[%{$][\w\}]{0,12}\/fd/
condition:
all of them
}
Loading

0 comments on commit c234760

Please sign in to comment.