diff --git a/rules/falco-deprecated_rules.yaml b/rules/falco-deprecated_rules.yaml index 57730b6f..d620d550 100644 --- a/rules/falco-deprecated_rules.yaml +++ b/rules/falco-deprecated_rules.yaml @@ -15,23 +15,34 @@ # See the License for the specific language governing permissions and # limitations under the License. # - -# Information about rules tags and fields can be found here: https://falco.org/docs/rules/#tags-for-current-falco-ruleset -# The initial item in the `tags` fields reflects the maturity level of the rules introduced upon the proposal https://github.com/falcosecurity/rules/blob/main/proposals/20230605-rules-adoption-management-maturity-framework.md -# `tags` fields also include information about the type of workload inspection (host and/or container), and Mitre Attack killchain phases and Mitre TTP code(s) +# Information about rules tags and fields can be found here: +# https://falco.org/docs/rules/#tags-for-current-falco-ruleset +# The initial item in the `tags` fields reflects the maturity level of +# the rules introduced upon the proposal +# Proposal: Rules Adoption Management Maturity Framework +# URL: https://github.com/falcosecurity/rules/blob/main/ +# proposals/20230605-rules-adoption-management-maturity-framework.md +# `tags` fields also include information about the type of +# workload inspection (host and/or container), and Mitre Attack killchain +# phases and Mitre TTP code(s) # Mitre Attack References: # [1] https://attack.mitre.org/tactics/enterprise/ -# [2] https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json +# [2] https://raw.githubusercontent.com/mitre/cti/master/ +# enterprise-attack/enterprise-attack.json # Starting with version 8, the Falco engine supports exceptions. # However the Falco rules file does not use them by default. -- required_engine_version: 0.31.0 +--- +required_engine_version: '0.31.0' -# This macro `never_true` is used as placeholder for tuning negative logical sub-expressions, for example +# This macro `never_true` is used as placeholder for +# tuning negative logical sub-expressions, for example # - macro: allowed_ssh_hosts # condition: (never_true) -# can be used in a rules' expression with double negation `and not allowed_ssh_hosts` which effectively evaluates -# to true and does nothing, the perfect empty template for `logical` cases as opposed to list templates. +# can be used in a rules' expression with double negation +# `and not allowed_ssh_hosts` which effectively evaluates +# to true and does nothing, the perfect empty template for +# `logical` cases as opposed to list templates. # When tuning the rule you can override the macro with something useful, e.g. # - macro: allowed_ssh_hosts # condition: (evt.hostname contains xyz) @@ -46,19 +57,20 @@ condition: > (((evt.type = connect and evt.dir=<) or (evt.type in (sendto,sendmsg) and evt.dir=< and - fd.l4proto != tcp and fd.connected=false and fd.name_changed=true)) and - (fd.typechar = 4 or fd.typechar = 6) and - (fd.ip != "0.0.0.0" and fd.net != "127.0.0.0/8" and not fd.snet in (rfc_1918_addresses)) and - (evt.rawres >= 0 or evt.res = EINPROGRESS)) + fd.l4proto != tcp and fd.connected=false and fd.name_changed=true)) and + (fd.typechar = 4 or fd.typechar = 6) and + (fd.ip != "0.0.0.0" and fd.net != "127.0.0.0/8" and + not fd.snet in (rfc_1918_addresses)) and + (evt.rawres >= 0 or evt.res = EINPROGRESS)) # Very similar to inbound/outbound, but combines the tests together # for efficiency. - macro: inbound_outbound condition: > ((((evt.type in (accept,accept4,listen,connect) and evt.dir=<)) and - (fd.typechar = 4 or fd.typechar = 6)) and - (fd.ip != "0.0.0.0" and fd.net != "127.0.0.0/8") and - (evt.rawres >= 0 or evt.res = EINPROGRESS)) + (fd.typechar = 4 or fd.typechar = 6)) and + (fd.ip != "0.0.0.0" and fd.net != "127.0.0.0/8") and + (evt.rawres >= 0 or evt.res = EINPROGRESS)) - macro: ssh_port condition: (fd.sport=22) @@ -77,19 +89,30 @@ condition: (never_true) - rule: Disallowed SSH Connection - desc: > - Detect any new SSH connection on port 22 to a host other than those in an allowed list of hosts. - This rule absolutely requires profiling your environment beforehand. Network-based rules are extremely - crucial in any security program, as they can often provide the only definitive evidence. However, - effectively operationalizing them can be challenging due to the potential for noise. - condition: > - inbound_outbound - and ssh_port + desc: > + Detect any new SSH connection on port 22 to a host other than + those in an allowed list of hosts. This rule absolutely requires + profiling your environment beforehand. Network-based rules are extremely + crucial in any security program, as they can often provide the only + definitive evidence. However, effectively operationalizing them can be + challenging due to the potential for noise. + condition: > + inbound_outbound + and ssh_port and not allowed_ssh_hosts enabled: false - output: Disallowed SSH Connection (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: > + Disallowed SSH Connection + (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type + fd_proto=fd.l4proto evt_type=%evt.type user=%user.name + user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: NOTICE - tags: [maturity_deprecated, host, container, network, mitre_lateral_movement, T1021.004] + tags: [ + maturity_deprecated, host, container, network, + mitre_latera_movement, T1021.004 + ] # These rules and supporting macros are more of an example for how to # use the fd.*ip and fd.*ip.name fields to match connection @@ -110,68 +133,93 @@ items: [google.com, www.yahoo.com] - rule: Unexpected outbound connection destination - desc: > - Detect any outbound connection to a destination outside of an allowed set of ips, networks, or domain names. - This rule absolutely requires profiling your environment beforehand. Network-based rules are extremely crucial - in any security program, as they can often provide the only definitive evidence. However, effectively operationalizing - them can be challenging due to the potential for noise. + desc: > + Detect any outbound connection to a destination outside of an allowed + set of ips, networks, or domain names. This rule absolutely requires + profiling your environment beforehand. Network-based rules are extremely + crucial in any security program, as they can often provide the only + definitive evidence. However, effectively operationalizing them can be + challenging due to the potential for noise. condition: > - outbound + outbound and not ((fd.sip in (allowed_outbound_destination_ipaddrs)) or - (fd.snet in (allowed_outbound_destination_networks)) or - (fd.sip.name in (allowed_outbound_destination_domains))) + (fd.snet in (allowed_outbound_destination_networks)) or + (fd.sip.name in (allowed_outbound_destination_domains))) enabled: false - output: Disallowed outbound connection destination (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: > + Disallowed outbound connection destination + (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type + fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + %container.info) + priority: NOTICE - tags: [maturity_deprecated, host, container, network, mitre_command_and_control, TA0011] + tags: [maturity_deprecated, host, container, network, + mitre_command_and_control, TA0011] # Use this to test whether the event occurred within a container. # When displaying container information in the output field, use # %container.info, without any leading term (file=%fd.name -# %container.info user=%user.name user_loginuid=%user.loginuid, and not file=%fd.name -# container=%container.info user=%user.name user_loginuid=%user.loginuid). The output will change -# based on the context and whether or not -pk/-pm/-pc was specified on -# the command line. +# %container.info user=%user.name user_loginuid=%user.loginuid, and +# not file=%fd.name container=%container.info user=%user.name +# user_loginuid=%user.loginuid). The output will change based on the context +# and whether or not -pk/-pm/-pc was specified on the command line. - macro: container condition: (container.id != host) - list: allowed_image - items: [] # add image to monitor, i.e.: bitnami/nginx + items: [] # add image to monitor, i.e.: bitnami/nginx - list: authorized_server_binary items: [] # add binary to allow, i.e.: nginx - + - list: authorized_server_port - items: [] # add port to allow, i.e.: 80 + items: [] # add port to allow, i.e.: 80 # # How to test: # kubectl run --image=nginx nginx-app --port=80 --env="DOMAIN=cluster" -# kubectl expose deployment nginx-app --port=80 --name=nginx-http --type=LoadBalancer +# kubectl expose deployment nginx-app +# --port=80 +# --name=nginx-http +# --type=LoadBalancer # # On minikube: # minikube service nginx-http # # On general K8s: # kubectl get services # kubectl cluster-info # # Visit the Nginx service and port, should not fire. -# # Change rule to different port, then different process name, and test again that it fires. +# # Change rule to different port, then different process name, and +# # test again that it fires. - rule: Outbound or Inbound Traffic not to Authorized Server Process and Port - desc: > - Detect traffic to an unauthorized server process and port within pre-defined containers. - This rule absolutely requires profiling your environment beforehand and also necessitates adjusting the list of containers - to which this rule will be applied. The current expression logic will never evaluate to true unless the list is populated. - Network-based rules are extremely crucial in any security program, as they can often provide the only definitive evidence. - However, effectively operationalizing them can be challenging due to the potential for noise. Notably, this rule is challenging - to operationalize. + desc: > + Detect traffic to an unauthorized server process and port within + pre-defined containers. This rule absolutely requires profiling + your environment beforehand and also necessitates adjusting the + list of containers to which this rule will be applied. The current + expression logic will never evaluate to true unless the list is + populated. Network-based rules are extremely crucial in any + security program, as they can often provide the only definitive + evidence. However, effectively operationalizing them can be + challenging due to the potential for noise. Notably, this rule is + challenging to operationalize. condition: > - inbound_outbound - and container - and container.image.repository in (allowed_image) - and not proc.name in (authorized_server_binary) + inbound_outbound + and container + and container.image.repository in (allowed_image) + and not proc.name in (authorized_server_binary) and not fd.sport in (authorized_server_port) enabled: false - output: Network connection outside authorized port and binary (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: > + Network connection outside authorized port and binary + (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type + fd_proto=fd.l4proto evt_type=%evt.type user=%user.name + user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: WARNING - tags: [maturity_deprecated, container, network, mitre_discovery, TA0011, NIST_800-53_CM-7] + tags: [maturity_deprecated, container, network, mitre_discovery, TA0011, + NIST_800-53_CM-7] - list: c2_server_ip_list items: [] @@ -180,17 +228,29 @@ items: [] - rule: Outbound Connection to C2 Servers - desc: > - Detect outbound connections to command and control servers using a list of IP addresses and fully qualified domain names (FQDNs). - This rule absolutely requires profiling your environment beforehand and also necessitates adjusting the template lists. The current - expression logic will never evaluate to true unless the lists are populated. Network-based rules are extremely crucial in any - security program, as they can often provide the only definitive evidence. However, effectively operationalizing them can be challenging - due to the potential for noise. Notably, this rule is challenging to operationalize. + desc: > + Detect outbound connections to command and control servers using a list + of IP addresses and fully qualified domain names (FQDNs). This rule + absolutely requires profiling your environment beforehand and also + necessitates adjusting the template lists. The current expression logic + will never evaluate to true unless the lists are populated. Network-based + rules are extremely crucial in any security program, as they can often + provide the only definitive evidence.However, effectively operationalizing + them can be challenging due to the potential for noise. Notably, this rule + is challenging to operationalize. condition: > - outbound + outbound and ((fd.sip in (c2_server_ip_list)) or - (fd.sip.name in (c2_server_fqdn_list))) - output: Outbound connection to C2 server (c2_domain=%fd.sip.name c2_addr=%fd.sip connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + (fd.sip.name in (c2_server_fqdn_list))) + output: > + Outbound connection to C2 server + (c2_domain=%fd.sip.name c2_addr=%fd.sip + connection=%fd.name lport=%fd.lport rport=%fd.rport + fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type + user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid + process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname + command=%proc.cmdline terminal=%proc.tty %container.info) priority: WARNING enabled: false - tags: [maturity_deprecated, host, container, network, mitre_command_and_control, TA0011] + tags: [maturity_deprecated, host, container, network, + mitre_command_and_control, TA0011] diff --git a/rules/falco-incubating_rules.yaml b/rules/falco-incubating_rules.yaml index d2472ac0..7a595eb3 100644 --- a/rules/falco-incubating_rules.yaml +++ b/rules/falco-incubating_rules.yaml @@ -16,40 +16,60 @@ # limitations under the License. # -# Information about rules tags and fields can be found here: https://falco.org/docs/rules/#tags-for-current-falco-ruleset -# The initial item in the `tags` fields reflects the maturity level of the rules introduced upon the proposal https://github.com/falcosecurity/rules/blob/main/proposals/20230605-rules-adoption-management-maturity-framework.md -# `tags` fields also include information about the type of workload inspection (host and/or container), and Mitre Attack killchain phases and Mitre TTP code(s) +# Information about rules tags and fields can be found here: +# https://falco.org/docs/rules/#tags-for-current-falco-ruleset +# The initial item in the `tags` fields reflects the maturitylevel of the rules +# introduced upon the proposal +# https://github.com/falcosecurity/rules/blob/main/proposals/ +# 20230605-rules-adoption-management-maturity-framework.md +# `tags` fields also include information about the type of +# workload inspection (host and/or container), and Mitre Attack killchain phases +# and Mitre TTP code(s) # Mitre Attack References: # [1] https://attack.mitre.org/tactics/enterprise/ -# [2] https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json +# [2] https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/ +# enterprise-attack.json # Starting with version 8, the Falco engine supports exceptions. # However the Falco rules file does not use them by default. +--- - required_engine_version: 0.31.0 - macro: open_write - condition: (evt.type in (open,openat,openat2) and evt.is_open_write=true and fd.typechar='f' and fd.num>=0) + condition: (evt.type in (open,openat,openat2) and evt.is_open_write=true and + fd.typechar='f' and fd.num>=0) - macro: open_read - condition: (evt.type in (open,openat,openat2) and evt.is_open_read=true and fd.typechar='f' and fd.num>=0) + condition: > + (evt.type in + ( + open,openat,openat2 + ) + and evt.is_open_read=true and fd.typechar='f' and fd.num>=0) - macro: open_directory - condition: (evt.type in (open,openat,openat2) and evt.is_open_read=true and fd.typechar='d' and fd.num>=0) + condition: (evt.type in (open,openat,openat2) and evt.is_open_read=true and + fd.typechar='d' and fd.num>=0) -# This macro `never_true` is used as placeholder for tuning negative logical sub-expressions, for example +# This macro `never_true` is used as placeholder for tuning negative logical +# sub-expressions, +# for example # - macro: allowed_ssh_hosts # condition: (never_true) -# can be used in a rules' expression with double negation `and not allowed_ssh_hosts` which effectively evaluates -# to true and does nothing, the perfect empty template for `logical` cases as opposed to list templates. +# can be used in a rules' expression with double negation `and +# not allowed_ssh_hosts` which effectively evaluates +# to true and does nothing, the perfect empty template for +# `logical` cases as opposed to list templates. # When tuning the rule you can override the macro with something useful, e.g. # - macro: allowed_ssh_hosts # condition: (evt.hostname contains xyz) - macro: never_true condition: (evt.num=0) -# This macro `always_true` is the flip side of the macro `never_true` and currently is commented out as -# it is not used. You can use it as placeholder for a positive logical sub-expression tuning template -# macro, e.g. `and custom_procs`, where +# This macro `always_true` is the flip side of the macro `never_true` and +# currently is commented out as it is not used. +# You can use it as placeholder for a positive logical sub-expression tuning +# template macro, e.g. `and custom_procs`, where # - macro: custom_procs # condition: (always_true) # later you can customize, override the macros to something like @@ -88,7 +108,7 @@ sshd, sftp-server, ssh-agent, ssh, scp, sftp, ssh-keygen, ssh-keysign, ssh-keyscan, ssh-add - ] + ] - list: coreutils_binaries items: [ @@ -102,38 +122,52 @@ tac, link, chroot, vdir, chown, touch, ls, dd, uname, "true", pwd, date, chgrp, chmod, mktemp, cat, mknod, sync, ln, "false", rm, mv, cp, echo, readlink, sleep, stty, mkdir, df, dir, rmdir, touch - ] + ] -# dpkg -L login | grep bin | xargs ls -ld | grep -v '^d' | awk '{print $9}' | xargs -L 1 basename | tr "\\n" "," +# dpkg -L login | +# grep bin | +# xargs ls -ld | +# grep -v '^d' | +# awk '{print $9}' | +# xargs -L 1 basename | +# tr "\\n" "," - list: login_binaries items: [ login, systemd, '"(systemd)"', systemd-logind, su, nologin, faillog, lastlog, newgrp, sg - ] + ] -# dpkg -L passwd | grep bin | xargs ls -ld | grep -v '^d' | awk '{print $9}' | xargs -L 1 basename | tr "\\n" "," +# dpkg -L passwd | +# grep bin | +# xargs ls -ld | +# grep -v '^d' | +# awk '{print $9}' | +# xargs -L 1 basename | +# tr "\\n" "," - list: passwd_binaries items: [ shadowconfig, grpck, pwunconv, grpconv, pwck, groupmod, vipw, pwconv, useradd, newusers, cppw, chpasswd, usermod, - groupadd, groupdel, grpunconv, chgpasswd, userdel, chage, chsh, - gpasswd, chfn, expiry, passwd, vigr, cpgr, adduser, addgroup, deluser, delgroup - ] + groupadd, groupdel, grpunconv, chgpasswd, userdel, chage, chsh, gpasswd, + chfn, expiry, passwd, vigr, cpgr, adduser, addgroup, deluser, delgroup + ] # repoquery -l shadow-utils | grep bin | xargs ls -ld | grep -v '^d' | # awk '{print $9}' | xargs -L 1 basename | tr "\\n" "," - list: shadowutils_binaries items: [ chage, gpasswd, lastlog, newgrp, sg, adduser, deluser, chpasswd, - groupadd, groupdel, addgroup, delgroup, groupmems, groupmod, grpck, grpconv, grpunconv, - newusers, pwck, pwconv, pwunconv, useradd, userdel, usermod, vigr, vipw, unix_chkpwd - ] + groupadd, groupdel, addgroup, delgroup, groupmems, groupmod, grpck, + grpconv, grpunconv, newusers, pwck, pwconv, pwunconv, useradd, + userdel, usermod, vigr, vipw, unix_chkpwd + ] - list: sysdigcloud_binaries items: [setup-backend, dragent, sdchecks] - list: k8s_binaries - items: [hyperkube, skydns, kube2sky, exechealthz, weave-net, loopback, bridge, openshift-sdn, openshift] + items: [hyperkube, skydns, kube2sky, exechealthz, weave-net, + loopback, bridge, openshift-sdn, openshift] - list: lxd_binaries items: [lxd, lxcfs] @@ -144,22 +178,29 @@ # The explicit quotes are needed to avoid the - characters being # interpreted by the filter expression. - list: rpm_binaries - items: [dnf, dnf-automatic, rpm, rpmkey, yum, '"75-system-updat"', rhsmcertd-worke, rhsmcertd, subscription-ma, - repoquery, rpmkeys, rpmq, yum-cron, yum-config-mana, yum-debug-dump, - abrt-action-sav, rpmdb_stat, microdnf, rhn_check, yumdb] + items: [ + dnf, dnf-automatic, rpm, rpmkey, yum, '"75-system-updat"', + rhsmcertd-worke, rhsmcertd, subscription-ma, + repoquery, rpmkeys, rpmq, yum-cron, yum-config-mana, yum-debug-dump, + abrt-action-sav, rpmdb_stat, microdnf, rhn_check, yumdb] - list: deb_binaries - items: [dpkg, dpkg-preconfigu, dpkg-reconfigur, dpkg-divert, apt, apt-get, aptitude, - frontend, preinst, add-apt-reposit, apt-auto-remova, apt-key, - apt-listchanges, unattended-upgr, apt-add-reposit, apt-cache, apt.systemd.dai - ] + items: [ + dpkg, dpkg-preconfigu, dpkg-reconfigur, dpkg-divert, apt, apt-get, + aptitude, frontend, preinst, add-apt-reposit, apt-auto-remova, + apt-key, apt-listchanges, unattended-upgr, apt-add-reposit, + apt-cache, apt.systemd.dai + ] - list: python_package_managers items: [pip, pip3, conda] # The truncated dpkg-preconfigu is intentional, process names are # truncated at the falcosecurity-libs level. - list: package_mgmt_binaries - items: [rpm_binaries, deb_binaries, update-alternat, gem, npm, python_package_managers, sane-utils.post, alternatives, chef-client, apk, snapd] + items: [ + rpm_binaries, deb_binaries, update-alternat, gem, npm, + python_package_managers, sane-utils.post, alternatives, chef-client, + apk, snapd] - macro: package_mgmt_procs condition: (proc.name in (package_mgmt_binaries)) @@ -180,7 +221,7 @@ sshd, dbus-daemon-lau, ping, ping6, critical-stack-, pmmcli, filemng, PassengerAgent, bwrap, osdetect, nginxmng, sw-engine-fpm, start-stop-daem - ] + ] - list: user_mgmt_binaries items: [login_binaries, passwd_binaries, shadowutils_binaries] @@ -199,7 +240,7 @@ sendmail, sendmail-msp, postfix, procmail, exim4, pickup, showq, mailq, dovecot, imap-login, imap, mailmng-core, pop3-login, dovecot-lda, pop3 - ] + ] # RFC1918 addresses were assigned for private network usage - list: rfc_1918_addresses @@ -211,7 +252,8 @@ (evt.type in (sendto,sendmsg) and evt.dir=< and fd.l4proto != tcp and fd.connected=false and fd.name_changed=true)) and (fd.typechar = 4 or fd.typechar = 6) and - (fd.ip != "0.0.0.0" and fd.net != "127.0.0.0/8" and not fd.snet in (rfc_1918_addresses)) and + (fd.ip != "0.0.0.0" and fd.net != "127.0.0.0/8" and + not fd.snet in (rfc_1918_addresses)) and (evt.rawres >= 0 or evt.res = EINPROGRESS)) # Very similar to inbound/outbound, but combines the tests together @@ -224,7 +266,8 @@ (evt.rawres >= 0 or evt.res = EINPROGRESS)) - list: bash_config_filenames - items: [.bashrc, .bash_profile, .bash_history, .bash_login, .bash_logout, .inputrc, .profile] + items: [.bashrc, .bash_profile, .bash_history, .bash_login, + .bash_logout, .inputrc, .profile] - list: bash_config_files items: [/etc/profile, /etc/bashrc] @@ -252,48 +295,66 @@ condition: (never_true) - rule: Modify Shell Configuration File - desc: > - Detect attempts to modify shell configuration files, primarily aimed at establishing persistence by automatically inserting - commands into scripts executed by shells. The upstream rule excludes shell processes because they often create unnecessary noise. - However, this might lead to missed detections. To customize the rule for your situation, you can fine-tune it using enhanced profiling. - For example, you might want to only consider interactive shell processes (where proc.tty != 0). + desc: > + Detect attempts to modify shell configuration files, primarily aimed at + establishing persistence by automatically inserting commands into scripts + executed by shells. The upstream rule excludes shell processes + because they often create unnecessary noise.However, + this might lead to missed detections.To customize the rule for your + situation, you can fine-tune it using enhanced profiling. For example, + you might want to only consider interactive shell processes + (where proc.tty != 0). condition: > - open_write + open_write and (fd.filename in (shell_config_filenames) or fd.name in (shell_config_files) or fd.directory in (shell_config_directories)) and not proc.name in (shell_binaries) and not exe_running_docker_save and not user_known_shell_config_modifiers - output: A shell configuration file has been modified (file=%fd.name pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: A shell configuration file has been modified + (file=%fd.name pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name + user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: WARNING - tags: [maturity_incubating, host, container, filesystem, mitre_persistence, T1546.004] + tags: [maturity_incubating, host, container, filesystem, mitre_persistence, + T1546.004] - macro: user_known_cron_jobs condition: (never_true) - rule: Schedule Cron Jobs desc: > - Detect scheduled cron jobs; this is a highly generic detection and certainly needs adjustments and profiling in your environment before - operationalization. Simultaneously, exploiting the functionality of cron jobs is among one of the oldest TTPs used by adversaries. + Detect scheduled cron jobs; this is a highly generic detection and + certainly needs adjustments and profiling in your environment before + operationalization. Simultaneously, exploiting the functionality + of cron jobs is among one of the oldest TTPs used by adversaries. condition: > ((open_write and fd.name startswith /etc/cron) or - (spawned_process and proc.name = "crontab")) + (spawned_process and proc.name = "crontab")) and not user_known_cron_jobs - output: Cron jobs were scheduled to run (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Cron jobs were scheduled to run + (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: NOTICE - tags: [maturity_incubating, host, container, filesystem, mitre_execution, T1053.003] + tags: [ + maturity_incubating, host, container, filesystem, mitre_execution, + T1053.003] # Use this to test whether the event occurred within a container. # # When displaying container information in the output field, use # %container.info, without any leading term (file=%fd.name -# %container.info user=%user.name user_loginuid=%user.loginuid, and not file=%fd.name -# container=%container.info user=%user.name user_loginuid=%user.loginuid). The output will change -# based on the context and whether or not -pk/-pm/-pc was specified on -# the command line. +# %container.info user=%user.name user_loginuid=%user.loginuid, and +# not file=%fd.name container=%container.info user=%user.name +# user_loginuid=%user.loginuid). +# The output will change based on the context and whether or +# not -pk/-pm/-pc was specified on the command line. + - macro: container condition: (container.id != host) @@ -344,10 +405,13 @@ condition: (proc.pname=kubelet and proc.name=loopback) - macro: rancher_agent - condition: (proc.name=agent and container.image.repository contains "rancher/agent") + condition: > + (proc.name=agent and container.image.repository contains "rancher/agent") - macro: rancher_network_manager - condition: (proc.name=rancher-bridge and container.image.repository contains "rancher/network-manager") + condition: > + (proc.name=rancher-bridge and + container.image.repository contains "rancher/network-manager") - macro: exe_running_docker_save condition: > @@ -365,45 +429,68 @@ condition: (never_true) - rule: Read ssh information - desc: > - This rule identifies attempts to read files within ssh directories using programs that are not related to ssh. It's a simple and - versatile detection method that works well alongside more specific rules focused on sensitive file access. You have a couple of - options for using this rule effectively: you can adjust the specialized rules to cover all the important scenarios and ensure - precedence in rule smatching for those, or you can analyze the combined view of ssh-related file access across various rules on - your downstream computing platform. Just like with other rules, you can narrow down monitoring to specific processes, or you can + desc: > + This rule identifies attempts to read files within ssh directories + using programs that are not related to ssh. It's a simple and + versatile detection method that works well alongside more specific rules + focused on sensitive file access. You have a couple of options for using + this rule effectively: you can adjust the specialized rules to cover all the + important scenarios and ensure precedence in rule smatching for those, or + you can analyze the combined view of ssh-related file access across + various rules on your downstream computing platform. Just like with other + rules, you can narrow down monitoring to specific processes, or you can limit it to interactive access only. condition: > - (open_read or open_directory) + (open_read or open_directory) and (user_ssh_directory or fd.name startswith /root/.ssh) - and not user_known_read_ssh_information_activities + and not user_known_read_ssh_information_activities and not proc.name in (ssh_binaries) - output: ssh-related file/directory read by non-ssh program (file=%fd.name pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: ssh-related file/directory read by non-ssh program + (file=%fd.name pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name + user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: ERROR - tags: [maturity_incubating, host, container, filesystem, mitre_collection, T1005] + tags: > + [maturity_incubating, host, container, filesystem, mitre_collection, T1005] - macro: calico_node - condition: (container.image.repository endswith calico/node and proc.name=calico-node) + condition: > + (container.image.repository endswith calico/node and proc.name=calico-node) - macro: postgres_running_wal_e - condition: (proc.pname=postgres and (proc.cmdline startswith "sh -c envdir /etc/wal-e.d/env /usr/local/bin/wal-e" or proc.cmdline startswith "sh -c envdir \"/run/etc/wal-e.d/env\" wal-g wal-push")) + condition: > + (proc.pname=postgres and + (proc.cmdline startswith + "sh -c envdir /etc/wal-e.d/env /usr/local/bin/wal-e" or + proc.cmdline startswith + "sh -c envdir \"/run/etc/wal-e.d/env\" wal-g wal-push") + ) - macro: user_known_db_spawned_processes condition: (never_true) - rule: DB program spawned process desc: > - A program related to the database server creates an unexpected child process (other than itself). - This is not supposed to happen and often follows SQL injection attacks. This behavioral detection could - indicate potential unauthorized data extraction or tampering with the database. + A program related to the database server creates an unexpected child process + (other than itself.This is not supposed to happen and often follows + SQL injection attacks. This behavioral detection could indicate potential + unauthorized data extraction or tampering with the database. condition: > spawned_process and proc.pname in (db_server_binaries) and not proc.name in (db_server_binaries) and not postgres_running_wal_e and not user_known_db_spawned_processes - output: Database-related program spawned process other than itself (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: Database-related program spawned process other than itself + (evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) priority: NOTICE - tags: [maturity_incubating, host, container, process, database, mitre_execution, T1190] + tags: > + [maturity_incubating, host, container, process, database, mitre_execution, + T1190] # This list allows for easy additions to the set of commands allowed # to change thread namespace without having to copy and override the @@ -418,23 +505,31 @@ items: [aws-cni, azure-vnet] - macro: weaveworks_scope - condition: (container.image.repository endswith weaveworks/scope and proc.name=scope) + condition: > + (container.image.repository endswith weaveworks/scope and proc.name=scope) - rule: Change thread namespace desc: > - An attempt to alter the namespace of a process (often performed while creating a container) through the setns syscall. - Conversely, the same syscall setns is triggered when an unauthorized attempt is made to break out from the container - to the host, for example, when using commands like `nsenter --target 1` and similar ones. Recommending to profile your - environment and refine this rule for effective operationalization. + An attempt to alter the namespace of a process + (often performed while creating a container) through the setns syscall. + Conversely, the same syscall setns is triggered when an unauthorized + attempt is made to break out from the container to the host, for example, + when using commands like `nsenter --target 1` and similar ones. Recommending + to profile your environment and refine this rule for effective + operationalization. condition: > evt.type=setns and evt.dir=< and proc_name_exists - and not (container.id=host and proc.name in (docker_binaries, k8s_binaries, lxd_binaries, nsenter)) - and not proc.name in (sysdigcloud_binaries, sysdig, calico, oci-umount, cilium-cni, network_plugin_binaries) + and not (container.id=host and proc.name in + (docker_binaries, k8s_binaries, lxd_binaries, nsenter)) + and not proc.name in + (sysdigcloud_binaries, sysdig, calico, oci-umount, cilium-cni, + network_plugin_binaries) and not proc.name in (user_known_change_thread_namespace_binaries) and not proc.name startswith "runc" and not proc.cmdline startswith "containerd" - and not proc.pname in (sysdigcloud_binaries, hyperkube, kubelet, protokube, dockerd, tini, aws) + and not proc.pname in + (sysdigcloud_binaries, hyperkube, kubelet, protokube, dockerd, tini, aws) and not java_running_sdjagent and not kubelet_running_loopback and not rancher_agent @@ -442,21 +537,33 @@ and not calico_node and not weaveworks_scope and not user_known_change_thread_namespace_activities - output: Namespace change (setns) by unexpected program (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Namespace change (setns) by unexpected program + (evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: NOTICE - tags: [maturity_incubating, host, container, process, mitre_privilege_escalation, T1611] + tags: [ + maturity_incubating, host, container, process, + mitre_privilege_escalation, T1611] - rule: Change namespace privileges via unshare - desc: > - Unprivileged users in containers may not have CAP_SYS_ADMIN or other elevated privileges. However, they can - use the unshare system call with CLONE_NEWNS or CLONE_NEWUSER to create or clone a namespace or user with the - necessary privileges to conduct further attacks. It is best practice to block the unshare system call via - seccomp if it is not needed. Misuse of unshare can be related to misconfigured Kubernetes clusters, for example. + desc: > + Unprivileged users in containers may not have CAP_SYS_ADMIN or other + elevated privileges. However, they can use the unshare system call with + CLONE_NEWNS or CLONE_NEWUSER to create or clone a namespace or user + with the necessary privileges to conduct further attacks. It is best + practice to block the unshare system call via seccomp if it is not needed. + Misuse of unshare can be related to misconfigured Kubernetes clusters, + for example. condition: > - evt.type=unshare and evt.dir=< - and container + evt.type=unshare and evt.dir=< + and container and not thread.cap_permitted contains CAP_SYS_ADMIN - output: Change namespace privileges via unshare (res=%evt.res evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Change namespace privileges via unshare + (res=%evt.res evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: NOTICE tags: [maturity_incubating, container, mitre_privilege_escalation, T1611] @@ -464,9 +571,12 @@ condition: > (container.image.repository startswith openshift3/ or container.image.repository startswith registry.redhat.io/openshift3/ or - container.image.repository startswith registry.access.redhat.com/openshift3/) + container.image.repository startswith + registry.access.redhat.com/openshift3/) -# Source: https://docs.openshift.com/enterprise/3.2/install_config/install/disconnected_install.html +# Source: +# https://docs.openshift.com/enterprise/3.2/install_config/install/ +# disconnected_install.html - macro: openshift_image condition: > (allowed_openshift_registry_root and @@ -490,7 +600,11 @@ container.image.repository endswith /image-inspector)) - list: redhat_io_images_privileged - items: [registry.redhat.io/openshift-logging/fluentd-rhel8, registry.redhat.io/openshift4/ose-csi-node-driver-registrar, registry.redhat.io/openshift4/ose-kubernetes-nmstate-handler-rhel8, registry.redhat.io/openshift4/ose-local-storage-diskmaker] + items: [ + registry.redhat.io/openshift-logging/fluentd-rhel8, + registry.redhat.io/openshift4/ose-csi-node-driver-registrar, + registry.redhat.io/openshift4/ose-kubernetes-nmstate-handler-rhel8, + registry.redhat.io/openshift4/ose-local-storage-diskmaker] - macro: redhat_image condition: > @@ -541,10 +655,12 @@ condition: (never_true) - list: sematext_images - items: [docker.io/sematext/sematext-agent-docker, docker.io/sematext/agent, docker.io/sematext/logagent, - registry.access.redhat.com/sematext/sematext-agent-docker, - registry.access.redhat.com/sematext/agent, - registry.access.redhat.com/sematext/logagent] + items: [ + docker.io/sematext/sematext-agent-docker, docker.io/sematext/agent, + docker.io/sematext/logagent, + registry.access.redhat.com/sematext/sematext-agent-docker, + registry.access.redhat.com/sematext/agent, + registry.access.redhat.com/sematext/logagent] # Falco containers - list: falco_containers @@ -552,13 +668,13 @@ - falcosecurity/falco - docker.io/falcosecurity/falco - public.ecr.aws/falcosecurity/falco + - falcosecurity/falco-no-driver # Falco no driver containers + - docker.io/falcosecurity/falco-no-driver # Falco no driver containers + - public.ecr.aws/falcosecurity/falco-no-driver # Falco no driver containers -# Falco no driver containers - - falcosecurity/falco-no-driver - - docker.io/falcosecurity/falco-no-driver - - public.ecr.aws/falcosecurity/falco-no-driver - -# These container images are allowed to run with --privileged and full set of capabilities +# These container images are allowed to run with --privileged and +# full set of capabilities +# TODO: Remove k8s.gcr.io reference after 01/Dec/2023 - list: falco_privileged_images items: [ falco_containers, @@ -577,12 +693,16 @@ gke.gcr.io/netd-amd64, gke.gcr.io/watcher-daemonset, gcr.io/google-containers/prometheus-to-sd, + k8s.gcr.io/ip-masq-agent-amd64, + k8s.gcr.io/kube-proxy, + k8s.gcr.io/prometheus-to-sd, registry.k8s.io/ip-masq-agent-amd64, registry.k8s.io/kube-proxy, registry.k8s.io/prometheus-to-sd, quay.io/calico/node, sysdig/sysdig, sematext_images, + k8s.gcr.io/dns/k8s-dns-node-cache, registry.k8s.io/dns/k8s-dns-node-cache, mcr.microsoft.com/oss/kubernetes/kube-proxy ] @@ -606,21 +726,27 @@ condition: (never_true) - rule: Launch Privileged Container - desc: > - Detect the initial process initiation within a privileged container, with exemptions for known and trusted images. - This rule primarily serves as an excellent auditing mechanism since highly privileged containers, when compromised, - can result in significant harm. For instance, if another rule triggers within such a privileged container, it could be + desc: > + Detect the initial process initiation within a privileged container, + with exemptions for known and trusted images.This rule primarily serves as + an excellent auditing mechanism since highly privileged containers, + when compromised, can result in significant harm. For instance, + if another rule triggers within such a privileged container, it could be seen as more suspicious, prompting a closer inspection. condition: > - container_started + container_started and container and container.privileged=true and not falco_privileged_containers and not user_privileged_containers and not redhat_image - output: Privileged container started (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Privileged container started + (evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: INFO - tags: [maturity_incubating, container, cis, mitre_execution, T1610, PCI_DSS_10.2.5] + tags: > + [maturity_incubating, container, cis, mitre_execution, T1610, PCI_DSS_10.2.5] # These capabilities were used in the past to escape from containers - macro: excessively_capable_container @@ -636,39 +762,52 @@ or thread.cap_permitted contains CAP_BPF) - rule: Launch Excessively Capable Container - desc: > - Identify containers that start with a powerful set of capabilities, with exceptions for recognized trusted images. - Similar to the "Launch Privileged Container" rule, this functions as a robust auditing rule. Compromised highly privileged - containers can lead to substantial harm. For instance, if another rule is triggered within such a container, it might - raise suspicion, prompting closer scrutiny. + desc: > + Identify containers that start with a powerful set of capabilities, + with exceptions for recognized trusted images.Similar to the + "Launch Privileged Container" rule, this functions as a robust + auditing rule. Compromised highly privileged containers can lead + to substantial harm. For instance, if another rule is triggered + within such a container, it might raise suspicion, prompting closer scrutiny condition: > - container_started + container_started and container and excessively_capable_container and not falco_privileged_containers and not user_privileged_containers - output: Excessively capable container started (cap_permitted=%thread.cap_permitted evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Excessively capable container started + (cap_permitted=%thread.cap_permitted evt_type=%evt.type user=%user.name + user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: INFO tags: [maturity_incubating, container, cis, mitre_execution, T1610] - macro: login_doing_dns_lookup condition: (proc.name=login and fd.l4proto=udp and fd.sport=53) -# sockfamily ip is to exclude certain processes (like 'groups') that communicate on unix-domain sockets +# sockfamily ip is to exclude certain processes (like 'groups') +# that communicate on unix-domain sockets # systemd can listen on ports to launch things like sshd on demand - rule: System procs network activity desc: > - Detect any unexpected network activity performed by system binaries that typically shouldn't perform network activity, including - coreutils binaries (like sleep, mkdir, who, date, and others) or user management binaries (such as login, systemd, usermod, deluser, - adduser, chpasswd, and others). This serves as a valuable baseline detection for network-related activities. + Detect any unexpected network activity performed by system binaries that + typically shouldn't perform network activity, including coreutils binaries + (like sleep, mkdir, who, date, and others) or user management binaries + (such as login, systemd, usermod, deluser, adduser, chpasswd, and others). + This serves as a valuable baseline detection for network-related activities. condition: > inbound_outbound - and fd.sockfamily = ip + and fd.sockfamily = ip and (system_procs or proc.name in (shell_binaries)) and not proc.name in (known_system_procs_network_activity_binaries) and not login_doing_dns_lookup and not user_expected_system_procs_network_activity_conditions - output: Known system binary sent/received network traffic (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Known system binary sent/received network traffic + (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type + fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: NOTICE tags: [maturity_incubating, host, network, process, mitre_execution, T1059] @@ -699,15 +838,23 @@ - rule: Program run with disallowed http proxy env desc: > - Detect curl or wget usage with HTTP_PROXY environment variable. Attackers can manipulate the HTTP_PROXY variable's - value to redirect application's internal HTTP requests. This could expose sensitive information like authentication + Detect curl or wget usage with HTTP_PROXY environment variable. + Attackers can manipulate the HTTP_PROXY variable's + value to redirect application's internal HTTP requests. + This could expose sensitive information like authentication keys and private data. condition: > - spawned_process - and http_proxy_procs + spawned_process + and http_proxy_procs and proc.env icontains HTTP_PROXY - and not allowed_ssh_proxy_env - output: Curl or wget run with disallowed HTTP_PROXY environment variable (env=%proc.env evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + and not allowed_ssh_proxy_env + output: > + Curl or wget run with disallowed HTTP_PROXY environment variable + (env=%proc.env evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) + priority: NOTICE tags: [maturity_incubating, host, container, users, mitre_execution, T1204] @@ -734,22 +881,30 @@ items: [0, 9, 80, 3306] - list: expected_udp_ports - items: [53, openvpn_udp_ports, l2tp_udp_ports, statsd_ports, ntp_ports, test_connect_ports] + items: [53, openvpn_udp_ports, l2tp_udp_ports, statsd_ports, + ntp_ports, test_connect_ports] - macro: expected_udp_traffic condition: fd.port in (expected_udp_ports) - rule: Unexpected UDP Traffic - desc: > - Detecting UDP traffic on ports other than 53 (DNS) or other commonly used ports. Misusing UDP is a known TTP among attackers. - Monitoring unusual network activity is highly valuable but often generates significant noise, as is the case with this detection. - condition: > - inbound_outbound - and fd.l4proto=udp + desc: > + Detecting UDP traffic on ports other than 53 (DNS) or other commonly used + ports. Misusing UDP is a known TTP among attackers. + Monitoring unusual network activity is highly valuable + but often generates significant noise, as is the case with this detection. + condition: > + inbound_outbound + and fd.l4proto=udp and not expected_udp_traffic - output: Unexpected UDP Traffic Seen (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Unexpected UDP Traffic Seen + (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type + fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: NOTICE - tags: [maturity_incubating, host, container, network, mitre_exfiltration, TA0011] + tags: > + [maturity_incubating, host, container, network, mitre_exfiltration, TA0011] - macro: somebody_becoming_themselves condition: ((user.name=nobody and evt.arg.uid=nobody) or @@ -780,66 +935,90 @@ - macro: user_known_non_sudo_setuid_conditions condition: (user.name=root) -# sshd, mail programs attempt to setuid to root even when running as non-root. Excluding here to avoid meaningless FPs +# sshd, mail programs attempt to setuid to root even when running as non-root. +# Excluding here to avoid meaningless FPs - rule: Non sudo setuid desc: > - Detect attempts to change users through the use of setuid, with exceptions for sudo/su. - The users "root" and "nobody" using setuid on themselves are also excluded, as setuid calls in these cases - typically involve reducing privileges. By setting the setuid bit, an attacker could execute code in a - different user's context, potentially with higher privileges. One drawback is the potential for noise, - as many applications legitimately use this approach. + Detect attempts to change users through the use of setuid, with exceptions + for sudo/su.The users "root" and "nobody" using setuid on themselves are + also excluded, as setuid calls in these cases typically involve reducing + privileges. By setting the setuid bit, an attacker could execute code in + a different user's context, potentially with higher privileges. One + drawback is the potential for noise, as many applications legitimately + use this approach. condition: > evt.type=setuid and evt.dir=> and (known_user_in_container or not container) and not (user.name=root or user.uid=0) and not somebody_becoming_themselves - and not proc.name in (known_setuid_binaries, userexec_binaries, mail_binaries, docker_binaries, - nomachine_binaries) + and not proc.name in (known_setuid_binaries, userexec_binaries, + mail_binaries, docker_binaries, nomachine_binaries) + and not proc.name startswith "runc:" and not java_running_sdjagent and not nrpe_becoming_nagios and not user_known_non_sudo_setuid_conditions - output: Unexpected setuid call by non-sudo, non-root program (arg_uid=%evt.arg.uid evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Unexpected setuid call by non-sudo, non-root program + (arg_uid=%evt.arg.uid evt_type=%evt.type user=%user.name + user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: NOTICE - tags: [maturity_incubating, host, container, users, mitre_privilege_escalation, T1548.001] + tags: > + [maturity_incubating, host, container, users, + mitre_privilege_escalation, T1548.001] - macro: user_known_user_management_activities condition: (never_true) - macro: chage_list - condition: (proc.name=chage and (proc.cmdline contains "-l" or proc.cmdline contains "--list")) + condition: > + (proc.name=chage and (proc.cmdline contains "-l" or + proc.cmdline contains "--list")) - rule: User mgmt binaries desc: > - Detect activity by any programs that can manage users, passwords, or permissions (such as login, systemd, usermod, deluser, adduser, - chpasswd, and others). sudo and su are excluded. Activity in containers is also excluded -- some containers create custom users on - top of a base linux distribution at startup. Some innocuous command lines that don't actually change anything are excluded. You might - want to consider applying this rule to container actions as well. + Detect activity by any programs that can manage users, passwords, or + permissions + (such as login, systemd, usermod, deluser, adduser, chpasswd, and others). + sudo and su are excluded. Activity in containers is also excluded + -- some containers create custom users on top of a base linux distribution + at startup. Some innocuous command lines that don't actually change anything + are excluded. You might want to consider applying this rule to container + actions as well. condition: > - spawned_process + spawned_process and not container - and proc.name in (user_mgmt_binaries) - and not proc.name in (su, sudo, lastlog, nologin, unix_chkpwd) - and not proc.pname in (cron_binaries, systemd, systemd.postins, udev.postinst, run-parts) - and not proc.cmdline startswith "passwd -S" - and not proc.cmdline startswith "useradd -D" - and not proc.cmdline startswith "systemd --version" - and not run_by_qualys - and not run_by_sumologic_securefiles - and not run_by_yum - and not run_by_ms_oms + and proc.name in (user_mgmt_binaries) + and not proc.name in (su, sudo, lastlog, nologin, unix_chkpwd) + and not proc.pname in (cron_binaries, systemd, systemd.postins, + udev.postinst, run-parts) + and not proc.cmdline startswith "passwd -S" + and not proc.cmdline startswith "useradd -D" + and not proc.cmdline startswith "systemd --version" + and not run_by_qualys + and not run_by_sumologic_securefiles + and not run_by_yum + and not run_by_ms_oms and not run_by_google_accounts_daemon - and not chage_list + and not chage_list and not user_known_user_management_activities - output: User management binary command run outside of container (gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: User management binary command run outside of container + (gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] + evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) priority: NOTICE - tags: [maturity_incubating, host, users, software_mgmt, mitre_persistence, T1098] + tags: [ + maturity_incubating, host, users, software_mgmt, mitre_persistence, + T1098] - list: allowed_dev_files items: [ /dev/null, /dev/stdin, /dev/stdout, /dev/stderr, /dev/random, /dev/urandom, /dev/console, /dev/kmsg - ] + ] - macro: user_known_create_files_below_dev_activities condition: (never_true) @@ -847,10 +1026,11 @@ # (we may need to add additional checks against false positives, see: # https://bugs.launchpad.net/ubuntu/+source/rkhunter/+bug/86153) - rule: Create files below dev - desc: > - Detect the creation of files under /dev except for authorized device management programs. This can reveal rootkits hiding - files in /dev. Additionally, consider the "Execution from /dev/shm" rule. The upstream rule already covers some tuning - scenarios that you can further expand upon. + desc: > + Detect the creation of files under /dev except for authorized device + management programs. This can reveal rootkits hiding files in /dev. + Additionally, consider the "Execution from /dev/shm" rule. The upstream + rule already covers some tuning scenarios that you can further expand upon. condition: > (evt.type = creat or (evt.type in (open,openat,openat2))) and evt.arg.flags contains O_CREAT @@ -859,7 +1039,10 @@ and not fd.name in (allowed_dev_files) and not fd.name startswith /dev/tty and not user_known_create_files_below_dev_activities - output: File created below /dev by untrusted program (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: File created below /dev by untrusted program + (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: ERROR tags: [maturity_incubating, host, filesystem, mitre_persistence, T1543] @@ -878,41 +1061,58 @@ # metadata about the instance. It may be desirable to prevent access # to this IP from containers. - rule: Contact EC2 Instance Metadata Service From Container - desc: > - Detects attempts to communicate with the EC2 Instance Metadata Service from a container. This detection is narrowly focused - and might not apply to your environment. In addition, it could generate noise and require fine-tuning. - condition: > - outbound + desc: > + Detects attempts to communicate with the EC2 Instance Metadata Service + from a container. This detection is narrowly focused and might not + apply to your environment. In addition, it could generate noise and + require fine-tuning. + condition: > + outbound and container - and fd.sip="169.254.169.254" + and fd.sip="169.254.169.254" and not ec2_metadata_containers - output: Outbound connection to EC2 instance metadata service (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Outbound connection to EC2 instance metadata service + (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type + fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: NOTICE - tags: [maturity_incubating, network, aws, container, mitre_credential_access, T1552.005] + tags: [maturity_incubating, network, aws, container, mitre_credential_access, + T1552.005] -# This rule is not enabled by default, since this rule is for cloud environment(GCP, AWS and Azure) only. -# You can filter the container that you want to allow access to metadata by overwriting user_known_metadata_access macro. +# This rule is not enabled by default, since this rule is for +# cloud environment(GCP, AWS and Azure) only. +# You can filter the container that you want to allow access to metadata +# by overwriting user_known_metadata_access macro. - macro: user_known_metadata_access condition: (k8s.ns.name = "kube-system") # On GCP, AWS and Azure, 169.254.169.254 is a special IP used to fetch -# metadata about the instance. The metadata could be used to get credentials by attackers. +# metadata about the instance. The metadata could be used to get credentials +# by attackers. - rule: Contact cloud metadata service from container - desc: > - Detects attempts to communicate with the Cloud Instance Metadata Service from a container. This detection is narrowly focused - and might not apply to your environment. In addition, it could generate noise and require fine-tuning. - condition: > - outbound - and container - and fd.sip="169.254.169.254" + desc: > + Detects attempts to communicate with the Cloud Instance Metadata Service + from a container. This detection is narrowly focused and might not apply + to your environment. In addition, it could generate noise and require + fine-tuning. + condition: > + outbound + and container + and fd.sip="169.254.169.254" and not user_known_metadata_access enabled: true - output: Outbound connection to cloud instance metadata service (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Outbound connection to cloud instance metadata service + (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type + fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: NOTICE tags: [maturity_incubating, network, container, mitre_discovery, T1565] - list: network_tool_binaries - items: [nc, ncat, netcat, nmap, dig, tcpdump, tshark, ngrep, telnet, mitmproxy, socat, zmap] + items: [nc, ncat, netcat, nmap, dig, tcpdump, tshark, ngrep, telnet, + mitmproxy, socat, zmap] - macro: network_tool_procs condition: (proc.name in (network_tool_binaries)) @@ -926,18 +1126,24 @@ - macro: user_known_package_manager_in_container condition: (never_true) -# Container is supposed to be immutable. Package management should be done in building the image. +# Container is supposed to be immutable. +# Package management should be done in building the image. +# TODO: Remove k8s.gcr.io reference after 01/Dec/2023 - macro: pkg_mgmt_in_kube_proxy condition: > (proc.cmdline startswith "update-alternat" - and container.image.repository = "registry.k8s.io/kube-proxy") + and (container.image.repository = "registry.k8s.io/kube-proxy" + or container.image.repository = "k8s.gcr.io/kube-proxy")) - rule: Launch Package Management Process in Container - desc: > - Detect package management processes executed within containers. An excellent auditing rule to monitor general drifts - in containers. Particularly useful for newer rules like "Drop and execute new binary in container" during incident - response investigations. This helps identify common anti-patterns of ad-hoc debugging. Simultaneously, to maintain - optimal hygiene, it's recommended to prevent container drifts and instead opt for redeploying new containers. + desc: > + Detect package management processes executed within containers.An excellent + auditing rule to monitor general drifts in containers. Particularly + useful for newer rules like "Drop and execute new binary in container" + during incident response investigations.This helps identify common + anti-patterns of ad-hoc debugging. Simultaneously, to maintain optimal + hygiene, it's recommended to prevent container drifts and instead opt + for redeploying new containers. condition: > spawned_process and container @@ -946,38 +1152,57 @@ and not package_mgmt_ancestor_procs and not user_known_package_manager_in_container and not pkg_mgmt_in_kube_proxy - output: Package management process launched in container (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: Package management process launched in container + (evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) priority: ERROR - tags: [maturity_incubating, container, process, software_mgmt, mitre_persistence, T1505] + tags: [maturity_incubating, container, process, software_mgmt, + mitre_persistence, T1505] - macro: user_known_network_tool_activities condition: (never_true) - rule: Launch Suspicious Network Tool in Container desc: > - Detect network tools (like netcat, nmap, tcpdump, socat, and more) launched within containers without any additional filters. - This serves as a valuable general detection, but it's recommended to invest engineering effort to fine-tune it and prevent a - high volume of legitimate logs. This rule complements the more specific "Netcat Remote Code Execution in Container" rule. + Detect network tools (like netcat, nmap, tcpdump, socat, and more) + launched within containers without any additional filters. This serves + as a valuable general detection, but it's recommended to invest engineering + effort to fine-tune it and prevent a high volume of legitimate logs. + This rule complements the more specific + "Netcat Remote Code Execution in Container" rule. condition: > - spawned_process - and container - and network_tool_procs + spawned_process + and container + and network_tool_procs and not user_known_network_tool_activities - output: Network tool launched in container (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: Network tool launched in container + (evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) priority: NOTICE - tags: [maturity_incubating, container, network, process, mitre_execution, T1059] + tags: + [maturity_incubating, container, network, process, mitre_execution, T1059] - rule: Launch Suspicious Network Tool on Host desc: > - Detect network tools (like netcat, nmap, tcpdump, socat, and more) launched within containers without any additional filters. - This serves as a valuable general detection, but it's recommended to invest engineering effort to fine-tune it and prevent a - high volume of legitimate logs. The host equivalent of "Launch Suspicious Network Tool in Container.". + Detect network tools (like netcat, nmap, tcpdump, socat, and more) launched + within containers without any additional filters. This serves as a + valuable general detection, but it's recommended to invest engineering + effort to fine-tune it and prevent a high volume of legitimate logs. The + host equivalent of "Launch Suspicious Network Tool in Container.". condition: > - spawned_process - and not container - and network_tool_procs + spawned_process + and not container + and network_tool_procs and not user_known_network_tool_activities - output: Network tool launched on host (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags) + output: Network tool launched on host + (evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags) priority: NOTICE tags: [maturity_incubating, host, network, process, mitre_execution, T1059] @@ -1008,32 +1233,41 @@ fd.name endswith "fish_history") and evt.arg.flags contains "O_TRUNC") - macro: var_lib_docker_filepath - condition: (evt.arg.name startswith /var/lib/docker or fd.name startswith /var/lib/docker) + condition: (evt.arg.name startswith /var/lib/docker or + fd.name startswith /var/lib/docker) # todo!: the usage of `evt.arg*` filter check in the output should be avoided # when more than one event type is involved because some event will populate # the filtercheck and others will always return . It would be better to use # a more generic filter like `fs.path.*` - rule: Delete or rename shell history - desc: > - Detect shell history deletion, frequently used by unsophisticated adversaries to eliminate evidence. - Note that it can also trigger when exiting a Terminal shell, such as with `kubectl exec`, which + desc: > + Detect shell history deletion, frequently used by unsophisticated + adversaries to eliminate evidence. Note that it can also trigger + when exiting a Terminal shell, such as with `kubectl exec`, which may introduce some noise. condition: > - (modify_shell_history or truncate_shell_history) - and not var_lib_docker_filepath + (modify_shell_history or truncate_shell_history) + and not var_lib_docker_filepath and not proc.name in (docker_binaries) - output: Shell history deleted or renamed (file=%fd.name name=%evt.arg.name path=%evt.arg.path oldpath=%evt.arg.oldpath evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Shell history deleted or renamed + (file=%fd.name name=%evt.arg.name path=%evt.arg.path + oldpath=%evt.arg.oldpath evt_type=%evt.type user=%user.name + user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: WARNING - tags: [maturity_incubating, host, container, process, filesystem, mitre_defense_evasion, T1070] + tags: [maturity_incubating, host, container, process, filesystem, + mitre_defense_evasion, T1070] - list: user_known_chmod_applications items: [hyperkube, kubelet, k3s-agent] -# This macro should be overridden in user rules as needed. This is useful if a given application -# should not be ignored altogether with the user_known_chmod_applications list, but only in -# specific conditions. +# This macro should be overridden in user rules as needed. This is useful +# if a given application +# should not be ignored altogether with the user_known_chmod_applications +# list, but only in specific conditions. - macro: user_known_set_setuid_or_setgid_bit_conditions condition: (never_true) @@ -1044,20 +1278,28 @@ # we will always return ``. - rule: Set Setuid or Setgid bit desc: > - This rule is focused on detecting the use of setuid or setgid bits set via chmod. These bits, when set for an application, - result in the application running with the privileges of the owning user or group. By enabling the setuid or setgid bits, - an attacker could run code in a different user's context, possibly with elevated privileges. However, there's a trade-off - with noise, given that numerous applications legitimately run chmod. This rule is related to the "Non sudo setuid" rule. + This rule is focused on detecting the use of setuid or setgid bits + set via chmod. These bits, when set for an application, result in the + application running with the privileges of the owning user or group. + By enabling the setuid or setgid bits, an attacker could run code in a + different user's context, possibly with elevated privileges. However, + there's a trade-off with noise, given that numerous applications + legitimately run chmod. This rule is related to the "Non sudo setuid" rule. condition: > - chmod + chmod and (evt.arg.mode contains "S_ISUID" or evt.arg.mode contains "S_ISGID") and not proc.name in (user_known_chmod_applications) and not exe_running_docker_save and not user_known_set_setuid_or_setgid_bit_conditions - output: Setuid or setgid bit is set via chmod (fd=%evt.arg.fd filename=%evt.arg.filename mode=%evt.arg.mode evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Setuid or setgid bit is set via chmod + (fd=%evt.arg.fd filename=%evt.arg.filename mode=%evt.arg.mode + evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: NOTICE - tags: [maturity_incubating, host, container, process, users, mitre_privilege_escalation, T1548.001] + tags: [maturity_incubating, host, container, process, users, + mitre_privilege_escalation, T1548.001] - list: remote_file_copy_binaries items: [rsync, scp, sftp, dcp] @@ -1071,17 +1313,24 @@ condition: (never_true) - rule: Launch Remote File Copy Tools in Container - desc: > - Detect remote file copy tools (like rsync, scp, sftp, dcp) launched within a container, potentially indicating data - exfiltration. Suggest refining this rule to accommodate legitimate use cases. + desc: > + Detect remote file copy tools (like rsync, scp, sftp, dcp) launched within + a container, potentially indicating data exfiltration. Suggest refining + this rule to accommodate legitimate use cases. condition: > spawned_process and container and remote_file_copy_procs and not user_known_remote_file_copy_activities - output: Remote file copy tool launched in container (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: Remote file copy tool launched in container + (evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) priority: NOTICE - tags: [maturity_incubating, container, network, process, mitre_exfiltration, T1020] + tags: [ + maturity_incubating, container, network, process, mitre_exfiltration, + T1020] # Namespaces where the rule is enforce - list: namespace_scope_network_only_subnet @@ -1097,21 +1346,33 @@ # # How to test: # # Add 'default' to namespace_scope_network_only_subnet # # Run: -# kubectl run --generator=run-pod/v1 -n default -i --tty busybox --image=busybox --rm -- wget google.com -O /var/google.html +# kubectl run --generator=run-pod/v1 -n default -i --tty busybox --image=busybox +# --rm -- wget google.com -O /var/google.html # # Check logs running - rule: Network Connection outside Local Subnet - desc: > - Detect network traffic (inbound or outbound) from a container to a destination outside the local subnet. - To operationalize this rule, profile your environment and update the template macro namespace_scope_network_only_subnet. - Customizing network-related rules usually demands substantial engineering effort to ensure their functionality. + desc: > + Detect network traffic (inbound or outbound) from a container to a + destination outside the local subnet. To operationalize this rule, + profile your environment and update the template macro + namespace_scope_network_only_subnet. Customizing network-related rules + usually demands substantial engineering effort to ensure their + functionality. condition: > - inbound_outbound - and container - and k8s.ns.name in (namespace_scope_network_only_subnet) - and not network_local_subnet - output: Network connection outside local subnet (fd_rip_name=%fd.rip.name fd_lip_name=%fd.lip.name fd_cip_name=%fd.cip.name fd_sip_name=%fd.sip.name connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + inbound_outbound + and container + and k8s.ns.name in (namespace_scope_network_only_subnet) + and not network_local_subnet + output: Network connection outside local subnet + (fd_rip_name=%fd.rip.name fd_lip_name=%fd.lip.name fd_cip_name=%fd.cip.name + fd_sip_name=%fd.sip.name connection=%fd.name lport=%fd.lport rport=%fd.rport + fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name + user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: WARNING - tags: [maturity_incubating, container, network, mitre_discovery, T1046, PCI_DSS_6.4.2] + tags: > + [maturity_incubating, container, network, mitre_discovery, T1046, + PCI_DSS_6.4.2] - macro: mount_info condition: (proc.args="" or proc.args intersects ("-V", "-l", "-h")) @@ -1119,23 +1380,33 @@ - macro: known_gke_mount_in_privileged_containers condition: (k8s.ns.name = kube-system - and container.image.repository = gke.gcr.io/gcp-compute-persistent-disk-csi-driver) + and + container.image.repository = gke.gcr.io/ + gcp-compute-persistent-disk-csi-driver) - macro: known_aks_mount_in_privileged_containers condition: - ((k8s.ns.name = kube-system and container.image.repository in (mcr.microsoft.com/oss/kubernetes-csi/azuredisk-csi,mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi)) - or (k8s.ns.name = system and container.image.repository = mcr.microsoft.com/oss/kubernetes-csi/secrets-store/driver)) + ( + (k8s.ns.name = kube-system and container.image.repository in + (mcr.microsoft.com/oss/kubernetes-csi/azuredisk-csi, + mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi) + ) + or + (k8s.ns.name = system and container.image.repository = + mcr.microsoft.com/oss/kubernetes-csi/secrets-store/driver)) - macro: user_known_mount_in_privileged_containers condition: (never_true) - rule: Mount Launched in Privileged Container - desc: > - Detect filesystem mounts (using the mount binary) within a privileged container. Due to the elevated privileges, - this action could be one of the TTPs used in an attempt to escape from a container to the host. This type of action - is often preceded by reconnaissance activities, for which you can also create custom rules. + desc: > + Detect filesystem mounts (using the mount binary) within a privileged + container. Due to the elevated privileges, this action could be one + of the TTPs used in an attempt to escape from a container to the host. + This type of action is often preceded by reconnaissance activities, + for which you can also create custom rules. condition: > - spawned_process + spawned_process and container and container.privileged=true and proc.name=mount @@ -1143,9 +1414,15 @@ and not known_gke_mount_in_privileged_containers and not known_aks_mount_in_privileged_containers and not user_known_mount_in_privileged_containers - output: Mount was executed inside a privileged container (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: Mount was executed inside a privileged container + (evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) priority: WARNING - tags: [maturity_incubating, container, cis, filesystem, mitre_privilege_escalation, T1611] + tags: > + [maturity_incubating, container, cis, filesystem, + mitre_privilege_escalation, T1611] - list: ingress_remote_file_copy_binaries items: [wget] @@ -1166,41 +1443,62 @@ proc.cmdline contains " --remote-name ")) - rule: Launch Ingress Remote File Copy Tools in Container - desc: > - Detect ingress remote file copy tools (such as curl or wget) launched inside containers. This rule can be - considered a valuable auditing tool, but it has the potential to generate notable noise and requires careful - profiling before full operationalization. + desc: > + Detect ingress remote file copy tools (such as curl or wget) + launched inside containers. This rule can be considered a valuable + auditing tool, but it has the potential to generate notable noise + and requires careful profiling before full operationalization. condition: > - spawned_process - and container - and (ingress_remote_file_copy_procs or curl_download) + spawned_process + and container + and (ingress_remote_file_copy_procs or curl_download) and not user_known_ingress_remote_file_copy_activities - output: Ingress remote file copy tool launched in container (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: Ingress remote file copy tool launched in container + (evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) priority: NOTICE - tags: [maturity_incubating, container, network, process, mitre_command_and_control, TA0011] + tags: > + [maturity_incubating, container, network, process, + mitre_command_and_control, TA0011] - list: docker_binaries - items: [docker, dockerd, containerd-shim, "runc:[1:CHILD]", pause, exe, docker-compose, docker-entrypoi, docker-runc-cur, docker-current, dockerd-current] + items: [ + docker, dockerd, containerd-shim, "runc:[1:CHILD]", + pause, exe, docker-compose, docker-entrypoi, docker-runc-cur, + docker-current, dockerd-current] - list: known_binaries_to_read_environment_variables_from_proc_files items: [scsi_id, argoexec] - rule: Read environment variable from /proc files - desc: > - An attempt to read process environment variables from /proc files. The consequences are akin to accessing traditional - sensitive files, as sensitive data, including secrets, might be stored in environment variables. Understanding your - environment, such as identifying critical namespaces, and incorporating extra filtering statements to alert exclusively - for those, can enhance the rule's effectiveness. + desc: > + An attempt to read process environment variables from /proc files. + The consequences are akin to accessing traditional sensitive files, + as sensitive data, including secrets, might be stored in environment + variables. Understanding your environment, such as identifying critical + namespaces, and incorporating extra filtering statements to alert + exclusively for those, can enhance the rule's effectiveness. condition: > - open_read - and container + open_read + and container and (fd.name glob /proc/*/environ) - and not proc.name in (known_binaries_to_read_environment_variables_from_proc_files) - output: Environment variables were retrieved from /proc files (file=%fd.name gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + and not proc.name in + (known_binaries_to_read_environment_variables_from_proc_files) + output: Environment variables were retrieved from /proc files + (file=%fd.name gparent=%proc.aname[2] ggparent=%proc.aname[3] + gggparent=%proc.aname[4] evt_type=%evt.type user=%user.name + user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: WARNING - tags: [maturity_incubating, container, filesystem, process, mitre_discovery, T1083] + tags: > + [maturity_incubating, container, filesystem, process, + mitre_discovery, T1083] -# The steps libcontainer performs to set up the root program for a container are: +# The steps libcontainer performs to set up the root program +# for a container are: # - clone + exec self to a program runc:[0:PARENT] # - clone a program runc:[1:CHILD] which sets up all the namespaces # - clone a second program runc:[2:INIT] + exec to the root program. @@ -1211,48 +1509,62 @@ # We also let runc:[1:CHILD] count as the parent process, which can occur # when we lose events and lose track of state. - macro: container_entrypoint - condition: (not proc.pname exists or proc.pname in (runc:[0:PARENT], runc:[1:CHILD], runc, docker-runc, exe, docker-runc-cur, containerd-shim, systemd, crio)) + condition: (not proc.pname exists or proc.pname in (runc:[0:PARENT], + runc:[1:CHILD], runc, docker-runc, exe, docker-runc-cur, + containerd-shim, systemd, crio)) - macro: system_level_side_effect_artifacts_kubectl_cp - condition: (fd.name startswith /etc or - fd.name startswith /proc or - fd.name startswith /lib or - fd.name startswith /run or - fd.name startswith /usr or + condition: (fd.name startswith /etc or + fd.name startswith /proc or + fd.name startswith /lib or + fd.name startswith /run or + fd.name startswith /usr or fd.name="/") - rule: Exfiltrating Artifacts via Kubernetes Control Plane desc: > - Detect the copying of artifacts from a container's file system using the Kubernetes control plane (kubectl cp). - This rule can identify potential exfiltration of application secrets from containers' file systems, potentially - revealing the outcomes of unauthorized access and control plane misuse via stolen identities (such as stolen - credentials like Kubernetes serviceaccount tokens). Can be customized by the adopter to only monitor specific - artifact paths, containers, or namespaces as needed. + Detect the copying of artifacts from a container's file system using the + Kubernetes control plane (kubectl cp). This rule can identify potential + exfiltration of application secrets from containers' file systems, + potentially revealing the outcomes of unauthorized access and control + plane misuse via stolen identities (such as stolen credentials like + Kubernetes serviceaccount tokens). Can be customized by the adopter to + only monitor specific artifact paths, containers, or namespaces as needed. condition: > - open_read - and container - and proc.name=tar - and container_entrypoint - and proc.tty=0 + open_read + and container + and proc.name=tar + and container_entrypoint + and proc.tty=0 and not system_level_side_effect_artifacts_kubectl_cp - output: Exfiltrating Artifacts via Kubernetes Control Plane (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Exfiltrating Artifacts via Kubernetes Control Plane + (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: NOTICE - tags: [maturity_incubating, container, filesystem, mitre_exfiltration, TA0010] + tags: > + [maturity_incubating, container, filesystem, mitre_exfiltration, TA0010] - rule: Adding ssh keys to authorized_keys desc: > - After gaining access, attackers can modify the authorized_keys file to maintain persistence on a victim host. - Where authorized_keys files are modified via cloud APIs or command line interfaces, an adversary may achieve - privilege escalation on the target virtual machine if they add a key to a higher-privileged user. - This rules aims at detecting any modification to the authorized_keys file, that is usually located under the .ssh - directory in any user's home directory. This rule complements the more generic auditing rule "Read ssh information" - by specifically detecting the writing of new, potentially attacker-provided keys. + After gaining access, attackers can modify the authorized_keys file to + maintain persistence on a victim host.Where authorized_keys files are + modified via cloud APIs or command line interfaces, an adversary may + achieve privilege escalation on the target virtual machine if they add + a key to a higher-privileged user.This rules aims at detecting any + modification to the authorized_keys file, that is usually located under + the .ssh directory in any user's home directory. This rule complements + the more generic auditing rule "Read ssh information" by specifically + detecting the writing of new, potentially attacker-provided keys. condition: > open_write and (user_ssh_directory or fd.name startswith /root/.ssh) and fd.name endswith authorized_keys and not proc.name in (ssh_binaries) - output: Adding ssh keys to authorized_keys (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty) + output: Adding ssh keys to authorized_keys + (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty) priority: WARNING tags: [maturity_incubating, host, filesystem, mitre_persistence, T1098.004] @@ -1262,15 +1574,25 @@ - rule: Potential Local Privilege Escalation via Environment Variables Misuse desc: > - Process run with suspect environment variable that could be attempting privilege escalation. One use case is - detecting the use of the GLIBC_TUNABLES environment variable, which could be used for privilege escalation - on systems running vulnerable glibc versions. Only known and carefully profiled processes that legitimately - exhibit this behavior should be excluded from this rule. This rule is expected to trigger on every attempt, - even failed ones. + Process run with suspect environment variable that could be attempting + privilege escalation.One use case is detecting the use of the GLIBC_TUNABLES + environment variable, which could be used for privilege escalation on + systems running vulnerable glibc versions. Only known and carefully + profiled processes that legitimately exhibit this behavior should be + excluded from this rule. This rule is expected to trigger on every + attempt, even failed ones. condition: > - spawned_process + spawned_process and glibc_tunables_env enabled: true - output: Process run with suspect environment variable which could be attempting privilege escalation (env=%proc.env evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: > + Process run with suspect environment variable which could be attempting + privilege escalation + (env=%proc.env evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) priority: NOTICE - tags: [maturity_incubating, host, container, users, mitre_privilege_escalation, TA0004] + tags: > + [maturity_incubating, host, container, users, mitre_privilege_escalation, + TA0004] diff --git a/rules/falco-sandbox_rules.yaml b/rules/falco-sandbox_rules.yaml index a4388781..09283123 100644 --- a/rules/falco-sandbox_rules.yaml +++ b/rules/falco-sandbox_rules.yaml @@ -16,15 +16,23 @@ # limitations under the License. # -# Information about rules tags and fields can be found here: https://falco.org/docs/rules/#tags-for-current-falco-ruleset -# The initial item in the `tags` fields reflects the maturity level of the rules introduced upon the proposal https://github.com/falcosecurity/rules/blob/main/proposals/20230605-rules-adoption-management-maturity-framework.md -# `tags` fields also include information about the type of workload inspection (host and/or container), and Mitre Attack killchain phases and Mitre TTP code(s) +# Information about rules tags and fields can be found here:/ +# https://falco.org/docs/rules/#tags-for-current-falco-ruleset +# The initial item in the `tags` fields reflects the maturity level of +# the rules introduced upon the proposal +# https://github.com/falcosecurity/rules/blob/main/proposals/ +# 20230605-rules-adoption-management-maturity-framework.md +# `tags` fields also include information about the type of workload inspection +# (host and/or container), and Mitre Attack killchain phases and +# Mitre TTP code(s) # Mitre Attack References: # [1] https://attack.mitre.org/tactics/enterprise/ -# [2] https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json +# [2] https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/ +# enterprise-attack.json # Starting with version 8, the Falco engine supports exceptions. # However the Falco rules file does not use them by default. +--- - required_engine_version: 0.35.0 # Currently disabled as read/write are ignored syscalls. The nearly @@ -33,27 +41,36 @@ # - macro: write # condition: (syscall.type=write and fd.type in (file, directory)) # - macro: read -# condition: (syscall.type=read and evt.dir=> and fd.type in (file, directory)) +# condition: +# (syscall.type=read and evt.dir=> and fd.type in (file, directory)) - macro: open_write - condition: (evt.type in (open,openat,openat2) and evt.is_open_write=true and fd.typechar='f' and fd.num>=0) + condition: (evt.type in (open,openat,openat2) and evt.is_open_write=true and + fd.typechar='f' and fd.num>=0) - macro: open_read - condition: (evt.type in (open,openat,openat2) and evt.is_open_read=true and fd.typechar='f' and fd.num>=0) + condition: (evt.type in (open,openat,openat2) and evt.is_open_read=true and + fd.typechar='f' and fd.num>=0) -# This macro `never_true` is used as placeholder for tuning negative logical sub-expressions, for example +# This macro `never_true` is used as placeholder for tuning negative logical +# sub-expressions, for example # - macro: allowed_ssh_hosts # condition: (never_true) -# can be used in a rules' expression with double negation `and not allowed_ssh_hosts` which effectively evaluates -# to true and does nothing, the perfect empty template for `logical` cases as opposed to list templates. +# can be used in a rules' expression with double negation +# `and not allowed_ssh_hosts` +# which effectively evaluates +# to true and does nothing, the perfect empty template for `logical` cases as +# opposed to list templates. # When tuning the rule you can override the macro with something useful, e.g. # - macro: allowed_ssh_hosts # condition: (evt.hostname contains xyz) - macro: never_true condition: (evt.num=0) -# This macro `always_true` is the flip side of the macro `never_true` and currently is commented out as -# it is not used. You can use it as placeholder for a positive logical sub-expression tuning template +# This macro `always_true` is the flip side of the macro `never_true` and +# currently is commented out as it is not used. You can use it as placeholder +# for a positive +# logical sub-expression tuning template # macro, e.g. `and custom_procs`, where # - macro: custom_procs # condition: (always_true) @@ -131,29 +148,37 @@ - list: shell_mgmt_binaries items: [add-shell, remove-shell] -# dpkg -L passwd | grep bin | xargs ls -ld | grep -v '^d' | awk '{print $9}' | xargs -L 1 basename | tr "\\n" "," +# dpkg -L passwd | +# grep bin | +# xargs ls -ld | +# grep -v '^d' | +# awk '{print $9}' | +# xargs -L 1 basename | +# tr "\\n" "," - list: passwd_binaries items: [ - shadowconfig, grpck, pwunconv, grpconv, pwck, - groupmod, vipw, pwconv, useradd, newusers, cppw, chpasswd, usermod, - groupadd, groupdel, grpunconv, chgpasswd, userdel, chage, chsh, - gpasswd, chfn, expiry, passwd, vigr, cpgr, adduser, addgroup, deluser, delgroup - ] + shadowconfig, grpck, pwunconv, grpconv, pwck, groupmod, vipw, + pwconv, useradd, newusers, cppw, chpasswd, usermod, groupadd, + groupdel, grpunconv, chgpasswd, userdel, chage, chsh, gpasswd, + chfn, expiry, passwd, vigr, cpgr, adduser, addgroup, deluser, delgroup + ] # repoquery -l shadow-utils | grep bin | xargs ls -ld | grep -v '^d' | # awk '{print $9}' | xargs -L 1 basename | tr "\\n" "," - list: shadowutils_binaries items: [ chage, gpasswd, lastlog, newgrp, sg, adduser, deluser, chpasswd, - groupadd, groupdel, addgroup, delgroup, groupmems, groupmod, grpck, grpconv, grpunconv, - newusers, pwck, pwconv, pwunconv, useradd, userdel, usermod, vigr, vipw, unix_chkpwd - ] + groupadd, groupdel, addgroup, delgroup, groupmems, groupmod, grpck, + grpconv, grpunconv, newusers, pwck, pwconv, pwunconv, useradd, userdel, + usermod, vigr, vipw, unix_chkpwd + ] - list: sysdigcloud_binaries items: [setup-backend, dragent, sdchecks] - list: interpreted_binaries - items: [lua, node, perl, perl5, perl6, php, python, python2, python3, ruby, tcl] + items: [lua, node, perl, perl5, perl6, php, python, python2, + python3, ruby, tcl] - macro: interpreted_procs condition: > @@ -162,28 +187,37 @@ # The explicit quotes are needed to avoid the - characters being # interpreted by the filter expression. - list: rpm_binaries - items: [dnf, dnf-automatic, rpm, rpmkey, yum, '"75-system-updat"', rhsmcertd-worke, rhsmcertd, subscription-ma, - repoquery, rpmkeys, rpmq, yum-cron, yum-config-mana, yum-debug-dump, - abrt-action-sav, rpmdb_stat, microdnf, rhn_check, yumdb] + items: [ + dnf, dnf-automatic, rpm, rpmkey, yum, '"75-system-updat"', + rhsmcertd-worke, rhsmcertd, subscription-ma, repoquery, rpmkeys, + rpmq, yum-cron, yum-config-mana, yum-debug-dump, abrt-action-sav, + rpmdb_stat, microdnf, rhn_check, yumdb] - list: openscap_rpm_binaries - items: [probe_rpminfo, probe_rpmverify, probe_rpmverifyfile, probe_rpmverifypackage] + items: [ + probe_rpminfo, probe_rpmverify, probe_rpmverifyfile, + probe_rpmverifypackage] - macro: rpm_procs - condition: (proc.name in (rpm_binaries, openscap_rpm_binaries) or proc.name in (salt-call, salt-minion)) + condition: (proc.name in (rpm_binaries, openscap_rpm_binaries) or + proc.name in (salt-call, salt-minion)) - list: deb_binaries - items: [dpkg, dpkg-preconfigu, dpkg-reconfigur, dpkg-divert, apt, apt-get, aptitude, - frontend, preinst, add-apt-reposit, apt-auto-remova, apt-key, - apt-listchanges, unattended-upgr, apt-add-reposit, apt-cache, apt.systemd.dai - ] + items: [ + dpkg, dpkg-preconfigu, dpkg-reconfigur, dpkg-divert, apt, + apt-get, aptitude, frontend, preinst, add-apt-reposit, + apt-auto-remova, apt-key, apt-listchanges, unattended-upgr, + apt-add-reposit, apt-cache, apt.systemd.dai + ] - list: python_package_managers items: [pip, pip3, conda] # The truncated dpkg-preconfigu is intentional, process names are # truncated at the falcosecurity-libs level. - list: package_mgmt_binaries - items: [rpm_binaries, deb_binaries, update-alternat, gem, npm, python_package_managers, sane-utils.post, alternatives, chef-client, apk, snapd] + items: [rpm_binaries, deb_binaries, update-alternat, gem, npm, + python_package_managers, sane-utils.post, alternatives, chef-client, + apk, snapd] - macro: package_mgmt_procs condition: (proc.name in (package_mgmt_binaries)) @@ -195,7 +229,8 @@ proc.aname[4] in (package_mgmt_binaries)) - macro: coreos_write_ssh_dir - condition: (proc.name=update-ssh-keys and fd.name startswith /home/core/.ssh) + condition: (proc.name=update-ssh-keys and + fd.name startswith /home/core/.ssh) - list: ssl_mgmt_binaries items: [ca-certificates] @@ -214,7 +249,7 @@ update_conf, parse_mc, makemap_hash, newaliases, update_mk, update_tlsm4, update_db, update_mc, ssmtp.postinst, mailq, postalias, postfix.config., postfix.config, postfix-script, postconf - ] + ] # Network - macro: inbound @@ -236,7 +271,8 @@ (evt.type in (sendto,sendmsg) and evt.dir=< and fd.l4proto != tcp and fd.connected=false and fd.name_changed=true)) and (fd.typechar = 4 or fd.typechar = 6) and - (fd.ip != "0.0.0.0" and fd.net != "127.0.0.0/8" and not fd.snet in (rfc_1918_addresses)) and + (fd.ip != "0.0.0.0" and fd.net != "127.0.0.0/8" and + not fd.snet in (rfc_1918_addresses)) and (evt.rawres >= 0 or evt.res = EINPROGRESS)) # Very similar to inbound/outbound, but combines the tests together @@ -258,23 +294,31 @@ items: [google.com] - rule: Unexpected inbound connection source - desc: > - Detect any inbound connection from a source outside of an allowed set of ips, networks, or domain names. - This rule absolutely requires profiling your environment beforehand. Network-based rules are extremely crucial - in any security program, as they can often provide the only definitive evidence. However, effectively operationalizing - them can be challenging due to the potential for noise. + desc: > + Detect any inbound connection from a source outside of an allowed set of ips + ,networks, or domain names. This rule absolutely requires profiling your + environment beforehand. Network-based rules are extremely crucial in any + security program, as they can often provide the only definitive evidence. + However, effectively operationalizing them can be challenging due to the + potential for noise. condition: > - inbound + inbound and not ((fd.cip in (allowed_inbound_source_ipaddrs)) or (fd.cnet in (allowed_inbound_source_networks)) or (fd.cip.name in (allowed_inbound_source_domains))) enabled: false - output: Disallowed inbound connection source (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Disallowed inbound connection source + (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type + fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: NOTICE - tags: [maturity_sandbox, host, container, network, mitre_command_and_control, TA0011] + tags: [maturity_sandbox, host, container, network, + mitre_command_and_control, TA0011] - list: bash_config_filenames - items: [.bashrc, .bash_profile, .bash_history, .bash_login, .bash_logout, .inputrc, .profile] + items: [.bashrc, .bash_profile, .bash_history, .bash_login, .bash_logout, + .inputrc, .profile] - list: bash_config_files items: [/etc/profile, /etc/bashrc] @@ -301,29 +345,36 @@ # This rule is not enabled by default, as there are many legitimate # readers of shell config files. - rule: Read Shell Configuration File - desc: > - This rule detects attempts made by non-shell programs to read shell configuration files. It offers additional generic auditing. - It serves as a baseline detection alert for unusual shell configuration file accesses. The rule "Modify Shell Configuration File" - might be more relevant and adequate for your specific cases. + desc: > + This rule detects attempts made by non-shell programs to read shell + configuration files. It offers additional generic auditing. It serves as a + baseline detection alert for unusual shell configuration file accesses. + The rule "Modify Shell Configuration File" might be more relevant and + adequate for your specific cases. condition: > open_read and (fd.filename in (shell_config_filenames) or fd.name in (shell_config_files) or - fd.directory in (shell_config_directories)) + fd.directory in (shell_config_directories)) and not proc.name in (shell_binaries) enabled: false - output: A shell configuration file was read by a non-shell program (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: A shell configuration file was read by a non-shell program + (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: WARNING - tags: [maturity_sandbox, host, container, filesystem, mitre_discovery, T1546.004] + tags: [maturity_sandbox, host, container, filesystem, + mitre_discovery, T1546.004] # Use this to test whether the event occurred within a container. # When displaying container information in the output field, use # %container.info, without any leading term (file=%fd.name -# %container.info user=%user.name user_loginuid=%user.loginuid, and not file=%fd.name -# container=%container.info user=%user.name user_loginuid=%user.loginuid). The output will change -# based on the context and whether or not -pk/-pm/-pc was specified on -# the command line. +# %container.info user=%user.name user_loginuid=%user.loginuid, and +# not file=%fd.name container=%container.info user=%user.name +# user_loginuid=%user.loginuid). +# The output will change based on the context and whether or +# not -pk/-pm/-pc was specified on the command line. - macro: container condition: (container.id != host) @@ -343,17 +394,23 @@ - macro: httpd_writing_ssl_conf condition: > (proc.pname=run-httpd and - (proc.cmdline startswith "sed -ri" or proc.cmdline startswith "sed -i") and - (fd.name startswith /etc/httpd/conf.d/ or fd.name startswith /etc/httpd/conf)) + (proc.cmdline startswith "sed -ri" or proc.cmdline startswith "sed -i") + and + (fd.name startswith /etc/httpd/conf.d/ or + fd.name startswith /etc/httpd/conf)) - macro: userhelper_writing_etc_security condition: (proc.name=userhelper and fd.name startswith /etc/security) - macro: ansible_running_python - condition: (proc.name in (python, pypy, python3) and proc.cmdline contains ansible) + condition: (proc.name in (python, pypy, python3) and + proc.cmdline contains ansible) - macro: python_running_chef - condition: (proc.name=python and (proc.cmdline contains yum-dump.py or proc.cmdline="python /usr/bin/chef-monitor.py")) + condition: > + (proc.name=python and + (proc.cmdline contains yum-dump.py or + proc.cmdline="python /usr/bin/chef-monitor.py")): - macro: python_running_denyhosts condition: > @@ -362,24 +419,29 @@ proc.cmdline contains /usr/local/bin/denyhosts.py)) - macro: run_by_chef - condition: (proc.aname[2]=chef_command_wr or proc.aname[3]=chef_command_wr or - proc.aname[2]=chef-client or proc.aname[3]=chef-client or - proc.name=chef-client) + condition: > + (proc.aname[2]=chef_command_wr or proc.aname[3]=chef_command_wr or + proc.aname[2]=chef-client or proc.aname[3]=chef-client or + proc.name=chef-client) - macro: run_by_adclient - condition: (proc.aname[2]=adclient or proc.aname[3]=adclient or proc.aname[4]=adclient) + condition: (proc.aname[2]=adclient or proc.aname[3]=adclient or + proc.aname[4]=adclient) - macro: run_by_centrify - condition: (proc.aname[2]=centrify or proc.aname[3]=centrify or proc.aname[4]=centrify) + condition: (proc.aname[2]=centrify or proc.aname[3]=centrify or + proc.aname[4]=centrify) - macro: parent_supervise_running_multilog condition: (proc.name=multilog and proc.pname=supervise) - macro: supervise_writing_status - condition: (proc.name in (supervise,svc) and fd.name startswith "/etc/sb/") + condition: (proc.name in (supervise,svc) and + fd.name startswith "/etc/sb/") - macro: pki_realm_writing_realms - condition: (proc.cmdline startswith "bash /usr/local/lib/pki/pki-realm" and fd.name startswith /etc/pki/realms) + condition: (proc.cmdline startswith "bash /usr/local/lib/pki/pki-realm" + and fd.name startswith /etc/pki/realms) - macro: htpasswd_writing_passwd condition: (proc.name=htpasswd and fd.name=/etc/nginx/.htpasswd) @@ -400,32 +462,43 @@ - macro: consul_template_writing_conf condition: > ((proc.name=consul-template and fd.name startswith /etc/haproxy) or - (proc.name=reload.sh and proc.aname[2]=consul-template and fd.name startswith /etc/ssl)) + (proc.name=reload.sh and proc.aname[2]=consul-template and + fd.name startswith /etc/ssl)) - macro: countly_writing_nginx_conf - condition: (proc.cmdline startswith "nodejs /opt/countly/bin" and fd.name startswith /etc/nginx) + condition: (proc.cmdline startswith "nodejs /opt/countly/bin" and + fd.name startswith /etc/nginx) - list: ms_oms_binaries items: [omi.postinst, omsconfig.posti, scx.postinst, omsadmin.sh, omiagent] - macro: ms_oms_writing_conf condition: > - ((proc.name in (omiagent,omsagent,in_heartbeat_r*,omsadmin.sh,PerformInventor,dsc_host) + ((proc.name in + (omiagent,omsagent,in_heartbeat_r*,omsadmin.sh,PerformInventor,dsc_host) or proc.pname in (ms_oms_binaries) or proc.aname[2] in (ms_oms_binaries)) - and (fd.name startswith /etc/opt/omi or fd.name startswith /etc/opt/microsoft/omsagent)) + and (fd.name startswith /etc/opt/omi or + fd.name startswith /etc/opt/microsoft/omsagent)) - macro: ms_scx_writing_conf - condition: (proc.name in (GetLinuxOS.sh) and fd.name startswith /etc/opt/microsoft/scx) + condition: > + (proc.name in (GetLinuxOS.sh) and fd.name startswith /etc/opt/microsoft/scx) - macro: azure_scripts_writing_conf - condition: (proc.pname startswith "bash /var/lib/waagent/" and fd.name startswith /etc/azure) + condition: > + (proc.pname startswith "bash /var/lib/waagent/" and + fd.name startswith /etc/azure) - macro: azure_networkwatcher_writing_conf - condition: (proc.name in (NetworkWatcherA) and fd.name=/etc/init.d/AzureNetworkWatcherAgent) + condition: > + (proc.name in (NetworkWatcherA) and + fd.name=/etc/init.d/AzureNetworkWatcherAgent) - macro: couchdb_writing_conf - condition: (proc.name=beam.smp and proc.cmdline contains couchdb and fd.name startswith /etc/couchdb) + condition: > + (proc.name=beam.smp and proc.cmdline contains couchdb and + fd.name startswith /etc/couchdb) - macro: update_texmf_writing_conf condition: (proc.name=update-texmf and fd.name startswith /etc/texmf) @@ -437,7 +510,9 @@ condition: (proc.pname=run-openldap.sh and fd.name startswith /etc/openldap) - macro: ucpagent_writing_conf - condition: (proc.name=apiserver and container.image.repository=docker/ucp-agent and fd.name=/etc/authorization_config.cfg) + condition: (proc.name=apiserver and + container.image.repository=docker/ucp-agent + and fd.name=/etc/authorization_config.cfg) - macro: iscsi_writing_conf condition: (proc.name=iscsiadm and fd.name startswith /etc/iscsi) @@ -451,7 +526,8 @@ (proc.name=navdefutil and fd.name=/etc/symc-defutils.conf)) - macro: liveupdate_writing_conf - condition: (proc.cmdline startswith "java LiveUpdate" and fd.name in (/etc/liveupdate.conf, /etc/Product.Catalog.JavaLiveUpdate)) + condition: (proc.cmdline startswith "java LiveUpdate" and fd.name in + (/etc/liveupdate.conf, /etc/Product.Catalog.JavaLiveUpdate)) - macro: sosreport_writing_files condition: > @@ -464,16 +540,19 @@ (fd.name startswith /etc/pkt/nssdb or fd.name startswith /etc/pki/nssdb)) - macro: update_ca_trust_writing_pki - condition: (proc.pname=update-ca-trust and proc.name=trust and fd.name startswith /etc/pki) + condition: (proc.pname=update-ca-trust and proc.name=trust and + fd.name startswith /etc/pki) - macro: brandbot_writing_os_release condition: (proc.name=brandbot and fd.name=/etc/os-release) - macro: selinux_writing_conf - condition: (proc.name in (semodule,genhomedircon,sefcontext_comp) and fd.name startswith /etc/selinux) + condition: (proc.name in (semodule,genhomedircon,sefcontext_comp) and + fd.name startswith /etc/selinux) - list: veritas_binaries - items: [vxconfigd, sfcache, vxclustadm, vxdctl, vxprint, vxdmpadm, vxdisk, vxdg, vxassist, vxtune] + items: [vxconfigd, sfcache, vxclustadm, vxdctl, vxprint, vxdmpadm, + vxdisk, vxdg, vxassist, vxtune] - macro: veritas_driver_script condition: (proc.cmdline startswith "perl /opt/VRTSsfmh/bin/mh_driver.pl") @@ -482,23 +561,30 @@ condition: (proc.name in (veritas_binaries) or veritas_driver_script) - macro: veritas_writing_config - condition: (veritas_progs and (fd.name startswith /etc/vx or fd.name startswith /etc/opt/VRTS or fd.name startswith /etc/vom)) + condition: (veritas_progs and (fd.name startswith /etc/vx or + fd.name startswith /etc/opt/VRTS or fd.name startswith /etc/vom)) - macro: nginx_writing_conf - condition: (proc.name in (nginx,nginx-ingress-c,nginx-ingress) and (fd.name startswith /etc/nginx or fd.name startswith /etc/ingress-controller)) + condition: (proc.name in (nginx,nginx-ingress-c,nginx-ingress) and + (fd.name startswith /etc/nginx or + fd.name startswith /etc/ingress-controller)) - macro: nginx_writing_certs condition: > - (((proc.name=openssl and proc.pname=nginx-launch.sh) or proc.name=nginx-launch.sh) and fd.name startswith /etc/nginx/certs) + (((proc.name=openssl and proc.pname=nginx-launch.sh) or + proc.name=nginx-launch.sh) + and fd.name startswith /etc/nginx/certs) - macro: chef_client_writing_conf - condition: (proc.pcmdline startswith "chef-client /opt/gitlab" and fd.name startswith /etc/gitlab) + condition: (proc.pcmdline startswith "chef-client /opt/gitlab" and + fd.name startswith /etc/gitlab) - macro: centrify_writing_krb condition: (proc.name in (adjoin,addns) and fd.name startswith /etc/krb5) - macro: sssd_writing_krb - condition: (proc.name=adcli and proc.aname[2]=sssd and fd.name startswith /etc/krb5) + condition: (proc.name=adcli and proc.aname[2]=sssd and + fd.name startswith /etc/krb5) - macro: cockpit_writing_conf condition: > @@ -533,7 +619,8 @@ condition: (proc.name=dse-entrypoint and fd.name=/root/tmp__) - macro: zap_writing_state - condition: (proc.exe endswith java and proc.cmdline contains "jar /zap" and fd.name startswith /root/.ZAP) + condition: (proc.exe endswith java and proc.cmdline contains "jar /zap" and + fd.name startswith /root/.ZAP) - macro: airflow_writing_state condition: (proc.name=airflow and fd.name startswith /root/airflow) @@ -542,7 +629,8 @@ condition: (proc.name=rpm and fd.directory=/root/.rpmdb) - macro: maven_writing_groovy - condition: (proc.exe endswith java and proc.cmdline contains "classpath /usr/local/apache-maven" and fd.name startswith /root/.groovy) + condition: (proc.exe endswith java and proc.cmdline contains + "classpath /usr/local/apache-maven" and fd.name startswith /root/.groovy) - macro: chef_writing_conf condition: (proc.name=chef-client and fd.name startswith /root/.chef) @@ -564,10 +652,12 @@ items: [/healthready, /healthliveness] - macro: calico_writing_state - condition: (proc.name=kube-controller and fd.name startswith /status.json and k8s.pod.name startswith calico) + condition: (proc.name=kube-controller and fd.name startswith /status.json and + k8s.pod.name startswith calico) - macro: calico_writing_envvars - condition: (proc.name=start_runit and fd.name startswith "/etc/envvars" and container.image.repository endswith "calico/node") + condition: (proc.name=start_runit and fd.name startswith "/etc/envvars" and + container.image.repository endswith "calico/node") - list: repository_files items: [sources.list] @@ -589,19 +679,24 @@ # todo!: the usage of `evt.arg*` filter check in the output should be avoided # when more than one event type is involved because some event will populate # the filtercheck and others will always return . In this specific -# rule, 'open_write' events don't have a `%evt.arg.newpath` argument for example so -# we will always return ``. +# rule, 'open_write' events don't have a `%evt.arg.newpath` argument for +# example so we will always return ``. - rule: Update Package Repository - desc: > - This rule generically detects updates to package repositories and can be seen as an auditing measure. - Recommend evaluating its relevance for your specific environment. + desc: > + This rule generically detects updates to package repositories and + can be seen as an auditing measure. Recommend evaluating its relevance for + your specific environment. condition: > ((open_write and access_repositories) or (modify and modify_repositories)) and not package_mgmt_procs and not package_mgmt_ancestor_procs and not exe_running_docker_save and not user_known_update_package_registry - output: Repository files get updated (newpath=%evt.arg.newpath file=%fd.name pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Repository files get updated + (newpath=%evt.arg.newpath file=%fd.name pcmdline=%proc.pcmdline + evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: NOTICE tags: [maturity_sandbox, host, container, filesystem, mitre_execution, T1072] @@ -613,28 +708,36 @@ condition: (never_true) - rule: Write below binary dir - desc: > - Trying to write to any file below specific binary directories can serve as an auditing rule to track general system changes. - Such rules can be noisy and challenging to interpret, particularly if your system frequently undergoes updates. However, careful - profiling of your environment can transform this rule into an effective rule for detecting unusual behavior associated with system - changes, including compliance-related cases. + desc: > + Trying to write to any file below specific binary directories can serve as + an auditing rule to track general system changes. Such rules can be noisy + and challenging to interpret, particularly if your system frequently + undergoes updates. However, careful profiling of your environment can + transform this rule into an effective rule for detecting unusual behavior + associated with system changes, including compliance-related cases. condition: > - open_write and evt.dir=< + open_write and evt.dir=< and bin_dir and not package_mgmt_procs and not exe_running_docker_save and not python_running_get_pip and not python_running_ms_oms and not user_known_write_below_binary_dir_activities - output: File below a known binary directory opened for writing (file=%fd.name pcmdline=%proc.pcmdline gparent=%proc.aname[2] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: File below a known binary directory opened for writing + (file=%fd.name pcmdline=%proc.pcmdline gparent=%proc.aname[2] + evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: ERROR - tags: [maturity_sandbox, host, container, filesystem, mitre_persistence, T1543] + tags: [maturity_sandbox, host, container, filesystem, mitre_persistence, + T1543] # If you'd like to generally monitor a wider set of directories on top # of the ones covered by the rule Write below binary dir, you can use # the following rule and lists. - list: monitored_directories - items: [/boot, /lib, /lib64, /usr/lib, /usr/local/lib, /usr/local/sbin, /usr/local/bin, /root/.ssh] + items: [/boot, /lib, /lib64, /usr/lib, /usr/local/lib, /usr/local/sbin, + /usr/local/bin, /root/.ssh] - macro: user_ssh_directory condition: (fd.name contains '/.ssh/' and fd.name glob '/home/*/.ssh/*') @@ -647,7 +750,8 @@ condition: (proc.name=cloud-init and user_ssh_directory) - macro: mkinitramfs_writing_boot - condition: (proc.pname in (mkinitramfs, update-initramf) and fd.directory=/boot) + condition: (proc.pname in (mkinitramfs, update-initramf) and + fd.directory=/boot) - macro: monitored_dir condition: > @@ -665,11 +769,13 @@ condition: (never_true) - rule: Write below monitored dir - desc: > - Trying to write to any file below a set of monitored directories can serve as an auditing rule to track general system changes. - Such rules can be noisy and challenging to interpret, particularly if your system frequently undergoes updates. However, careful - profiling of your environment can transform this rule into an effective rule for detecting unusual behavior associated with system - changes, including compliance-related cases. + desc: > + Trying to write to any file below a set of monitored directories can serve + as an auditing rule to track general system changes.Such rules can be noisy + and challenging to interpret, particularly if your system frequently + undergoes updates. However, careful profiling of your environment can + transform this rule into an effective rule for detecting unusual behavior + associated with system changes, including compliance-related cases. condition: > open_write and evt.dir=< and monitored_dir @@ -681,28 +787,42 @@ and not google_accounts_daemon_writing_ssh and not cloud_init_writing_ssh and not user_known_write_monitored_dir_conditions - output: File below a monitored directory opened for writing (file=%fd.name pcmdline=%proc.pcmdline gparent=%proc.aname[2] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: File below a monitored directory opened for writing + (file=%fd.name pcmdline=%proc.pcmdline gparent=%proc.aname[2 + evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: ERROR - tags: [maturity_sandbox, host, container, filesystem, mitre_persistence, T1543] + tags: > + [maturity_sandbox, host, container, filesystem, mitre_persistence, T1543] - list: safe_etc_dirs - items: [/etc/cassandra, /etc/ssl/certs/java, /etc/logstash, /etc/nginx/conf.d, /etc/container_environment, /etc/hrmconfig, /etc/fluent/configs.d. /etc/alertmanager] + items: > + [/etc/cassandra, /etc/ssl/certs/java, /etc/logstash, /etc/nginx/conf.d, + /etc/container_environment, /etc/hrmconfig, /etc/fluent/configs.d. + /etc/alertmanager] - macro: fluentd_writing_conf_files - condition: (proc.name=start-fluentd and fd.name in (/etc/fluent/fluent.conf, /etc/td-agent/td-agent.conf)) + condition: (proc.name=start-fluentd and fd.name in + (/etc/fluent/fluent.conf, /etc/td-agent/td-agent.conf)) - macro: qualys_writing_conf_files - condition: (proc.name=qualys-cloud-ag and fd.name=/etc/qualys/cloud-agent/qagent-log.conf) + condition: > + (proc.name=qualys-cloud-ag and + fd.name=/etc/qualys/cloud-agent/qagent-log.conf) - macro: git_writing_nssdb condition: (proc.name=git-remote-http and fd.directory=/etc/pki/nssdb) - macro: plesk_writing_keys - condition: (proc.name in (plesk_binaries) and fd.name startswith /etc/sw/keys) + condition: > + (proc.name in (plesk_binaries) and fd.name startswith /etc/sw/keys) - macro: plesk_install_writing_apache_conf - condition: (proc.cmdline startswith "bash -hB /usr/lib/plesk-9.0/services/webserver.apache configure" - and fd.name="/etc/apache2/apache2.conf.tmp") + condition: (proc.cmdline startswith + "bash -hB /usr/lib/plesk-9.0/services/webserver.apache configure" + and fd.name="/etc/apache2/apache2.conf.tmp") - macro: plesk_running_mktemp condition: (proc.name=mktemp and proc.aname[3] in (plesk_binaries)) @@ -714,28 +834,31 @@ condition: (proc.name=add-shell and fd.name=/etc/shells.tmp) - macro: duply_writing_exclude_files - condition: (proc.name=touch and proc.pcmdline startswith "bash /usr/bin/duply" and fd.name startswith "/etc/duply") + condition: (proc.name=touch and proc.pcmdline startswith "bash /usr/bin/duply" + and fd.name startswith "/etc/duply") - macro: xmlcatalog_writing_files condition: (proc.name=update-xmlcatal and fd.directory=/etc/xml) - macro: datadog_writing_conf condition: ((proc.cmdline startswith "python /opt/datadog-agent" or - proc.cmdline startswith "entrypoint.sh /entrypoint.sh datadog start" or - proc.cmdline startswith "agent.py /opt/datadog-agent") - and fd.name startswith "/etc/dd-agent") + proc.cmdline startswith "entrypoint.sh /entrypoint.sh datadog start" or + proc.cmdline startswith "agent.py /opt/datadog-agent") + and fd.name startswith "/etc/dd-agent") - macro: rancher_writing_conf condition: ((proc.name in (healthcheck, lb-controller, rancher-dns)) and (container.image.repository contains "rancher/healthcheck" or - container.image.repository contains "rancher/lb-service-haproxy" or - container.image.repository contains "rancher/dns") and - (fd.name startswith "/etc/haproxy" or fd.name startswith "/etc/rancher-dns")) + container.image.repository contains "rancher/lb-service-haproxy" + or container.image.repository contains "rancher/dns") and + (fd.name startswith "/etc/haproxy" or + fd.name startswith "/etc/rancher-dns")) - macro: rancher_writing_root condition: (proc.name=rancher-metadat and - (container.image.repository contains "rancher/metadata" or container.image.repository contains "rancher/lb-service-haproxy") and - fd.name startswith "/answers.json") + (container.image.repository contains "rancher/metadata" or + container.image.repository contains "rancher/lb-service-haproxy") and + fd.name startswith "/answers.json") - macro: checkpoint_writing_state condition: (proc.name=checkpoint and @@ -753,11 +876,13 @@ condition: (proc.name=curl and fd.directory=/etc/pki/nssdb) - macro: haproxy_writing_conf - condition: ((proc.name in (update-haproxy-,haproxy_reload.) or proc.pname in (update-haproxy-,haproxy_reload,haproxy_reload.)) - and (fd.name=/etc/openvpn/client.map or fd.name startswith /etc/haproxy)) + condition: ((proc.name in (update-haproxy-,haproxy_reload.) or + proc.pname in (update-haproxy-,haproxy_reload,haproxy_reload.)) + and (fd.name=/etc/openvpn/client.map or fd.name startswith /etc/haproxy)) - macro: java_writing_conf - condition: (proc.exe endswith java and fd.name=/etc/.java/.systemPrefs/.system.lock) + condition: > + (proc.exe endswith java and fd.name=/etc/.java/.systemPrefs/.system.lock) - macro: rabbitmq_writing_conf condition: (proc.name=rabbitmq-server and fd.directory=/etc/rabbitmq) @@ -771,15 +896,17 @@ - macro: mysql_writing_conf condition: > - ((proc.name in (start-mysql.sh, run-mysqld) or proc.pname=start-mysql.sh) and - (fd.name startswith /etc/mysql or fd.directory=/etc/my.cnf.d)) + ((proc.name in (start-mysql.sh, run-mysqld) or proc.pname=start-mysql.sh) + and (fd.name startswith /etc/mysql or fd.directory=/etc/my.cnf.d)) - macro: redis_writing_conf condition: > - (proc.name in (run-redis, redis-launcher.) and (fd.name=/etc/redis.conf or fd.name startswith /etc/redis)) + (proc.name in (run-redis, redis-launcher.) and (fd.name=/etc/redis.conf or + fd.name startswith /etc/redis)) - macro: openvpn_writing_conf - condition: (proc.name in (openvpn,openvpn-entrypo) and fd.name startswith /etc/openvpn) + condition: > + (proc.name in (openvpn,openvpn-entrypo) and fd.name startswith /etc/openvpn) - macro: php_handlers_writing_conf condition: (proc.name=php_handlers_co and fd.name=/etc/psa/php_versions.json) @@ -792,7 +919,8 @@ fd.name startswith /etc/apt/apt.conf.d/sed))) - macro: cron_start_writing_pam_env - condition: (proc.cmdline="bash /usr/sbin/start-cron" and fd.name=/etc/security/pam_env.conf) + condition: (proc.cmdline="bash /usr/sbin/start-cron" and + fd.name=/etc/security/pam_env.conf) # In some cases dpkg-reconfigur runs commands that modify /etc. Not # putting the full set of package management programs yet. @@ -805,18 +933,23 @@ - macro: calico_writing_conf condition: > (((proc.name = calico-node) or - (container.image.repository=gcr.io/projectcalico-org/node and proc.name in (start_runit, cp)) or - (container.image.repository=gcr.io/projectcalico-org/cni and proc.name=sed)) + (container.image.repository=gcr.io/projectcalico-org/node and + proc.name in (start_runit, cp)) or + (container.image.repository=gcr.io/projectcalico-org/cni and + proc.name=sed)) and fd.name startswith /etc/calico) - macro: prometheus_conf_writing_conf - condition: (proc.name=prometheus-conf and fd.name startswith /etc/prometheus/config_out) + condition: > + (proc.name=prometheus-conf and fd.name startswith + /etc/prometheus/config_out) - macro: openshift_writing_conf condition: (proc.name=oc and fd.name startswith /etc/origin/node) - macro: keepalived_writing_conf - condition: (proc.name in (keepalived, kube-keepalived) and fd.name=/etc/keepalived/keepalived.conf) + condition: (proc.name in (keepalived, kube-keepalived) and + fd.name=/etc/keepalived/keepalived.conf) - macro: etcd_manager_updating_dns condition: (container and proc.name=etcd-manager and fd.name=/etc/hosts) @@ -849,35 +982,44 @@ - macro: user_known_write_etc_conditions condition: (proc.name=confd) -# This is a placeholder for user to extend the whitelist for write below etc rule +# This is placeholder for user to extend the whitelist for write below etc rule - macro: user_known_write_below_etc_activities condition: (never_true) - macro: calico_node - condition: (container.image.repository endswith calico/node and proc.name=calico-node) + condition: (container.image.repository endswith calico/node and + proc.name=calico-node) - macro: write_etc_common condition: > - (open_write - and etc_dir and evt.dir=< + (open_write + and etc_dir and evt.dir=< and proc_name_exists - and not proc.name in (passwd_binaries, shadowutils_binaries, sysdigcloud_binaries, - package_mgmt_binaries, ssl_mgmt_binaries, dhcp_binaries, + and not proc.name in (passwd_binaries, shadowutils_binaries, + sysdigcloud_binaries, package_mgmt_binaries, + ssl_mgmt_binaries, dhcp_binaries, dev_creation_binaries, shell_mgmt_binaries, mail_config_binaries, sshkit_script_binaries, ldconfig.real, ldconfig, confd, gpg, insserv, - apparmor_parser, update-mime, tzdata.config, tzdata.postinst, - systemd, systemd-machine, systemd-sysuser, - debconf-show, rollerd, bind9.postinst, sv, - gen_resolvconf., update-ca-certi, certbot, runsv, - qualys-cloud-ag, locales.postins, nomachine_binaries, - adclient, certutil, crlutil, pam-auth-update, parallels_insta, + apparmor_parser, update-mime, tzdata.config, + tzdata.postinst, systemd, systemd-machine, + systemd-sysuser, debconf-show, rollerd, + bind9.postinst, sv, gen_resolvconf., + update-ca-certi, certbot, runsv, qualys-cloud-ag, + locales.postins, nomachine_binaries, adclient, + certutil, crlutil, pam-auth-update, parallels_insta, openshift-launc, update-rc.d, puppet, falcoctl) - and not (container and proc.cmdline in ("cp /run/secrets/kubernetes.io/serviceaccount/ca.crt /etc/pki/ca-trust/source/anchors/openshift-ca.crt")) - and not proc.pname in (sysdigcloud_binaries, mail_config_binaries, hddtemp.postins, sshkit_script_binaries, locales.postins, deb_binaries, dhcp_binaries) + and not (container and proc.cmdline in + ("cp /run/secrets/kubernetes.io/serviceaccount/ + ca.crt /etc/pki/ca-trust/source/anchors/openshift-ca.crt")) + and not proc.pname in (sysdigcloud_binaries, mail_config_binaries, + hddtemp.postins, sshkit_script_binaries, + locales.postins, deb_binaries, dhcp_binaries) and not fd.name pmatch (safe_etc_dirs) - and not fd.name in (/etc/container_environment.sh, /etc/container_environment.json, /etc/motd, /etc/motd.svc) + and not fd.name in (/etc/container_environment.sh, + /etc/container_environment.json, + /etc/motd, /etc/motd.svc) and not sed_temporary_file and not exe_running_docker_save and not ansible_running_python @@ -965,20 +1107,33 @@ and not calico_node) - rule: Write below etc - desc: > - Trying to write to any file below /etc can serve as an auditing rule to track general system changes. - Such rules can be noisy and challenging to interpret, particularly if your system frequently undergoes updates. However, careful - profiling of your environment can transform this rule into an effective rule for detecting unusual behavior associated with system - changes, including compliance-related cases. + desc: > + Trying to write to any file below /etc can serve as an auditing rule to + track general system changes. Such rules can be noisy and challenging to + interpret, particularly if your system frequently undergoes updates. + However, careful profiling of your environment can transform this rule + into an effective rule for detecting unusual behavior associated with + system changes, including compliance-related cases. condition: write_etc_common - output: File below /etc opened for writing (file=%fd.name pcmdline=%proc.pcmdline gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: File below /etc opened for writing + (file=%fd.name pcmdline=%proc.pcmdline gparent=%proc.aname[2] + ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type + user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid + process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname + command=%proc.cmdline terminal=%proc.tty %container.info) priority: ERROR - tags: [maturity_sandbox, host, container, filesystem, mitre_persistence, T1098] + tags: > + [maturity_sandbox, host, container, filesystem, mitre_persistence, T1098] - list: known_root_files - items: [/root/.monit.state, /root/.auth_tokens, /root/.bash_history, /root/.ash_history, /root/.aws/credentials, - /root/.viminfo.tmp, /root/.lesshst, /root/.bzr.log, /root/.gitconfig.lock, /root/.babel.json, /root/.localstack, - /root/.node_repl_history, /root/.mongorc.js, /root/.dbshell, /root/.augeas/history, /root/.rnd, /root/.wget-hsts, /health, /exec.fifo] + items: [ + /root/.monit.state, /root/.auth_tokens, /root/.bash_history, + /root/.ash_history, /root/.aws/credentials, /root/.viminfo.tmp, + /root/.lesshst, /root/.bzr.log, /root/.gitconfig.lock, + /root/.babel.json, /root/.localstack, /root/.node_repl_history, + /root/.mongorc.js, /root/.dbshell, /root/.augeas/history, + /root/.rnd, /root/.wget-hsts, /health, /exec.fifo + ] - list: known_root_directories items: [/root/.oracle_jre_usage, /root/.ssh, /root/.subversion, /root/.nami] @@ -1030,7 +1185,8 @@ - macro: user_known_write_root_conditions condition: (fd.name=/root/.bash_history) -# This is a placeholder for user to extend the whitelist for write below root rule +# This is a placeholder for user to extend the whitelist for write below +# root rule - macro: user_known_write_below_root_activities condition: (never_true) @@ -1038,18 +1194,23 @@ condition: (proc.cmdline="runc:[1:CHILD] init" and fd.name=/exec.fifo) - macro: runc_writing_var_lib_docker - condition: (proc.cmdline="runc:[1:CHILD] init" and evt.arg.filename startswith /var/lib/docker) + condition: > + (proc.cmdline="runc:[1:CHILD] init" and evt.arg.filename startswith + /var/lib/docker) - macro: mysqlsh_writing_state condition: (proc.name=mysqlsh and fd.directory=/root/.mysqlsh) - rule: Write below root - desc: > - Trying to write to any file directly below / or /root can serve as an auditing rule to track general system changes. - Such rules can be noisy and challenging to interpret, particularly if your system frequently undergoes updates. However, careful - profiling of your environment can transform this rule into an effective rule for detecting unusual behavior associated with system - changes, including compliance-related cases. Lastly, this rule stands out as potentially the noisiest one among rules related - to "write below. + desc: > + Trying to write to any file directly below / or /root can serve as + an auditing rule to track general system changes. Such rules can be + noisy and challenging to interpret, particularly if your system + frequently undergoes updates. However, careful profiling of your + environment can transform this rule into an effective rule for detecting + unusual behavior associated with system changes, including + compliance-related cases. Lastly, this rule stands out as potentially + the noisiest one among rules related to "write below. condition: > open_write and evt.dir=< and root_dir @@ -1074,9 +1235,13 @@ and not known_root_conditions and not user_known_write_root_conditions and not user_known_write_below_root_activities - output: File below / or /root opened for writing (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: File below / or /root opened for writing + (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: ERROR - tags: [maturity_sandbox, host, container, filesystem, mitre_persistence, TA0003] + tags: > + [maturity_sandbox, host, container, filesystem, mitre_persistence, TA0003] - macro: amazon_linux_running_python_yum condition: > @@ -1089,11 +1254,13 @@ # Only let rpm-related programs write to the rpm database - rule: Write below rpm database - desc: > - Trying to write to the rpm database by any non-rpm related program can serve as an auditing rule to track general system changes. - Such rules can be noisy and challenging to interpret, particularly if your system frequently undergoes updates. However, careful - profiling of your environment can transform this rule into an effective rule for detecting unusual behavior associated with system - changes, including compliance-related cases. + desc: > + Trying to write to the rpm database by any non-rpm related program can serve + as an auditing rule to track general system changes. Such rules can be noisy + and challenging to interpret, particularly if your system frequently + undergoes updates. However, careful profiling of your environment can + transform this rule into an effective rule for detecting unusual behavior + associated with system changes, including compliance-related cases. condition: > open_write and fd.name startswith /var/lib/rpm @@ -1103,47 +1270,67 @@ and not exe_running_docker_save and not amazon_linux_running_python_yum and not user_known_write_rpm_database_activities - output: rpm database opened for writing by a non-rpm program (file=%fd.name pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: rpm database opened for writing by a non-rpm program + (file=%fd.name pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name + user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: ERROR - tags: [maturity_sandbox, host, container, filesystem, software_mgmt, mitre_persistence, T1072] + tags: [maturity_sandbox, host, container, filesystem, software_mgmt, + mitre_persistence, T1072] - macro: user_known_modify_bin_dir_activities condition: (never_true) - rule: Modify binary dirs - desc: > - Trying to modify any file below a set of binary directories can serve as an auditing rule to track general system changes. - Such rules can be noisy and challenging to interpret, particularly if your system frequently undergoes updates. However, careful - profiling of your environment can transform this rule into an effective rule for detecting unusual behavior associated with system - changes, including compliance-related cases. - condition: > - modify + desc: > + Trying to modify any file below a set of binary directories can serve as an + auditing rule to track general system changes. Such rules can be noisy and + challenging to interpret, particularly if your system frequently undergoes + updates. However, careful profiling of your environment can transform this + rule into an effective rule for detecting unusual behavior associated with + system changes, including compliance-related cases. + condition: > + modify and bin_dir_rename - and not package_mgmt_procs - and not exe_running_docker_save + and not package_mgmt_procs + and not exe_running_docker_save and not user_known_modify_bin_dir_activities - output: File below known binary directory renamed/removed (file=%fd.name pcmdline=%proc.pcmdline evt_args=%evt.args evt_type=%evt.type evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: File below known binary directory renamed/removed + (file=%fd.name pcmdline=%proc.pcmdline evt_args=%evt.args evt_type=%evt.type + evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: ERROR - tags: [maturity_sandbox, host, container, filesystem, mitre_defense_evasion, T1222.002] + tags: > + [maturity_sandbox, host, container, filesystem, mitre_defense_evasion, + T1222.002] - macro: user_known_mkdir_bin_dir_activities condition: (never_true) - rule: Mkdir binary dirs desc: > - Trying to create a directory below a set of binary directories can serve as an auditing rule to track general system changes. - Such rules can be noisy and challenging to interpret, particularly if your system frequently undergoes updates. However, careful - profiling of your environment can transform this rule into an effective rule for detecting unusual behavior associated with system - changes, including compliance-related cases. + Trying to create a directory below a set of binary directories can serve as + an auditing rule to track general system changes. Such rules can be noisy + and challenging to interpret, particularly if your system frequently + undergoes updates. However, careful profiling of your environment can + transform this rule into an effective rule for detecting unusual behavior + associated with system changes, including compliance-related cases. condition: > mkdir and bin_dir_mkdir and not package_mgmt_procs and not user_known_mkdir_bin_dir_activities and not exe_running_docker_save - output: Directory below known binary directory created (directory=%evt.arg.path evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Directory below known binary directory created + (directory=%evt.arg.path evt_type=%evt.type user=%user.name + user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: ERROR - tags: [maturity_sandbox, host, container, filesystem, mitre_persistence, T1222.002] + tags: [maturity_sandbox, host, container, filesystem, mitre_persistence, + T1222.002] # https://docs.aws.amazon.com/eks/latest/userguide/add-ons-images.html # official AWS EKS registry list. AWS has different ECR repo per region @@ -1161,7 +1348,8 @@ - macro: aws_eks_image_sensitive_mount condition: > - (allowed_aws_ecr_registry_root_for_eks and container.image.repository endswith ".amazonaws.com/amazon-k8s-cni") + (allowed_aws_ecr_registry_root_for_eks and container.image.repository + endswith ".amazonaws.com/amazon-k8s-cni") # These images are allowed both to run with --privileged and to mount # sensitive paths from the host filesystem. @@ -1193,11 +1381,9 @@ - falcosecurity/falco - docker.io/falcosecurity/falco - public.ecr.aws/falcosecurity/falco - -# Falco no driver containers - - falcosecurity/falco-no-driver - - docker.io/falcosecurity/falco-no-driver - - public.ecr.aws/falcosecurity/falco-no-driver + - falcosecurity/falco-no-driver # Falco no driver containers + - docker.io/falcosecurity/falco-no-driver # Falco no driver containers + - public.ecr.aws/falcosecurity/falco-no-driver # Falco no driver containers # These container images are allowed to mount sensitive paths from the # host filesystem. @@ -1207,11 +1393,14 @@ docker.io/sysdig/sysdig, sysdig/sysdig, gcr.io/google_containers/hyperkube, gcr.io/google_containers/kube-proxy, docker.io/calico/node, - docker.io/rook/toolbox, docker.io/cloudnativelabs/kube-router, docker.io/consul, - docker.io/datadog/docker-dd-agent, docker.io/datadog/agent, docker.io/docker/ucp-agent, docker.io/gliderlabs/logspout, - docker.io/netdata/netdata, docker.io/google/cadvisor, docker.io/prom/node-exporter, - amazon/amazon-ecs-agent, prom/node-exporter, amazon/cloudwatch-agent - ] + docker.io/rook/toolbox, docker.io/cloudnativelabs/kube-router, + docker.io/consul, docker.io/datadog/docker-dd-agent, + docker.io/datadog/agent, docker.io/docker/ucp-agent, + docker.io/gliderlabs/logspout, + docker.io/netdata/netdata, docker.io/google/cadvisor, + docker.io/prom/node-exporter, amazon/amazon-ecs-agent, + prom/node-exporter, amazon/cloudwatch-agent + ] - macro: falco_sensitive_mount_containers condition: (user_trusted_containers or @@ -1250,16 +1439,21 @@ - rule: Launch Sensitive Mount Container desc: > - Detect the initial process launched within a container that has a mount from a sensitive host directory (e.g. /proc). - Exceptions are made for known trusted images. This rule holds value for generic auditing; however, its noisiness - varies based on your environment. + Detect the initial process launched within a container that has a mount + from a sensitive host directory (e.g. /proc). Exceptions are made for known + trusted images. This rule holds value for generic auditing; however, its + noisiness varies based on your environment. condition: > - container_started + container_started and container and sensitive_mount and not falco_sensitive_mount_containers and not user_sensitive_mount_containers - output: Container with sensitive mount started (mounts=%container.mounts evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Container with sensitive mount started + (mounts=%container.mounts evt_type=%evt.type user=%user. + user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: INFO tags: [maturity_sandbox, container, cis, mitre_execution, T1610] @@ -1276,15 +1470,19 @@ - rule: Launch Disallowed Container desc: > - Detect the initial process launched within a container that is not in a list of allowed containers. - This rule holds value for generic auditing; however, this rule requires a good understanding of your - setup and consistent effort to keep the list of allowed containers current. In some situations, - this can be challenging to manage. - condition: > - container_started - and container + Detect the initial process launched within a container that is not in + a list of allowed containers. This rule holds value for generic auditing; + however, this rule requires a good understanding of your setup and + consistent effort to keep the list of allowed containers current. In + some situations, this can be challenging to manage. + condition: > + container_started + and container and not allowed_containers - output: Container started and not in allowed list (evt_type=%evt.type user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Container started and not in allowed list + (evt_type=%evt.type user_uid=%user.uid user_loginuid=%user.loginuid + process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname + command=%proc.cmdline terminal=%proc.tty %container.info) priority: WARNING tags: [maturity_sandbox, container, mitre_lateral_movement, T1610] @@ -1293,28 +1491,42 @@ # outgoing connections might be suspicious. These rules are not # enabled by default. - rule: Interpreted procs inbound network activity - desc: > - Any inbound network activity performed by any interpreted program (perl, python, ruby, etc.). While it offers broad coverage and behavioral - insights, operationalizing it effectively requires significant time and might result in a moderate level of noise. Suggesting customizing - this rule to be more specific. For example, you could set it up to alert only for important namespaces after studying their usual behavior. + desc: > + Any inbound network activity performed by any interpreted program + (perl, python, ruby, etc.). While it offers broad coverage and behavioral + insights, operationalizing it effectively requires significant time and + might result in a moderate level of noise. Suggesting customizing this + rule to be more specific. For example, you could set it up to alert only + for important namespaces after studying their usual behavior. condition: > - inbound + inbound and interpreted_procs enabled: false - output: Interpreted program received/listened for network traffic (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Interpreted program received/listened for network traffic + (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type + fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: NOTICE tags: [maturity_sandbox, host, container, network, mitre_exfiltration, TA0011] - rule: Interpreted procs outbound network activity - desc: > - Any outbound network activity performed by any interpreted program (perl, python, ruby, etc.). While it offers broad coverage and behavioral - insights, operationalizing it effectively requires significant time and might result in a moderate level of noise. Suggesting customizing - this rule to be more specific. For example, you could set it up to alert only for important namespaces after studying their usual behavior. + desc: > + Any outbound network activity performed by any interpreted program + (perl, python, ruby, etc.). While it offers broad coverage and behavioral + insights, operationalizing it effectively requires significant time and + might result in a moderate level of noise. Suggesting customizing this + rule to be more specific. For example, you could set it up to alert only + for important namespaces after studying their usual behavior. condition: > - outbound + outbound and interpreted_procs enabled: false - output: Interpreted program performed outgoing network connection (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Interpreted program performed outgoing network connection + (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type + fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: NOTICE tags: [maturity_sandbox, host, container, network, mitre_exfiltration, TA0011] @@ -1328,21 +1540,28 @@ condition: (never_true) - rule: Unexpected K8s NodePort Connection - desc: > - Detect attempts to utilize K8s NodePorts from a container. K8s NodePorts are accessible on the eth0 interface of - each node, and they facilitate external traffic into a Kubernetes cluster. Attackers could misuse them for - unauthorized access. The rule uses default port ranges, but check for custom ranges and make necessary adjustments. - Also, consider tuning this rule as needed. - condition: > - inbound_outbound - and container - and fd.sport >= 30000 - and fd.sport <= 32767 + desc: > + Detect attempts to utilize K8s NodePorts from a container. K8s NodePorts are + accessible on the eth0 interface of each node, and they facilitate external + traffic into a Kubernetes cluster. Attackers could misuse them for + unauthorized access. The rule uses default port ranges, but check for custom + ranges and make necessary adjustments. Also, consider tuning this rule as + needed. + condition: > + inbound_outbound + and container + and fd.sport >= 30000 + and fd.sport <= 32767 and not nodeport_containers enabled: false - output: Unexpected K8s NodePort Connection (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Unexpected K8s NodePort Connection + (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type + fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: NOTICE - tags: [maturity_sandbox, network, k8s, container, mitre_persistence, T1205.001, NIST_800-53_AC-6] + tags: [maturity_sandbox, network, k8s, container, mitre_persistence, + T1205.001, NIST_800-53_AC-6] - list: exclude_hidden_directories items: [/root/.cassandra] @@ -1352,67 +1571,77 @@ condition: (never_true) - rule: Create Hidden Files or Directories - desc: > - Detecting hidden files or directories creation can serve as an auditing rule to track general system changes. - Such rules can be noisy and challenging to interpret, particularly if your system frequently undergoes updates. However, careful - profiling of your environment can transform this rule into an effective rule for detecting unusual behavior associated with system - changes, including compliance-related cases. + desc: > + Detecting hidden files or directories creation can serve as an auditing + rule to track general system changes.Such rules can be noisy and challenging + to interpret, particularly if your system frequently undergoes updates. + However, careful profiling of your environment can transform this rule + into an effective rule for detecting unusual behavior associated with + system changes, including compliance-related cases. condition: > ((modify and evt.arg.newpath contains "/.") or (mkdir and evt.arg.path contains "/.") or - (open_write and evt.arg.flags contains "O_CREAT" and fd.name contains "/." and not fd.name pmatch (exclude_hidden_directories))) + (open_write and evt.arg.flags contains "O_CREAT" and + fd.name contains "/." and + not fd.name pmatch (exclude_hidden_directories))) and not user_known_create_hidden_file_activities and not exe_running_docker_save enabled: false - output: Hidden file or directory created (file=%fd.name newpath=%evt.arg.newpath evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Hidden file or directory created + (file=%fd.name newpath=%evt.arg.newpath evt_type=%evt.type user=%user.name + user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: NOTICE - tags: [maturity_sandbox, host, container, filesystem, mitre_defense_evasion, T1564.001] + tags: > + [maturity_sandbox, host, container, filesystem, mitre_defense_evasion, + T1564.001] - list: miner_ports items: [ - 25, 3333, 3334, 3335, 3336, 3357, 4444, - 5555, 5556, 5588, 5730, 6099, 6666, 7777, - 7778, 8000, 8001, 8008, 8080, 8118, 8333, - 8888, 8899, 9332, 9999, 14433, 14444, - 45560, 45700 - ] + 25, 3333, 3334, 3335, 3336, 3357, 4444, + 5555, 5556, 5588, 5730, 6099, 6666, 7777, + 7778, 8000, 8001, 8008, 8080, 8118, 8333, + 8888, 8899, 9332, 9999, 14433, 14444, + 45560, 45700 + ] - list: miner_domains items: [ - "asia1.ethpool.org","ca.minexmr.com", - "cn.stratum.slushpool.com","de.minexmr.com", - "eth-ar.dwarfpool.com","eth-asia.dwarfpool.com", - "eth-asia1.nanopool.org","eth-au.dwarfpool.com", - "eth-au1.nanopool.org","eth-br.dwarfpool.com", - "eth-cn.dwarfpool.com","eth-cn2.dwarfpool.com", - "eth-eu.dwarfpool.com","eth-eu1.nanopool.org", - "eth-eu2.nanopool.org","eth-hk.dwarfpool.com", - "eth-jp1.nanopool.org","eth-ru.dwarfpool.com", - "eth-ru2.dwarfpool.com","eth-sg.dwarfpool.com", - "eth-us-east1.nanopool.org","eth-us-west1.nanopool.org", - "eth-us.dwarfpool.com","eth-us2.dwarfpool.com", - "eu.stratum.slushpool.com","eu1.ethermine.org", - "eu1.ethpool.org","fr.minexmr.com", - "mine.moneropool.com","mine.xmrpool.net", - "pool.minexmr.com","pool.monero.hashvault.pro", - "pool.supportxmr.com","sg.minexmr.com", - "sg.stratum.slushpool.com","stratum-eth.antpool.com", - "stratum-ltc.antpool.com","stratum-zec.antpool.com", - "stratum.antpool.com","us-east.stratum.slushpool.com", - "us1.ethermine.org","us1.ethpool.org", - "us2.ethermine.org","us2.ethpool.org", - "xmr-asia1.nanopool.org","xmr-au1.nanopool.org", - "xmr-eu1.nanopool.org","xmr-eu2.nanopool.org", - "xmr-jp1.nanopool.org","xmr-us-east1.nanopool.org", - "xmr-us-west1.nanopool.org","xmr.crypto-pool.fr", - "xmr.pool.minergate.com", "rx.unmineable.com", - "ss.antpool.com","dash.antpool.com", - "eth.antpool.com","zec.antpool.com", - "xmc.antpool.com","btm.antpool.com", - "stratum-dash.antpool.com","stratum-xmc.antpool.com", - "stratum-btm.antpool.com" - ] + "asia1.ethpool.org", "ca.minexmr.com", + "cn.stratum.slushpool.com", "de.minexmr.com", + "eth-ar.dwarfpool.com", "eth-asia.dwarfpool.com", + "eth-asia1.nanopool.org", "eth-au.dwarfpool.com", + "eth-au1.nanopool.org", "eth-br.dwarfpool.com", + "eth-cn.dwarfpool.com", "eth-cn2.dwarfpool.com", + "eth-eu.dwarfpool.com", "eth-eu1.nanopool.org", + "eth-eu2.nanopool.org", "eth-hk.dwarfpool.com", + "eth-jp1.nanopool.org", "eth-ru.dwarfpool.com", + "eth-ru2.dwarfpool.com", "eth-sg.dwarfpool.com", + "eth-us-east1.nanopool.org", "eth-us-west1.nanopool.org", + "eth-us.dwarfpool.com", "eth-us2.dwarfpool.com", + "eu.stratum.slushpool.com", "eu1.ethermine.org", + "eu1.ethpool.org", "fr.minexmr.com", + "mine.moneropool.com", "mine.xmrpool.net", + "pool.minexmr.com", "pool.monero.hashvault.pro", + "pool.supportxmr.com", "sg.minexmr.com", + "sg.stratum.slushpool.com", "stratum-eth.antpool.com", + "stratum-ltc.antpool.com", "stratum-zec.antpool.com", + "stratum.antpool.com", "us-east.stratum.slushpool.com", + "us1.ethermine.org", "us1.ethpool.org", + "us2.ethermine.org", "us2.ethpool.org", + "xmr-asia1.nanopool.org", "xmr-au1.nanopool.org", + "xmr-eu1.nanopool.org", "xmr-eu2.nanopool.org", + "xmr-jp1.nanopool.org", "xmr-us-east1.nanopool.org", + "xmr-us-west1.nanopool.org", "xmr.crypto-pool.fr", + "xmr.pool.minergate.com", "rx.unmineable.com", + "ss.antpool.com", "dash.antpool.com", + "eth.antpool.com", "zec.antpool.com", + "xmc.antpool.com", "btm.antpool.com", + "stratum-dash.antpool.com", "stratum-xmc.antpool.com", + "stratum-btm.antpool.com" + ] - list: https_miner_domains items: [ @@ -1459,45 +1688,65 @@ condition: (fd.sport in (miner_ports) and fd.sip.name in (miner_domains)) - macro: net_miner_pool - condition: (evt.type in (sendto, sendmsg, connect) and evt.dir=< and (fd.net != "127.0.0.0/8" and not fd.snet in (rfc_1918_addresses)) and ((minerpool_http) or (minerpool_https) or (minerpool_other))) + condition: (evt.type in (sendto, sendmsg, connect) and evt.dir=< and + (fd.net != "127.0.0.0/8" and not fd.snet in (rfc_1918_addresses)) and + ((minerpool_http) or (minerpool_https) or (minerpool_other))) - macro: trusted_images_query_miner_domain_dns condition: (container.image.repository in (falco_containers)) # The rule is disabled by default. -# Note: falco will send DNS request to resolve miner pool domain which may trigger alerts in your environment. +# Note: falco will send DNS request to resolve miner pool domain which +# may trigger alerts in your environment. - rule: Detect outbound connections to common miner pool ports - desc: > - Miners usually connect to miner pools using standard ports, and this rule flags such activity. Important: Falco currently sends DNS - requests to resolve miner pool domains, which could trigger other alerts. Prior to enabling this rule, it's advised to ensure whether - this is acceptable for your environment. This rule is specifically disabled for that reason. - condition: > - net_miner_pool + desc: > + Miners usually connect to miner pools using standard ports, and this rule + flags such activity. Important: Falco currently sends DNS requests to + resolve miner pool domains, which could trigger other alerts. Prior to + enabling this rule, it's advised to ensure whether this is acceptable + for your environment. This rule is specifically disabled for that reason. + condition: > + net_miner_pool and not trusted_images_query_miner_domain_dns enabled: false - output: Outbound connection to IP/Port flagged by https://cryptoioc.ch (ip=%fd.rip connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Outbound connection to IP/Port flagged by https://cryptoioc.ch + (ip=%fd.rip connection=%fd.name lport=%fd.lport rport=%fd.rport + fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name + user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: CRITICAL tags: [maturity_sandbox, host, container, network, mitre_impact, T1496] - rule: Detect crypto miners using the Stratum protocol - desc: > - Miners commonly specify the mining pool to connect to using a URI that starts with "stratum+tcp". However, this rule is highly specific to - this technique, and matching command-line arguments can generally be bypassed quite easily. - condition: > - spawned_process - and (proc.cmdline contains "stratum+tcp" or - proc.cmdline contains "stratum2+tcp" or - proc.cmdline contains "stratum+ssl" or + desc: > + Miners commonly specify the mining pool to connect to using a URI that + starts with "stratum+tcp". However, this rule is highly specific to this + technique, and matching command-line arguments can generally be bypassed + quite easily. + condition: > + spawned_process + and (proc.cmdline contains "stratum+tcp" or + proc.cmdline contains "stratum2+tcp" or + proc.cmdline contains "stratum+ssl" or proc.cmdline contains "stratum2+ssl") - output: Possible miner running (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: > + Possible miner running (evt_type=%evt.type user=%user.name + user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) priority: CRITICAL - tags: [maturity_sandbox, host, container, process, mitre_impact, T1496] + tags: > + [maturity_sandbox, host, container, process, mitre_impact, T1496] - list: k8s_client_binaries items: [docker, kubectl, crictl] +# TODO: Remove k8s.gcr.io reference after 01/Dec/2023 - list: user_known_k8s_ns_kube_system_images items: [ + k8s.gcr.io/fluentd-gcp-scaler, + k8s.gcr.io/node-problem-detector/node-problem-detector, registry.k8s.io/fluentd-gcp-scaler, registry.k8s.io/node-problem-detector/node-problem-detector ] @@ -1508,80 +1757,112 @@ ] # Whitelist for known docker client binaries run inside container -# - registry.k8s.io/fluentd-gcp-scaler in GCP/GKE +# - k8s.gcr.io/fluentd-gcp-scaler / registry.k8s.io/fluentd-gcp-scaler +# in GCP/GKE +# TODO: Remove k8s.gcr.io reference after 01/Dec/2023 - macro: user_known_k8s_client_container condition: > - (k8s.ns.name="kube-system" and container.image.repository in (user_known_k8s_ns_kube_system_images)) or container.image.repository in (user_known_k8s_images) + (k8s.ns.name="kube-system" and container.image.repository in + (user_known_k8s_ns_kube_system_images)) or container.image.repository in + (user_known_k8s_images) - macro: user_known_k8s_client_container_parens condition: (user_known_k8s_client_container) - rule: Kubernetes Client Tool Launched in Container - desc: > - Detect the execution of a Kubernetes client tool (like docker, kubectl, crictl) within a container, which is typically not expected behavior. - Although this rule targets container workloads, monitoring the use of tools like crictl on the host over interactive access could also be - valuable for broader auditing objectives. - condition: > - spawned_process - and container - and not user_known_k8s_client_container_parens + desc: > + Detect the execution of a Kubernetes client tool + (like docker, kubectl, crictl) within a container, which is typically + not expected behavior. Although this rule targets container workloads, + monitoring the use of tools like crictl on the host over interactive + access could also be valuable for broader auditing objectives. + condition: > + spawned_process + and container + and not user_known_k8s_client_container_parens and proc.name in (k8s_client_binaries) - output: Kubernetes Client Tool Launched in Container (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: Kubernetes Client Tool Launched in Container + (evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) priority: WARNING tags: [maturity_sandbox, container, mitre_execution, T1610] -# The two Container Drift rules below will fire when a new executable is created in a container. -# There are two ways to create executables - file is created with execution permissions or permissions change of existing file. -# We will use a new filter, is_open_exec, to find all files creations with execution permission, and will trace all chmods in a container. -# The use case we are targeting here is an attempt to execute code that was not shipped as part of a container (drift) - -# an activity that might be malicious or non-compliant. +# The two Container Drift rules below will fire when a new executable is +# created in a container. There are two ways to create executables - file +# is created with execution permissions or permissions change of existing file. +# We will use a new filter, is_open_exec, to find all files creations with +# execution permission, and will trace all chmods in a container. The use case +# we are targeting here is an attempt to execute code that was not shipped +# as part of a container (drift) -an activity that might be malicious or +# non-compliant. # Two things to pay attention to: -# 1) In most cases, 'docker cp' will not be identified, but the assumption is that if an attacker gained access to the container runtime daemon, they are already privileged -# 2) Drift rules will be noisy in environments in which containers are built (e.g. docker build) +# 1) In most cases, 'docker cp' will not be identified, but the assumption +# is that if an attacker gained access to the container runtime daemon, +# they are already privileged +# 2) Drift rules will be noisy in environments in which containers are built +# (e.g. docker build) # These two rules are not enabled by default. - macro: user_known_container_drift_activities condition: (never_true) - rule: Container Drift Detected (chmod) - desc: > - Detect new executables created within a container as a result of chmod. While this detection can generate significant noise, chmod - usage is frequently linked to dropping and executing malicious implants. The newer rule "Drop and execute new binary in container" - provides more precise detection of this TTP using unambiguous kernel signals. It is recommended to use the new rule. However, this - rule might be more relevant for auditing if applicable in your environment, such as when chmod is used on files within the /tmp folder. - condition: > - chmod - and container - and evt.rawres>=0 + desc: > + Detect new executables created within a container as a result of chmod. + While this detection can generate significant noise, chmod usage is + frequently linked to dropping and executing malicious implants. The + newer rule "Drop and execute new binary in container" provides more + precise detection of this TTP using unambiguous kernel signals. It is + recommended to use the new rule. However, this rule might be more + relevant for auditing if applicable in your environment, such as + when chmod is used on files within the /tmp folder. + condition: > + chmod + and container + and evt.rawres>=0 and ((evt.arg.mode contains "S_IXUSR") or (evt.arg.mode contains "S_IXGRP") or (evt.arg.mode contains "S_IXOTH")) - and not runc_writing_exec_fifo - and not runc_writing_var_lib_docker - and not user_known_container_drift_activities + and not runc_writing_exec_fifo + and not runc_writing_var_lib_docker + and not user_known_container_drift_activities enabled: false - output: Drift detected (chmod), new executable created in a container (filename=%evt.arg.filename name=%evt.arg.name mode=%evt.arg.mode evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Drift detected (chmod), new executable created in a container + (filename=%evt.arg.filename name=%evt.arg.name mode=%evt.arg.mode + evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: ERROR - tags: [maturity_sandbox, container, process, filesystem, mitre_execution, T1059] + tags: > + [maturity_sandbox, container, process, filesystem, mitre_execution, T1059] # **************************************************************************** # * "Container Drift Detected (open+create)" requires FALCO_ENGINE_VERSION 6 * # **************************************************************************** - rule: Container Drift Detected (open+create) desc: > - Detect new executables created within a container as a result of open+create. The newer rule "Drop and execute new binary in container" - provides more precise detection of this TTP using unambiguous kernel signals. It is recommended to use the new rule. + Detect new executables created within a container as a result of + open+create. The newer rule "Drop and execute new binary in container" + provides more precise detection of this TTP using unambiguous kernel + signals. It is recommended to use the new rule. condition: > - evt.type in (open,openat,openat2,creat) + evt.type in (open,openat,openat2,creat) and evt.rawres>=0 - and evt.is_open_exec=true - and container - and not runc_writing_exec_fifo - and not runc_writing_var_lib_docker - and not user_known_container_drift_activities + and evt.is_open_exec=true + and container + and not runc_writing_exec_fifo + and not runc_writing_var_lib_docker + and not user_known_container_drift_activities enabled: false - output: Drift detected (open+create), new executable created in a container (filename=%evt.arg.filename name=%evt.arg.name mode=%evt.arg.mode evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Drift detected (open+create), new executable created in a container + (filename=%evt.arg.filename name=%evt.arg.name mode=%evt.arg.mode + evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: ERROR - tags: [maturity_sandbox, container, process, filesystem, mitre_execution, T1059] + tags: > + [maturity_sandbox, container, process, filesystem, mitre_execution, T1059] - list: run_as_root_image_list items: [] @@ -1589,108 +1870,154 @@ - macro: user_known_run_as_root_container condition: (container.image.repository in (run_as_root_image_list)) -# The rule is disabled by default and should be enabled when non-root container policy has been applied. -# Note the rule will not work as expected when usernamespace is applied, e.g. userns-remap is enabled. +# The rule is disabled by default and should be enabled when non-root container +# policy has been applied. +# Note the rule will not work as expected when usernamespace is applied, +# e.g. userns-remap is enabled. - rule: Container Run as Root User - desc: > - Container detected running as the root user. This should be taken into account especially when policies disallow containers from running with - root user privileges. Note that a root user in containers doesn't inherently possess extensive power, as modern container environments define - privileges through Linux capabilities. To learn more, check out the rule "Launch Privileged Container". - condition: > - spawned_process - and container - and proc.vpid=1 - and user.uid=0 + desc: > + Container detected running as the root user. This should be taken into + account especially when policies disallow containers from running with + root user privileges. Note that a root user in containers doesn't + inherently possess extensive power, as modern container environments + define privileges through Linux capabilities. To learn more, check out + the rule "Launch Privileged Container". + condition: > + spawned_process + and container + and proc.vpid=1 + and user.uid=0 and not user_known_run_as_root_container enabled: false - output: Container launched with root user privilege (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: Container launched with root user privilege + (evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) priority: INFO tags: [maturity_sandbox, container, process, users, mitre_execution, T1610] # This rule helps detect CVE-2021-3156: # A privilege escalation to root through heap-based buffer overflow - rule: Sudo Potential Privilege Escalation - desc: > - Affecting sudo (<= 1.9.5p2), there's a privilege escalation vulnerability. By executing sudo using the sudoedit -s or sudoedit -i command with a - command-line argument that ends with a single backslash character, an unprivileged user can potentially escalate privileges to root. This rule is - highly specific and might be bypassed due to potential issues with string matching on command line arguments. - condition: > - spawned_process - and user.uid != 0 - and (proc.name=sudoedit or proc.name = sudo) - and (proc.args contains -s or proc.args contains -i or proc.args contains --login) + desc: > + Affecting sudo (<= 1.9.5p2), there's a privilege escalation vulnerability. + By executing sudo using the sudoedit -s or sudoedit -i command with a + command-line argument that ends with a single backslash character, + an unprivileged user can potentially escalate privileges to root. + This rule is highly specific and might be bypassed due to potential + issues with string matching on command line arguments. + condition: > + spawned_process + and user.uid != 0 + and (proc.name=sudoedit or proc.name = sudo) + and (proc.args contains -s or proc.args contains -i or proc.args + contains --login) and (proc.args contains "\ " or proc.args endswith \) - output: Detect Sudo Privilege Escalation Exploit (CVE-2021-3156) (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: Detect Sudo Privilege Escalation Exploit (CVE-2021-3156) + (evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) priority: CRITICAL - tags: [maturity_sandbox, host, container, filesystem, users, mitre_privilege_escalation, T1548.003] + tags: [maturity_sandbox, host, container, filesystem, users, + mitre_privilege_escalation, T1548.003] - list: user_known_userfaultfd_processes items: [] - rule: Unprivileged Delegation of Page Faults Handling to a Userspace Process - desc: > - Detect a successful unprivileged userfaultfd syscall, which could serve as an attack primitive for exploiting other vulnerabilities. - To fine-tune this rule, consider using the template list "user_known_userfaultfd_processes". + desc: > + Detect a successful unprivileged userfaultfd syscall, which could serve as + an attack primitive for exploiting other vulnerabilities. To fine-tune this + rule, consider using the template list "user_known_userfaultfd_processes". condition: > - evt.type = userfaultfd - and user.uid != 0 - and (evt.rawres >= 0 or evt.res != -1) + evt.type = userfaultfd + and user.uid != 0 + and (evt.rawres >= 0 or evt.res != -1) and not proc.name in (user_known_userfaultfd_processes) - output: An userfaultfd syscall was successfully executed by an unprivileged user (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: > + An userfaultfd syscall was successfully executed by an unprivileged user + (evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: CRITICAL - tags: [maturity_sandbox, host, container, process, mitre_defense_evasion, TA0005] + tags: > + [maturity_sandbox, host, container, process, mitre_defense_evasion, TA0005] # This rule helps detect CVE-2021-4034: # A privilege escalation to root through memory corruption - rule: Polkit Local Privilege Escalation Vulnerability (CVE-2021-4034) - desc: > - This rule detects attempts to exploit a privilege escalation vulnerability in Polkit's pkexec. Through the execution of specially - crafted code, a local user can exploit this weakness to attain root privileges on a compromised system. This rule is highly - specific in its scope. + desc: > + This rule detects attempts to exploit a privilege escalation vulnerability + in Polkit's pkexec. Through the execution of specially crafted code, a + local user can exploit this weakness to attain root privileges on a + compromised system. This rule is highly specific in its scope. condition: - spawned_process - and user.uid != 0 - and proc.name=pkexec + spawned_process + and user.uid != 0 + and proc.name=pkexec and proc.args = '' - output: Detect Polkit pkexec Local Privilege Escalation Exploit (CVE-2021-4034) (args=%proc.args evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: > + Detect Polkit pkexec Local Privilege Escalation Exploit (CVE-2021-4034) + (args=%proc.args evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags%container.info) priority: CRITICAL - tags: [maturity_sandbox, host, container, process, users, mitre_privilege_escalation, TA0004] + tags: [maturity_sandbox, host, container, process, users, + mitre_privilege_escalation, TA0004] # Rule for detecting potential Log4Shell (CVE-2021-44228) exploitation # Note: Not compatible with Java 17+, which uses read() syscalls - macro: java_network_read - condition: (evt.type=recvfrom and fd.type in (ipv4, ipv6) and proc.exe endswith java) + condition: (evt.type=recvfrom and fd.type in (ipv4, ipv6) and proc.exe + endswith java) - rule: Java Process Class File Download - desc: > - Detecting a Java process downloading a class file which could indicate a successful exploit of the log4shell Log4j vulnerability (CVE-2021-44228). + desc: > + Detecting a Java process downloading a class file which could indicate a + successful exploit of the log4shell Log4j vulnerability (CVE-2021-44228). This rule is highly specific in its scope. condition: > - java_network_read + java_network_read and evt.buffer bcontains cafebabe - output: Java process class file download (server_ip=%fd.sip server_port=%fd.sport connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Java process class file download + (server_ip=%fd.sip server_port=%fd.sport connection=%fd.name lport=%fd.lport + rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type + user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid + process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname + command=%proc.cmdline terminal=%proc.tty %container.info) priority: CRITICAL enabled: false - tags: [maturity_sandbox, host, container, process, mitre_initial_access, T1190] + tags: [maturity_sandbox, host, container, process, mitre_initial_access, + T1190] - list: docker_binaries - items: [docker, dockerd, containerd-shim, "runc:[1:CHILD]", pause, exe, docker-compose, docker-entrypoi, docker-runc-cur, docker-current, dockerd-current] + items: [ + docker, dockerd, containerd-shim, "runc:[1:CHILD]", pause, exe, + docker-compose, docker-entrypoi, docker-runc-cur, docker-current, + dockerd-current] - macro: docker_procs condition: proc.name in (docker_binaries) - rule: Modify Container Entrypoint - desc: > - This rule detect an attempt to write on container entrypoint symlink (/proc/self/exe). Possible CVE-2019-5736 Container Breakout exploitation attempt. - This rule has a more narrow scope. - condition: > - open_write - and container - and (fd.name=/proc/self/exe or fd.name startswith /proc/self/fd/) - and not docker_procs + desc: > + This rule detect an attempt to write on container entrypoint symlink + (/proc/self/exe). Possible CVE-2019-5736 Container Breakout exploitation + attempt. This rule has a more narrow scope. + condition: > + open_write + and container + and (fd.name=/proc/self/exe or fd.name startswith /proc/self/fd/) + and not docker_procs and not proc.cmdline = "runc:[1:CHILD] init" enabled: false - output: Detect Potential Container Breakout Exploit (CVE-2019-5736) (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Detect Potential Container Breakout Exploit (CVE-2019-5736) + (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: WARNING tags: [maturity_sandbox, container, filesystem, mitre_initial_access, T1611] @@ -1701,17 +2028,23 @@ condition: (proc.name in (bpf_profiled_binaries)) - rule: BPF Program Not Profiled - desc: > - BPF is a kernel technology that can be misused for malicious purposes, like "Linux Kernel Module Injection". This - rule should be considered an auditing rule to notify you of any unprofiled BPF tools running in your environment. - However, it requires customization after profiling your environment. BPF-powered agents make bpf syscalls all the - time, so this rule only sends logs for BPF_PROG_LOAD calls (bpf cmd=5) in the enter event. If you also want to log - whether the syscall failed or succeeded, remove the direction filter and add the evt.arg.res_or_fd output field. - condition: > - evt.type=bpf and evt.dir=> + desc: > + BPF is a kernel technology that can be misused for malicious purposes, like + "Linux Kernel Module Injection". This rule should be considered an auditing + rule to notify you of any unprofiled BPF tools running in your environment. + However, it requires customization after profiling your environment. + BPF-powered agents make bpf syscalls all the time, so this rule only sends + logs for BPF_PROG_LOAD calls (bpf cmd=5) in the enter event. If you also + want to log whether the syscall failed or succeeded, remove the direction + filter and add the evt.arg.res_or_fd output field. + condition: > + evt.type=bpf and evt.dir=> and evt.arg.cmd=BPF_PROG_LOAD and not bpf_profiled_procs - output: BPF Program Not Profiled (bpf_cmd=%evt.arg.cmd evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: BPF Program Not Profiled + (bpf_cmd=%evt.arg.cmd evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: NOTICE tags: [maturity_sandbox, host, container, mitre_persistence, TA0003] @@ -1719,24 +2052,36 @@ items: [] - macro: base64_decoding - condition: (proc.cmdline contains "base64" and (proc.cmdline contains "--decode" or proc.cmdline contains "-d")) + condition: (proc.cmdline contains "base64" and + (proc.cmdline contains "--decode" or proc.cmdline contains "-d")) - rule: Decoding Payload in Container - desc: > - Detect any use of {base64} decoding in a container. Legitimate applications may decode encoded payloads. The template list - known_decode_payload_containers can be used for simple tuning and customization, or you can adopt custom, more refined tuning. Less - sophisticated adversaries may {base64}-decode their payloads not only to obfuscate them, but also to ensure that the payload remains - intact when the application processes it. Note that injecting commands into an application's input often results in the application - processing passed strings like "sh -c". In these cases, you may be lucky and the encoded blob will also be logged. Otherwise, all you - will see is the {base64} decoding command, as the encoded blob was already interpreted by the shell. - condition: > - spawned_process - and container - and base64_decoding + desc: > + Detect any use of {base64} decoding in a container. Legitimate applications + may decode encoded payloads. The template list + known_decode_payload_containers can be used for simple tuning and + customization, or you can adopt custom, more refined tuning. Less + sophisticated adversaries may {base64}-decode their payloads not + only to obfuscate them, but also to ensure that the payload remains + intact when the application processes it. Note that injecting commands + into an application's input often results in the application processing + passed strings like "sh -c". In these cases, you may be lucky and the + encoded blob will also be logged. Otherwise, all you will see is the + {base64} decoding command, as the encoded blob was already interpreted + by the shell. + condition: > + spawned_process + and container + and base64_decoding and not container.image.repository in (known_decode_payload_containers) - output: Decoding Payload in Container (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: Decoding Payload in Container + (evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuidprocess=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) priority: INFO - tags: [maturity_sandbox, container, process, mitre_command_and_control, T1132] + tags: > + [maturity_sandbox, container, process, mitre_command_and_control, T1132] - list: recon_binaries items: [w, whoami, id, who, uname] @@ -1745,18 +2090,28 @@ - rule: Basic Interactive Reconnaissance desc: > - This rule detects basic interactive reconnaissance commands that are typically run by unsophisticated attackers or used - in internal Red Team exercises. Interactive is defined as a terminal being present (proc.tty != 0). This could be any - form of reverse shell or usage of kubectl exec or ssh etc. In addition, filtering for the process being the process group - leader indicates that the command was "directly" typed into the terminal and not run as a result of a script. This rule - is a basic auditing or template rule. You can expand the list of reconnaissance commands, such as by adding "ls". Common - anti-patterns are SRE activity or debugging, but it is still worth capturing this generically. Typically, you would expect - other rules to fire as well in relation to this activity. - condition: > - spawned_process - and recon_binaries_procs - and proc.tty != 0 + This rule detects basic interactive reconnaissance commands that are + typically run by unsophisticated attackers or used in internal Red + Team exercises. Interactive is defined as a terminal being present + (proc.tty != 0). This could be any form of reverse shell or usage of + kubectl exec or ssh etc. In addition, filtering for the process being + the process group leader indicates that the command was "directly" + typed into the terminal and not run as a result of a script. This rule + is a basic auditing or template rule. You can expand the list of + reconnaissance commands, such as by adding "ls". Common anti-patterns + are SRE activity or debugging, but it is still worth capturing this + generically. Typically, you would expect other rules to fire as well + in relation to this activity. + condition: > + spawned_process + and recon_binaries_procs + and proc.tty != 0 and proc.is_vpgid_leader=true - output: Basic Interactive Reconnaissance (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: Basic Interactive Reconnaissance + (evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) priority: NOTICE - tags: [maturity_sandbox, host, container, process, mitre_reconnaissance, TA0043] + tags: > + [maturity_sandbox, host, container, process, mitre_reconnaissance, TA0043] diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index 723c6f7a..0b74ccc4 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -16,15 +16,23 @@ # limitations under the License. # -# Information about rules tags and fields can be found here: https://falco.org/docs/rules/#tags-for-current-falco-ruleset -# The initial item in the `tags` fields reflects the maturity level of the rules introduced upon the proposal https://github.com/falcosecurity/rules/blob/main/proposals/20230605-rules-adoption-management-maturity-framework.md -# `tags` fields also include information about the type of workload inspection (host and/or container), and Mitre Attack killchain phases and Mitre TTP code(s) +# Information about rules tags and fields can be found here: +# https://falco.org/docs/rules/#tags-for-current-falco-ruleset +# The initial item in the `tags` fields reflects the maturity level of +# the rules introduced upon the proposal +# https://github.com/falcosecurity/rules/blob/main/proposals/ +# 20230605-rules-adoption-management-maturity-framework.md +# `tags` fields also include information about the type of workload inspection +# (host and/or container), and Mitre Attack killchain phases and +# Mitre TTP code(s) # Mitre Attack References: # [1] https://attack.mitre.org/tactics/enterprise/ -# [2] https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json +# [2] https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/ +# enterprise-attack.json # Starting with version 8, the Falco engine supports exceptions. # However the Falco rules file does not use them by default. +--- - required_engine_version: 0.31.0 # Currently disabled as read/write are ignored syscalls. The nearly @@ -33,34 +41,47 @@ # - macro: write # condition: (syscall.type=write and fd.type in (file, directory)) # - macro: read -# condition: (syscall.type=read and evt.dir=> and fd.type in (file, directory)) +# condition: +# (syscall.type=read and evt.dir=> and fd.type in (file, directory)) - macro: open_write - condition: (evt.type in (open,openat,openat2) and evt.is_open_write=true and fd.typechar='f' and fd.num>=0) + condition: > + (evt.type in (open,openat,openat2) and + evt.is_open_write=true and fd.typechar='f' and fd.num>=0) - macro: open_read - condition: (evt.type in (open,openat,openat2) and evt.is_open_read=true and fd.typechar='f' and fd.num>=0) + condition: > + (evt.type in (open,openat,openat2) and evt.is_open_read=true + and fd.typechar='f' and fd.num>=0) # Failed file open attempts, useful to detect threat actors making mistakes # https://man7.org/linux/man-pages/man3/errno.3.html # evt.res=ENOENT - No such file or directory # evt.res=EACCESS - Permission denied - macro: open_file_failed - condition: (evt.type in (open,openat,openat2) and fd.typechar='f' and fd.num=-1 and evt.res startswith E) + condition: > + (evt.type in (open,openat,openat2) and fd.typechar='f' + and fd.num=-1 and evt.res startswith E) -# This macro `never_true` is used as placeholder for tuning negative logical sub-expressions, for example +# This macro `never_true` is used as placeholder +# for tuning negative logical sub-expressions, +# for example # - macro: allowed_ssh_hosts # condition: (never_true) -# can be used in a rules' expression with double negation `and not allowed_ssh_hosts` which effectively evaluates -# to true and does nothing, the perfect empty template for `logical` cases as opposed to list templates. +# can be used in a rules' expression with double negation +# `and not allowed_ssh_hosts` which effectively evaluates +# to true and does nothing, the perfect empty template +# for `logical` cases as opposed to list templates. # When tuning the rule you can override the macro with something useful, e.g. # - macro: allowed_ssh_hosts # condition: (evt.hostname contains xyz) - macro: never_true condition: (evt.num=0) -# This macro `always_true` is the flip side of the macro `never_true` and currently is commented out as -# it is not used. You can use it as placeholder for a positive logical sub-expression tuning template +# This macro `always_true` is the flip side of the macro `never_true` +# and currently is commented out as +# it is not used. You can use it as placeholder +# for a positive logical sub-expression tuning template # macro, e.g. `and custom_procs`, where # - macro: custom_procs # condition: (always_true) @@ -102,30 +123,45 @@ - macro: shell_procs condition: (proc.name in (shell_binaries)) -# dpkg -L login | grep bin | xargs ls -ld | grep -v '^d' | awk '{print $9}' | xargs -L 1 basename | tr "\\n" "," +# dpkg -L login | +# grep bin | +# xargs ls -ld | +# grep -v '^d' | +# awk '{print $9}' | +# xargs -L 1 basename | +# tr "\\n" "," + - list: login_binaries items: [ login, systemd, '"(systemd)"', systemd-logind, su, nologin, faillog, lastlog, newgrp, sg - ] + ] -# dpkg -L passwd | grep bin | xargs ls -ld | grep -v '^d' | awk '{print $9}' | xargs -L 1 basename | tr "\\n" "," +# dpkg -L passwd | +# grep bin | +# xargs ls -ld | +# grep -v '^d' | +# awk '{print $9}' | +# xargs -L 1 basename | +# tr "\\n" "," - list: passwd_binaries items: [ shadowconfig, grpck, pwunconv, grpconv, pwck, groupmod, vipw, pwconv, useradd, newusers, cppw, chpasswd, usermod, groupadd, groupdel, grpunconv, chgpasswd, userdel, chage, chsh, - gpasswd, chfn, expiry, passwd, vigr, cpgr, adduser, addgroup, deluser, delgroup - ] + gpasswd, chfn, expiry, passwd, vigr, cpgr, adduser, + addgroup, deluser, delgroup + ] # repoquery -l shadow-utils | grep bin | xargs ls -ld | grep -v '^d' | # awk '{print $9}' | xargs -L 1 basename | tr "\\n" "," - list: shadowutils_binaries items: [ chage, gpasswd, lastlog, newgrp, sg, adduser, deluser, chpasswd, - groupadd, groupdel, addgroup, delgroup, groupmems, groupmod, grpck, grpconv, grpunconv, - newusers, pwck, pwconv, pwunconv, useradd, userdel, usermod, vigr, vipw, unix_chkpwd - ] + groupadd, groupdel, addgroup, delgroup, groupmems, groupmod, + grpck, grpconv, grpunconv, newusers, pwck, pwconv, pwunconv, + useradd, userdel, usermod, vigr, vipw, unix_chkpwd + ] - list: http_server_binaries items: [nginx, httpd, httpd-foregroun, lighttpd, apache, apache2] @@ -143,27 +179,39 @@ items: [gitlab-shell, gitlab-mon, gitlab-runner-b, git] - macro: server_procs - condition: (proc.name in (http_server_binaries, db_server_binaries, docker_binaries, sshd)) + condition: > + ( + proc.name in ( + http_server_binaries, + db_server_binaries, + docker_binaries, + sshd + ) + ) # The explicit quotes are needed to avoid the - characters being # interpreted by the filter expression. - list: rpm_binaries - items: [dnf, dnf-automatic, rpm, rpmkey, yum, '"75-system-updat"', rhsmcertd-worke, rhsmcertd, subscription-ma, - repoquery, rpmkeys, rpmq, yum-cron, yum-config-mana, yum-debug-dump, - abrt-action-sav, rpmdb_stat, microdnf, rhn_check, yumdb] + items: [dnf, dnf-automatic, rpm, rpmkey, yum, '"75-system-updat"', + rhsmcertd-worke, rhsmcertd, subscription-ma, repoquery, rpmkeys, + rpmq, yum-cron, yum-config-mana, yum-debug-dump, + abrt-action-sav, rpmdb_stat, microdnf, rhn_check, yumdb] - list: deb_binaries - items: [dpkg, dpkg-preconfigu, dpkg-reconfigur, dpkg-divert, apt, apt-get, aptitude, - frontend, preinst, add-apt-reposit, apt-auto-remova, apt-key, - apt-listchanges, unattended-upgr, apt-add-reposit, apt-cache, apt.systemd.dai - ] + items: [dpkg, dpkg-preconfigu, dpkg-reconfigur, dpkg-divert, apt, + apt-get, aptitude, frontend, preinst, add-apt-reposit, apt-auto-remova, + apt-key, apt-listchanges, unattended-upgr, apt-add-reposit, apt-cache, + apt.systemd.dai + ] - list: python_package_managers items: [pip, pip3, conda] # The truncated dpkg-preconfigu is intentional, process names are # truncated at the falcosecurity-libs level. - list: package_mgmt_binaries - items: [rpm_binaries, deb_binaries, update-alternat, gem, npm, python_package_managers, sane-utils.post, alternatives, chef-client, apk, snapd] + items: [rpm_binaries, deb_binaries, update-alternat, gem, npm, + python_package_managers, + sane-utils.post, alternatives, chef-client, apk, snapd] - macro: run_by_package_mgmt_binaries condition: (proc.aname in (package_mgmt_binaries, needrestart)) @@ -177,7 +225,9 @@ items: [login_binaries, passwd_binaries, shadowutils_binaries] - list: hids_binaries - items: [aide, aide.wrapper, update-aide.con, logcheck, syslog-summary, osqueryd, ossec-syscheckd] + items: [ + aide, aide.wrapper, update-aide.con, logcheck, syslog-summary, + osqueryd, ossec-syscheckd] - list: vpn_binaries items: [openvpn] @@ -190,17 +240,18 @@ sendmail, sendmail-msp, postfix, procmail, exim4, pickup, showq, mailq, dovecot, imap-login, imap, mailmng-core, pop3-login, dovecot-lda, pop3 - ] + ] - list: mail_config_binaries items: [ update_conf, parse_mc, makemap_hash, newaliases, update_mk, update_tlsm4, update_db, update_mc, ssmtp.postinst, mailq, postalias, postfix.config., postfix.config, postfix-script, postconf - ] + ] - list: sensitive_file_names - items: [/etc/shadow, /etc/sudoers, /etc/pam.conf, /etc/security/pwquality.conf] + items: > + [/etc/shadow, /etc/sudoers, /etc/pam.conf, /etc/security/pwquality.conf] - list: sensitive_directory_names items: [/, /etc, /etc/, /root, /root/] @@ -218,9 +269,10 @@ # Use this to test whether the event occurred within a container. # When displaying container information in the output field, use # %container.info, without any leading term (file=%fd.name -# %container.info user=%user.name user_loginuid=%user.loginuid, and not file=%fd.name -# container=%container.info user=%user.name user_loginuid=%user.loginuid). The output will change -# based on the context and whether or not -pk/-pm/-pc was specified on +# %container.info user=%user.name user_loginuid=%user.loginuid, and +# not file=%fd.name container=%container.info user=%user.name +# user_loginuid=%user.loginuid). The output will change based on the +# context and whether or not -pk/-pm/-pc was specified on # the command line. - macro: container condition: (container.id != host) @@ -244,10 +296,16 @@ # System users that should never log into a system. Consider adding your own # service users (e.g. 'apache' or 'mysqld') here. - macro: system_users - condition: (user.name in (bin, daemon, games, lp, mail, nobody, sshd, sync, uucp, www-data)) + condition: > + ( + user.name in + (bin, daemon, games, lp, mail, nobody, sshd, sync, uucp, www-data) + ) + - macro: ansible_running_python - condition: (proc.name in (python, pypy, python3) and proc.cmdline contains ansible) + condition: > + (proc.name in (python, pypy, python3) and proc.cmdline contains ansible) # Qualys seems to run a variety of shell subprocesses, at various # levels. This checks at a few levels without the cost of a full @@ -275,18 +333,22 @@ - macro: run_by_foreman condition: > (user.name=foreman and - ((proc.pname in (rake, ruby, scl) and proc.aname[5] in (tfm-rake,tfm-ruby)) or + ((proc.pname in (rake, ruby, scl) and + proc.aname[5] in (tfm-rake,tfm-ruby)) or (proc.pname=scl and proc.aname[2] in (tfm-rake,tfm-ruby)))) - macro: python_mesos_marathon_scripting condition: (proc.pcmdline startswith "python3 /marathon-lb/marathon_lb.py") - macro: splunk_running_forwarder - condition: (proc.pname=splunkd and proc.cmdline startswith "sh -c /opt/splunkforwarder") + condition: > + (proc.pname=splunkd and proc.cmdline startswith "sh -c /opt/splunkforwarder") - macro: perl_running_plesk - condition: (proc.cmdline startswith "perl /opt/psa/admin/bin/plesk_agent_manager" or - proc.pcmdline startswith "perl /opt/psa/admin/bin/plesk_agent_manager") + condition: (proc.cmdline startswith + "perl /opt/psa/admin/bin/plesk_agent_manager" or + proc.pcmdline startswith + "perl /opt/psa/admin/bin/plesk_agent_manager") - macro: perl_running_updmap condition: (proc.cmdline startswith "perl /usr/bin/updmap") @@ -318,20 +380,35 @@ # ****************************************************************************** - rule: Directory traversal monitored file read desc: > - Web applications can be vulnerable to directory traversal attacks that allow accessing files outside of the web app's root directory - (e.g. Arbitrary File Read bugs). System directories like /etc are typically accessed via absolute paths. Access patterns outside of this - (here path traversal) can be regarded as suspicious. This rule includes failed file open attempts. - condition: > - (open_read or open_file_failed) - and (etc_dir or user_ssh_directory or - fd.name startswith /root/.ssh or - fd.name contains "id_rsa") - and directory_traversal - and not proc.pname in (shell_binaries) + Web applications can be vulnerable to directory traversal attacks + that allow accessing files outside of the web app's root directory + (e.g. Arbitrary File Read bugs). + System directories like /etc are typically accessed via absolute paths. + Access patterns outside of this (here path traversal) can be regarded as + suspicious. This rule includes failed file open attempts. +condition: > + ( + open_read or open_file_failed + ) + and ( + etc_dir or user_ssh_directory or + fd.name startswith /root/.ssh or + fd.name contains "id_rsa" + ) + and directory_traversal + and not proc.pname in (shell_binaries) + enabled: true - output: Read monitored file via directory traversal (file=%fd.name fileraw=%fd.nameraw gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Read monitored file via directory traversal + (file=%fd.name fileraw=%fd.nameraw gparent=%proc.aname[2] + ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type + user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid + process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname + command=%proc.cmdline terminal=%proc.tty %container.info) + priority: WARNING - tags: [maturity_stable, host, container, filesystem, mitre_credential_access, T1555] + tags: [maturity_stable, host, container, filesystem, mitre_credential_access, + T1555] - macro: cmp_cp_by_passwd condition: (proc.name in (cmp, cp) and proc.pname in (passwd, run-parts)) @@ -341,31 +418,42 @@ - rule: Read sensitive file trusted after startup desc: > - An attempt to read any sensitive file (e.g. files containing user/password/authentication - information) by a trusted program after startup. Trusted programs might read these files - at startup to load initial state, but not afterwards. Can be customized as needed. - In modern containerized cloud infrastructures, accessing traditional Linux sensitive files - might be less relevant, yet it remains valuable for baseline detections. While we provide additional - rules for SSH or cloud vendor-specific credentials, you can significantly enhance your security - program by crafting custom rules for critical application credentials unique to your environment. - condition: > - open_read - and sensitive_files - and server_procs - and not proc_is_new - and proc.name!="sshd" + An attempt to read any sensitive file (e.g. files containing + user/password/authentication information) by a trusted program after + startup. Trusted programs might read these files at startup to load + initial state, but not afterwards. Can be customized as needed. In modern + containerized cloud infrastructures, accessing traditional Linux sensitive + files might be less relevant, yet it remains valuable for baseline + detections. While we provide additional rules for SSH or cloud + vendor-specific credentials, you can significantly enhance your security + program by crafting custom rules for critical application credentials + unique to your environment. + condition: > + open_read + and sensitive_files + and server_procs + and not proc_is_new + and proc.name!="sshd" and not user_known_read_sensitive_files_activities - output: Sensitive file opened for reading by trusted program after startup (file=%fd.name pcmdline=%proc.pcmdline gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Sensitive file opened for reading by trusted program after startup + (file=%fd.name pcmdline=%proc.pcmdline gparent=%proc.aname[2] + ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type + user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid + process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname + command=%proc.cmdline terminal=%proc.tty %container.info) priority: WARNING - tags: [maturity_stable, host, container, filesystem, mitre_credential_access, T1555] + tags: > + [maturity_stable, host, container, filesystem, mitre_credential_access, + T1555] - list: read_sensitive_file_binaries items: [ iptables, ps, lsb_release, check-new-relea, dumpe2fs, accounts-daemon, sshd, vsftpd, systemd, mysql_install_d, psql, screen, debconf-show, sa-update, - pam-auth-update, pam-config, /usr/sbin/spamd, polkit-agent-he, lsattr, file, sosreport, - scxcimservera, adclient, rtvscand, cockpit-session, userhelper, ossec-syscheckd - ] + pam-auth-update, pam-config, /usr/sbin/spamd, polkit-agent-he, lsattr, file, + sosreport, scxcimservera, adclient, rtvscand, cockpit-session, userhelper, + ossec-syscheckd + ] # Add conditions to this macro (probably in a separate file, # overwriting this macro) to allow for specific combinations of @@ -383,9 +471,11 @@ items: [] - macro: user_read_sensitive_file_containers - condition: (container and container.image.repository in (read_sensitive_file_images)) + condition: > + (container and container.image.repository in (read_sensitive_file_images)) -# This macro detects man-db postinst, see https://salsa.debian.org/debian/man-db/-/blob/master/debian/postinst +# This macro detects man-db postinst +# see https://salsa.debian.org/debian/man-db/-/blob/master/debian/postinst # The rule "Read sensitive file untrusted" use this macro to avoid FPs. - macro: mandb_postinst condition: > @@ -396,22 +486,25 @@ - rule: Read sensitive file untrusted desc: > - An attempt to read any sensitive file (e.g. files containing user/password/authentication - information). Exceptions are made for known trusted programs. Can be customized as needed. - In modern containerized cloud infrastructures, accessing traditional Linux sensitive files - might be less relevant, yet it remains valuable for baseline detections. While we provide additional - rules for SSH or cloud vendor-specific credentials, you can significantly enhance your security - program by crafting custom rules for critical application credentials unique to your environment. + An attempt to read any sensitive file + (e.g. files containing user/password/authentication information). + Exceptions are made for known trusted programs. Can be customized as needed. + In modern containerized cloud infrastructures, accessing traditional + Linux sensitive files might be less relevant, yet it remains valuable + for baseline detections. While we provide additional rules for SSH or + cloud vendor-specific credentials, you can significantly enhance your + security program by crafting custom rules for critical application + credentials unique to your environment. condition: > open_read and sensitive_files and proc_name_exists - and not proc.name in (user_mgmt_binaries, userexec_binaries, package_mgmt_binaries, - cron_binaries, read_sensitive_file_binaries, shell_binaries, hids_binaries, - vpn_binaries, mail_config_binaries, nomachine_binaries, sshkit_script_binaries, - in.proftpd, mandb, salt-call, salt-minion, postgres_mgmt_binaries, - google_oslogin_ - ) + and not proc.name in + (user_mgmt_binaries, userexec_binaries, package_mgmt_binaries, + cron_binaries, read_sensitive_file_binaries, shell_binaries, + hids_binaries, vpn_binaries, mail_config_binaries, nomachine_binaries, + sshkit_script_binaries, in.proftpd, mandb, salt-call, salt-minion, + postgres_mgmt_binaries, google_oslogin_) and not cmp_cp_by_passwd and not ansible_running_python and not run_by_qualys @@ -427,29 +520,57 @@ and not linux_bench_reading_etc_shadow and not user_known_read_sensitive_files_activities and not user_read_sensitive_file_containers - output: Sensitive file opened for reading by non-trusted program (file=%fd.name gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Sensitive file opened for reading by non-trusted program + (file=%fd.name gparent=%proc.aname[2] ggparent=%proc.aname[3] + gggparent=%proc.aname[4] evt_type=%evt.type user=%user.name + user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: WARNING - tags: [maturity_stable, host, container, filesystem, mitre_credential_access, T1555] + tags: > + [maturity_stable, host, container, filesystem, mitre_credential_access, + T1555] - macro: postgres_running_wal_e - condition: (proc.pname=postgres and (proc.cmdline startswith "sh -c envdir /etc/wal-e.d/env /usr/local/bin/wal-e" or proc.cmdline startswith "sh -c envdir \"/run/etc/wal-e.d/env\" wal-g wal-push")) + condition: > + ( + proc.pname=postgres and + ( + proc.cmdline startswith + "sh -c envdir /etc/wal-e.d/env /usr/local/bin/wal-e" or + proc.cmdline startswith + "sh -c envdir \"/run/etc/wal-e.d/env\" wal-g wal-push" + ) + ) - macro: redis_running_prepost_scripts - condition: (proc.aname[2]=redis-server and (proc.cmdline contains "redis-server.post-up.d" or proc.cmdline contains "redis-server.pre-up.d")) + condition: > + ( + proc.aname[2]=redis-server and + ( + proc.cmdline contains "redis-server.post-up.d" or + proc.cmdline contains "redis-server.pre-up.d" + ) + ) - macro: rabbitmq_running_scripts condition: > - (proc.pname=beam.smp and - (proc.cmdline startswith "sh -c exec ps" or - proc.cmdline startswith "sh -c exec inet_gethost" or - proc.cmdline= "sh -s unix:cmd" or - proc.cmdline= "sh -c exec /bin/sh -s unix:cmd 2>&1")) + ( + proc.pname=beam.smp and + ( + proc.cmdline startswith "sh -c exec ps" or + proc.cmdline startswith "sh -c exec inet_gethost" or + proc.cmdline= "sh -s unix:cmd" or + proc.cmdline= "sh -c exec /bin/sh -s unix:cmd 2>&1" + ) + ) - macro: rabbitmqctl_running_scripts condition: (proc.aname[2]=rabbitmqctl and proc.cmdline startswith "sh -c ") - macro: run_by_appdynamics - condition: (proc.pexe endswith java and proc.pcmdline contains " -jar -Dappdynamics") + condition: > + (proc.pexe endswith java and proc.pcmdline contains " -jar -Dappdynamics") # The binaries in this list and their descendents are *not* allowed # spawn shells. This includes the binaries spawning shells directly as @@ -458,48 +579,72 @@ # has apache as an ancestor. - list: protected_shell_spawning_binaries items: [ - http_server_binaries, db_server_binaries, nosql_server_binaries, mail_binaries, - fluentd, flanneld, splunkd, consul, smbd, runsv, PM2 - ] + http_server_binaries, db_server_binaries, nosql_server_binaries, + mail_binaries, fluentd, flanneld, splunkd, consul, smbd, runsv, PM2 + ] - macro: parent_java_running_zookeeper - condition: (proc.pexe endswith java and proc.pcmdline contains org.apache.zookeeper.server) + condition: > + (proc.pexe endswith java and proc.pcmdline contains + org.apache.zookeeper.server) - macro: parent_java_running_kafka condition: (proc.pexe endswith java and proc.pcmdline contains kafka.Kafka) - macro: parent_java_running_elasticsearch - condition: (proc.pexe endswith java and proc.pcmdline contains org.elasticsearch.bootstrap.Elasticsearch) + condition: > + (proc.pexe endswith java and proc.pcmdline + contains org.elasticsearch.bootstrap.Elasticsearch) - macro: parent_java_running_activemq condition: (proc.pexe endswith java and proc.pcmdline contains activemq.jar) - macro: parent_java_running_cassandra - condition: (proc.pexe endswith java and (proc.pcmdline contains "-Dcassandra.config.loader" or proc.pcmdline contains org.apache.cassandra.service.CassandraDaemon)) + condition: > + ( + proc.pexe endswith java and + ( + proc.pcmdline contains "-Dcassandra.config.loader" or + proc.pcmdline contains org.apache.cassandra.service.CassandraDaemon + ) + ) - macro: parent_java_running_jboss_wildfly condition: (proc.pexe endswith java and proc.pcmdline contains org.jboss) - macro: parent_java_running_glassfish - condition: (proc.pexe endswith java and proc.pcmdline contains com.sun.enterprise.glassfish) + condition: (proc.pexe endswith java and proc.pcmdline contains + com.sun.enterprise.glassfish) - macro: parent_java_running_hadoop - condition: (proc.pexe endswith java and proc.pcmdline contains org.apache.hadoop) + condition: > + (proc.pexe endswith java and proc.pcmdline contains org.apache.hadoop) - macro: parent_java_running_datastax condition: (proc.pexe endswith java and proc.pcmdline contains com.datastax) - macro: nginx_starting_nginx - condition: (proc.pname=nginx and proc.cmdline contains "/usr/sbin/nginx -c /etc/nginx/nginx.conf") + condition: > + (proc.pname=nginx and proc.cmdline contains + "/usr/sbin/nginx -c /etc/nginx/nginx.conf") - macro: nginx_running_aws_s3_cp - condition: (proc.pname=nginx and proc.cmdline startswith "sh -c /usr/local/bin/aws s3 cp") + condition: (proc.pname=nginx and proc.cmdline startswith + "sh -c /usr/local/bin/aws s3 cp") - macro: consul_running_net_scripts - condition: (proc.pname=consul and (proc.cmdline startswith "sh -c curl" or proc.cmdline startswith "sh -c nc")) + condition: > + ( + proc.pname=consul and + ( + proc.cmdline startswith "sh -c curl" or proc.cmdline startswith + "sh -c nc" + ) + ) - macro: consul_running_alert_checks - condition: (proc.pname=consul and proc.cmdline startswith "sh -c /bin/consul-alerts") + condition: > + (proc.pname=consul and proc.cmdline startswith "sh -c /bin/consul-alerts") - macro: serf_script condition: (proc.cmdline startswith "sh -c serf") @@ -523,7 +668,8 @@ # run in a container as a protected shell spawner, override the below # macro to remove the "never_true" clause, which allows it to take effect. - macro: possibly_node_in_container - condition: (never_true and (proc.pname=node and proc.aname[3]=docker-containe)) + condition: > + (never_true and (proc.pname=node and proc.aname[3]=docker-containe)) # Similarly, you may want to consider any shell spawned by apache # tomcat as suspect. The famous apache struts attack (CVE-2017-5638) @@ -534,7 +680,9 @@ # # Like for node, we make this case opt-in. - macro: possibly_parent_java_running_tomcat - condition: (never_true and proc.pexe endswith java and proc.pcmdline contains org.apache.catalina.startup.Bootstrap) + condition: > + (never_true and proc.pexe endswith java and + proc.pcmdline contains org.apache.catalina.startup.Bootstrap) - macro: protected_shell_spawner condition: > @@ -559,28 +707,36 @@ # (the ./run and ./finish scripts), but the processes runsv can not # spawn shells. - rule: Run shell untrusted - desc: > - An attempt to spawn a shell below a non-shell application. The non-shell applications that are monitored are - defined in the protected_shell_spawner macro, with protected_shell_spawning_binaries being the list you can - easily customize. For Java parent processes, please note that Java often has a custom process name. Therefore, - rely more on proc.exe to define Java applications. This rule can be noisier, as you can see in the exhaustive - existing tuning. However, given it is very behavior-driven and broad, it is universally relevant to catch - general Remote Code Execution (RCE). Allocate time to tune this rule for your use cases and reduce noise. - Tuning suggestions include looking at the duration of the parent process (proc.ppid.duration) to define your - long-running app processes. Checking for newer fields such as proc.vpgid.name and proc.vpgid.exe instead of the - direct parent process being a non-shell application could make the rule more robust. + desc: > + An attempt to spawn a shell below a non-shell application. + The non-shell applications that are monitored are defined in the + protected_shell_spawner macro, with protected_shell_spawning_binaries + being the list you can easily customize. For Java parent processes, + please note that Java often has a custom process name. Therefore, + rely more on proc.exe to define Java applications. This rule can be noisier, + as you can see in the exhaustive existing tuning. However, + given it is very behavior-driven and broad, it is universally relevant + to catch general Remote Code Execution (RCE). Allocate time to tune + this rule for your use cases and reduce noise. Tuning suggestions include + looking at the duration of the parent process (proc.ppid.duration) to + define your long-running app processes. Checking for newer fields such + as proc.vpgid.name and proc.vpgid.exe instead of the direct parent process + being a non-shell application could make the rule more robust. condition: > spawned_process and shell_procs and proc.pname exists and protected_shell_spawner - and not proc.pname in (shell_binaries, gitlab_binaries, cron_binaries, user_known_shell_spawn_binaries, + and not proc.pname in (shell_binaries, gitlab_binaries, cron_binaries, + user_known_shell_spawn_binaries, needrestart_binaries, mesos_shell_binaries, erl_child_setup, exechealthz, - PM2, PassengerWatchd, c_rehash, svlogd, logrotate, hhvm, serf, - lb-controller, nvidia-installe, runsv, statsite, erlexec, calico-node, - "puma reactor") + PM2, PassengerWatchd, c_rehash, svlogd, + logrotate, hhvm, serf, lb-controller, + nvidia-installe, runsv, statsite, erlexec, + calico-node, "puma reactor") + and not proc.cmdline in (known_shell_spawn_cmdlines) and not proc.aname in (unicorn_launche) and not consul_running_net_scripts @@ -599,9 +755,19 @@ and not rabbitmqctl_running_scripts and not run_by_appdynamics and not user_shell_container_exclusions - output: Shell spawned by untrusted binary (parent_exe=%proc.pexe parent_exepath=%proc.pexepath pcmdline=%proc.pcmdline gparent=%proc.aname[2] ggparent=%proc.aname[3] aname[4]=%proc.aname[4] aname[5]=%proc.aname[5] aname[6]=%proc.aname[6] aname[7]=%proc.aname[7] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: > + Shell spawned by untrusted binary + (parent_exe=%proc.pexe parent_exepath=%proc.pexepath + pcmdline=%proc.pcmdline gparent=%proc.aname[2] ggparent=%proc.aname[3] + aname[4]=%proc.aname[4] aname[5]=%proc.aname[5] + aname[6]=%proc.aname[6] aname[7]=%proc.aname[7] evt_type=%evt.type + user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid + process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname + command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags + %container.info) priority: NOTICE - tags: [maturity_stable, host, container, process, shell, mitre_execution, T1059.004] + tags: [maturity_stable, host, container, process, shell, + mitre_execution, T1059.004] # These images are allowed both to run with --privileged and to mount # sensitive paths from the host filesystem. @@ -614,10 +780,12 @@ items: [] - list: sematext_images - items: [docker.io/sematext/sematext-agent-docker, docker.io/sematext/agent, docker.io/sematext/logagent, - registry.access.redhat.com/sematext/sematext-agent-docker, - registry.access.redhat.com/sematext/agent, - registry.access.redhat.com/sematext/logagent] + items: [docker.io/sematext/sematext-agent-docker, + docker.io/sematext/agent, + docker.io/sematext/logagent, + registry.access.redhat.com/sematext/sematext-agent-docker, + registry.access.redhat.com/sematext/agent, + registry.access.redhat.com/sematext/logagent] # Falco containers - list: falco_containers @@ -633,7 +801,9 @@ - docker.io/falcosecurity/falco-no-driver - public.ecr.aws/falcosecurity/falco-no-driver -# These container images are allowed to run with --privileged and full set of capabilities +# These container images are allowed to run with --privileged and +# full set of capabilities +# TODO: Remove k8s.gcr.io reference after 01/Dec/2023 - list: falco_privileged_images items: [ falco_containers, @@ -652,17 +822,22 @@ gke.gcr.io/netd-amd64, gke.gcr.io/watcher-daemonset, gcr.io/google-containers/prometheus-to-sd, + k8s.gcr.io/ip-masq-agent-amd64, + k8s.gcr.io/kube-proxy, + k8s.gcr.io/prometheus-to-sd, registry.k8s.io/ip-masq-agent-amd64, registry.k8s.io/kube-proxy, registry.k8s.io/prometheus-to-sd, quay.io/calico/node, sysdig/sysdig, sematext_images, + k8s.gcr.io/dns/k8s-dns-node-cache, registry.k8s.io/dns/k8s-dns-node-cache, mcr.microsoft.com/oss/kubernetes/kube-proxy ] -# The steps libcontainer performs to set up the root program for a container are: +# The steps libcontainer performs to set up the root program +# for a container are: # - clone + exec self to a program runc:[0:PARENT] # - clone a program runc:[1:CHILD] which sets up all the namespaces # - clone a second program runc:[2:INIT] + exec to the root program. @@ -673,54 +848,84 @@ # We also let runc:[1:CHILD] count as the parent process, which can occur # when we lose events and lose track of state. - macro: container_entrypoint - condition: (not proc.pname exists or proc.pname in (runc:[0:PARENT], runc:[1:CHILD], runc, docker-runc, exe, docker-runc-cur, containerd-shim, systemd, crio)) + condition: > + ( + not proc.pname exists or proc.pname in + ( + runc:[0:PARENT], runc:[1:CHILD], runc, docker-runc, + exe, docker-runc-cur, containerd-shim, systemd, crio + ) + ) - macro: user_known_system_user_login condition: (never_true) # Anything run interactively by root -# - condition: evt.type != switch and user.name = root and proc.name != sshd and interactive -# output: "Interactive root (%user.name %proc.name %evt.dir %evt.type %evt.args %fd.name)" +# - condition: evt.type != switch and user.name = root and +# proc.name != sshd and interactive +# output: +# "Interactive root (%user.name %proc.name %evt.dir %evt.type %evt.args +# %fd.name)" # priority: WARNING - rule: System user interactive - desc: > - System (e.g. non-login) users spawning new processes. Can add custom service users (e.g. apache or mysqld). - 'Interactive' is defined as new processes as descendants of an ssh session or login process. Consider further tuning - by only looking at processes in a terminal / tty (proc.tty != 0). A newer field proc.is_vpgid_leader could be of help - to distinguish if the process was "directly" executed, for instance, in a tty, or executed as a descendant process in the - same process group, which, for example, is the case when subprocesses are spawned from a script. Consider this rule - as a great template rule to monitor interactive accesses to your systems more broadly. However, such a custom rule would be - unique to your environment. The rule "Terminal shell in container" that fires when using "kubectl exec" is more Kubernetes - relevant, whereas this one could be more interesting for the underlying host. - condition: > - spawned_process - and system_users - and interactive + desc: > + System (e.g. non-login) users spawning new processes. Can add custom service + users (e.g. apache or mysqld). 'Interactive' is defined as new processes as + descendants of an ssh session or login process. Consider further tuning + by only looking at processes in a terminal / tty (proc.tty != 0). + A newer field proc.is_vpgid_leader could be of help to distinguish + if the process was "directly" executed, for instance, in a tty, or + executed as a descendant process in the same process group, which, for + example, is the case when subprocesses are spawned from a script. + Consider this rule as a great template rule to monitor interactive + accesses to your systems more broadly. However, such a custom rule would + be unique to your environment. The rule "Terminal shell in container" + that fires when using "kubectl exec" is more Kubernetes relevant, whereas + this one could be more interesting for the underlying host. + condition: > + spawned_process + and system_users + and interactive and not user_known_system_user_login - output: System user ran an interactive command (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: > + System user ran an interactive command + (evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) priority: INFO - tags: [maturity_stable, host, container, users, mitre_execution, T1059, NIST_800-53_AC-2] + tags: [maturity_stable, host, container, users, mitre_execution, + T1059, NIST_800-53_AC-2] -# In some cases, a shell is expected to be run in a container. For example, configuration +# In some cases, a shell is expected to be run in a container. +# For example, configuration # management software may do this, which is expected. - macro: user_expected_terminal_shell_in_container_conditions condition: (never_true) - rule: Terminal shell in container desc: > - A shell was used as the entrypoint/exec point into a container with an attached terminal. Parent process may have - legitimately already exited and be null (read container_entrypoint macro). Common when using "kubectl exec" in Kubernetes. - Correlate with k8saudit exec logs if possible to find user or serviceaccount token used (fuzzy correlation by namespace and pod name). - Rather than considering it a standalone rule, it may be best used as generic auditing rule while examining other triggered - rules in this container/tty. + A shell was used as the entrypoint/exec point into a container with + an attached terminal. Parent process may have legitimately already + exited and be null (read container_entrypoint macro). Common when + using "kubectl exec" in Kubernetes. Correlate with k8saudit exec logs + if possible to find user or serviceaccount token used (fuzzy correlation + by namespace and pod name). Rather than considering it a standalone rule, + it may be best used as generic auditing rule while examining other + triggered rules in this container/tty. condition: > - spawned_process + spawned_process and container - and shell_procs + and shell_procs and proc.tty != 0 and container_entrypoint and not user_expected_terminal_shell_in_container_conditions - output: A shell was spawned in a container with an attached terminal (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: > + A shell was spawned in a container with an attached terminal + (evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) priority: NOTICE tags: [maturity_stable, container, shell, mitre_execution, T1059] @@ -763,7 +968,7 @@ '"bash -c id -Gn kafadmin"', '"sh -c /bin/sh -c ''date +%%s''"', '"sh -c /usr/share/lighttpd/create-mime.conf.pl"' - ] + ] # This list allows for easy additions to the set of commands allowed # to run shells in containers without having to without having to copy @@ -791,22 +996,31 @@ # allowed to contact the K8s API Server from within a container. This # might cover cases where the K8s infrastructure itself is running # within a container. +# TODO: Remove k8s.gcr.io reference after 01/Dec/2023 - macro: k8s_containers condition: > (container.image.repository in (gcr.io/google_containers/hyperkube-amd64, gcr.io/google_containers/kube2sky, docker.io/sysdig/sysdig, sysdig/sysdig, - fluent/fluentd-kubernetes-daemonset, prom/prometheus, + fluent/fluentd-kubernetes-daemonset, + prom/prometheus, falco_containers, falco_no_driver_containers, ibm_cloud_containers, velero/velero, - quay.io/jetstack/cert-manager-cainjector, weaveworks/kured, + quay.io/jetstack/cert-manager-cainjector, + weaveworks/kured, quay.io/prometheus-operator/prometheus-operator, - registry.k8s.io/ingress-nginx/kube-webhook-certgen, quay.io/spotahome/redis-operator, - registry.opensource.zalan.do/acid/postgres-operator, registry.opensource.zalan.do/acid/postgres-operator-ui, - rabbitmqoperator/cluster-operator, quay.io/kubecost1/kubecost-cost-model, - docker.io/bitnami/prometheus, docker.io/bitnami/kube-state-metrics, mcr.microsoft.com/oss/azure/aad-pod-identity/nmi) + k8s.gcr.io/ingress-nginx/kube-webhook-certgen, + registry.k8s.io/ingress-nginx/kube-webhook-certgen, + quay.io/spotahome/redis-operator, + registry.opensource.zalan.do/acid/postgres-operator, + registry.opensource.zalan.do/acid/postgres-operator-ui, + rabbitmqoperator/cluster-operator, + quay.io/kubecost1/kubecost-cost-model, + docker.io/bitnami/prometheus, + docker.io/bitnami/kube-state-metrics, + mcr.microsoft.com/oss/azure/aad-pod-identity/nmi) or (k8s.ns.name = "kube-system")) - macro: k8s_api_server @@ -817,40 +1031,56 @@ - rule: Contact K8S API Server From Container desc: > - Detect attempts to communicate with the K8S API Server from a container by non-profiled users. Kubernetes APIs play a - pivotal role in configuring the cluster management lifecycle. Detecting potential unauthorized access to the API server - is of utmost importance. Audit your complete infrastructure and pinpoint any potential machines from which the API server - might be accessible based on your network layout. If Falco can't operate on all these machines, consider analyzing the - Kubernetes audit logs (typically drained from control nodes, and Falco offers a k8saudit plugin) as an additional data - source for detections within the control plane. + Detect attempts to communicate with the K8S API Server from a container + by non-profiled users. Kubernetes APIs play a pivotal role in configuring + the cluster management lifecycle. Detecting potential unauthorized access + to the API server is of utmost importance. Audit your complete + infrastructure and pinpoint any potential machines from which the API + server might be accessible based on your network layout. If Falco can't + operate on all these machines, consider analyzing the Kubernetes audit + logs (typically drained from control nodes, and Falco offers a k8saudit + plugin) as an additional data source for detections within + the control plane. condition: > - evt.type=connect and evt.dir=< - and (fd.typechar=4 or fd.typechar=6) - and container - and k8s_api_server - and not k8s_containers + evt.type=connect and evt.dir=< + and (fd.typechar=4 or fd.typechar=6) + and container + and k8s_api_server + and not k8s_containers and not user_known_contact_k8s_api_server_activities - output: Unexpected connection to K8s API Server from container (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Unexpected connection to K8s API Server from container + (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type + fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: NOTICE tags: [maturity_stable, container, network, k8s, mitre_discovery, T1565] - rule: Netcat Remote Code Execution in Container - desc: > - Netcat Program runs inside container that allows remote code execution and may be utilized - as a part of a variety of reverse shell payload https://github.com/swisskyrepo/PayloadsAllTheThings/. - These programs are of higher relevance as they are commonly installed on UNIX-like operating systems. - Can fire in combination with the "Redirect STDOUT/STDIN to Network Connection in Container" + desc: > + Netcat Program runs inside container that allows remote code execution and + may be utilized as a part of a variety of reverse shell payload + https://github.com/swisskyrepo/PayloadsAllTheThings/. These programs are of + higher relevance as they are commonly installed on UNIX-like operating + systems. Can fire in combination with the + "Redirect STDOUT/STDIN to Network Connection in Container" rule as it utilizes a different evt.type. condition: > - spawned_process - and container - and ((proc.name = "nc" and (proc.cmdline contains " -e" or + spawned_process + and container + and ((proc.name = "nc" and (proc.cmdline contains " -e" or proc.cmdline contains " -c")) or - (proc.name = "ncat" and (proc.args contains "--sh-exec" or - proc.args contains "--exec" or proc.args contains "-e " or - proc.args contains "-c " or proc.args contains "--lua-exec")) + (proc.name = "ncat" and (proc.args contains "--sh-exec" or + proc.args contains "--exec" or + proc.args contains "-e " or + proc.args contains "-c " or + proc.args contains "--lua-exec")) ) - output: Netcat runs inside container that allows remote code execution (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: Netcat runs inside container that allows remote code execution + (evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) priority: WARNING tags: [maturity_stable, container, network, process, mitre_execution, T1059] @@ -879,63 +1109,89 @@ - rule: Search Private Keys or Passwords desc: > - Detect attempts to search for private keys or passwords using the grep or find command. This is often seen with - unsophisticated attackers, as there are many ways to access files using bash built-ins that could go unnoticed. - Regardless, this serves as a solid baseline detection that can be tailored to cover these gaps while maintaining + Detect attempts to search for private keys or passwords using + the grep or find command. This is often seen with unsophisticated + attackers, as there are many ways to access files using bash built-ins + that could go unnoticed. Regardless, this serves as a solid baseline + detection that can be tailored to cover these gaps while maintaining an acceptable noise level. condition: > - spawned_process + spawned_process and ((grep_commands and private_key_or_password) or - (proc.name = "find" and (proc.args contains "id_rsa" or - proc.args contains "id_dsa" or - proc.args contains "id_ed25519" or + (proc.name = "find" and (proc.args contains "id_rsa" or + proc.args contains "id_dsa" or + proc.args contains "id_ed25519" or proc.args contains "id_ecdsa" ) )) - output: Grep private keys or passwords activities found (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: > + Grep private keys or passwords activities found + (evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) priority: WARNING - tags: [maturity_stable, host, container, process, filesystem, mitre_credential_access, T1552.001] + tags: [maturity_stable, host, container, process, + filesystem, mitre_credential_access, T1552.001] - list: log_directories items: [/var/log, /dev/log] - list: log_files - items: [syslog, auth.log, secure, kern.log, cron, user.log, dpkg.log, last.log, yum.log, access_log, mysql.log, mysqld.log] + items: [syslog, auth.log, secure, kern.log, cron, user.log, + dpkg.log, last.log, yum.log, access_log, mysql.log, mysqld.log] - macro: access_log_files condition: (fd.directory in (log_directories) or fd.filename in (log_files)) -# a placeholder for whitelist log files that could be cleared. Recommend the macro as (fd.name startswith "/var/log/app1*") +# a placeholder for whitelist log files that could be cleared. +# Recommend the macro as (fd.name startswith "/var/log/app1*") - macro: allowed_clear_log_files condition: (never_true) - macro: trusted_logging_images - condition: (container.image.repository endswith "splunk/fluentd-hec" or - container.image.repository endswith "fluent/fluentd-kubernetes-daemonset" or - container.image.repository endswith "openshift3/ose-logging-fluentd" or - container.image.repository endswith "containernetworking/azure-npm") + condition: > + (container.image.repository endswith "splunk/fluentd-hec" or + container.image.repository endswith "fluent/fluentd-kubernetes-daemonset" or + container.image.repository endswith "openshift3/ose-logging-fluentd" or + container.image.repository endswith "containernetworking/azure-npm") - macro: containerd_activities - condition: (proc.name=containerd and (fd.name startswith "/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/" or - fd.name startswith "/var/lib/containerd/tmpmounts/")) + condition: > + ( + proc.name=containerd and + ( + fd.name startswith + "/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/" + or fd.name startswith "/var/lib/containerd/tmpmounts/" + ) + ) - rule: Clear Log Activities - desc: > - Detect clearing of critical access log files, typically done to erase evidence that could be attributed to an adversary's - actions. To effectively customize and operationalize this detection, check for potentially missing log file destinations - relevant to your environment, and adjust the profiled containers you wish not to be alerted on. + desc: > + Detect clearing of critical access log files, typically done to erase + evidence that could be attributed to an adversary's actions. To + effectively customize and operationalize this detection, check for + potentially missing log file destinationsrelevant to your environment, + and adjust the profiled containers you wish not to be alerted on. condition: > - open_write - and access_log_files - and evt.arg.flags contains "O_TRUNC" + open_write + and access_log_files + and evt.arg.flags contains "O_TRUNC" and not containerd_activities - and not trusted_logging_images + and not trusted_logging_images and not allowed_clear_log_files - output: Log files were tampered (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: > + Log files were tampered + (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: WARNING - tags: [maturity_stable, host, container, filesystem, mitre_defense_evasion, T1070, NIST_800-53_AU-10] + tags: [maturity_stable, host, container, filesystem, + mitre_defense_evasion, T1070, NIST_800-53_AU-10] - list: data_remove_commands items: [shred, mkfs, mke2fs] @@ -947,58 +1203,85 @@ condition: (never_true) - rule: Remove Bulk Data from Disk - desc: > - Detect a process running to clear bulk data from disk with the intention to destroy data, possibly interrupting availability - to systems. Profile your environment and use user_known_remove_data_activities to tune this rule. - condition: > - spawned_process - and clear_data_procs + desc: > + Detect a process running to clear bulk data from disk with + the intention to destroy data, possibly interrupting availability + to systems. Profile your environment and + use user_known_remove_data_activities to tune this rule. + condition: > + spawned_process + and clear_data_procs and not user_known_remove_data_activities - output: Bulk data has been removed from disk (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: Bulk data has been removed from disk + (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) priority: WARNING - tags: [maturity_stable, host, container, process, filesystem, mitre_impact, T1485] + tags: [maturity_stable, host, container, process, filesystem, mitre_impact, + T1485] - rule: Create Symlink Over Sensitive Files - desc: > - Detect symlinks created over a curated list of sensitive files or subdirectories under /etc/ or - root directories. Can be customized as needed. Refer to further and equivalent guidance within the + desc: > + Detect symlinks created over a curated list of sensitive files or + subdirectories under /etc/ or root directories. Can be customized as needed. + Refer to further and equivalent guidance within the rule "Read sensitive file untrusted". condition: > - create_symlink - and (evt.arg.target in (sensitive_file_names) or evt.arg.target in (sensitive_directory_names)) - output: Symlinks created over sensitive files (target=%evt.arg.target linkpath=%evt.arg.linkpath evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + create_symlink + and (evt.arg.target in (sensitive_file_names) or + evt.arg.target in (sensitive_directory_names)) + output: Symlinks created over sensitive files + (target=%evt.arg.target linkpath=%evt.arg.linkpath evt_type=%evt.type + user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid + process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname + command=%proc.cmdline terminal=%proc.tty %container.info) priority: WARNING - tags: [maturity_stable, host, container, filesystem, mitre_credential_access, T1555] + tags: [maturity_stable, host, container, filesystem, mitre_credential_access, + T1555] - rule: Create Hardlink Over Sensitive Files - desc: > - Detect hardlink created over a curated list of sensitive files or subdirectories under /etc/ or - root directories. Can be customized as needed. Refer to further and equivalent guidance within the - rule "Read sensitive file untrusted". + desc: > + Detect hardlink created over a curated list of sensitive files or + subdirectories under /etc/ or root directories. Can be customized as + needed. Refer to further and equivalent guidance within the rule + "Read sensitive file untrusted". condition: > - create_hardlink + create_hardlink and (evt.arg.oldpath in (sensitive_file_names)) - output: Hardlinks created over sensitive files (target=%evt.arg.oldpath linkpath=%evt.arg.newpath evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Hardlinks created over sensitive files + (target=%evt.arg.oldpath linkpath=%evt.arg.newpath evt_type=%evt.type + user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid + process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname + command=%proc.cmdline terminal=%proc.tty %container.info) priority: WARNING - tags: [maturity_stable, host, container, filesystem, mitre_credential_access, T1555] + tags: [maturity_stable, host, container, filesystem, mitre_credential_access, + T1555] - list: user_known_packet_socket_binaries items: [] - rule: Packet socket created in container - desc: > - Detect new packet socket at the device driver (OSI Layer 2) level in a container. Packet socket could be used for ARP Spoofing - and privilege escalation (CVE-2020-14386) by an attacker. Noise can be reduced by using the user_known_packet_socket_binaries - template list. - condition: > + desc: > + Detect new packet socket at the device driver (OSI Layer 2) level in a + container. Packet socket could be used for ARP Spoofing and privilege + escalation (CVE-2020-14386) by an attacker. Noise can be reduced by + using the user_known_packet_socket_binaries template list. + condition: > evt.type=socket and evt.dir=> - and container - and evt.arg.domain contains AF_PACKET + and container + and evt.arg.domain contains AF_PACKET and not proc.name in (user_known_packet_socket_binaries) - output: Packet socket was created in a container (socket_info=%evt.args connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Packet socket was created in a container + (socket_info=%evt.args connection=%fd.name lport=%fd.lport rport=%fd.rport + fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name + user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: NOTICE - tags: [maturity_stable, container, network, mitre_credential_access, T1557.002] + tags: [maturity_stable, container, network, mitre_credential_access, + T1557.002] - macro: user_known_stand_streams_redirect_activities condition: (never_true) @@ -1011,25 +1294,39 @@ # items: ["ipv4", "ipv6"] # # - rule: Redirect STDOUT/STDIN to Network Connection in Container once -# condition: dup and container and evt.rawres in (0, 1, 2) and fd.type in (ip_sockets) and fd.types[0] in (ip_sockets) and fd.types[1] in (ip_sockets) and fd.types[2] in (ip_sockets) and not user_known_stand_streams_redirect_activities +# condition: dup and container and evt.rawres in (0, 1, 2) and +# fd.type in (ip_sockets) and fd.types[0] in (ip_sockets) and +# fd.types[1] in (ip_sockets) and fd.types[2] in (ip_sockets) and +# not user_known_stand_streams_redirect_activities # # The following rule has not been changed by default as existing users could be # relying on the rule triggering when any of std{out,err,in} are redirected. - rule: Redirect STDOUT/STDIN to Network Connection in Container desc: > - Detect redirection of stdout/stdin to a network connection within a container, achieved by utilizing a - variant of the dup syscall (potential reverse shell or remote code execution - https://github.com/swisskyrepo/PayloadsAllTheThings/). This detection is behavior-based and may generate - noise in the system, and can be adjusted using the user_known_stand_streams_redirect_activities template - macro. Tuning can be performed similarly to existing detections based on process lineage or container images, - and/or it can be limited to interactive tty (tty != 0). - condition: > - dup - and container - and evt.rawres in (0, 1, 2) - and fd.type in ("ipv4", "ipv6") + Detect redirection of stdout/stdin to a network connection within a + container, achieved by utilizing a variant of the dup syscall + (potential reverse shell or remote code execution + https://github.com/swisskyrepo/PayloadsAllTheThings/). + This detection is behavior-based and may generate noise in the + system, and can be adjusted using the + user_known_stand_streams_redirect_activities template + macro. Tuning can be performed similarly to existing detections + based on process lineage or container images, and/or + it can be limited to interactive tty (tty != 0). + condition: > + dup + and container + and evt.rawres in (0, 1, 2) + and fd.type in ("ipv4", "ipv6") and not user_known_stand_streams_redirect_activities - output: Redirect stdout/stdin to network connection (gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] fd.sip=%fd.sip connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: > + Redirect stdout/stdin to network connection + (gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] + fd.sip=%fd.sip connection=%fd.name lport=%fd.lport rport=%fd.rport + fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name + user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: NOTICE tags: [maturity_stable, container, network, process, mitre_execution, T1059] @@ -1038,48 +1335,70 @@ - rule: Linux Kernel Module Injection Detected desc: > - Inject Linux Kernel Modules from containers using insmod or modprobe with init_module and finit_module - syscalls, given the precondition of sys_module effective capabilities. Profile the environment and consider - allowed_container_images_loading_kernel_module to reduce noise and account for legitimate cases. - condition: > - kernel_module_load - and container - and thread.cap_effective icontains sys_module - and not container.image.repository in (allowed_container_images_loading_kernel_module) - output: Linux Kernel Module injection from container (parent_exepath=%proc.pexepath gparent=%proc.aname[2] gexepath=%proc.aexepath[2] module=%proc.args res=%evt.res evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + Inject Linux Kernel Modules from containers using insmod or modprobe with + init_module and finit_module syscalls, given the precondition of + sys_module effective capabilities. Profile the environment and consider + allowed_container_images_loading_kernel_module to reduce noise + and account for legitimate cases. + condition: > + kernel_module_load + and container + and thread.cap_effective icontains sys_module + and not container.image.repository in + (allowed_container_images_loading_kernel_module) + output: Linux Kernel Module injection from container + (parent_exepath=%proc.pexepath gparent=%proc.aname[2] + gexepath=%proc.aexepath[2] module=%proc.args res=%evt.res + evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: WARNING tags: [maturity_stable, host, container, process, mitre_persistence, TA0003] - rule: Debugfs Launched in Privileged Container - desc: > - Detect file system debugger debugfs launched inside a privileged container which might lead to container escape. - This rule has a more narrow scope. + desc: > + Detect file system debugger debugfs launched inside a privileged container + which might lead to container escape. This rule has a more narrow scope. condition: > - spawned_process + spawned_process and container and container.privileged=true and proc.name=debugfs - output: Debugfs launched started in a privileged container (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: Debugfs launched started in a privileged container + (evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) priority: WARNING - tags: [maturity_stable, container, cis, process, mitre_privilege_escalation, T1611] + tags: [maturity_stable, container, cis, process, + mitre_privilege_escalation, T1611] - rule: Detect release_agent File Container Escapes - desc: > - Detect an attempt to exploit a container escape using release_agent file. - By running a container with certains capabilities, a privileged user can modify - release_agent file and escape from the container. + desc: > + Detect an attempt to exploit a container escape using release_agent file. + By running a container with certains capabilities, a privileged user can + modify release_agent file and escape from the container. condition: > - open_write - and container - and fd.name endswith release_agent - and (user.uid=0 or thread.cap_effective contains CAP_DAC_OVERRIDE) + open_write + and container + and fd.name endswith release_agent + and (user.uid=0 or thread.cap_effective contains CAP_DAC_OVERRIDE) and thread.cap_effective contains CAP_SYS_ADMIN - output: Detect an attempt to exploit a container escape using release_agent file (file=%fd.name cap_effective=%thread.cap_effective evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: > + Detect an attempt to exploit a container escape using release_agent file + (file=%fd.name cap_effective=%thread.cap_effective evt_type=%evt.type + user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid + process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname + command=%proc.cmdline terminal=%proc.tty %container.info) priority: CRITICAL - tags: [maturity_stable, container, process, mitre_privilege_escalation, T1611] + tags: [maturity_stable, container, process, mitre_privilege_escalation, + T1611] - list: docker_binaries - items: [docker, dockerd, containerd-shim, "runc:[1:CHILD]", pause, exe, docker-compose, docker-entrypoi, docker-runc-cur, docker-current, dockerd-current] + items: [docker, dockerd, containerd-shim, "runc:[1:CHILD]", pause, exe, + docker-compose, docker-entrypoi, docker-runc-cur, docker-current, + dockerd-current] - list: known_ptrace_binaries items: [] @@ -1097,31 +1416,43 @@ evt.arg.request contains PTRACE_SETREGS)) - rule: PTRACE attached to process - desc: > - Detect an attempt to inject potentially malicious code into a process using PTRACE in order to evade - process-based defenses or elevate privileges. Common anti-patterns are debuggers. Additionally, profiling - your environment via the known_ptrace_procs template macro can reduce noise. + desc: > + Detect an attempt to inject potentially malicious code into a process + using PTRACE in order to evade process-based defenses or elevate privileges. + Common anti-patterns are debuggers. Additionally, profiling your environment + via the known_ptrace_procs template macro can reduce noise. A successful ptrace syscall generates multiple logs at once. - condition: > - ptrace_attach_or_injection - and proc_name_exists + condition: > + ptrace_attach_or_injection + and proc_name_exists and not known_ptrace_procs - output: Detected ptrace PTRACE_ATTACH attempt (proc_pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Detected ptrace PTRACE_ATTACH attempt + (proc_pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name + user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: WARNING - tags: [maturity_stable, host, container, process, mitre_privilege_escalation, T1055.008] - + tags: [maturity_stable, host, container, process, mitre_privilege_escalation, + T1055.008] + - rule: PTRACE anti-debug attempt - desc: > - Detect usage of the PTRACE system call with the PTRACE_TRACEME argument, indicating a program actively attempting - to avoid debuggers attaching to the process. This behavior is typically indicative of malware activity. + desc: > + Detect usage of the PTRACE system call with the PTRACE_TRACEME argument, + indicating a program actively attempting to avoid debuggers attaching to + the process. This behavior is typically indicative of malware activity. Read more about PTRACE in the "PTRACE attached to process" rule. - condition: > - evt.type=ptrace and evt.dir=> - and evt.arg.request contains PTRACE_TRACEME + condition: > + evt.type=ptrace and evt.dir=> + and evt.arg.request contains PTRACE_TRACEME and proc_name_exists - output: Detected potential PTRACE_TRACEME anti-debug attempt (proc_pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Detected potential PTRACE_TRACEME anti-debug attempt + (proc_pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name + user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name + proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline + terminal=%proc.tty %container.info) priority: NOTICE - tags: [maturity_stable, host, container, process, mitre_defense_evasion, T1622] + tags: > + [maturity_stable, host, container, process, mitre_defense_evasion, T1622] - macro: private_aws_credentials condition: > @@ -1133,63 +1464,95 @@ - rule: Find AWS Credentials desc: > - Detect attempts to search for private keys or passwords using the grep or find command, particularly targeting standard - AWS credential locations. This is often seen with unsophisticated attackers, as there are many ways to access files - using bash built-ins that could go unnoticed. Regardless, this serves as a solid baseline detection that can be tailored - to cover these gaps while maintaining an acceptable noise level. This rule complements the rule "Search Private Keys or Passwords". + Detect attempts to search for private keys or passwords using the grep or + find command, particularly targeting standard AWS credential locations. + This is often seen with unsophisticated attackers, as there are many ways + to access files using bash built-ins that could go unnoticed. Regardless, + this serves as a solid baseline detection that can be tailored to cover + these gaps while maintaining an acceptable noise level. This rule + complements the rule "Search Private Keys or Passwords". condition: > - spawned_process + spawned_process and ((grep_commands and private_aws_credentials) or (proc.name = "find" and proc.args endswith ".aws/credentials")) - output: Detected AWS credentials search activity (proc_pcmdline=%proc.pcmdline proc_cwd=%proc.cwd group_gid=%group.gid group_name=%group.name user_loginname=%user.loginname evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: Detected AWS credentials search activity + (proc_pcmdline=%proc.pcmdline proc_cwd=%proc.cwd group_gid=%group.gid + group_name=%group.name user_loginname=%user.loginname evt_type=%evt.type + user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid + process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname + command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) priority: WARNING - tags: [maturity_stable, host, container, process, aws, mitre_credential_access, T1552] + tags: [maturity_stable, host, container, process, aws, + mitre_credential_access, T1552] - rule: Execution from /dev/shm - desc: > - This rule detects file execution in the /dev/shm directory, a tactic often used by threat actors to store their readable, writable, and - occasionally executable files. /dev/shm acts as a link to the host or other containers, creating vulnerabilities for their compromise - as well. Notably, /dev/shm remains unchanged even after a container restart. Consider this rule alongside the newer - "Drop and execute new binary in container" rule. + desc: > + This rule detects file execution in the /dev/shm directory, a tactic + often used by threat actors to store their readable, writable, and + occasionally executable files. /dev/shm acts as a link to the host or + other containers, creating vulnerabilities for their compromise as + well. Notably, /dev/shm remains unchanged even after a container restart. + Consider this rule alongside the newer "Drop and execute new binary in + container" rule. condition: > - spawned_process - and (proc.exe startswith "/dev/shm/" or - (proc.cwd startswith "/dev/shm/" and proc.exe startswith "./" ) or - (shell_procs and proc.args startswith "-c /dev/shm") or - (shell_procs and proc.args startswith "-i /dev/shm") or - (shell_procs and proc.args startswith "/dev/shm") or - (proc.cwd startswith "/dev/shm/" and proc.args startswith "./" )) - and not container.image.repository in (falco_privileged_images, trusted_images) - output: File execution detected from /dev/shm (evt_res=%evt.res file=%fd.name proc_cwd=%proc.cwd proc_pcmdline=%proc.pcmdline user_loginname=%user.loginname group_gid=%group.gid group_name=%group.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + spawned_process + and (proc.exe startswith "/dev/shm/" or + (proc.cwd startswith "/dev/shm/" and proc.exe startswith "./" ) or + (shell_procs and proc.args startswith "-c /dev/shm") or + (shell_procs and proc.args startswith "-i /dev/shm") or + (shell_procs and proc.args startswith "/dev/shm") or + (proc.cwd startswith "/dev/shm/" and proc.args startswith "./" )) + and not container.image.repository in + (falco_privileged_images, trusted_images) + output: File execution detected from /dev/shm + (evt_res=%evt.res file=%fd.name proc_cwd=%proc.cwd + proc_pcmdline=%proc.pcmdline user_loginname=%user.loginname + group_gid=%group.gid group_name=%group.name evt_type=%evt.type + user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid + process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname + command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) priority: WARNING tags: [maturity_stable, host, container, mitre_execution, T1059.004] -# List of allowed container images that are known to execute binaries not part of their base image. +# List of allowed container images that are known to execute binaries not +# part of their base image. - list: known_drop_and_execute_containers items: [] -- macro: known_drop_and_execute_activities - condition: (never_true) - - rule: Drop and execute new binary in container desc: > - Detect if an executable not belonging to the base image of a container is being executed. - The drop and execute pattern can be observed very often after an attacker gained an initial foothold. - is_exe_upper_layer filter field only applies for container runtimes that use overlayfs as union mount filesystem. - Adopters can utilize the provided template list known_drop_and_execute_containers containing allowed container - images known to execute binaries not included in their base image. Alternatively, you could exclude non-production - namespaces in Kubernetes settings by adjusting the rule further. This helps reduce noise by applying application - and environment-specific knowledge to this rule. Common anti-patterns include administrators or SREs performing - ad-hoc debugging. + Detect if an executable not belonging to the base image of a container + is being executed. The drop and execute pattern can be observed very + often after an attacker gained an initial foothold.is_exe_upper_layer + filter field only applies for container runtimes that use overlayfs as + union mount filesystem.Adopters can utilize the provided template list + known_drop_and_execute_containers containing allowed container images + known to execute binaries not included in their base image. Alternatively, + you could exclude non-production namespaces in Kubernetes settings by + adjusting the rule further. This helps reduce noise by applying + application and environment-specific knowledge to this rule. Common + anti-patterns include administrators or SREs performing ad-hoc debugging. condition: > spawned_process and container - and proc.is_exe_upper_layer=true + and proc.is_exe_upper_layer=true and not container.image.repository in (known_drop_and_execute_containers) - and not known_drop_and_execute_activities - output: Executing binary not part of base image (proc_exe=%proc.exe proc_sname=%proc.sname gparent=%proc.aname[2] proc_exe_ino_ctime=%proc.exe_ino.ctime proc_exe_ino_mtime=%proc.exe_ino.mtime proc_exe_ino_ctime_duration_proc_start=%proc.exe_ino.ctime_duration_proc_start proc_cwd=%proc.cwd container_start_ts=%container.start_ts evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: Executing binary not part of base image + proc_exe=%proc.exe proc_sname=%proc.sname gparent=%proc.aname[2] + proc_exe_ino_ctime=%proc.exe_ino.ctime + proc_exe_ino_mtime=%proc.exe_ino.mtime + proc_exe_ino_ctime_duration_proc_start=%proc.exe_ino.ctime_duration_proc_start + proc_cwd=%proc.cwd container_start_ts=%container.start_ts evt_type=%evt.type + user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid + process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname + command=%proc.cmdline terminal=%proc.tty + exe_flags=%evt.arg.flags %container.info) priority: CRITICAL - tags: [maturity_stable, container, process, mitre_persistence, TA0003, PCI_DSS_11.5.1] + tags: > + [maturity_stable, container, process, mitre_persistence, + TA0003, PCI_DSS_11.5.1] # RFC1918 addresses were assigned for private network usage - list: rfc_1918_addresses @@ -1201,8 +1564,9 @@ (evt.type in (sendto,sendmsg) and evt.dir=< and fd.l4proto != tcp and fd.connected=false and fd.name_changed=true)) and (fd.typechar = 4 or fd.typechar = 6) and - (fd.ip != "0.0.0.0" and fd.net != "127.0.0.0/8" and not fd.snet in (rfc_1918_addresses)) and - (evt.rawres >= 0 or evt.res = EINPROGRESS)) + (fd.ip != "0.0.0.0" and fd.net != "127.0.0.0/8" and not fd.snet in + (rfc_1918_addresses)) + and (evt.rawres >= 0 or evt.res = EINPROGRESS)) - list: ssh_non_standard_ports items: [80, 8080, 88, 443, 8443, 53, 4444] @@ -1211,22 +1575,31 @@ condition: (fd.sport in (ssh_non_standard_ports)) - rule: Disallowed SSH Connection Non Standard Port - desc: > - Detect any new outbound SSH connection from the host or container using a non-standard port. This rule holds the potential - to detect a family of reverse shells that cause the victim machine to connect back out over SSH, with STDIN piped from - the SSH connection to a shell's STDIN, and STDOUT of the shell piped back over SSH. Such an attack can be launched against - any app that is vulnerable to command injection. The upstream rule only covers a limited selection of non-standard ports. - We suggest adding more ports, potentially incorporating ranges based on your environment's knowledge and custom SSH port - configurations. This rule can complement the "Redirect STDOUT/STDIN to Network Connection in Container" or - "Disallowed SSH Connection" rule. - condition: > - outbound - and proc.exe endswith ssh - and fd.l4proto=tcp + desc: > + Detect any new outbound SSH connection from the host or container using + a non-standard port. This rule holds the potential to detect a family + of reverse shells that cause the victim machine to connect back out over + SSH, with STDIN piped from the SSH connection to a shell's STDIN, and + STDOUT of the shell piped back over SSH. Such an attack can belaunched + against any app that is vulnerable to command injection. The upstream + rule only covers a limited selection of non-standard ports. We suggest + adding more ports, potentially incorporating ranges based on your + environment's knowledge and custom SSH port configurations. This rule + can complement the "Redirect STDOUT/STDIN to Network Connection in + Container" or "Disallowed SSH Connection" rule. + condition: > + outbound + and proc.exe endswith ssh + and fd.l4proto=tcp and ssh_non_standard_ports_network - output: Disallowed SSH Connection (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) + output: Disallowed SSH Connection + (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type + fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid + user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath + parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info) priority: NOTICE - tags: [maturity_stable, host, container, network, process, mitre_execution, T1059] + tags: > + [maturity_stable, host, container, network, process, mitre_execution, T1059] - list: known_memfd_execution_binaries items: [] @@ -1236,14 +1609,23 @@ - rule: Fileless execution via memfd_create desc: > - Detect if a binary is executed from memory using the memfd_create technique. This is a well-known defense evasion - technique for executing malware on a victim machine without storing the payload on disk and to avoid leaving traces - about what has been executed. Adopters can whitelist processes that may use fileless execution for benign purposes - by adding items to the list known_memfd_execution_processes. + Detect if a binary is executed from memory using the memfd_create technique. + This is a well-known defense evasion technique for executing malware on a + victim machine without storing the payload on disk and to avoid leaving + traces about what has been executed. Adopters can whitelist processes that + may use fileless execution for benign purposes by adding items to the list + known_memfd_execution_processes. condition: > spawned_process and proc.is_exe_from_memfd=true and not known_memfd_execution_processes - output: Fileless execution via memfd_create (container_start_ts=%container.start_ts proc_cwd=%proc.cwd evt_res=%evt.res proc_sname=%proc.sname gparent=%proc.aname[2] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info) + output: Fileless execution via memfd_create + (container_start_ts=%container.start_ts proc_cwd=%proc.cwd evt_res=%evt.res + proc_sname=%proc.sname gparent=%proc.aname[2] evt_type=%evt.type + user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid + process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname + command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags + %container.info) priority: CRITICAL - tags: [maturity_stable, host, container, process, mitre_defense_evasion, T1620] + tags: > + [maturity_stable, host, container, process, mitre_defense_evasion, T1620]