Skip to content

Commit

Permalink
Improve detection of malicious RubyGems (#588)
Browse files Browse the repository at this point in the history
* rules

Add RubyGems inspired rules

* refresh testdata
  • Loading branch information
tstromberg authored Nov 6, 2024
1 parent e61545e commit 9470054
Show file tree
Hide file tree
Showing 65 changed files with 441 additions and 71 deletions.
7 changes: 3 additions & 4 deletions rules/anti-behavior/anti-debugger.yara
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
rule win_debugger_present: medium {
rule win_debugger_present: medium windows {
meta:
description = "Detects if process is being executed within a debugger"

strings:
$debug_idp = "IsDebuggerPresent"
$debug_qpc = "QueryPerformanceCounter"
$debug_uhf = "UnhandledExceptionFilter"
condition:
filesize < 25MB and $debug_idp and any of ($debug*)
filesize < 25MB and any of them
}

rule win_debugger_or_cpu: medium {
rule win_debugger_or_vm: medium windows {
meta:
description = "Detects if process is being executed within a debugger or VM"

Expand Down
1 change: 1 addition & 0 deletions rules/anti-static/obfuscation/ruby.yara
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions rules/data/embedded/embedded-base64-gzip.yara
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ rule base64_gz_small: high {
$not_assertEquals = "assertEquals" fullword
$not_test_case = "test_case" fullword
$not_gzipped_binary = "gzipped binary" fullword
$not_example = "H4sIAAAAAAAAAOlongstringtoken"
condition:
filesize < 32KB and $header and none of ($not*)
Expand Down
14 changes: 14 additions & 0 deletions rules/discover/ip/public_ip.yara
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,34 @@ rule iplookup_website: high {
$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"
condition:
any of them
}

rule iplookup_obfuscated: critical {
meta:
description = "obfuscated public service to discover external IP address"

strings:
$ipify_x = "ipify.org" xor(1-255)
$wtfismyip_x = "wtfismyip" xor(1-255)
$iplogger_x = "iplogger.org" xor(1-255)
$grabify_x = "grabify.link" xor(1-255)
$getjsonip_x = "getjsonip" xor(1-255)
$ipinfo_x = "ipinfo.io" xor(1-255)
$iplog_ugh = /iplogger\".{0,8}org/
condition:
any of them
}

rule iplookup_website_base64: critical {
Expand Down
11 changes: 11 additions & 0 deletions rules/evasion/hidden_files/hidden.yara
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ rule hidden_short_path: high {
$crit and none of ($not*)
}

rule hidden_shell_script: high {
meta:
description = "hidden shell script"

strings:
$crit = /[\w\/\.]{0,32}\/(tmp|usr\/\w{0,8}|bin|lib|LaunchAgents|lib64|var|etc|shm|mqueue|spool|log|Users|Movies|Music|WebServer|Applications|Shared|Library|System)\/\.\w.{0,32}\.sh/ fullword
condition:
$crit
}

rule hidden_danger_path: critical {
meta:
description = "hidden dangerous-looking path in a system directory"
Expand Down
14 changes: 7 additions & 7 deletions rules/evasion/mimicry/fake-process.yara
Original file line number Diff line number Diff line change
Expand Up @@ -63,17 +63,17 @@ rule known_fake_process_names: high {
description = "mentions known fake process name"

strings:
$kdevchecker = "kdevchecker" fullword
$kworkerr = "kworkerr" fullword
$ksoftriqd = "ksoftriqd" fullword
$kdevtmpfsi = "kdevtmpfsi" fullword
$kthreaddk = "kthreaddk" fullword
$deamon = "deamon" fullword
$e_kdevchecker = "kdevchecker" fullword
$e_kworkerr = "kworkerr" fullword
$e_ksoftriqd = "ksoftriqd" fullword
$e_kdevtmpfsi = "kdevtmpfsi" fullword
$e_kthreaddk = "kthreaddk" fullword
$e_deamon = "deamon" fullword
$not_password_list = "qwer1234"
condition:
filesize < 10MB and any of them and not ($deamon and $not_password_list)
filesize < 10MB and any of ($e*) and not ($e_deamon and $not_password_list)
}

rule multiple_known_fake_process_names: critical {
Expand Down
26 changes: 26 additions & 0 deletions rules/exec/cmd/cmd.yara
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,29 @@ rule exec: medium {
condition:
any of them
}

rule ruby_exec: medium {
meta:
description = "executes a command"
filetypes = "rb"

strings:
$require = "require" fullword
$val = /exec\(".{2,64}"\)/
condition:
filesize < 1MB and $require and $val
}

rule ruby_run_exe: high {
meta:
description = "runs an executable program"
filetypes = "rb"

strings:
$require = "require" fullword
$val = /exec\(".{0,64}\.exe"\)/
condition:
filesize < 1MB and $require and $val
}
2 changes: 2 additions & 0 deletions rules/exec/dylib/open.yara
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ rule dylib: harmless {
strings:
$dlopen = "dlopen" fullword
$dlclose = "dlclose" fullword
$win = "LoadLibrary"
condition:
any of them
}

12 changes: 12 additions & 0 deletions rules/exec/program/program.yara
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,18 @@ rule perl_system: notable {
filesize < 65535 and $perl and $system
}

rule ruby_system: medium {
meta:
description = "executes external program"

strings:
$system = /system\(.{1,32}\)/
$require = "require" fullword
condition:
filesize < 65535 and $require and $system
}

rule py_subprocess: notable {
meta:
syscall = "execve"
Expand Down
9 changes: 5 additions & 4 deletions rules/exec/remote_commands/code_eval.yara
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ rule eval: medium {
$not_empty = "eval()"
condition:
$val and none of ($not*)
filesize < 1MB and $val and none of ($not*)
}

rule python_exec: medium {
Expand All @@ -21,11 +21,12 @@ rule python_exec: medium {
hash_2023_misc_mr_robot = "630bbcf0643d9fc9840f2f54ea4ae1ea34dc94b91ee011779c8e8c91f733c9f5"

strings:
$val = /exec\([a-z\"\'\(\,\)]{1,32}/ fullword
$empty = "exec()"
$import = "import" fullword
$val = /exec\([a-z\"\'\(\,\)]{1,32}/ fullword
$empty = "exec()"
condition:
$val and not $empty
filesize < 1MB and $import and $val and not $empty
}

rule shell_eval: medium {
Expand Down
1 change: 1 addition & 0 deletions rules/exfil/smtp.yara
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

67 changes: 67 additions & 0 deletions rules/exfil/stealer/browser.yara
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,70 @@ rule leveldb_exfil: high {
condition:
filesize < 3MB and $leveldb and any of ($h*) and 3 of ($b*)
}

rule select_chrome_obviously: high {
meta:
description = "Steals data from the Chrome Browser"

strings:
$chrome = "steal_chrome"
$cookie = "cookie"
$cookie2 = "Cookie"
condition:
filesize < 1MB and $chrome and any of ($cook*)
}

rule sqlite3_chrome_cookies: high {
meta:
description = "Reads Chrome Browser cookies"

strings:
$Chrome = "Chrome"
$Google = "Google"
$Cookies = "Cookies"
$sqlite3_up = "SQLite3"
$sqlite3_down = "sqlite3"
condition:
filesize < 128KB and all of them
}

rule select_chrome_cookies: high {
meta:
description = "Reads Chrome Browser cookies"

strings:
$Chrome = "Chrome"
$select = /SELECT \* FROM .{0,1}cookies/
condition:
filesize < 128KB and all of them
}

rule sqlite3_chrome_logins: high {
meta:
description = "Reads Chrome Browser logins"

strings:
$Chrome = "Chrome"
$Google = "Google"
$login_data = "Login Data"
$sqlite3_up = "SQLite3"
$sqlite3_down = "sqlite3"
condition:
filesize < 128KB and all of them
}

rule select_chrome_logins: high {
meta:
description = "Reads Chrome Browser logins"

strings:
$Chrome = "Chrome"
$select = /SELECT \* FROM .{0,1}logins/
condition:
filesize < 128KB and all of them
}
15 changes: 15 additions & 0 deletions rules/exfil/stealer/creds.yara
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,18 @@ rule suspected_data_stealer: high {
condition:
(8 of them and none of ($not*)) or 5 of ($s*)
}

rule steal_creds: high {
meta:
description = "may steal credentials"

strings:
$StealCreds = "StealCreds"
$StealCredentials = "StealCredentials"
$steal_credentials = "steal_credentials"
$steal_creds = "steal_creds" fullword
condition:
any of them
}

1 change: 1 addition & 0 deletions rules/fs/directory/directory-create.yara
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ rule mkdir {
$mkdir = "mkdir" fullword
$createFolder = "createFolder" fullword
$py = "os.makedirs" fullword
$win = /CreateDirectory\w{0,8}/
condition:
any of them
Expand Down
11 changes: 11 additions & 0 deletions rules/fs/file/file-create.yara
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,14 @@ rule creat: medium {
condition:
all of them in (1000..3000)
}

rule CreateFile: medium {
meta:
description = "create a new file"

strings:
$create = /CreateFile\w{0,8}/
condition:
any of them
}
11 changes: 11 additions & 0 deletions rules/fs/file/file-delete.yara
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,14 @@ rule del: medium windows {
condition:
filesize < 16KB and $del and any of ($cmd*)
}

rule DeleteFile: medium {
meta:
description = "delete a file"

strings:
$create = /DeleteFile\w{0,8}/
condition:
any of them
}
11 changes: 11 additions & 0 deletions rules/fs/file/file-make_executable.yara
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,14 @@ rule chmod_executable_ruby: high {
condition:
any of them
}

rule rename_executable_ruby: high windows {
meta:
description = "renames a file to become executable"

strings:
$rename = /File\.rename\(.{0,24}\w{0,8}\.exe\"\)/
condition:
any of them
}
2 changes: 2 additions & 0 deletions rules/fs/file/file-rename.yara
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ rule rename: harmless posix {
$rename = "rename" fullword
$renameat = "renameat" fullword
$rename_file = "renameFile" fullword
$move_file = "MoveFile"
$ruby = "File.rename"
condition:
any of them
Expand Down
14 changes: 13 additions & 1 deletion rules/fs/file/file-write.yara
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ rule file_write {
description = "writes to file"

strings:
$ref = /[\w\:]{0,16}write[\w\:]{0,8}File[\w\:]{0,32}/
$ref = /[\w\:]{0,16}write[\w\:]{0,8}File[\w\:]{0,32}/
$ref2 = "WriteFile"
condition:
any of them
Expand All @@ -20,6 +21,17 @@ rule python_file_write {
filesize < 1MB and any of them
}

rule ruby_file_write: medium {
meta:
description = "writes to a file"

strings:
$val = /File\.open\(.{1,64}, {0,2}["'][wa]["']\)/
condition:
filesize < 1MB and any of them
}

rule powershell_fs_write {
meta:
description = "writes content to disk"
Expand Down
1 change: 1 addition & 0 deletions rules/impact/remote_access/remote_eval.yara
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ rule remote_eval: critical {
strings:
$http = "http"
$eval_open_ruby = /eval\(open[\(\)\"\'\-\w:\/\.]{0,64}/
$eval_http_ruby = /eval\(Net::HTTP.get.{0,4}[\(\)\"\'\-\w:\/\.]{0,64}/
$exec_requests = /exec\(requests\.get[\(\)\"\'\-\w:\/\.]{0,64}/
$eval_requests = /eval\(requests\.get[\(\)\"\'\-\w:\/\.]{0,64}/
$eval_request_urllib = /exec\(urllib\.request\.urlopen\([\(\)\"\'\-\w:\/\.]{0,64}\).read\(\)/
Expand Down
Loading

0 comments on commit 9470054

Please sign in to comment.