From f93a18d1125fcf2eab16fc1f6b578a21280aa4e2 Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Mon, 7 Nov 2022 20:36:37 -0500 Subject: [PATCH] Refactor execdir, remove false positives --- .../c2/unexpected-dns-traffic-events.sql | 2 + .../c2/unexpected-https-client-linux.sql | 5 ++- detection/c2/unexpected-talkers-linux.sql | 4 +- detection/evasion/empty_environ_linux.sql | 2 + .../execution/exotic-command-events-linux.sql | 1 + .../execution/exotic-command-events-macos.sql | 3 +- .../recently-created-executables-linux.sql | 10 ++--- .../unexpected-execdir-events-macos.sql | 26 +++++------ .../execution/unexpected-execdir-macos.sql | 24 +++++----- .../unexpected-listening-port-linux.sql | 1 + .../unexpected-listening-port-macos.sql | 0 .../unexpected-uid0-daemon-linux.sql | 2 + .../privesc/setxid-env-overflow-attempt.sql | 36 +++++++++++++++ ...pected-elevated-children-events_linux.sql} | 6 ++- ...xpected-elevated-children-events_macos.sql | 45 +++++++++++++++++++ ...unexpected-privilege-escalation_linux.sql} | 6 +-- .../unexpected-privilege-escalation_macos.sql | 44 ++++++++++++++++++ 17 files changed, 179 insertions(+), 38 deletions(-) rename detection/{c2 => persistence}/unexpected-listening-port-linux.sql (98%) rename detection/{c2 => persistence}/unexpected-listening-port-macos.sql (100%) create mode 100644 detection/privesc/setxid-env-overflow-attempt.sql rename detection/privesc/{unexpected-privilege-escalation-events.sql => unexpected-elevated-children-events_linux.sql} (96%) create mode 100644 detection/privesc/unexpected-elevated-children-events_macos.sql rename detection/privesc/{unexpected-privilege-escalation.sql => unexpected-privilege-escalation_linux.sql} (96%) create mode 100644 detection/privesc/unexpected-privilege-escalation_macos.sql diff --git a/detection/c2/unexpected-dns-traffic-events.sql b/detection/c2/unexpected-dns-traffic-events.sql index ee542b3..47dbb2c 100644 --- a/detection/c2/unexpected-dns-traffic-events.sql +++ b/detection/c2/unexpected-dns-traffic-events.sql @@ -63,6 +63,7 @@ WHERE '8.8.8.8', -- Google '8.8.4.4', -- Google (backup) '208.67.222.222', -- OpenDNS + '208.67.222.123', -- OpenDNS '75.75.75.75', -- Comcast '75.75.76.76', -- Comcast '68.105.28.13' -- Cox @@ -71,6 +72,7 @@ WHERE AND exception_key NOT IN ( 'coredns,0.0.0.0,53', 'syncthing,46.162.192.181,53', + 'Code Helper,208.67.222.123,53', 'Jabra Direct Helper,208.67.222.123,53' ) AND p.name != 'nessusd' diff --git a/detection/c2/unexpected-https-client-linux.sql b/detection/c2/unexpected-https-client-linux.sql index ef2b742..123c32d 100644 --- a/detection/c2/unexpected-https-client-linux.sql +++ b/detection/c2/unexpected-https-client-linux.sql @@ -89,11 +89,11 @@ WHERE '500,/home/chainctl,500u,500g,chainctl', '500,/home/code,500u,500g,code', '500,/home/gitsign,500u,500g,gitsign', - '500,/home/ko,500u,500g,ko', '500,/home/go,500u,500g,go', '500,/home/grype,500u,500g,grype', '500,/home/java,500u,500g,java', '500,/home/jcef_helper,500u,500g,jcef_helper', + '500,/home/ko,500u,500g,ko', '500,/home/steam,500u,100g,steam', '500,/home/steamwebhelper,500u,100g,steamwebhelper', '500,/home/WPILibInstaller,500u,500g,WPILibInstaller', @@ -101,6 +101,7 @@ WHERE '500,/ko-app/controlplane,u,g,controlplane', '500,/opt/1password,0u,0g,1password', '500,/opt/Brackets,0u,0g,Brackets', + '500,/opt/todoist,0u,0g,todoist', '500,/opt/chrome,0u,0g,chrome', '500,/opt/Discord,0u,0g,Discord', '500,/opt/firefox,0u,0g,firefox', @@ -108,6 +109,7 @@ WHERE '500,/opt/kubectl,0u,0g,kubectl', '500,/opt/slack,0u,0g,slack', '500,/opt/spotify,0u,0g,spotify', + '500,/usr/spotify,0u,0g,spotify', '500,/tmp/jetbrains-toolbox,u,g,jetbrains-toolb', '500,/usr/abrt-action-generate-core-backtrace,0u,0g,abrt-action-gen', '500,/usr/bom,500u,500g,bom', @@ -138,6 +140,7 @@ WHERE '500,/usr/rpi-imager,0u,0g,rpi-imager', '500,/usr/signal-desktop,0u,0g,signal-desktop', '500,/usr/slack,0u,0g,slack', + '500,/usr/spotify,0u,0g,spotify', '500,/usr/syncthing,0u,0g,syncthing', '500,/usr/terraform,0u,0g,terraform', '500,/usr/trivy,0u,0g,trivy', diff --git a/detection/c2/unexpected-talkers-linux.sql b/detection/c2/unexpected-talkers-linux.sql index 7b93e5e..3c358f9 100644 --- a/detection/c2/unexpected-talkers-linux.sql +++ b/detection/c2/unexpected-talkers-linux.sql @@ -92,11 +92,12 @@ WHERE '32768,6,0,/usr/tailscaled,0u,0g,tailscaled', '3443,6,500,/opt/chrome,0u,0g,chrome', '3478,6,500,/opt/chrome,0u,0g,chrome', - '4070,6,500,/opt/spotify,0u,0g,spotify', '3478,6,500,/usr/firefox,0u,0g,firefox', + '4070,6,500,/opt/spotify,0u,0g,spotify', '43,6,500,/usr/whois,0u,0g,whois', '5228,6,500,/opt/chrome,0u,0g,chrome', '5228,6,500,/usr/chrome,0u,0g,chrome', + '67,17,0,/usr/NetworkManager,0u,0g,NetworkManager', '8000,6,500,/opt/chrome,0u,0g,chrome', '8000,6,500,/usr/firefox,0u,0g,firefox', '80,6,0,/usr/applydeltarpm,0u,0g,applydeltarpm', @@ -125,6 +126,7 @@ WHERE '8443,6,500,/opt/chrome,0u,0g,chrome', '8443,6,500,/usr/firefox,0u,0g,firefox', '8801,17,500,/app/zoom.real,u,g,zoom.real', + '8801,17,500,/opt/zoom,0u,0g,zoom', '993,6,500,/app/thunderbird,u,g,thunderbird' ) AND NOT ( diff --git a/detection/evasion/empty_environ_linux.sql b/detection/evasion/empty_environ_linux.sql index 4c2b396..e8e4b26 100644 --- a/detection/evasion/empty_environ_linux.sql +++ b/detection/evasion/empty_environ_linux.sql @@ -34,6 +34,8 @@ WHERE -- This time should match the interval 'chrome', 'jcef_helper', 'slack', + 'gnome-boxes-sea', + 'gnome-contacts-', 'sshd', 'zoom.real', 'zypak-sandbox' diff --git a/detection/execution/exotic-command-events-linux.sql b/detection/execution/exotic-command-events-linux.sql index 1bc96f7..c8d3b30 100644 --- a/detection/execution/exotic-command-events-linux.sql +++ b/detection/execution/exotic-command-events-linux.sql @@ -69,6 +69,7 @@ WHERE OR cmd LIKE '%iptables -F%' OR cmd LIKE '%chattr -ia%' OR cmd LIKE '%chmod 777 %' + OR cmd LIKE '%history' OR cmd LIKE '%touch%acmr%' OR cmd LIKE '%touch -r%' OR cmd LIKE '%ld.so.preload%' diff --git a/detection/execution/exotic-command-events-macos.sql b/detection/execution/exotic-command-events-macos.sql index fa81ca9..7d0f063 100644 --- a/detection/execution/exotic-command-events-macos.sql +++ b/detection/execution/exotic-command-events-macos.sql @@ -82,6 +82,7 @@ WHERE OR cmd LIKE '%rm -f /tmp%' OR cmd LIKE '%xargs kill -9%' OR cmd LIKE '%nohup /bin/bash%' + OR cmd LIKE '%history' OR cmd LIKE '%echo%|%base64 --decode %|%' OR cmd LIKE '%launchctl list%' OR ( @@ -123,7 +124,7 @@ WHERE '/bin/launchctl list homebrew.mxcl.yabai', '/bin/launchctl asuser 0 /bin/launchctl list' ) - AND p.parent = -1 + OR p.parent = -1 ) AND NOT cmd LIKE '/bin/rm -f /tmp/periodic.%' AND NOT cmd LIKE 'rm -f /tmp/locate%/_updatedb%' diff --git a/detection/execution/recently-created-executables-linux.sql b/detection/execution/recently-created-executables-linux.sql index fec78b7..221949d 100644 --- a/detection/execution/recently-created-executables-linux.sql +++ b/detection/execution/recently-created-executables-linux.sql @@ -59,8 +59,9 @@ WHERE '/usr/bin/rpi-imager', '/usr/bin/tailscaled', '/usr/bin/udevadm', - '/usr/libexec/snapd/snapd', - '/usr/share/spotify-client/spotify', + '/usr/bin/wpa_supplicant', + '/usr/lib64/firefox/firefox', + '/usr/lib64/google-cloud-sdk/platform/bundledpythonunix/bin/python3', '/usr/lib/at-spi2-registryd', '/usr/lib/at-spi-bus-launcher', '/usr/libexec/docker/docker-proxy', @@ -73,12 +74,10 @@ WHERE '/usr/lib/gdm-x-session', '/usr/lib/google-cloud-sdk/platform/bundledpythonunix/bin/python3', '/usr/lib/polkit-1/polkitd', - '/usr/bin/wpa_supplicant', '/usr/lib/slack/chrome_crashpad_handler', '/usr/lib/slack/slack', '/usr/lib/snapd/snapd', '/usr/lib/systemd/systemd', - '/usr/lib64/google-cloud-sdk/platform/bundledpythonunix/bin/python3', '/usr/lib/systemd/systemd-journald', '/usr/lib/systemd/systemd-logind', '/usr/lib/systemd/systemd-oomd', @@ -88,7 +87,8 @@ WHERE '/usr/lib/xf86-video-intel-backlight-helper', '/usr/sbin/chronyd', '/usr/sbin/cupsd', - '/usr/sbin/tailscaled' + '/usr/sbin/tailscaled', + '/usr/share/spotify-client/spotify' ) AND NOT p.path LIKE '%-go-build%' AND NOT p.path LIKE '/home/%/bin/%' diff --git a/detection/execution/unexpected-execdir-events-macos.sql b/detection/execution/unexpected-execdir-events-macos.sql index c62128d..377d588 100644 --- a/detection/execution/unexpected-execdir-events-macos.sql +++ b/detection/execution/unexpected-execdir-events-macos.sql @@ -16,7 +16,7 @@ SELECT REGEX_MATCH (p.path, '(.*)/', 1) AS dir, REGEX_MATCH (p.path, '(/.*?/.*?/.*?)/', 1) AS top_dir, -- 3 levels deep REPLACE(file.directory, u.directory, '~') AS homedir, - REGEX_MATCH (REPLACE(file.directory, u.directory, '~'), '(~/.*?/.*?/)', 1) AS top_homedir, -- 2 levels deep + REGEX_MATCH (REPLACE(file.directory, u.directory, '~'), '(~/.*?/)', 1) AS top_homedir, -- 1 level deep p.cmdline, p.mode, p.cwd, @@ -110,23 +110,23 @@ WHERE '~/projects/go/bin' ) AND top_homedir NOT IN ( - '~/Applications/Chrome Apps.localized/', - '~/.config/nvm/', - '~/homebrew/Cellar/', - '~/Library/Application Support/', - '~/Library/Printers', - '~/.local/share', - '~/projects/go', - '~/code/src', - '~/.tflint.d/plugins', - '~/.vscode/extensions', - '~/.vs-kubernetes/tools' + '~/Applications/', + '~/code/', + '~/.config/', + '~/homebrew/', + '~/Library/', + '~/.local/', + '~/projects/', + '~/src/', + '~/.tflint.d/', + '~/.vscode/', + '~/.vs-kubernetes/' ) -- Locally built executables AND NOT ( signature.identifier = "a.out" AND homedir LIKE '~/%' - AND pp.name LIKE '%sh' + AND pp.name IN ('fish', 'sh', 'bash', 'zsh', 'terraform', 'code') ) AND dir NOT LIKE '../%' -- data issue AND dir NOT LIKE '/Applications/%' diff --git a/detection/execution/unexpected-execdir-macos.sql b/detection/execution/unexpected-execdir-macos.sql index 651db0d..33da0af 100644 --- a/detection/execution/unexpected-execdir-macos.sql +++ b/detection/execution/unexpected-execdir-macos.sql @@ -17,7 +17,7 @@ SELECT f.directory AS dir, REGEX_MATCH (p.path, '(/.*?/.*?/.*?)/', 1) AS top_dir, -- 3 levels deep REPLACE(f.directory, u.directory, '~') AS homedir, - REGEX_MATCH (REPLACE(f.directory, u.directory, '~'), '(~/.*?/.*?/)', 1) AS top_homedir, -- 2 levels deep + REGEX_MATCH (REPLACE(f.directory, u.directory, '~'), '(~/.*?/)', 1) AS top_homedir, -- 1 level deep p.cmdline, hash.sha256, pp.path AS parent_path, @@ -101,17 +101,17 @@ WHERE '~/projects/go/bin' ) AND top_homedir NOT IN ( - '~/Applications/Chrome Apps.localized/', - '~/.config/nvm/', - '~/homebrew/Cellar/', - '~/Library/Application Support/', - '~/Library/Printers', - '~/.local/share', - '~/projects/go', - '~/code/src', - '~/.tflint.d/plugins', - '~/.vscode/extensions', - '~/.vs-kubernetes/tools' + '~/Applications/', + '~/code/', + '~/.config/', + '~/homebrew/', + '~/Library/', + '~/.local/', + '~/projects/', + '~/src/', + '~/.tflint.d/', + '~/.vscode/', + '~/.vs-kubernetes/' ) -- Locally built executables AND NOT ( diff --git a/detection/c2/unexpected-listening-port-linux.sql b/detection/persistence/unexpected-listening-port-linux.sql similarity index 98% rename from detection/c2/unexpected-listening-port-linux.sql rename to detection/persistence/unexpected-listening-port-linux.sql index d460264..bf87ae4 100644 --- a/detection/c2/unexpected-listening-port-linux.sql +++ b/detection/persistence/unexpected-listening-port-linux.sql @@ -75,6 +75,7 @@ WHERE '32768,6,0,.tailscaled-wra', '32768,6,500,com.docker.backend', '32768,6,500,dleyna-renderer', + '32768,6,500,jetbrains-toolb', '32768,6,500,spotify', '3551,6,0,apcupsd', '4143,6,500,linkerd2-proxy', diff --git a/detection/c2/unexpected-listening-port-macos.sql b/detection/persistence/unexpected-listening-port-macos.sql similarity index 100% rename from detection/c2/unexpected-listening-port-macos.sql rename to detection/persistence/unexpected-listening-port-macos.sql diff --git a/detection/persistence/unexpected-uid0-daemon-linux.sql b/detection/persistence/unexpected-uid0-daemon-linux.sql index 9853cac..cabc902 100644 --- a/detection/persistence/unexpected-uid0-daemon-linux.sql +++ b/detection/persistence/unexpected-uid0-daemon-linux.sql @@ -53,6 +53,7 @@ WHERE '/usr/bin/crond', '/usr/bin/dbus-daemon', '/usr/bin/dbus-launch', + '/usr/bin/dnsmasq', '/usr/bin/dockerd', '/usr/bin/docker-proxy', '/usr/bin/fish', @@ -65,6 +66,7 @@ WHERE '/usr/bin/sshd', '/usr/bin/tailscaled', '/usr/bin/vim', + '/usr/bin/virtlogd', '/usr/bin/wpa_supplicant', '/usr/libexec/accounts-daemon', '/usr/libexec/docker/docker-proxy', diff --git a/detection/privesc/setxid-env-overflow-attempt.sql b/detection/privesc/setxid-env-overflow-attempt.sql new file mode 100644 index 0000000..3bb3532 --- /dev/null +++ b/detection/privesc/setxid-env-overflow-attempt.sql @@ -0,0 +1,36 @@ +-- Find setuid process events with large environment sizes +-- +-- ****************************************************************** +-- NOTE: This is a rare case of a non-working query. It does not work +-- in my environment (osquery 5.5.1 running with Kolide) as +-- process_events.env_size is NULL. I believe this to be a bug, but +-- requires more investigation. +-- ****************************************************************** +-- +-- tags: events process escalation disabled seldom +-- platform: posix +-- +-- Uncomment once the underlying problem is addressed: +-- XintervalX: 60 +SELECT + p.pid AS child_pid, + p.path AS child_path, + REGEX_MATCH (RTRIM(file.path, '/'), '.*/(.*?)$', 1) AS child_name, + p.cmdline AS child_cmdline, + p.euid AS child_euid, + file.mode AS child_mode, + p.parent AS parent_pid, + pp.cmdline AS parent_cmdline, + p.env, + p.env_size +FROM + process_events p + JOIN processes pp ON p.parent = pp.pid + LEFT JOIN file ON p.path = file.path + LEFT JOIN hash ON p.path = hash.path + LEFT JOIN file AS pfile ON pp.path = pfile.path + LEFT JOIN hash AS phash ON pp.path = phash.path +WHERE + p.time > (strftime('%s', 'now') -60) + AND file.mode NOT LIKE '0%' + AND p.env_size > 3500 diff --git a/detection/privesc/unexpected-privilege-escalation-events.sql b/detection/privesc/unexpected-elevated-children-events_linux.sql similarity index 96% rename from detection/privesc/unexpected-privilege-escalation-events.sql rename to detection/privesc/unexpected-elevated-children-events_linux.sql index 894f481..e922a44 100644 --- a/detection/privesc/unexpected-privilege-escalation-events.sql +++ b/detection/privesc/unexpected-elevated-children-events_linux.sql @@ -8,13 +8,15 @@ -- * unexpected-privilege-escalation.sql -- -- tags: events process escalation --- platform: posix +-- platform: linux -- interval: 30 SELECT p.pid AS child_pid, p.path AS child_path, REGEX_MATCH (RTRIM(file.path, '/'), '.*/(.*?)$', 1) AS child_name, p.cmdline AS child_cmdline, + p.time, + pp.start_time, p.euid AS child_euid, file.mode AS child_mode, hash.sha256 AS child_hash, @@ -24,7 +26,7 @@ SELECT pp.cmdline AS parent_cmdline, pp.euid AS parent_euid, pfile.mode AS parent_mode, - hash.sha256 AS parent_hash + phash.sha256 AS parent_hash FROM process_events p JOIN processes pp ON p.parent = pp.pid diff --git a/detection/privesc/unexpected-elevated-children-events_macos.sql b/detection/privesc/unexpected-elevated-children-events_macos.sql new file mode 100644 index 0000000..5b0f654 --- /dev/null +++ b/detection/privesc/unexpected-elevated-children-events_macos.sql @@ -0,0 +1,45 @@ +-- Find processes that run with a lower effective UID than their parent (event-based) +-- +-- references: +-- * https://attack.mitre.org/techniques/T1548/001/ (Setuid and Setgid) +-- * https://cybersecurity.att.com/blogs/labs-research/shikitega-new-stealthy-malware-targeting-linux +-- +-- related: +-- * unexpected-privilege-escalation.sql +-- +-- tags: events process escalation +-- platform: darwin +-- interval: 30 +SELECT + p.pid AS child_pid, + p.path AS child_path, + REGEX_MATCH (RTRIM(file.path, '/'), '.*/(.*?)$', 1) AS child_name, + p.cmdline AS child_cmdline, + p.time, + pp.start_time, + p.euid AS child_euid, + file.mode AS child_mode, + hash.sha256 AS child_hash, + p.parent AS parent_pid, + pp.path AS parent_path, + pp.name AS parent_name, + pp.cmdline AS parent_cmdline, + pp.euid AS parent_euid, + pfile.mode AS parent_mode, + phash.sha256 AS parent_hash +FROM + process_events p + JOIN processes pp ON p.parent = pp.pid + LEFT JOIN file ON p.path = file.path + LEFT JOIN hash ON p.path = hash.path + LEFT JOIN file AS pfile ON pp.path = pfile.path + LEFT JOIN hash AS phash ON pp.path = phash.path +WHERE + p.time > (strftime('%s', 'now') -30) + AND p.euid < pp.euid + AND p.path NOT IN ( + '/usr/bin/login', + '/usr/bin/su', + '/usr/bin/sudo', + '/usr/local/bin/doas' + ) diff --git a/detection/privesc/unexpected-privilege-escalation.sql b/detection/privesc/unexpected-privilege-escalation_linux.sql similarity index 96% rename from detection/privesc/unexpected-privilege-escalation.sql rename to detection/privesc/unexpected-privilege-escalation_linux.sql index a61843c..abfa6af 100644 --- a/detection/privesc/unexpected-privilege-escalation.sql +++ b/detection/privesc/unexpected-privilege-escalation_linux.sql @@ -8,7 +8,7 @@ -- * unexpected-privilege-escalation-events.sql -- -- tags: transient rapid state process escalation --- platform: posix +-- platform: linux SELECT p.pid AS child_pid, p.path AS child_path, @@ -24,7 +24,7 @@ SELECT pp.cmdline AS parent_cmdline, pp.euid AS parent_euid, pfile.mode AS parent_mode, - hash.sha256 AS parent_hash + phash.sha256 AS parent_hash FROM processes p JOIN processes pp ON p.parent = pp.pid @@ -33,7 +33,7 @@ FROM LEFT JOIN file AS pfile ON pp.path = pfile.path LEFT JOIN hash AS phash ON pp.path = phash.path WHERE - p.euid < pp.euid + p.euid < p.uid AND p.path NOT IN ( '/bin/ps', '/usr/bin/doas', diff --git a/detection/privesc/unexpected-privilege-escalation_macos.sql b/detection/privesc/unexpected-privilege-escalation_macos.sql new file mode 100644 index 0000000..03eb205 --- /dev/null +++ b/detection/privesc/unexpected-privilege-escalation_macos.sql @@ -0,0 +1,44 @@ +-- Find processes that run with a lower effective UID than their parent (state-based) +-- +-- references: +-- * https://attack.mitre.org/techniques/T1548/001/ (Setuid and Setgid) +-- * https://cybersecurity.att.com/blogs/labs-research/shikitega-new-stealthy-malware-targeting-linux +-- +-- related: +-- * unexpected-privilege-escalation-events.sql +-- +-- tags: transient rapid state process escalation +-- platform: darwin +SELECT + p.pid AS child_pid, + p.path AS child_path, + p.name AS child_name, + p.cmdline AS child_cmdline, + p.euid AS child_euid, + p.state AS child_state, + file.mode AS child_mode, + hash.sha256 AS child_hash, + p.parent AS parent_pid, + pp.path AS parent_path, + pp.name AS parent_name, + pp.cmdline AS parent_cmdline, + pp.euid AS parent_euid, + pfile.mode AS parent_mode, + phash.sha256 AS parent_hash +FROM + processes p + JOIN processes pp ON p.parent = pp.pid + LEFT JOIN file ON p.path = file.path + LEFT JOIN hash ON p.path = hash.path + LEFT JOIN file AS pfile ON pp.path = pfile.path + LEFT JOIN hash AS phash ON pp.path = phash.path +WHERE + p.euid < p.uid + AND p.path NOT IN ( + '/Library/DropboxHelperTools/Dropbox_u501/dbkextd', + '/usr/bin/login', + '/usr/bin/su', + '/usr/bin/sudo', + '/usr/local/bin/doas', + '/usr/bin/top' + )