mirror of
https://github.com/falcosecurity/falco.git
synced 2026-03-30 16:42:34 +00:00
Compare commits
12 Commits
fix/dev_ve
...
add-except
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dbd4ff08eb | ||
|
|
9c70ae19be | ||
|
|
9cb25be5bd | ||
|
|
1f533e5964 | ||
|
|
854318cacf | ||
|
|
0cc10b0fbe | ||
|
|
e3f1ac1be3 | ||
|
|
fb4e07e220 | ||
|
|
9014153d7b | ||
|
|
0bb6addcc0 | ||
|
|
3aa8ff6e84 | ||
|
|
a4b7d46717 |
@@ -15,15 +15,8 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
# See xxx for details on falco engine and rules versioning. Currently,
|
# Falco engine 8 supports exception properties on rules.
|
||||||
# this specific rules file is compatible with engine version 0
|
- required_engine_version: 8
|
||||||
# (e.g. falco releases <= 0.13.1), so we'll keep the
|
|
||||||
# required_engine_version lines commented out, so maintain
|
|
||||||
# compatibility with older falco releases. With the first incompatible
|
|
||||||
# change to this rules file, we'll uncomment this line and set it to
|
|
||||||
# the falco engine version in use at the time.
|
|
||||||
#
|
|
||||||
- required_engine_version: 7
|
|
||||||
|
|
||||||
# Currently disabled as read/write are ignored syscalls. The nearly
|
# Currently disabled as read/write are ignored syscalls. The nearly
|
||||||
# similar open_write/open_read check for files being opened for
|
# similar open_write/open_read check for files being opened for
|
||||||
@@ -244,9 +237,6 @@
|
|||||||
proc.aname[3] in (package_mgmt_binaries) or
|
proc.aname[3] in (package_mgmt_binaries) or
|
||||||
proc.aname[4] in (package_mgmt_binaries)
|
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)
|
|
||||||
|
|
||||||
- macro: run_by_package_mgmt_binaries
|
- macro: run_by_package_mgmt_binaries
|
||||||
condition: proc.aname in (package_mgmt_binaries, needrestart)
|
condition: proc.aname in (package_mgmt_binaries, needrestart)
|
||||||
|
|
||||||
@@ -362,12 +352,17 @@
|
|||||||
# repeats ssh_port, which effectively allows ssh from all hosts. In
|
# repeats ssh_port, which effectively allows ssh from all hosts. In
|
||||||
# the overridden macro, the condition would look something like
|
# the overridden macro, the condition would look something like
|
||||||
# "fd.sip="a.b.c.d" or fd.sip="e.f.g.h" or ..."
|
# "fd.sip="a.b.c.d" or fd.sip="e.f.g.h" or ..."
|
||||||
|
#
|
||||||
|
# If at all possible, use the rule exceptions instead.
|
||||||
- macro: allowed_ssh_hosts
|
- macro: allowed_ssh_hosts
|
||||||
condition: ssh_port
|
condition: ssh_port
|
||||||
|
|
||||||
- rule: Disallowed SSH Connection
|
- rule: Disallowed SSH Connection
|
||||||
desc: Detect any new ssh connection to a host other than those in an allowed group of hosts
|
desc: Detect any new ssh connection to a host other than those in an allowed group of hosts
|
||||||
condition: (inbound_outbound) and ssh_port and not allowed_ssh_hosts
|
condition: (inbound_outbound) and ssh_port and not allowed_ssh_hosts
|
||||||
|
exceptions:
|
||||||
|
- name: allowed_ssh_ipaddrs
|
||||||
|
fields: fd.sip
|
||||||
output: Disallowed SSH Connection (command=%proc.cmdline connection=%fd.name user=%user.name user_loginuid=%user.loginuid container_id=%container.id image=%container.image.repository)
|
output: Disallowed SSH Connection (command=%proc.cmdline connection=%fd.name user=%user.name user_loginuid=%user.loginuid container_id=%container.id image=%container.image.repository)
|
||||||
priority: NOTICE
|
priority: NOTICE
|
||||||
tags: [network, mitre_remote_service]
|
tags: [network, mitre_remote_service]
|
||||||
@@ -395,10 +390,20 @@
|
|||||||
- rule: Unexpected outbound connection destination
|
- rule: Unexpected outbound connection destination
|
||||||
desc: Detect any outbound connection to a destination outside of an allowed set of ips, networks, or domain names
|
desc: Detect any outbound connection to a destination outside of an allowed set of ips, networks, or domain names
|
||||||
condition: >
|
condition: >
|
||||||
consider_all_outbound_conns and outbound and not
|
consider_all_outbound_conns and outbound
|
||||||
((fd.sip in (allowed_outbound_destination_ipaddrs)) or
|
exceptions:
|
||||||
(fd.snet in (allowed_outbound_destination_networks)) or
|
- name: allowed_outbound_ipaddrs
|
||||||
(fd.sip.name in (allowed_outbound_destination_domains)))
|
fields: fd.sip
|
||||||
|
values:
|
||||||
|
- allowed_outbound_destination_ipaddrs
|
||||||
|
- name: allowed_outbound_networks
|
||||||
|
fields: fd.snet
|
||||||
|
values:
|
||||||
|
- allowed_outbound_destination_networks
|
||||||
|
- name: allowed_outbound_domains
|
||||||
|
fields: fd.sip.name
|
||||||
|
values:
|
||||||
|
- allowed_outbound_destination_domains
|
||||||
output: Disallowed outbound connection destination (command=%proc.cmdline connection=%fd.name user=%user.name user_loginuid=%user.loginuid container_id=%container.id image=%container.image.repository)
|
output: Disallowed outbound connection destination (command=%proc.cmdline connection=%fd.name user=%user.name user_loginuid=%user.loginuid container_id=%container.id image=%container.image.repository)
|
||||||
priority: NOTICE
|
priority: NOTICE
|
||||||
tags: [network]
|
tags: [network]
|
||||||
@@ -418,10 +423,20 @@
|
|||||||
- rule: Unexpected inbound connection source
|
- rule: Unexpected inbound connection source
|
||||||
desc: Detect any inbound connection from a source outside of an allowed set of ips, networks, or domain names
|
desc: Detect any inbound connection from a source outside of an allowed set of ips, networks, or domain names
|
||||||
condition: >
|
condition: >
|
||||||
consider_all_inbound_conns and inbound and not
|
consider_all_inbound_conns and inbound
|
||||||
((fd.cip in (allowed_inbound_source_ipaddrs)) or
|
exceptions:
|
||||||
(fd.cnet in (allowed_inbound_source_networks)) or
|
- name: allowed_inbound_ipaddrs
|
||||||
(fd.cip.name in (allowed_inbound_source_domains)))
|
fields: fd.cip
|
||||||
|
values:
|
||||||
|
- allowed_inbound_source_ipaddrs
|
||||||
|
- name: allowed_inbound_networks
|
||||||
|
fields: fd.cnet
|
||||||
|
values:
|
||||||
|
- allowed_inbound_source_networks
|
||||||
|
- name: allowed_inbound_domains
|
||||||
|
fields: fd.cip.name
|
||||||
|
values:
|
||||||
|
- allowed_inbound_source_domains
|
||||||
output: Disallowed inbound connection source (command=%proc.cmdline connection=%fd.name user=%user.name user_loginuid=%user.loginuid container_id=%container.id image=%container.image.repository)
|
output: Disallowed inbound connection source (command=%proc.cmdline connection=%fd.name user=%user.name user_loginuid=%user.loginuid container_id=%container.id image=%container.image.repository)
|
||||||
priority: NOTICE
|
priority: NOTICE
|
||||||
tags: [network]
|
tags: [network]
|
||||||
@@ -460,6 +475,10 @@
|
|||||||
fd.directory in (shell_config_directories))
|
fd.directory in (shell_config_directories))
|
||||||
and not proc.name in (shell_binaries)
|
and not proc.name in (shell_binaries)
|
||||||
and not exe_running_docker_save
|
and not exe_running_docker_save
|
||||||
|
exceptions:
|
||||||
|
- name: known_shell_conf_writers
|
||||||
|
fields: [proc.name, fd.name]
|
||||||
|
comps: [=, contains]
|
||||||
output: >
|
output: >
|
||||||
a shell configuration file has been modified (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline pcmdline=%proc.pcmdline file=%fd.name container_id=%container.id image=%container.image.repository)
|
a shell configuration file has been modified (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline pcmdline=%proc.pcmdline file=%fd.name container_id=%container.id image=%container.image.repository)
|
||||||
priority:
|
priority:
|
||||||
@@ -482,6 +501,10 @@
|
|||||||
fd.name in (shell_config_files) or
|
fd.name in (shell_config_files) or
|
||||||
fd.directory in (shell_config_directories)) and
|
fd.directory in (shell_config_directories)) and
|
||||||
(not proc.name in (shell_binaries))
|
(not proc.name in (shell_binaries))
|
||||||
|
exceptions:
|
||||||
|
- name: known_shell_conf_readers
|
||||||
|
fields: [proc.name, fd.name]
|
||||||
|
comps: [=, contains]
|
||||||
output: >
|
output: >
|
||||||
a shell configuration file was read by a non-shell program (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline file=%fd.name container_id=%container.id image=%container.image.repository)
|
a shell configuration file was read by a non-shell program (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline file=%fd.name container_id=%container.id image=%container.image.repository)
|
||||||
priority:
|
priority:
|
||||||
@@ -501,6 +524,10 @@
|
|||||||
(spawned_process and proc.name = "crontab")) and
|
(spawned_process and proc.name = "crontab")) and
|
||||||
consider_all_cron_jobs and
|
consider_all_cron_jobs and
|
||||||
not user_known_cron_jobs
|
not user_known_cron_jobs
|
||||||
|
exceptions:
|
||||||
|
- name: known_cron_writer
|
||||||
|
fields: [proc.name, fd.name]
|
||||||
|
comps: [=, contains]
|
||||||
output: >
|
output: >
|
||||||
Cron jobs were scheduled to run (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline
|
Cron jobs were scheduled to run (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline
|
||||||
file=%fd.name container_id=%container.id container_name=%container.name image=%container.image.repository:%container.image.tag)
|
file=%fd.name container_id=%container.id container_name=%container.name image=%container.image.repository:%container.image.tag)
|
||||||
@@ -609,9 +636,6 @@
|
|||||||
(proc.cmdline startswith "sed -ri" or proc.cmdline startswith "sed -i") 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))
|
(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: parent_Xvfb_running_xkbcomp
|
- macro: parent_Xvfb_running_xkbcomp
|
||||||
condition: (proc.pname=Xvfb and proc.cmdline startswith 'sh -c "/usr/bin/xkbcomp"')
|
condition: (proc.pname=Xvfb and proc.cmdline startswith 'sh -c "/usr/bin/xkbcomp"')
|
||||||
|
|
||||||
@@ -714,25 +738,6 @@
|
|||||||
- macro: parent_supervise_running_multilog
|
- macro: parent_supervise_running_multilog
|
||||||
condition: (proc.name=multilog and proc.pname=supervise)
|
condition: (proc.name=multilog and proc.pname=supervise)
|
||||||
|
|
||||||
- macro: supervise_writing_status
|
|
||||||
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)
|
|
||||||
|
|
||||||
- macro: htpasswd_writing_passwd
|
|
||||||
condition: (proc.name=htpasswd and fd.name=/etc/nginx/.htpasswd)
|
|
||||||
|
|
||||||
- macro: lvprogs_writing_conf
|
|
||||||
condition: >
|
|
||||||
(proc.name in (dmeventd,lvcreate,pvscan,lvs) and
|
|
||||||
(fd.name startswith /etc/lvm/archive or
|
|
||||||
fd.name startswith /etc/lvm/backup or
|
|
||||||
fd.name startswith /etc/lvm/cache))
|
|
||||||
|
|
||||||
- macro: ovsdb_writing_openvswitch
|
|
||||||
condition: (proc.name=ovsdb-server and fd.directory=/etc/openvswitch)
|
|
||||||
|
|
||||||
- macro: perl_running_plesk
|
- macro: perl_running_plesk
|
||||||
condition: (proc.cmdline startswith "perl /opt/psa/admin/bin/plesk_agent_manager" or
|
condition: (proc.cmdline startswith "perl /opt/psa/admin/bin/plesk_agent_manager" or
|
||||||
proc.pcmdline startswith "perl /opt/psa/admin/bin/plesk_agent_manager")
|
proc.pcmdline startswith "perl /opt/psa/admin/bin/plesk_agent_manager")
|
||||||
@@ -761,9 +766,6 @@
|
|||||||
((proc.name=consul-template and fd.name startswith /etc/haproxy) or
|
((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)
|
|
||||||
|
|
||||||
- list: ms_oms_binaries
|
- list: ms_oms_binaries
|
||||||
items: [omi.postinst, omsconfig.posti, scx.postinst, omsadmin.sh, omiagent]
|
items: [omi.postinst, omsconfig.posti, scx.postinst, omsadmin.sh, omiagent]
|
||||||
|
|
||||||
@@ -774,44 +776,9 @@
|
|||||||
or proc.aname[2] 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)
|
|
||||||
|
|
||||||
- macro: azure_scripts_writing_conf
|
|
||||||
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)
|
|
||||||
|
|
||||||
- macro: couchdb_writing_conf
|
- 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)
|
|
||||||
|
|
||||||
- macro: slapadd_writing_conf
|
|
||||||
condition: (proc.name=slapadd and fd.name startswith /etc/ldap)
|
|
||||||
|
|
||||||
- macro: openldap_writing_conf
|
|
||||||
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)
|
|
||||||
|
|
||||||
- macro: iscsi_writing_conf
|
|
||||||
condition: (proc.name=iscsiadm and fd.name startswith /etc/iscsi)
|
|
||||||
|
|
||||||
- macro: istio_writing_conf
|
|
||||||
condition: (proc.name=pilot-agent and fd.name startswith /etc/istio)
|
|
||||||
|
|
||||||
- macro: symantec_writing_conf
|
|
||||||
condition: >
|
|
||||||
((proc.name=symcfgd and fd.name startswith /etc/symantec) or
|
|
||||||
(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))
|
|
||||||
|
|
||||||
- macro: rancher_agent
|
- 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")
|
||||||
|
|
||||||
@@ -823,20 +790,6 @@
|
|||||||
(proc.name=urlgrabber-ext- and proc.aname[3]=sosreport and
|
(proc.name=urlgrabber-ext- and proc.aname[3]=sosreport and
|
||||||
(fd.name startswith /etc/pkt/nssdb or fd.name startswith /etc/pki/nssdb))
|
(fd.name startswith /etc/pkt/nssdb or fd.name startswith /etc/pki/nssdb))
|
||||||
|
|
||||||
- macro: pkgmgmt_progs_writing_pki
|
|
||||||
condition: >
|
|
||||||
(proc.name=urlgrabber-ext- and proc.pname in (yum, yum-cron, repoquery) and
|
|
||||||
(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)
|
|
||||||
|
|
||||||
- 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)
|
|
||||||
|
|
||||||
- list: veritas_binaries
|
- 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]
|
||||||
|
|
||||||
@@ -849,27 +802,15 @@
|
|||||||
- macro: veritas_writing_config
|
- 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))
|
|
||||||
|
|
||||||
- macro: nginx_writing_certs
|
- macro: nginx_writing_certs
|
||||||
condition: >
|
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)
|
|
||||||
|
|
||||||
- macro: centrify_writing_krb
|
|
||||||
condition: (proc.name in (adjoin,addns) and fd.name startswith /etc/krb5)
|
|
||||||
|
|
||||||
- macro: cockpit_writing_conf
|
- macro: cockpit_writing_conf
|
||||||
condition: >
|
condition: >
|
||||||
((proc.pname=cockpit-kube-la or proc.aname[2]=cockpit-kube-la)
|
((proc.pname=cockpit-kube-la or proc.aname[2]=cockpit-kube-la)
|
||||||
and fd.name startswith /etc/cockpit)
|
and fd.name startswith /etc/cockpit)
|
||||||
|
|
||||||
- macro: ipsec_writing_conf
|
|
||||||
condition: (proc.name=start-ipsec.sh and fd.directory=/etc/ipsec)
|
|
||||||
|
|
||||||
- macro: exe_running_docker_save
|
- macro: exe_running_docker_save
|
||||||
condition: >
|
condition: >
|
||||||
proc.name = "exe"
|
proc.name = "exe"
|
||||||
@@ -877,51 +818,24 @@
|
|||||||
or proc.cmdline contains "/var/run/docker")
|
or proc.cmdline contains "/var/run/docker")
|
||||||
and proc.pname in (dockerd, docker, dockerd-current, docker-current)
|
and proc.pname in (dockerd, docker, dockerd-current, docker-current)
|
||||||
|
|
||||||
# Ideally we'd have a length check here as well but sysdig
|
|
||||||
# filterchecks don't have operators like len()
|
|
||||||
- macro: sed_temporary_file
|
|
||||||
condition: (proc.name=sed and fd.name startswith "/etc/sed")
|
|
||||||
|
|
||||||
- macro: python_running_get_pip
|
- macro: python_running_get_pip
|
||||||
condition: (proc.cmdline startswith "python get-pip.py")
|
condition: (proc.cmdline startswith "python get-pip.py")
|
||||||
|
|
||||||
- macro: python_running_ms_oms
|
- macro: python_running_ms_oms
|
||||||
condition: (proc.cmdline startswith "python /var/lib/waagent/")
|
condition: (proc.cmdline startswith "python /var/lib/waagent/")
|
||||||
|
|
||||||
- macro: gugent_writing_guestagent_log
|
|
||||||
condition: (proc.name=gugent and fd.name=GuestAgent.log)
|
|
||||||
|
|
||||||
- macro: dse_writing_tmp
|
|
||||||
condition: (proc.name=dse-entrypoint and fd.name=/root/tmp__)
|
|
||||||
|
|
||||||
- macro: zap_writing_state
|
- macro: zap_writing_state
|
||||||
condition: (proc.name=java and proc.cmdline contains "jar /zap" and fd.name startswith /root/.ZAP)
|
condition: (proc.name=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)
|
|
||||||
|
|
||||||
- macro: rpm_writing_root_rpmdb
|
|
||||||
condition: (proc.name=rpm and fd.directory=/root/.rpmdb)
|
|
||||||
|
|
||||||
- macro: maven_writing_groovy
|
- macro: maven_writing_groovy
|
||||||
condition: (proc.name=java and proc.cmdline contains "classpath /usr/local/apache-maven" and fd.name startswith /root/.groovy)
|
condition: (proc.name=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)
|
|
||||||
|
|
||||||
- macro: kubectl_writing_state
|
|
||||||
condition: (proc.name in (kubectl,oc) and fd.name startswith /root/.kube)
|
|
||||||
|
|
||||||
- macro: java_running_cassandra
|
- macro: java_running_cassandra
|
||||||
condition: (proc.name=java and proc.cmdline contains "cassandra.jar")
|
condition: (proc.name=java and proc.cmdline contains "cassandra.jar")
|
||||||
|
|
||||||
- macro: cassandra_writing_state
|
- macro: cassandra_writing_state
|
||||||
condition: (java_running_cassandra and fd.directory=/root/.cassandra)
|
condition: (java_running_cassandra and fd.directory=/root/.cassandra)
|
||||||
|
|
||||||
# Istio
|
|
||||||
- macro: galley_writing_state
|
|
||||||
condition: (proc.name=galley and fd.name in (known_istio_files))
|
|
||||||
|
|
||||||
- list: known_istio_files
|
- list: known_istio_files
|
||||||
items: [/healthready, /healthliveness]
|
items: [/healthready, /healthliveness]
|
||||||
|
|
||||||
@@ -956,6 +870,12 @@
|
|||||||
and not package_mgmt_ancestor_procs
|
and not package_mgmt_ancestor_procs
|
||||||
and not exe_running_docker_save
|
and not exe_running_docker_save
|
||||||
and not user_known_update_package_registry
|
and not user_known_update_package_registry
|
||||||
|
exceptions:
|
||||||
|
- name: package_repo_filenames
|
||||||
|
fields: [proc.name, fd.name]
|
||||||
|
comps: [=, contains]
|
||||||
|
- name: package_repo_dirs
|
||||||
|
fields: [proc.name, fd.directory]
|
||||||
output: >
|
output: >
|
||||||
Repository files get updated (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline pcmdline=%proc.pcmdline file=%fd.name newpath=%evt.arg.newpath container_id=%container.id image=%container.image.repository)
|
Repository files get updated (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline pcmdline=%proc.pcmdline file=%fd.name newpath=%evt.arg.newpath container_id=%container.id image=%container.image.repository)
|
||||||
priority:
|
priority:
|
||||||
@@ -977,6 +897,10 @@
|
|||||||
and not python_running_get_pip
|
and not python_running_get_pip
|
||||||
and not python_running_ms_oms
|
and not python_running_ms_oms
|
||||||
and not user_known_write_below_binary_dir_activities
|
and not user_known_write_below_binary_dir_activities
|
||||||
|
exceptions:
|
||||||
|
- name: known_bin_writers
|
||||||
|
fields: [proc.name, fd.name]
|
||||||
|
comps: [=, contains]
|
||||||
output: >
|
output: >
|
||||||
File below a known binary directory opened for writing (user=%user.name user_loginuid=%user.loginuid
|
File below a known binary directory opened for writing (user=%user.name user_loginuid=%user.loginuid
|
||||||
command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline gparent=%proc.aname[2] container_id=%container.id image=%container.image.repository)
|
command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline gparent=%proc.aname[2] container_id=%container.id image=%container.image.repository)
|
||||||
@@ -998,13 +922,6 @@
|
|||||||
- macro: user_ssh_directory
|
- macro: user_ssh_directory
|
||||||
condition: (fd.name startswith '/home' and fd.name contains '.ssh')
|
condition: (fd.name startswith '/home' and fd.name contains '.ssh')
|
||||||
|
|
||||||
# google_accounts_(daemon)
|
|
||||||
- macro: google_accounts_daemon_writing_ssh
|
|
||||||
condition: (proc.name=google_accounts and user_ssh_directory)
|
|
||||||
|
|
||||||
- macro: cloud_init_writing_ssh
|
|
||||||
condition: (proc.name=cloud-init and user_ssh_directory)
|
|
||||||
|
|
||||||
- macro: mkinitramfs_writing_boot
|
- 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)
|
||||||
|
|
||||||
@@ -1028,13 +945,22 @@
|
|||||||
condition: >
|
condition: >
|
||||||
evt.dir = < and open_write and monitored_dir
|
evt.dir = < and open_write and monitored_dir
|
||||||
and not package_mgmt_procs
|
and not package_mgmt_procs
|
||||||
and not coreos_write_ssh_dir
|
|
||||||
and not exe_running_docker_save
|
and not exe_running_docker_save
|
||||||
and not python_running_get_pip
|
and not python_running_get_pip
|
||||||
and not python_running_ms_oms
|
and not python_running_ms_oms
|
||||||
and not google_accounts_daemon_writing_ssh
|
|
||||||
and not cloud_init_writing_ssh
|
|
||||||
and not user_known_write_monitored_dir_conditions
|
and not user_known_write_monitored_dir_conditions
|
||||||
|
exceptions:
|
||||||
|
- name: known_writer_prefix
|
||||||
|
fields: [proc.name, fd.name]
|
||||||
|
comps: [=, startswith]
|
||||||
|
values:
|
||||||
|
- [update-ssh-keys, /home/core/.ssh]
|
||||||
|
- name: known_writer_prefix_substring
|
||||||
|
fields: [proc.name, fd.name, fd.name]
|
||||||
|
comps: [=, startswith, contains]
|
||||||
|
values:
|
||||||
|
- [google_accounts, /home, .ssh]
|
||||||
|
- [cloud-init, /home, .ssh]
|
||||||
output: >
|
output: >
|
||||||
File below a monitored directory opened for writing (user=%user.name user_loginuid=%user.loginuid
|
File below a monitored directory opened for writing (user=%user.name user_loginuid=%user.loginuid
|
||||||
command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline gparent=%proc.aname[2] container_id=%container.id image=%container.image.repository)
|
command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline gparent=%proc.aname[2] container_id=%container.id image=%container.image.repository)
|
||||||
@@ -1058,6 +984,10 @@
|
|||||||
(user_ssh_directory or fd.name startswith /root/.ssh) 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))
|
not proc.name in (ssh_binaries))
|
||||||
|
exceptions:
|
||||||
|
- name: known_ssh_reader
|
||||||
|
fields: [proc.name, fd.name]
|
||||||
|
comps: [=, contains]
|
||||||
output: >
|
output: >
|
||||||
ssh-related file/directory read by non-ssh program (user=%user.name user_loginuid=%user.loginuid
|
ssh-related file/directory read by non-ssh program (user=%user.name user_loginuid=%user.loginuid
|
||||||
command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline container_id=%container.id image=%container.image.repository)
|
command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline container_id=%container.id image=%container.image.repository)
|
||||||
@@ -1067,43 +997,15 @@
|
|||||||
- list: safe_etc_dirs
|
- 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]
|
items: [/etc/cassandra, /etc/ssl/certs/java, /etc/logstash, /etc/nginx/conf.d, /etc/container_environment, /etc/hrmconfig, /etc/fluent/configs.d]
|
||||||
|
|
||||||
- macro: fluentd_writing_conf_files
|
|
||||||
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)
|
|
||||||
|
|
||||||
- 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)
|
|
||||||
|
|
||||||
- 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")
|
|
||||||
|
|
||||||
- macro: plesk_running_mktemp
|
- macro: plesk_running_mktemp
|
||||||
condition: (proc.name=mktemp and proc.aname[3] in (plesk_binaries))
|
condition: (proc.name=mktemp and proc.aname[3] in (plesk_binaries))
|
||||||
|
|
||||||
- macro: networkmanager_writing_resolv_conf
|
- macro: networkmanager_writing_resolv_conf
|
||||||
condition: proc.aname[2]=nm-dispatcher and fd.name=/etc/resolv.conf
|
condition: proc.aname[2]=nm-dispatcher and fd.name=/etc/resolv.conf
|
||||||
|
|
||||||
- macro: add_shell_writing_shells_tmp
|
|
||||||
condition: (proc.name=add-shell and fd.name=/etc/shells.tmp)
|
|
||||||
|
|
||||||
- macro: duply_writing_exclude_files
|
- 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")
|
|
||||||
|
|
||||||
- macro: rancher_writing_conf
|
- macro: rancher_writing_conf
|
||||||
condition: ((proc.name in (healthcheck, lb-controller, rancher-dns)) and
|
condition: ((proc.name in (healthcheck, lb-controller, rancher-dns)) and
|
||||||
(container.image.repository contains "rancher/healthcheck" or
|
(container.image.repository contains "rancher/healthcheck" or
|
||||||
@@ -1116,11 +1018,6 @@
|
|||||||
(container.image.repository contains "rancher/metadata" or container.image.repository contains "rancher/lb-service-haproxy") and
|
(container.image.repository contains "rancher/metadata" or container.image.repository contains "rancher/lb-service-haproxy") and
|
||||||
fd.name startswith "/answers.json")
|
fd.name startswith "/answers.json")
|
||||||
|
|
||||||
- macro: checkpoint_writing_state
|
|
||||||
condition: (proc.name=checkpoint and
|
|
||||||
container.image.repository contains "coreos/pod-checkpointer" and
|
|
||||||
fd.name startswith "/etc/kubernetes")
|
|
||||||
|
|
||||||
- macro: jboss_in_container_writing_passwd
|
- macro: jboss_in_container_writing_passwd
|
||||||
condition: >
|
condition: >
|
||||||
((proc.cmdline="run-java.sh /opt/jboss/container/java/run/run-java.sh"
|
((proc.cmdline="run-java.sh /opt/jboss/container/java/run/run-java.sh"
|
||||||
@@ -1128,41 +1025,6 @@
|
|||||||
and container
|
and container
|
||||||
and fd.name=/etc/passwd)
|
and fd.name=/etc/passwd)
|
||||||
|
|
||||||
- macro: curl_writing_pki_db
|
|
||||||
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))
|
|
||||||
|
|
||||||
- macro: java_writing_conf
|
|
||||||
condition: (proc.name=java and fd.name=/etc/.java/.systemPrefs/.system.lock)
|
|
||||||
|
|
||||||
- macro: rabbitmq_writing_conf
|
|
||||||
condition: (proc.name=rabbitmq-server and fd.directory=/etc/rabbitmq)
|
|
||||||
|
|
||||||
- macro: rook_writing_conf
|
|
||||||
condition: (proc.name=toolbox.sh and container.image.repository=rook/toolbox
|
|
||||||
and fd.directory=/etc/ceph)
|
|
||||||
|
|
||||||
- macro: httpd_writing_conf_logs
|
|
||||||
condition: (proc.name=httpd and fd.name startswith /etc/httpd/)
|
|
||||||
|
|
||||||
- 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))
|
|
||||||
|
|
||||||
- macro: redis_writing_conf
|
|
||||||
condition: >
|
|
||||||
(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)
|
|
||||||
|
|
||||||
- macro: php_handlers_writing_conf
|
|
||||||
condition: (proc.name=php_handlers_co and fd.name=/etc/psa/php_versions.json)
|
|
||||||
|
|
||||||
- macro: sed_writing_temp_file
|
- macro: sed_writing_temp_file
|
||||||
condition: >
|
condition: >
|
||||||
((proc.aname[3]=cron_start.sh and fd.name startswith /etc/security/sed) or
|
((proc.aname[3]=cron_start.sh and fd.name startswith /etc/security/sed) or
|
||||||
@@ -1170,55 +1032,18 @@
|
|||||||
fd.name startswith /etc/apt/sed or
|
fd.name startswith /etc/apt/sed or
|
||||||
fd.name startswith /etc/apt/apt.conf.d/sed)))
|
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)
|
|
||||||
|
|
||||||
# In some cases dpkg-reconfigur runs commands that modify /etc. Not
|
# In some cases dpkg-reconfigur runs commands that modify /etc. Not
|
||||||
# putting the full set of package management programs yet.
|
# putting the full set of package management programs yet.
|
||||||
- macro: dpkg_scripting
|
- macro: dpkg_scripting
|
||||||
condition: (proc.aname[2] in (dpkg-reconfigur, dpkg-preconfigu))
|
condition: (proc.aname[2] in (dpkg-reconfigur, dpkg-preconfigu))
|
||||||
|
|
||||||
- macro: ufw_writing_conf
|
|
||||||
condition: (proc.name=ufw and fd.directory=/etc/ufw)
|
|
||||||
|
|
||||||
- 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))
|
|
||||||
and fd.name startswith /etc/calico)
|
|
||||||
|
|
||||||
- macro: prometheus_conf_writing_conf
|
|
||||||
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=keepalived and fd.name=/etc/keepalived/keepalived.conf)
|
|
||||||
|
|
||||||
- macro: etcd_manager_updating_dns
|
- macro: etcd_manager_updating_dns
|
||||||
condition: (container and proc.name=etcd-manager and fd.name=/etc/hosts)
|
condition: (container and proc.name=etcd-manager and fd.name=/etc/hosts)
|
||||||
|
|
||||||
- macro: automount_using_mtab
|
|
||||||
condition: (proc.pname = automount and fd.name startswith /etc/mtab)
|
|
||||||
|
|
||||||
- macro: mcafee_writing_cma_d
|
|
||||||
condition: (proc.name=macompatsvc and fd.directory=/etc/cma.d)
|
|
||||||
|
|
||||||
- macro: avinetworks_supervisor_writing_ssh
|
|
||||||
condition: >
|
|
||||||
(proc.cmdline="se_supervisor.p /opt/avi/scripts/se_supervisor.py -d" and
|
|
||||||
(fd.name startswith /etc/ssh/known_host_ or
|
|
||||||
fd.name startswith /etc/ssh/ssh_monitor_config_ or
|
|
||||||
fd.name startswith /etc/ssh/ssh_config_))
|
|
||||||
|
|
||||||
# Add conditions to this macro (probably in a separate file,
|
# Add conditions to this macro (probably in a separate file,
|
||||||
# overwriting this macro) to allow for specific combinations of
|
# overwriting this macro) to allow for specific combinations of
|
||||||
# programs writing below specific directories below
|
# programs writing below specific directories below
|
||||||
# /etc. fluentd_writing_conf_files is a good example to follow, as it
|
# /etc.
|
||||||
# specifies both the program doing the writing as well as the specific
|
|
||||||
# files it is allowed to modify.
|
|
||||||
#
|
#
|
||||||
# In this file, it just takes one of the programs in the base macro
|
# In this file, it just takes one of the programs in the base macro
|
||||||
# and repeats it.
|
# and repeats it.
|
||||||
@@ -1234,110 +1059,206 @@
|
|||||||
condition: >
|
condition: >
|
||||||
etc_dir and evt.dir = < and open_write
|
etc_dir and evt.dir = < and open_write
|
||||||
and proc_name_exists
|
and proc_name_exists
|
||||||
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,
|
|
||||||
openshift-launc, update-rc.d, puppet)
|
|
||||||
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 (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 sed_temporary_file
|
|
||||||
and not exe_running_docker_save
|
and not exe_running_docker_save
|
||||||
and not ansible_running_python
|
and not ansible_running_python
|
||||||
and not python_running_denyhosts
|
and not python_running_denyhosts
|
||||||
and not fluentd_writing_conf_files
|
|
||||||
and not user_known_write_etc_conditions
|
and not user_known_write_etc_conditions
|
||||||
and not run_by_centrify
|
and not run_by_centrify
|
||||||
and not run_by_adclient
|
and not run_by_adclient
|
||||||
and not qualys_writing_conf_files
|
|
||||||
and not git_writing_nssdb
|
|
||||||
and not plesk_writing_keys
|
|
||||||
and not plesk_install_writing_apache_conf
|
|
||||||
and not plesk_running_mktemp
|
and not plesk_running_mktemp
|
||||||
and not networkmanager_writing_resolv_conf
|
and not networkmanager_writing_resolv_conf
|
||||||
and not run_by_chef
|
and not run_by_chef
|
||||||
and not add_shell_writing_shells_tmp
|
|
||||||
and not duply_writing_exclude_files
|
and not duply_writing_exclude_files
|
||||||
and not xmlcatalog_writing_files
|
|
||||||
and not parent_supervise_running_multilog
|
and not parent_supervise_running_multilog
|
||||||
and not supervise_writing_status
|
|
||||||
and not pki_realm_writing_realms
|
|
||||||
and not htpasswd_writing_passwd
|
|
||||||
and not lvprogs_writing_conf
|
|
||||||
and not ovsdb_writing_openvswitch
|
|
||||||
and not datadog_writing_conf
|
|
||||||
and not curl_writing_pki_db
|
|
||||||
and not haproxy_writing_conf
|
|
||||||
and not java_writing_conf
|
|
||||||
and not dpkg_scripting
|
and not dpkg_scripting
|
||||||
and not parent_ucf_writing_conf
|
and not parent_ucf_writing_conf
|
||||||
and not rabbitmq_writing_conf
|
|
||||||
and not rook_writing_conf
|
|
||||||
and not php_handlers_writing_conf
|
|
||||||
and not sed_writing_temp_file
|
and not sed_writing_temp_file
|
||||||
and not cron_start_writing_pam_env
|
|
||||||
and not httpd_writing_conf_logs
|
|
||||||
and not mysql_writing_conf
|
|
||||||
and not openvpn_writing_conf
|
|
||||||
and not consul_template_writing_conf
|
and not consul_template_writing_conf
|
||||||
and not countly_writing_nginx_conf
|
|
||||||
and not ms_oms_writing_conf
|
and not ms_oms_writing_conf
|
||||||
and not ms_scx_writing_conf
|
|
||||||
and not azure_scripts_writing_conf
|
|
||||||
and not azure_networkwatcher_writing_conf
|
|
||||||
and not couchdb_writing_conf
|
and not couchdb_writing_conf
|
||||||
and not update_texmf_writing_conf
|
|
||||||
and not slapadd_writing_conf
|
|
||||||
and not symantec_writing_conf
|
|
||||||
and not liveupdate_writing_conf
|
|
||||||
and not sosreport_writing_files
|
and not sosreport_writing_files
|
||||||
and not selinux_writing_conf
|
|
||||||
and not veritas_writing_config
|
and not veritas_writing_config
|
||||||
and not nginx_writing_conf
|
|
||||||
and not nginx_writing_certs
|
and not nginx_writing_certs
|
||||||
and not chef_client_writing_conf
|
|
||||||
and not centrify_writing_krb
|
|
||||||
and not cockpit_writing_conf
|
and not cockpit_writing_conf
|
||||||
and not ipsec_writing_conf
|
|
||||||
and not httpd_writing_ssl_conf
|
and not httpd_writing_ssl_conf
|
||||||
and not userhelper_writing_etc_security
|
|
||||||
and not pkgmgmt_progs_writing_pki
|
|
||||||
and not update_ca_trust_writing_pki
|
|
||||||
and not brandbot_writing_os_release
|
|
||||||
and not redis_writing_conf
|
|
||||||
and not openldap_writing_conf
|
|
||||||
and not ucpagent_writing_conf
|
|
||||||
and not iscsi_writing_conf
|
|
||||||
and not istio_writing_conf
|
|
||||||
and not ufw_writing_conf
|
|
||||||
and not calico_writing_conf
|
|
||||||
and not calico_writing_envvars
|
and not calico_writing_envvars
|
||||||
and not prometheus_conf_writing_conf
|
|
||||||
and not openshift_writing_conf
|
|
||||||
and not keepalived_writing_conf
|
|
||||||
and not rancher_writing_conf
|
and not rancher_writing_conf
|
||||||
and not checkpoint_writing_state
|
|
||||||
and not jboss_in_container_writing_passwd
|
and not jboss_in_container_writing_passwd
|
||||||
and not etcd_manager_updating_dns
|
and not etcd_manager_updating_dns
|
||||||
and not user_known_write_below_etc_activities
|
and not user_known_write_below_etc_activities
|
||||||
and not automount_using_mtab
|
|
||||||
and not mcafee_writing_cma_d
|
|
||||||
and not avinetworks_supervisor_writing_ssh
|
|
||||||
|
|
||||||
- rule: Write below etc
|
- rule: Write below etc
|
||||||
desc: an attempt to write to any file below /etc
|
desc: an attempt to write to any file below /etc
|
||||||
condition: write_etc_common
|
condition: write_etc_common
|
||||||
output: "File below /etc opened for writing (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline parent=%proc.pname pcmdline=%proc.pcmdline file=%fd.name program=%proc.name gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] container_id=%container.id image=%container.image.repository)"
|
output: "File below /etc opened for writing (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline parent=%proc.pname pcmdline=%proc.pcmdline file=%fd.name program=%proc.name gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] container_id=%container.id image=%container.image.repository)"
|
||||||
|
exceptions:
|
||||||
|
- name: proc_names
|
||||||
|
fields: proc.name
|
||||||
|
values:
|
||||||
|
- [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,
|
||||||
|
openshift-launc, update-rc.d, puppet]
|
||||||
|
- name: proc_pnames
|
||||||
|
fields: proc.pname
|
||||||
|
values: [sysdigcloud_binaries, mail_config_binaries, hddtemp.postins,
|
||||||
|
sshkit_script_binaries, locales.postins, deb_binaries, dhcp_binaries]
|
||||||
|
- name: dirs
|
||||||
|
fields: fd.name
|
||||||
|
comps: pmatch
|
||||||
|
values: [safe_etc_dirs]
|
||||||
|
- name: files
|
||||||
|
fields: fd.name
|
||||||
|
values: [/etc/container_environment.sh, /etc/container_environment.json, /etc/motd, /etc/motd.svc]
|
||||||
|
- name: proc_file
|
||||||
|
fields: [proc.name, fd.name]
|
||||||
|
comps: [in, in]
|
||||||
|
values:
|
||||||
|
- [[qualys-cloud-ag], [/etc/qualys/cloud-agent/qagent-log.conf]]
|
||||||
|
- [[add-shell], [/etc/shells.tmp]]
|
||||||
|
- [[htpasswd], [/etc/nginx/.htpasswd]]
|
||||||
|
- [[java], [/etc/.java/.systemPrefs/.system.lock]]
|
||||||
|
- [[php_handlers_co], [/etc/psa/php_versions.json]]
|
||||||
|
- [[NetworkWatcherA], [/etc/init.d/AzureNetworkWatcherAgent]]
|
||||||
|
- [[navdefutil], [/etc/symc-defutils.conf]]
|
||||||
|
- [[brandbot], [/etc/os-release]]
|
||||||
|
- [[keepalived], [/etc/keepalived/keepalived.conf]]
|
||||||
|
- [[update-haproxy-,haproxy_reload.], [/etc/openvpn/client.map]]
|
||||||
|
- [[start-fluentd], [/etc/fluent/fluent.conf, /etc/td-agent/td-agent.conf]]
|
||||||
|
- name: proc_file_prefix
|
||||||
|
fields: [proc.name, fd.name]
|
||||||
|
comps: [in, startswith]
|
||||||
|
values:
|
||||||
|
- [[sed], /etc/sed]
|
||||||
|
- [[httpd], /etc/httpd/]
|
||||||
|
- [[GetLinuxOS.sh], /etc/opt/microsoft/scx]
|
||||||
|
- [[update-texmf], /etc/texmf]
|
||||||
|
- [[slapadd], /etc/ldap]
|
||||||
|
- [[symcfgd], /etc/symantec]
|
||||||
|
- [[userhelper], /etc/security]
|
||||||
|
- [[iscsiadm], /etc/iscsi]
|
||||||
|
- [[pilot-agent], /etc/istio]
|
||||||
|
- [[calico-node], /etc/calico]
|
||||||
|
- [[prometheus-conf], /etc/prometheus/config_out]
|
||||||
|
- [[oc], /etc/origin/node]
|
||||||
|
- [[plesk_binaries], /etc/sw/keys]
|
||||||
|
- [[supervice,svc], /etc/sb/]
|
||||||
|
- [[openvpn,openvpn-entrypo], /etc/openvpn]
|
||||||
|
- [[semodule,genhomedircon,sefcontext_comp], /etc/selinux]
|
||||||
|
- [[dmeventd,lvcreate,pvscan,lvs], /etc/lvm/archive]
|
||||||
|
- [[dmeventd,lvcreate,pvscan,lvs], /etc/lvm/backup]
|
||||||
|
- [[dmeventd,lvcreate,pvscan,lvs], /etc/lvm/cache]
|
||||||
|
- [[nginx,nginx-ingress-c,nginx-ingress], /etc/nginx]
|
||||||
|
- [[nginx,nginx-ingress-c,nginx-ingress], /etc/ingress-controller]
|
||||||
|
- [[adjoin,addns], /etc/krb5]
|
||||||
|
- [[run-redis, redis-launcher.], /etc/redis]
|
||||||
|
- [[update-haproxy-,haproxy_reload.], /etc/haproxy]
|
||||||
|
- [[start-mysql.sh, run-mysqld], /etc/mysql]
|
||||||
|
- name: proc_directory
|
||||||
|
fields: [proc.name, fd.directory]
|
||||||
|
comps: [in, in]
|
||||||
|
values:
|
||||||
|
- [[git-remote-http], [/etc/pki/nssdb]]
|
||||||
|
- [[update-xmlcatal], [/etc/xml]]
|
||||||
|
- [[ovsdb-server], [/etc/openvswitch]]
|
||||||
|
- [[curl], [/etc/pki/nssdb]]
|
||||||
|
- [[rabbitmq-server], [/etc/rabbitmq]]
|
||||||
|
- [[start-ipsec.sh], [/etc/ipsec]]
|
||||||
|
- [[ufw], [/etc/ufw]]
|
||||||
|
- [[macompatsvc], [/etc/cma.d]]
|
||||||
|
- [[start-mysql.sh, run-mysqld], [/etc/my.cnf.d]]
|
||||||
|
- name: pname_file
|
||||||
|
fields: [proc.pname, fd.name]
|
||||||
|
comps: [in, in]
|
||||||
|
fields:
|
||||||
|
- [[update-haproxy-,haproxy_reload,haproxy_reload.], [/etc/openvpn/client.map]]
|
||||||
|
- name: pname_file_prefix
|
||||||
|
fields: [proc.pname, fd.name]
|
||||||
|
comps: [in, startswith]
|
||||||
|
fields:
|
||||||
|
- [[run-openldap.sh], /etc/openldap]
|
||||||
|
- [[start-mysql.sh], /etc/mysql]
|
||||||
|
- [[update-haproxy-,haproxy_reload.], /etc/haproxy]
|
||||||
|
- name: pname_directory
|
||||||
|
fields: [proc.pname, fd.directory]
|
||||||
|
comps: [in, in]
|
||||||
|
fields:
|
||||||
|
- [[start-mysql.sh], [/etc/my.cnf.d]]
|
||||||
|
- name: pname_prefix_file_prefix
|
||||||
|
fields: [proc.pname, fd.name]
|
||||||
|
comps: [startswith, startswith]
|
||||||
|
fields:
|
||||||
|
- ["bash /var/lib/waagent/", /etc/azure]
|
||||||
|
- [automount, /etc/mtab]
|
||||||
|
- name: proc_pname_file
|
||||||
|
fields: [proc.name, proc.pname, fd.name]
|
||||||
|
comps: [in, in, startswith]
|
||||||
|
values:
|
||||||
|
- [[urlgrabber-ext-], [yum, yum-cron, repoquery], /etc/pkt/nssdb or fd.name startswith /etc/pki/nssdb))
|
||||||
|
- [[urlgrabber-ext-], [yum, yum-cron, repoquery], /etc/pki/nssdb]
|
||||||
|
- [[trust], [update-ca-trust], /etc/pki]
|
||||||
|
- name: cmdline_file
|
||||||
|
fields: [proc.cmdline, fd.name]
|
||||||
|
fields: [in, in]
|
||||||
|
values:
|
||||||
|
- [["bash /usr/sbin/start-cron"], [/etc/security/pam_env.conf]]
|
||||||
|
- name: cmdline_file_prefix
|
||||||
|
fields: [proc.cmdline, fd.name]
|
||||||
|
comps: [in, startswith]
|
||||||
|
values:
|
||||||
|
- [["bash /usr/sbin/start-cron"], /etc/security/pam_env.conf]
|
||||||
|
- [["se_supervisor.p /opt/avi/scripts/se_supervisor.py -d"], /etc/ssh/known_host_]
|
||||||
|
- [["se_supervisor.p /opt/avi/scripts/se_supervisor.py -d"], /etc/ssh/ssh_monitor_config_]
|
||||||
|
- [["se_supervisor.p /opt/avi/scripts/se_supervisor.py -d"], /etc/ssh/ssh_config_]
|
||||||
|
- name: cmdline_prefix_file
|
||||||
|
fields: [proc.cmdline, fd.name]
|
||||||
|
comps: [startswith, in]
|
||||||
|
values:
|
||||||
|
- ["bash -hB /usr/lib/plesk-9.0/services/webserver.apache configure", ["/etc/apache2/apache2.conf.tmp"]]
|
||||||
|
- ["java LiveUpdate", [/etc/liveupdate.conf]]
|
||||||
|
- ["java LiveUpdate", [/etc/Product.Catalog.JavaLiveUpdate]]
|
||||||
|
- name: cmdline_prefix_file_prefix
|
||||||
|
fields: [proc.cmdline, fd.name]
|
||||||
|
comps: [startswith, startswith]
|
||||||
|
values:
|
||||||
|
- ["bash /usr/local/lib/pki/pki-realm", /etc/pki/realms]
|
||||||
|
- ["python /opt/datadog-agent", "/etc/dd-agent"]
|
||||||
|
- ["entrypoint.sh /entrypoint.sh datadog start", "/etc/dd-agent"]
|
||||||
|
- ["agent.py /opt/datadog-agent", "/etc/dd-agent"]
|
||||||
|
- ["nodejs /opt/countly/bin", /etc/nginx]
|
||||||
|
- name: pcmdline_prefix_file_prefix
|
||||||
|
fields: [proc.pcmdline, fd.name]
|
||||||
|
comps: [startswith, startswith]
|
||||||
|
fields:
|
||||||
|
- ["bash /var/lib/waagent/", /etc/azure]
|
||||||
|
- ["chef-client /opt/gitlab", /etc/gitlab]
|
||||||
|
- name: proc_container_dir
|
||||||
|
fields: [proc.name, container.image.repository, fd.directory]
|
||||||
|
comps: [in, in, in]
|
||||||
|
values:
|
||||||
|
- [[toolbox.sh], [rook/toolbox], [/etc/ceph]]
|
||||||
|
- name: proc_container_file
|
||||||
|
fields: [proc.name, container.image.repository, fd.name]
|
||||||
|
comps: [in, in, in]
|
||||||
|
values:
|
||||||
|
- [[apiserver], [docker/ucp-agent], [/etc/authorization_config.cfg]]
|
||||||
|
- name: proc_container_prefix
|
||||||
|
fields: [proc.name, container.image.repository, fd.name]
|
||||||
|
comps: [in, in, startswith]
|
||||||
|
values:
|
||||||
|
- [[start_runit, cp], [gcr.io/projectcalico-org/node], /etc/calico]
|
||||||
|
- [[sed], [gcr.io/projectcalico-org/cni], /etc/calico]
|
||||||
|
- [[checkpoint], ["coreos/pod-checkpointer"], "/etc/kubernetes"]
|
||||||
priority: ERROR
|
priority: ERROR
|
||||||
tags: [filesystem, mitre_persistence]
|
tags: [filesystem, mitre_persistence]
|
||||||
|
|
||||||
@@ -1349,43 +1270,6 @@
|
|||||||
- list: known_root_directories
|
- list: known_root_directories
|
||||||
items: [/root/.oracle_jre_usage, /root/.ssh, /root/.subversion, /root/.nami]
|
items: [/root/.oracle_jre_usage, /root/.ssh, /root/.subversion, /root/.nami]
|
||||||
|
|
||||||
- macro: known_root_conditions
|
|
||||||
condition: (fd.name startswith /root/orcexec.
|
|
||||||
or fd.name startswith /root/.m2
|
|
||||||
or fd.name startswith /root/.npm
|
|
||||||
or fd.name startswith /root/.pki
|
|
||||||
or fd.name startswith /root/.ivy2
|
|
||||||
or fd.name startswith /root/.config/Cypress
|
|
||||||
or fd.name startswith /root/.config/pulse
|
|
||||||
or fd.name startswith /root/.config/configstore
|
|
||||||
or fd.name startswith /root/jenkins/workspace
|
|
||||||
or fd.name startswith /root/.jenkins
|
|
||||||
or fd.name startswith /root/.cache
|
|
||||||
or fd.name startswith /root/.sbt
|
|
||||||
or fd.name startswith /root/.java
|
|
||||||
or fd.name startswith /root/.glide
|
|
||||||
or fd.name startswith /root/.sonar
|
|
||||||
or fd.name startswith /root/.v8flag
|
|
||||||
or fd.name startswith /root/infaagent
|
|
||||||
or fd.name startswith /root/.local/lib/python
|
|
||||||
or fd.name startswith /root/.pm2
|
|
||||||
or fd.name startswith /root/.gnupg
|
|
||||||
or fd.name startswith /root/.pgpass
|
|
||||||
or fd.name startswith /root/.theano
|
|
||||||
or fd.name startswith /root/.gradle
|
|
||||||
or fd.name startswith /root/.android
|
|
||||||
or fd.name startswith /root/.ansible
|
|
||||||
or fd.name startswith /root/.crashlytics
|
|
||||||
or fd.name startswith /root/.dbus
|
|
||||||
or fd.name startswith /root/.composer
|
|
||||||
or fd.name startswith /root/.gconf
|
|
||||||
or fd.name startswith /root/.nv
|
|
||||||
or fd.name startswith /root/.local/share/jupyter
|
|
||||||
or fd.name startswith /root/oradiag_root
|
|
||||||
or fd.name startswith /root/workspace
|
|
||||||
or fd.name startswith /root/jvm
|
|
||||||
or fd.name startswith /root/.node-gyp)
|
|
||||||
|
|
||||||
# Add conditions to this macro (probably in a separate file,
|
# Add conditions to this macro (probably in a separate file,
|
||||||
# overwriting this macro) to allow for specific combinations of
|
# overwriting this macro) to allow for specific combinations of
|
||||||
# programs writing below specific directories below
|
# programs writing below specific directories below
|
||||||
@@ -1400,40 +1284,94 @@
|
|||||||
- macro: user_known_write_below_root_activities
|
- macro: user_known_write_below_root_activities
|
||||||
condition: (never_true)
|
condition: (never_true)
|
||||||
|
|
||||||
- macro: runc_writing_exec_fifo
|
|
||||||
condition: (proc.cmdline="runc:[1:CHILD] init" and fd.name=/exec.fifo)
|
|
||||||
|
|
||||||
- macro: runc_writing_var_lib_docker
|
- 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
|
- rule: Write below root
|
||||||
desc: an attempt to write to any file directly below / or /root
|
desc: an attempt to write to any file directly below / or /root
|
||||||
condition: >
|
condition: >
|
||||||
root_dir and evt.dir = < and open_write
|
root_dir and evt.dir = < and open_write
|
||||||
and proc_name_exists
|
and proc_name_exists
|
||||||
and not fd.name in (known_root_files)
|
|
||||||
and not fd.directory pmatch (known_root_directories)
|
|
||||||
and not exe_running_docker_save
|
and not exe_running_docker_save
|
||||||
and not gugent_writing_guestagent_log
|
|
||||||
and not dse_writing_tmp
|
|
||||||
and not zap_writing_state
|
and not zap_writing_state
|
||||||
and not airflow_writing_state
|
|
||||||
and not rpm_writing_root_rpmdb
|
|
||||||
and not maven_writing_groovy
|
and not maven_writing_groovy
|
||||||
and not chef_writing_conf
|
|
||||||
and not kubectl_writing_state
|
|
||||||
and not cassandra_writing_state
|
and not cassandra_writing_state
|
||||||
and not galley_writing_state
|
|
||||||
and not calico_writing_state
|
and not calico_writing_state
|
||||||
and not rancher_writing_root
|
and not rancher_writing_root
|
||||||
and not runc_writing_exec_fifo
|
|
||||||
and not mysqlsh_writing_state
|
|
||||||
and not known_root_conditions
|
|
||||||
and not user_known_write_root_conditions
|
and not user_known_write_root_conditions
|
||||||
and not user_known_write_below_root_activities
|
and not user_known_write_below_root_activities
|
||||||
|
exceptions:
|
||||||
|
- name: files
|
||||||
|
field: fd.name
|
||||||
|
values: [known_root_files]
|
||||||
|
- name: dirs
|
||||||
|
field: fd.directory
|
||||||
|
comps: pmatch
|
||||||
|
values: [known_root_directories]
|
||||||
|
- name: prefixes
|
||||||
|
field: [fd.name]
|
||||||
|
comps: [startswith]
|
||||||
|
values:
|
||||||
|
- [/root/orcexec.]
|
||||||
|
- [/root/.m2]
|
||||||
|
- [/root/.npm]
|
||||||
|
- [/root/.pki]
|
||||||
|
- [/root/.ivy2]
|
||||||
|
- [/root/.config/Cypress]
|
||||||
|
- [/root/.config/pulse]
|
||||||
|
- [/root/.config/configstore]
|
||||||
|
- [/root/jenkins/workspace]
|
||||||
|
- [/root/.jenkins]
|
||||||
|
- [/root/.cache]
|
||||||
|
- [/root/.sbt]
|
||||||
|
- [/root/.java]
|
||||||
|
- [/root/.glide]
|
||||||
|
- [/root/.sonar]
|
||||||
|
- [/root/.v8flag]
|
||||||
|
- [/root/infaagent]
|
||||||
|
- [/root/.local/lib/python]
|
||||||
|
- [/root/.pm2]
|
||||||
|
- [/root/.gnupg]
|
||||||
|
- [/root/.pgpass]
|
||||||
|
- [/root/.theano]
|
||||||
|
- [/root/.gradle]
|
||||||
|
- [/root/.android]
|
||||||
|
- [/root/.ansible]
|
||||||
|
- [/root/.crashlytics]
|
||||||
|
- [/root/.dbus]
|
||||||
|
- [/root/.composer]
|
||||||
|
- [/root/.gconf]
|
||||||
|
- [/root/.nv]
|
||||||
|
- [/root/.local/share/jupyter]
|
||||||
|
- [/root/oradiag_root]
|
||||||
|
- [/root/workspace]
|
||||||
|
- [/root/jvm]
|
||||||
|
- [/root/.node-gyp]
|
||||||
|
- name: proc_file
|
||||||
|
fields: [proc.name, fd.name]
|
||||||
|
comps: [in, in]
|
||||||
|
values:
|
||||||
|
- [[gugent], [GuestAgent.log]]
|
||||||
|
- [[dse-entrypoint], [/root/tmp__]]
|
||||||
|
- [[galley], [known_istio_files]]
|
||||||
|
- name: proc_directory
|
||||||
|
fields: [proc.name, fd.directory]
|
||||||
|
comps: [in, in]
|
||||||
|
values:
|
||||||
|
- [[rpm], [/root/.rpmdb]]
|
||||||
|
- [[mysqlsh], [/root/.mysqlsh]]
|
||||||
|
- name: proc_file_prefix
|
||||||
|
fields: [proc.name, fd.name]
|
||||||
|
comps: [in, startswith]
|
||||||
|
values:
|
||||||
|
- [[airflow], /root/airflow]
|
||||||
|
- [[chef-client], /root/.chef]
|
||||||
|
- [[kubectl, oc], /root/.kube]
|
||||||
|
- name: cmdline_file
|
||||||
|
fields: [proc.cmdline, fd.name]
|
||||||
|
comps: [in, in]
|
||||||
|
values:
|
||||||
|
- ["runc:[1:CHILD] init"], [/exec.fifo]]
|
||||||
output: "File below / or /root opened for writing (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline parent=%proc.pname file=%fd.name program=%proc.name container_id=%container.id image=%container.image.repository)"
|
output: "File below / or /root opened for writing (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline parent=%proc.pname file=%fd.name program=%proc.name container_id=%container.id image=%container.image.repository)"
|
||||||
priority: ERROR
|
priority: ERROR
|
||||||
tags: [filesystem, mitre_persistence]
|
tags: [filesystem, mitre_persistence]
|
||||||
@@ -2424,9 +2362,9 @@
|
|||||||
- rule: Contact K8S API Server From Container
|
- rule: Contact K8S API Server From Container
|
||||||
desc: Detect attempts to contact the K8S API Server from a container
|
desc: Detect attempts to contact the K8S API Server from a container
|
||||||
condition: >
|
condition: >
|
||||||
evt.type=connect and evt.dir=< and
|
evt.type=connect and evt.dir=< and
|
||||||
(fd.typechar=4 or fd.typechar=6) and
|
(fd.typechar=4 or fd.typechar=6) and
|
||||||
container and
|
container and
|
||||||
not k8s_containers and
|
not k8s_containers and
|
||||||
k8s_api_server and
|
k8s_api_server and
|
||||||
not user_known_contact_k8s_api_server_activities
|
not user_known_contact_k8s_api_server_activities
|
||||||
@@ -2872,7 +2810,7 @@
|
|||||||
tags: [container, mitre_execution]
|
tags: [container, mitre_execution]
|
||||||
|
|
||||||
|
|
||||||
# This rule is enabled by default.
|
# This rule is enabled by default.
|
||||||
# If you want to disable it, modify the following macro.
|
# If you want to disable it, modify the following macro.
|
||||||
- macro: consider_packet_socket_communication
|
- macro: consider_packet_socket_communication
|
||||||
condition: (always_true)
|
condition: (always_true)
|
||||||
|
|||||||
@@ -585,7 +585,8 @@ class FalcoTest(Test):
|
|||||||
self.check_rules_warnings(res)
|
self.check_rules_warnings(res)
|
||||||
if len(self.rules_events) > 0:
|
if len(self.rules_events) > 0:
|
||||||
self.check_rules_events(res)
|
self.check_rules_events(res)
|
||||||
self.check_detections(res)
|
if len(self.validate_rules_file) == 0:
|
||||||
|
self.check_detections(res)
|
||||||
if len(self.detect_counts) > 0:
|
if len(self.detect_counts) > 0:
|
||||||
self.check_detections_by_rule(res)
|
self.check_detections_by_rule(res)
|
||||||
self.check_json_output(res)
|
self.check_json_output(res)
|
||||||
|
|||||||
@@ -262,6 +262,7 @@ trace_files: !mux
|
|||||||
invalid_not_yaml:
|
invalid_not_yaml:
|
||||||
exit_status: 1
|
exit_status: 1
|
||||||
stdout_is: |+
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
Rules content is not yaml
|
Rules content is not yaml
|
||||||
---
|
---
|
||||||
This is not yaml
|
This is not yaml
|
||||||
@@ -273,6 +274,7 @@ trace_files: !mux
|
|||||||
invalid_not_array:
|
invalid_not_array:
|
||||||
exit_status: 1
|
exit_status: 1
|
||||||
stdout_is: |+
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
Rules content is not yaml array of objects
|
Rules content is not yaml array of objects
|
||||||
---
|
---
|
||||||
foo: bar
|
foo: bar
|
||||||
@@ -284,6 +286,7 @@ trace_files: !mux
|
|||||||
invalid_array_item_not_object:
|
invalid_array_item_not_object:
|
||||||
exit_status: 1
|
exit_status: 1
|
||||||
stdout_is: |+
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
Unexpected element of type string. Each element should be a yaml associative array.
|
Unexpected element of type string. Each element should be a yaml associative array.
|
||||||
---
|
---
|
||||||
- foo
|
- foo
|
||||||
@@ -295,6 +298,7 @@ trace_files: !mux
|
|||||||
invalid_unexpected object:
|
invalid_unexpected object:
|
||||||
exit_status: 1
|
exit_status: 1
|
||||||
stdout_is: |+
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
Unknown rule object: {foo="bar"}
|
Unknown rule object: {foo="bar"}
|
||||||
---
|
---
|
||||||
- foo: bar
|
- foo: bar
|
||||||
@@ -306,6 +310,7 @@ trace_files: !mux
|
|||||||
invalid_engine_version_not_number:
|
invalid_engine_version_not_number:
|
||||||
exit_status: 1
|
exit_status: 1
|
||||||
stdout_is: |+
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
Value of required_engine_version must be a number
|
Value of required_engine_version must be a number
|
||||||
---
|
---
|
||||||
- required_engine_version: not-a-number
|
- required_engine_version: not-a-number
|
||||||
@@ -317,6 +322,7 @@ trace_files: !mux
|
|||||||
invalid_yaml_parse_error:
|
invalid_yaml_parse_error:
|
||||||
exit_status: 1
|
exit_status: 1
|
||||||
stdout_is: |+
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
mapping values are not allowed in this context
|
mapping values are not allowed in this context
|
||||||
---
|
---
|
||||||
this : is : not : yaml
|
this : is : not : yaml
|
||||||
@@ -328,6 +334,7 @@ trace_files: !mux
|
|||||||
invalid_list_without_items:
|
invalid_list_without_items:
|
||||||
exit_status: 1
|
exit_status: 1
|
||||||
stdout_is: |+
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
List must have property items
|
List must have property items
|
||||||
---
|
---
|
||||||
- list: bad_list
|
- list: bad_list
|
||||||
@@ -340,6 +347,7 @@ trace_files: !mux
|
|||||||
invalid_macro_without_condition:
|
invalid_macro_without_condition:
|
||||||
exit_status: 1
|
exit_status: 1
|
||||||
stdout_is: |+
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
Macro must have property condition
|
Macro must have property condition
|
||||||
---
|
---
|
||||||
- macro: bad_macro
|
- macro: bad_macro
|
||||||
@@ -352,6 +360,7 @@ trace_files: !mux
|
|||||||
invalid_rule_without_output:
|
invalid_rule_without_output:
|
||||||
exit_status: 1
|
exit_status: 1
|
||||||
stdout_is: |+
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
Rule must have property output
|
Rule must have property output
|
||||||
---
|
---
|
||||||
- rule: no output rule
|
- rule: no output rule
|
||||||
@@ -366,6 +375,7 @@ trace_files: !mux
|
|||||||
invalid_append_rule_without_condition:
|
invalid_append_rule_without_condition:
|
||||||
exit_status: 1
|
exit_status: 1
|
||||||
stdout_is: |+
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
Rule must have property condition
|
Rule must have property condition
|
||||||
---
|
---
|
||||||
- rule: no condition rule
|
- rule: no condition rule
|
||||||
@@ -378,6 +388,7 @@ trace_files: !mux
|
|||||||
invalid_append_macro_dangling:
|
invalid_append_macro_dangling:
|
||||||
exit_status: 1
|
exit_status: 1
|
||||||
stdout_is: |+
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
Macro dangling append has 'append' key but no macro by that name already exists
|
Macro dangling append has 'append' key but no macro by that name already exists
|
||||||
---
|
---
|
||||||
- macro: dangling append
|
- macro: dangling append
|
||||||
@@ -391,6 +402,7 @@ trace_files: !mux
|
|||||||
invalid_list_append_dangling:
|
invalid_list_append_dangling:
|
||||||
exit_status: 1
|
exit_status: 1
|
||||||
stdout_is: |+
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
List my_list has 'append' key but no list by that name already exists
|
List my_list has 'append' key but no list by that name already exists
|
||||||
---
|
---
|
||||||
- list: my_list
|
- list: my_list
|
||||||
@@ -404,6 +416,7 @@ trace_files: !mux
|
|||||||
invalid_rule_append_dangling:
|
invalid_rule_append_dangling:
|
||||||
exit_status: 1
|
exit_status: 1
|
||||||
stdout_is: |+
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
Rule my_rule has 'append' key but no rule by that name already exists
|
Rule my_rule has 'append' key but no rule by that name already exists
|
||||||
---
|
---
|
||||||
- rule: my_rule
|
- rule: my_rule
|
||||||
@@ -450,6 +463,7 @@ trace_files: !mux
|
|||||||
invalid_overwrite_macro_multiple_docs:
|
invalid_overwrite_macro_multiple_docs:
|
||||||
exit_status: 1
|
exit_status: 1
|
||||||
stdout_is: |+
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
Compilation error when compiling "foo": Undefined macro 'foo' used in filter.
|
Compilation error when compiling "foo": Undefined macro 'foo' used in filter.
|
||||||
---
|
---
|
||||||
- macro: some macro
|
- macro: some macro
|
||||||
@@ -463,6 +477,7 @@ trace_files: !mux
|
|||||||
invalid_append_macro_multiple_docs:
|
invalid_append_macro_multiple_docs:
|
||||||
exit_status: 1
|
exit_status: 1
|
||||||
stdout_is: |+
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
Compilation error when compiling "evt.type=execve foo": 17: syntax error, unexpected 'foo', expecting 'or', 'and'
|
Compilation error when compiling "evt.type=execve foo": 17: syntax error, unexpected 'foo', expecting 'or', 'and'
|
||||||
---
|
---
|
||||||
- macro: some macro
|
- macro: some macro
|
||||||
@@ -521,6 +536,7 @@ trace_files: !mux
|
|||||||
invalid_overwrite_rule_multiple_docs:
|
invalid_overwrite_rule_multiple_docs:
|
||||||
exit_status: 1
|
exit_status: 1
|
||||||
stdout_is: |+
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
Undefined macro 'bar' used in filter.
|
Undefined macro 'bar' used in filter.
|
||||||
---
|
---
|
||||||
- rule: some rule
|
- rule: some rule
|
||||||
@@ -559,6 +575,7 @@ trace_files: !mux
|
|||||||
invalid_missing_rule_name:
|
invalid_missing_rule_name:
|
||||||
exit_status: 1
|
exit_status: 1
|
||||||
stdout_is: |+
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
Rule name is empty
|
Rule name is empty
|
||||||
---
|
---
|
||||||
- rule:
|
- rule:
|
||||||
@@ -573,6 +590,7 @@ trace_files: !mux
|
|||||||
invalid_missing_list_name:
|
invalid_missing_list_name:
|
||||||
exit_status: 1
|
exit_status: 1
|
||||||
stdout_is: |+
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
List name is empty
|
List name is empty
|
||||||
---
|
---
|
||||||
- list:
|
- list:
|
||||||
@@ -585,6 +603,7 @@ trace_files: !mux
|
|||||||
invalid_missing_macro_name:
|
invalid_missing_macro_name:
|
||||||
exit_status: 1
|
exit_status: 1
|
||||||
stdout_is: |+
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
Macro name is empty
|
Macro name is empty
|
||||||
---
|
---
|
||||||
- macro:
|
- macro:
|
||||||
|
|||||||
323
test/falco_tests_exceptions.yaml
Normal file
323
test/falco_tests_exceptions.yaml
Normal file
@@ -0,0 +1,323 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2016-2020 The Falco Authors..
|
||||||
|
#
|
||||||
|
# This file is part of falco.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
trace_files: !mux
|
||||||
|
|
||||||
|
rule_exception_no_fields:
|
||||||
|
exit_status: 1
|
||||||
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
|
Rule exception item ex1: must have fields property with a list of fields
|
||||||
|
---
|
||||||
|
- rule: My Rule
|
||||||
|
desc: Some desc
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: Some output
|
||||||
|
exceptions:
|
||||||
|
- name: ex1
|
||||||
|
priority: error
|
||||||
|
---
|
||||||
|
validate_rules_file:
|
||||||
|
- rules/exceptions/item_no_fields.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_no_name:
|
||||||
|
exit_status: 1
|
||||||
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
|
Rule exception item must have name property
|
||||||
|
---
|
||||||
|
- rule: My Rule
|
||||||
|
desc: Some desc
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: Some output
|
||||||
|
exceptions:
|
||||||
|
- fields: [proc.name, fd.filename]
|
||||||
|
priority: error
|
||||||
|
---
|
||||||
|
validate_rules_file:
|
||||||
|
- rules/exceptions/item_no_name.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_append_no_name:
|
||||||
|
exit_status: 1
|
||||||
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
|
Rule exception item must have name property
|
||||||
|
---
|
||||||
|
- rule: My Rule
|
||||||
|
exceptions:
|
||||||
|
- values:
|
||||||
|
- [nginx, /tmp/foo]
|
||||||
|
append: true
|
||||||
|
---
|
||||||
|
validate_rules_file:
|
||||||
|
- rules/exceptions/append_item_no_name.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_unknown_fields:
|
||||||
|
exit_status: 1
|
||||||
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
|
Rule exception item ex1: field name not.exist is not a supported filter field
|
||||||
|
---
|
||||||
|
- rule: My Rule
|
||||||
|
desc: Some desc
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: Some output
|
||||||
|
exceptions:
|
||||||
|
- name: ex1
|
||||||
|
fields: [not.exist]
|
||||||
|
priority: error
|
||||||
|
---
|
||||||
|
validate_rules_file:
|
||||||
|
- rules/exceptions/item_unknown_fields.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_comps_fields_len_mismatch:
|
||||||
|
exit_status: 1
|
||||||
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
|
Rule exception item ex1: fields and comps lists must have equal length
|
||||||
|
---
|
||||||
|
- rule: My Rule
|
||||||
|
desc: Some desc
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: Some output
|
||||||
|
exceptions:
|
||||||
|
- name: ex1
|
||||||
|
fields: [proc.name, fd.filename]
|
||||||
|
comps: [=]
|
||||||
|
priority: error
|
||||||
|
---
|
||||||
|
validate_rules_file:
|
||||||
|
- rules/exceptions/item_comps_fields_len_mismatch.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_unknown_comp:
|
||||||
|
exit_status: 1
|
||||||
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
|
Rule exception item ex1: comparison operator no-comp is not a supported comparison operator
|
||||||
|
---
|
||||||
|
- rule: My Rule
|
||||||
|
desc: Some desc
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: Some output
|
||||||
|
exceptions:
|
||||||
|
- name: ex1
|
||||||
|
fields: [proc.name, fd.filename]
|
||||||
|
comps: [=, no-comp]
|
||||||
|
priority: error
|
||||||
|
---
|
||||||
|
validate_rules_file:
|
||||||
|
- rules/exceptions/item_unknown_comp.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_fields_values_len_mismatch:
|
||||||
|
exit_status: 1
|
||||||
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
|
Exception item ex1: fields and values lists must have equal length
|
||||||
|
---
|
||||||
|
- rule: My Rule
|
||||||
|
desc: Some desc
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: Some output
|
||||||
|
exceptions:
|
||||||
|
- name: ex1
|
||||||
|
fields: [proc.name, fd.filename]
|
||||||
|
values:
|
||||||
|
- [nginx]
|
||||||
|
priority: error
|
||||||
|
---
|
||||||
|
validate_rules_file:
|
||||||
|
- rules/exceptions/item_fields_values_len_mismatch.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_append_fields_values_len_mismatch:
|
||||||
|
exit_status: 1
|
||||||
|
stdout_is: |+
|
||||||
|
1 errors:
|
||||||
|
Exception item ex1: fields and values lists must have equal length
|
||||||
|
---
|
||||||
|
- rule: My Rule
|
||||||
|
desc: Some desc
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: Some output
|
||||||
|
exceptions:
|
||||||
|
- name: ex1
|
||||||
|
fields: [proc.name, fd.filename]
|
||||||
|
priority: error
|
||||||
|
|
||||||
|
- rule: My Rule
|
||||||
|
exceptions:
|
||||||
|
- name: ex1
|
||||||
|
values:
|
||||||
|
- [nginx]
|
||||||
|
append: true
|
||||||
|
---
|
||||||
|
validate_rules_file:
|
||||||
|
- rules/exceptions/append_item_fields_values_len_mismatch.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_append_item_not_in_rule:
|
||||||
|
exit_status: 0
|
||||||
|
stderr_contains: |+
|
||||||
|
1 warnings:
|
||||||
|
Rule My Rule with append=true: no set of fields matching name ex2
|
||||||
|
validate_rules_file:
|
||||||
|
- rules/exceptions/append_item_not_in_rule.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_without_exception:
|
||||||
|
exit_status: 0
|
||||||
|
stderr_contains: |+
|
||||||
|
1 warnings:
|
||||||
|
Rule My Rule: consider adding an exceptions property to define supported exceptions fields
|
||||||
|
validate_rules_file:
|
||||||
|
- rules/exceptions/rule_without_exception.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_no_values:
|
||||||
|
detect: True
|
||||||
|
detect_level: WARNING
|
||||||
|
rules_file:
|
||||||
|
- rules/exceptions/rule_exception_no_values.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_one_value:
|
||||||
|
detect: False
|
||||||
|
detect_level: WARNING
|
||||||
|
rules_file:
|
||||||
|
- rules/exceptions/rule_exception_one_value.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_append_one_value:
|
||||||
|
detect: False
|
||||||
|
detect_level: WARNING
|
||||||
|
rules_file:
|
||||||
|
- rules/exceptions/rule_exception_append_one_value.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_second_value:
|
||||||
|
detect: False
|
||||||
|
detect_level: WARNING
|
||||||
|
rules_file:
|
||||||
|
- rules/exceptions/rule_exception_second_value.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_append_second_value:
|
||||||
|
detect: False
|
||||||
|
detect_level: WARNING
|
||||||
|
rules_file:
|
||||||
|
- rules/exceptions/rule_exception_append_second_value.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_second_item:
|
||||||
|
detect: False
|
||||||
|
detect_level: WARNING
|
||||||
|
rules_file:
|
||||||
|
- rules/exceptions/rule_exception_second_item.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_append_second_item:
|
||||||
|
detect: False
|
||||||
|
detect_level: WARNING
|
||||||
|
rules_file:
|
||||||
|
- rules/exceptions/rule_exception_append_second_item.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_third_item:
|
||||||
|
detect: False
|
||||||
|
detect_level: WARNING
|
||||||
|
rules_file:
|
||||||
|
- rules/exceptions/rule_exception_third_item.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_append_third_item:
|
||||||
|
detect: False
|
||||||
|
detect_level: WARNING
|
||||||
|
rules_file:
|
||||||
|
- rules/exceptions/rule_exception_append_third_item.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_quoted:
|
||||||
|
detect: False
|
||||||
|
detect_level: WARNING
|
||||||
|
rules_file:
|
||||||
|
- rules/exceptions/rule_exception_quoted.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_append_multiple_values:
|
||||||
|
detect: False
|
||||||
|
detect_level: WARNING
|
||||||
|
rules_file:
|
||||||
|
- rules/exceptions/rule_exception_append_multiple.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_comp:
|
||||||
|
detect: False
|
||||||
|
detect_level: WARNING
|
||||||
|
rules_file:
|
||||||
|
- rules/exceptions/rule_exception_comp.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_append_comp:
|
||||||
|
detect: False
|
||||||
|
detect_level: WARNING
|
||||||
|
rules_file:
|
||||||
|
- rules/exceptions/rule_exception_append_comp.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_values_listref:
|
||||||
|
detect: False
|
||||||
|
detect_level: WARNING
|
||||||
|
rules_file:
|
||||||
|
- rules/exceptions/rule_exception_values_listref.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_values_listref_noparens:
|
||||||
|
detect: False
|
||||||
|
detect_level: WARNING
|
||||||
|
rules_file:
|
||||||
|
- rules/exceptions/rule_exception_values_listref_noparens.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_values_list:
|
||||||
|
detect: False
|
||||||
|
detect_level: WARNING
|
||||||
|
rules_file:
|
||||||
|
- rules/exceptions/rule_exception_values_list.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_single_field:
|
||||||
|
detect: False
|
||||||
|
detect_level: WARNING
|
||||||
|
rules_file:
|
||||||
|
- rules/exceptions/rule_exception_single_field.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
rule_exception_single_field_append:
|
||||||
|
detect: False
|
||||||
|
detect_level: WARNING
|
||||||
|
rules_file:
|
||||||
|
- rules/exceptions/rule_exception_single_field_append.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: My Rule
|
||||||
|
desc: Some desc
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: Some output
|
||||||
|
exceptions:
|
||||||
|
- name: ex1
|
||||||
|
fields: [proc.name, fd.filename]
|
||||||
|
priority: error
|
||||||
|
|
||||||
|
- rule: My Rule
|
||||||
|
exceptions:
|
||||||
|
- name: ex1
|
||||||
|
values:
|
||||||
|
- [nginx]
|
||||||
|
append: true
|
||||||
30
test/rules/exceptions/append_item_no_name.yaml
Normal file
30
test/rules/exceptions/append_item_no_name.yaml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: My Rule
|
||||||
|
desc: Some desc
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: Some output
|
||||||
|
exceptions:
|
||||||
|
- name: ex1
|
||||||
|
fields: [proc.name, fd.filename]
|
||||||
|
priority: error
|
||||||
|
|
||||||
|
- rule: My Rule
|
||||||
|
exceptions:
|
||||||
|
- values:
|
||||||
|
- [nginx, /tmp/foo]
|
||||||
|
append: true
|
||||||
31
test/rules/exceptions/append_item_not_in_rule.yaml
Normal file
31
test/rules/exceptions/append_item_not_in_rule.yaml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: My Rule
|
||||||
|
desc: Some desc
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: Some output
|
||||||
|
exceptions:
|
||||||
|
- name: ex1
|
||||||
|
fields: [proc.name, fd.filename]
|
||||||
|
priority: error
|
||||||
|
|
||||||
|
- rule: My Rule
|
||||||
|
exceptions:
|
||||||
|
- name: ex2
|
||||||
|
values:
|
||||||
|
- [apache, /tmp]
|
||||||
|
append: true
|
||||||
25
test/rules/exceptions/item_comps_fields_len_mismatch.yaml
Normal file
25
test/rules/exceptions/item_comps_fields_len_mismatch.yaml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: My Rule
|
||||||
|
desc: Some desc
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: Some output
|
||||||
|
exceptions:
|
||||||
|
- name: ex1
|
||||||
|
fields: [proc.name, fd.filename]
|
||||||
|
comps: [=]
|
||||||
|
priority: error
|
||||||
26
test/rules/exceptions/item_fields_values_len_mismatch.yaml
Normal file
26
test/rules/exceptions/item_fields_values_len_mismatch.yaml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: My Rule
|
||||||
|
desc: Some desc
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: Some output
|
||||||
|
exceptions:
|
||||||
|
- name: ex1
|
||||||
|
fields: [proc.name, fd.filename]
|
||||||
|
values:
|
||||||
|
- [nginx]
|
||||||
|
priority: error
|
||||||
23
test/rules/exceptions/item_no_fields.yaml
Normal file
23
test/rules/exceptions/item_no_fields.yaml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: My Rule
|
||||||
|
desc: Some desc
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: Some output
|
||||||
|
exceptions:
|
||||||
|
- name: ex1
|
||||||
|
priority: error
|
||||||
23
test/rules/exceptions/item_no_name.yaml
Normal file
23
test/rules/exceptions/item_no_name.yaml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: My Rule
|
||||||
|
desc: Some desc
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: Some output
|
||||||
|
exceptions:
|
||||||
|
- fields: [proc.name, fd.filename]
|
||||||
|
priority: error
|
||||||
25
test/rules/exceptions/item_unknown_comp.yaml
Normal file
25
test/rules/exceptions/item_unknown_comp.yaml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: My Rule
|
||||||
|
desc: Some desc
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: Some output
|
||||||
|
exceptions:
|
||||||
|
- name: ex1
|
||||||
|
fields: [proc.name, fd.filename]
|
||||||
|
comps: [=, no-comp]
|
||||||
|
priority: error
|
||||||
24
test/rules/exceptions/item_unknown_fields.yaml
Normal file
24
test/rules/exceptions/item_unknown_fields.yaml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: My Rule
|
||||||
|
desc: Some desc
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: Some output
|
||||||
|
exceptions:
|
||||||
|
- name: ex1
|
||||||
|
fields: [not.exist]
|
||||||
|
priority: error
|
||||||
38
test/rules/exceptions/rule_exception_append_comp.yaml
Normal file
38
test/rules/exceptions/rule_exception_append_comp.yaml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: Open From Cat
|
||||||
|
desc: A process named cat does an open
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: "An open was seen (command=%proc.cmdline)"
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name
|
||||||
|
fields: [proc.name]
|
||||||
|
- name: proc_name_contains
|
||||||
|
fields: [proc.name]
|
||||||
|
comps: [contains]
|
||||||
|
- name: proc_name_cmdline
|
||||||
|
fields: [proc.name, proc.cmdline]
|
||||||
|
- name: proc_name_cmdline_pname
|
||||||
|
fields: [proc.name, proc.cmdline, proc.pname]
|
||||||
|
priority: WARNING
|
||||||
|
|
||||||
|
- rule: Open From Cat
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name_contains
|
||||||
|
values:
|
||||||
|
- [cat]
|
||||||
|
append: true
|
||||||
42
test/rules/exceptions/rule_exception_append_multiple.yaml
Normal file
42
test/rules/exceptions/rule_exception_append_multiple.yaml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: Open From Cat
|
||||||
|
desc: A process named cat does an open
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: "An open was seen (command=%proc.cmdline)"
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name
|
||||||
|
fields: [proc.name]
|
||||||
|
- name: proc_name_cmdline
|
||||||
|
fields: [proc.name, proc.cmdline]
|
||||||
|
- name: proc_name_cmdline_pname
|
||||||
|
fields: [proc.name, proc.cmdline, proc.pname]
|
||||||
|
priority: WARNING
|
||||||
|
|
||||||
|
- rule: Open From Cat
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name
|
||||||
|
values:
|
||||||
|
- [not-cat]
|
||||||
|
append: true
|
||||||
|
|
||||||
|
- rule: Open From Cat
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name
|
||||||
|
values:
|
||||||
|
- [cat]
|
||||||
|
append: true
|
||||||
37
test/rules/exceptions/rule_exception_append_one_value.yaml
Normal file
37
test/rules/exceptions/rule_exception_append_one_value.yaml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: Open From Cat
|
||||||
|
desc: A process named cat does an open
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: "An open was seen (command=%proc.cmdline)"
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name
|
||||||
|
fields: [proc.name]
|
||||||
|
values:
|
||||||
|
- [cat]
|
||||||
|
- name: proc_name_cmdline
|
||||||
|
fields: [proc.name, proc.cmdline]
|
||||||
|
- name: proc_name_cmdline_pname
|
||||||
|
fields: [proc.name, proc.cmdline, proc.pname]
|
||||||
|
priority: WARNING
|
||||||
|
|
||||||
|
- rule: Open From Cat
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name
|
||||||
|
values:
|
||||||
|
- [cat]
|
||||||
|
append: true
|
||||||
41
test/rules/exceptions/rule_exception_append_second_item.yaml
Normal file
41
test/rules/exceptions/rule_exception_append_second_item.yaml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: Open From Cat
|
||||||
|
desc: A process named cat does an open
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: "An open was seen (command=%proc.cmdline)"
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name
|
||||||
|
fields: [proc.name]
|
||||||
|
- name: proc_name_cmdline
|
||||||
|
fields: [proc.name, proc.cmdline]
|
||||||
|
- name: proc_name_cmdline_pname
|
||||||
|
fields: [proc.name, proc.cmdline, proc.pname]
|
||||||
|
priority: WARNING
|
||||||
|
|
||||||
|
- rule: Open From Cat
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name
|
||||||
|
values:
|
||||||
|
- [not-cat]
|
||||||
|
- name: proc_name_cmdline
|
||||||
|
values:
|
||||||
|
- [cat, "cat /dev/null"]
|
||||||
|
- name: proc_name_cmdline_pname
|
||||||
|
values:
|
||||||
|
- [not-cat, "cat /dev/null", bash]
|
||||||
|
append: true
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: Open From Cat
|
||||||
|
desc: A process named cat does an open
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: "An open was seen (command=%proc.cmdline)"
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name
|
||||||
|
fields: [proc.name]
|
||||||
|
- name: proc_name_cmdline
|
||||||
|
fields: [proc.name, proc.cmdline]
|
||||||
|
- name: proc_name_cmdline_pname
|
||||||
|
fields: [proc.name, proc.cmdline, proc.pname]
|
||||||
|
priority: WARNING
|
||||||
|
|
||||||
|
- rule: Open From Cat
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name_cmdline
|
||||||
|
values:
|
||||||
|
- [not-cat, not-cat]
|
||||||
|
- [cat, "cat /dev/null"]
|
||||||
|
append: true
|
||||||
41
test/rules/exceptions/rule_exception_append_third_item.yaml
Normal file
41
test/rules/exceptions/rule_exception_append_third_item.yaml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: Open From Cat
|
||||||
|
desc: A process named cat does an open
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: "An open was seen (command=%proc.cmdline)"
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name
|
||||||
|
fields: [proc.name]
|
||||||
|
- name: proc_name_cmdline
|
||||||
|
fields: [proc.name, proc.cmdline]
|
||||||
|
- name: proc_name_cmdline_pname
|
||||||
|
fields: [proc.name, proc.cmdline, proc.pname]
|
||||||
|
priority: WARNING
|
||||||
|
|
||||||
|
- rule: Open From Cat
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name
|
||||||
|
values:
|
||||||
|
- [not-cat]
|
||||||
|
- name: proc_name_cmdline
|
||||||
|
values:
|
||||||
|
- [not-cat, "cat /dev/null"]
|
||||||
|
- name: proc_name_cmdline_pname
|
||||||
|
values:
|
||||||
|
- [cat, "cat /dev/null", bash]
|
||||||
|
append: true
|
||||||
34
test/rules/exceptions/rule_exception_comp.yaml
Normal file
34
test/rules/exceptions/rule_exception_comp.yaml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: Open From Cat
|
||||||
|
desc: A process named cat does an open
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: "An open was seen (command=%proc.cmdline)"
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name
|
||||||
|
fields: [proc.name]
|
||||||
|
- name: proc_name_contains
|
||||||
|
fields: [proc.name]
|
||||||
|
comps: [contains]
|
||||||
|
values:
|
||||||
|
- [cat]
|
||||||
|
- name: proc_name_cmdline
|
||||||
|
fields: [proc.name, proc.cmdline]
|
||||||
|
- name: proc_name_cmdline_pname
|
||||||
|
fields: [proc.name, proc.cmdline, proc.pname]
|
||||||
|
priority: WARNING
|
||||||
|
|
||||||
28
test/rules/exceptions/rule_exception_no_values.yaml
Normal file
28
test/rules/exceptions/rule_exception_no_values.yaml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: Open From Cat
|
||||||
|
desc: A process named cat does an open
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: "An open was seen (command=%proc.cmdline)"
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name
|
||||||
|
fields: [proc.name]
|
||||||
|
- name: proc_name_cmdline
|
||||||
|
fields: [proc.name, proc.cmdline]
|
||||||
|
- name: proc_name_cmdline_pname
|
||||||
|
fields: [proc.name, proc.cmdline, proc.pname]
|
||||||
|
priority: WARNING
|
||||||
30
test/rules/exceptions/rule_exception_one_value.yaml
Normal file
30
test/rules/exceptions/rule_exception_one_value.yaml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: Open From Cat
|
||||||
|
desc: A process named cat does an open
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: "An open was seen (command=%proc.cmdline)"
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name
|
||||||
|
fields: [proc.name]
|
||||||
|
values:
|
||||||
|
- [cat]
|
||||||
|
- name: proc_name_cmdline
|
||||||
|
fields: [proc.name, proc.cmdline]
|
||||||
|
- name: proc_name_cmdline_pname
|
||||||
|
fields: [proc.name, proc.cmdline, proc.pname]
|
||||||
|
priority: WARNING
|
||||||
36
test/rules/exceptions/rule_exception_quoted.yaml
Normal file
36
test/rules/exceptions/rule_exception_quoted.yaml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: Open From Cat
|
||||||
|
desc: A process named cat does an open
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: "An open was seen (command=%proc.cmdline)"
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name
|
||||||
|
fields: [proc.name]
|
||||||
|
- name: proc_name_cmdline
|
||||||
|
fields: [proc.name, proc.cmdline]
|
||||||
|
- name: proc_name_cmdline_pname
|
||||||
|
fields: [proc.name, proc.cmdline, proc.pname]
|
||||||
|
priority: WARNING
|
||||||
|
|
||||||
|
- rule: Open From Cat
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name_cmdline
|
||||||
|
values:
|
||||||
|
- [not-cat, not-cat]
|
||||||
|
- [cat, '"cat /dev/null"']
|
||||||
|
append: true
|
||||||
34
test/rules/exceptions/rule_exception_second_item.yaml
Normal file
34
test/rules/exceptions/rule_exception_second_item.yaml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: Open From Cat
|
||||||
|
desc: A process named cat does an open
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: "An open was seen (command=%proc.cmdline)"
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name
|
||||||
|
fields: [proc.name]
|
||||||
|
values:
|
||||||
|
- [not-cat]
|
||||||
|
- name: proc_name_cmdline
|
||||||
|
fields: [proc.name, proc.cmdline]
|
||||||
|
values:
|
||||||
|
- [cat, "cat /dev/null"]
|
||||||
|
- name: proc_name_cmdline_pname
|
||||||
|
fields: [proc.name, proc.cmdline, proc.pname]
|
||||||
|
values:
|
||||||
|
- [not-cat, "cat /dev/null", bash]
|
||||||
|
priority: WARNING
|
||||||
32
test/rules/exceptions/rule_exception_second_value.yaml
Normal file
32
test/rules/exceptions/rule_exception_second_value.yaml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: Open From Cat
|
||||||
|
desc: A process named cat does an open
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: "An open was seen (command=%proc.cmdline)"
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name
|
||||||
|
fields: [proc.name]
|
||||||
|
- name: proc_name_cmdline
|
||||||
|
fields: [proc.name, proc.cmdline]
|
||||||
|
values:
|
||||||
|
- [not-cat, not-cat]
|
||||||
|
- [cat, "cat /dev/null"]
|
||||||
|
- name: proc_name_cmdline_pname
|
||||||
|
fields: [proc.name, proc.cmdline, proc.pname]
|
||||||
|
priority: WARNING
|
||||||
|
|
||||||
30
test/rules/exceptions/rule_exception_single_field.yaml
Normal file
30
test/rules/exceptions/rule_exception_single_field.yaml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
- rule: Open From Cat
|
||||||
|
desc: A process named cat does an open
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: "An open was seen (command=%proc.cmdline)"
|
||||||
|
exceptions:
|
||||||
|
- name: proc_cmdline
|
||||||
|
fields: proc.cmdline
|
||||||
|
comps: in
|
||||||
|
values:
|
||||||
|
- cat /dev/zero
|
||||||
|
- "cat /dev/null"
|
||||||
|
priority: WARNING
|
||||||
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
- rule: Open From Cat
|
||||||
|
desc: A process named cat does an open
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: "An open was seen (command=%proc.cmdline)"
|
||||||
|
exceptions:
|
||||||
|
- name: proc_cmdline
|
||||||
|
fields: proc.cmdline
|
||||||
|
comps: in
|
||||||
|
values:
|
||||||
|
- cat /dev/zero
|
||||||
|
priority: WARNING
|
||||||
|
|
||||||
|
- rule: Open From Cat
|
||||||
|
exceptions:
|
||||||
|
- name: proc_cmdline
|
||||||
|
values:
|
||||||
|
- "cat /dev/null"
|
||||||
|
append: true
|
||||||
|
|
||||||
|
|
||||||
34
test/rules/exceptions/rule_exception_third_item.yaml
Normal file
34
test/rules/exceptions/rule_exception_third_item.yaml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: Open From Cat
|
||||||
|
desc: A process named cat does an open
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: "An open was seen (command=%proc.cmdline)"
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name
|
||||||
|
fields: [proc.name]
|
||||||
|
values:
|
||||||
|
- [not-cat]
|
||||||
|
- name: proc_name_cmdline
|
||||||
|
fields: [proc.name, proc.cmdline]
|
||||||
|
values:
|
||||||
|
- [not-cat, "cat /dev/null"]
|
||||||
|
- name: proc_name_cmdline_pname
|
||||||
|
fields: [proc.name, proc.cmdline, proc.pname]
|
||||||
|
values:
|
||||||
|
- [cat, "cat /dev/null", bash]
|
||||||
|
priority: WARNING
|
||||||
29
test/rules/exceptions/rule_exception_values_list.yaml
Normal file
29
test/rules/exceptions/rule_exception_values_list.yaml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
- rule: Open From Cat
|
||||||
|
desc: A process named cat does an open
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: "An open was seen (command=%proc.cmdline)"
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name_cmdline
|
||||||
|
fields: [proc.name, proc.cmdline]
|
||||||
|
comps: [=, in]
|
||||||
|
values:
|
||||||
|
- [cat, [cat /dev/zero, "cat /dev/null"]]
|
||||||
|
priority: WARNING
|
||||||
|
|
||||||
32
test/rules/exceptions/rule_exception_values_listref.yaml
Normal file
32
test/rules/exceptions/rule_exception_values_listref.yaml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
- list: cat_cmdlines
|
||||||
|
items: [cat /dev/zero, "cat /dev/null"]
|
||||||
|
|
||||||
|
- rule: Open From Cat
|
||||||
|
desc: A process named cat does an open
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: "An open was seen (command=%proc.cmdline)"
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name_cmdline
|
||||||
|
fields: [proc.name, proc.cmdline]
|
||||||
|
comps: [=, in]
|
||||||
|
values:
|
||||||
|
- [cat, (cat_cmdlines)]
|
||||||
|
priority: WARNING
|
||||||
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
- list: cat_cmdlines
|
||||||
|
items: [cat /dev/zero, "cat /dev/null"]
|
||||||
|
|
||||||
|
- rule: Open From Cat
|
||||||
|
desc: A process named cat does an open
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: "An open was seen (command=%proc.cmdline)"
|
||||||
|
exceptions:
|
||||||
|
- name: proc_name_cmdline
|
||||||
|
fields: [proc.name, proc.cmdline]
|
||||||
|
comps: [=, in]
|
||||||
|
values:
|
||||||
|
- [cat, cat_cmdlines]
|
||||||
|
priority: WARNING
|
||||||
|
|
||||||
21
test/rules/exceptions/rule_without_exception.yaml
Normal file
21
test/rules/exceptions/rule_without_exception.yaml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2020 The Falco Authors.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
- rule: My Rule
|
||||||
|
desc: Some desc
|
||||||
|
condition: evt.type=open and proc.name=cat
|
||||||
|
output: Some output
|
||||||
|
priority: error
|
||||||
@@ -98,7 +98,7 @@ function run_tests() {
|
|||||||
# as we're watching the return status when running avocado.
|
# as we're watching the return status when running avocado.
|
||||||
set +e
|
set +e
|
||||||
TEST_RC=0
|
TEST_RC=0
|
||||||
suites=($SCRIPTDIR/falco_traces.yaml $SCRIPTDIR/falco_tests.yaml $SCRIPTDIR/falco_k8s_audit_tests.yaml $SCRIPTDIR/falco_tests_psp.yaml)
|
suites=($SCRIPTDIR/falco_traces.yaml $SCRIPTDIR/falco_tests.yaml $SCRIPTDIR/falco_k8s_audit_tests.yaml $SCRIPTDIR/falco_tests_psp.yaml $SCRIPTDIR/falco_tests_exceptions.yaml)
|
||||||
|
|
||||||
if [ "$SKIP_PACKAGES_TESTS" = false ] ; then
|
if [ "$SKIP_PACKAGES_TESTS" = false ] ; then
|
||||||
suites+=($SCRIPTDIR/falco_tests_package.yaml)
|
suites+=($SCRIPTDIR/falco_tests_package.yaml)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ limitations under the License.
|
|||||||
|
|
||||||
// The version of rules/filter fields/etc supported by this falco
|
// The version of rules/filter fields/etc supported by this falco
|
||||||
// engine.
|
// engine.
|
||||||
#define FALCO_ENGINE_VERSION (7)
|
#define FALCO_ENGINE_VERSION (8)
|
||||||
|
|
||||||
// This is the result of running "falco --list -N | sha256sum" and
|
// This is the result of running "falco --list -N | sha256sum" and
|
||||||
// represents the fields supported by this version of falco. It's used
|
// represents the fields supported by this version of falco. It's used
|
||||||
|
|||||||
@@ -126,6 +126,31 @@ function set_output(output_format, state)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- This should be keep in sync with parser.lua
|
||||||
|
defined_comp_operators = {
|
||||||
|
["="]=1,
|
||||||
|
["=="] = 1,
|
||||||
|
["!"] = 1,
|
||||||
|
["<="] = 1,
|
||||||
|
[">="] = 1,
|
||||||
|
["<"] = 1,
|
||||||
|
[">"] = 1,
|
||||||
|
["contains"] = 1,
|
||||||
|
["icontains"] = 1,
|
||||||
|
["glob"] = 1,
|
||||||
|
["startswith"] = 1,
|
||||||
|
["endswith"] = 1,
|
||||||
|
["in"] = 1,
|
||||||
|
["intersects"] = 1,
|
||||||
|
["pmatch"] = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
defined_list_comp_operators = {
|
||||||
|
["in"] = 1,
|
||||||
|
["intersects"] = 1,
|
||||||
|
["pmatch"] = 1
|
||||||
|
}
|
||||||
|
|
||||||
-- Note that the rules_by_name and rules_by_idx refer to the same rule
|
-- Note that the rules_by_name and rules_by_idx refer to the same rule
|
||||||
-- object. The by_name index is used for things like describing rules,
|
-- object. The by_name index is used for things like describing rules,
|
||||||
-- and the by_idx index is used to map the relational node index back
|
-- and the by_idx index is used to map the relational node index back
|
||||||
@@ -253,19 +278,89 @@ function get_lines(rules_lines, row, num_lines)
|
|||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function quote_item(item)
|
||||||
|
if string.sub(item, 1, 1) ~= "'" and string.sub(item, 1, 1) ~= '"' then
|
||||||
|
item = "\""..item.."\""
|
||||||
|
end
|
||||||
|
|
||||||
|
return item
|
||||||
|
end
|
||||||
|
|
||||||
|
function paren_item(item)
|
||||||
|
if string.sub(item, 1, 1) ~= "(" then
|
||||||
|
item = "("..item..")"
|
||||||
|
end
|
||||||
|
|
||||||
|
return item
|
||||||
|
end
|
||||||
|
|
||||||
function build_error(rules_lines, row, num_lines, err)
|
function build_error(rules_lines, row, num_lines, err)
|
||||||
local ret = err.."\n---\n"..get_lines(rules_lines, row, num_lines).."---"
|
local ret = err.."\n---\n"..get_lines(rules_lines, row, num_lines).."---"
|
||||||
|
|
||||||
return ret
|
return {ret}
|
||||||
end
|
end
|
||||||
|
|
||||||
function build_error_with_context(ctx, err)
|
function build_error_with_context(ctx, err)
|
||||||
local ret = err.."\n---\n"..ctx.."---"
|
local ret = err.."\n---\n"..ctx.."---"
|
||||||
return ret
|
return {ret}
|
||||||
|
end
|
||||||
|
|
||||||
|
function validate_exception_item_multi_fields(eitem, context)
|
||||||
|
|
||||||
|
local name = eitem['name']
|
||||||
|
local fields = eitem['fields']
|
||||||
|
local values = eitem['values']
|
||||||
|
local comps = eitem['comps']
|
||||||
|
|
||||||
|
if comps == nil then
|
||||||
|
comps = {}
|
||||||
|
for c=1,#fields do
|
||||||
|
table.insert(comps, "=")
|
||||||
|
end
|
||||||
|
eitem['comps'] = comps
|
||||||
|
else
|
||||||
|
if #fields ~= #comps then
|
||||||
|
return false, build_error_with_context(context, "Rule exception item "..name..": fields and comps lists must have equal length"), warnings
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for k, fname in ipairs(fields) do
|
||||||
|
if defined_noarg_filters[fname] == nil then
|
||||||
|
return false, build_error_with_context(context, "Rule exception item "..name..": field name "..fname.." is not a supported filter field"), warnings
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for k, comp in ipairs(comps) do
|
||||||
|
if defined_comp_operators[comp] == nil then
|
||||||
|
return false, build_error_with_context(context, "Rule exception item "..name..": comparison operator "..comp.." is not a supported comparison operator"), warnings
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function validate_exception_item_single_field(eitem, context)
|
||||||
|
|
||||||
|
local name = eitem['name']
|
||||||
|
local fields = eitem['fields']
|
||||||
|
local values = eitem['values']
|
||||||
|
local comps = eitem['comps']
|
||||||
|
|
||||||
|
if comps == nil then
|
||||||
|
eitem['comps'] = "in"
|
||||||
|
else
|
||||||
|
if type(fields) ~= "string" or type(comps) ~= "string" then
|
||||||
|
return false, build_error_with_context(context, "Rule exception item "..name..": fields and comps must both be strings"), warnings
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if defined_noarg_filters[fields] == nil then
|
||||||
|
return false, build_error_with_context(context, "Rule exception item "..name..": field name "..fields.." is not a supported filter field"), warnings
|
||||||
|
end
|
||||||
|
if defined_comp_operators[comps] == nil then
|
||||||
|
return false, build_error_with_context(context, "Rule exception item "..name..": comparison operator "..comps.." is not a supported comparison operator"), warnings
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function load_rules_doc(rules_mgr, doc, load_state)
|
function load_rules_doc(rules_mgr, doc, load_state)
|
||||||
|
|
||||||
|
local warnings = {}
|
||||||
|
|
||||||
-- Iterate over yaml list. In this pass, all we're doing is
|
-- Iterate over yaml list. In this pass, all we're doing is
|
||||||
-- populating the set of rules, macros, and lists. We're not
|
-- populating the set of rules, macros, and lists. We're not
|
||||||
-- expanding/compiling anything yet. All that will happen in a
|
-- expanding/compiling anything yet. All that will happen in a
|
||||||
@@ -279,7 +374,7 @@ function load_rules_doc(rules_mgr, doc, load_state)
|
|||||||
load_state.indices[load_state.cur_item_idx])
|
load_state.indices[load_state.cur_item_idx])
|
||||||
|
|
||||||
if (not (type(v) == "table")) then
|
if (not (type(v) == "table")) then
|
||||||
return false, build_error_with_context(context, "Unexpected element of type " ..type(v)..". Each element should be a yaml associative array.")
|
return false, build_error_with_context(context, "Unexpected element of type " ..type(v)..". Each element should be a yaml associative array."), warnings
|
||||||
end
|
end
|
||||||
|
|
||||||
v['context'] = context
|
v['context'] = context
|
||||||
@@ -291,13 +386,13 @@ function load_rules_doc(rules_mgr, doc, load_state)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if falco_rules.engine_version(rules_mgr) < v['required_engine_version'] then
|
if falco_rules.engine_version(rules_mgr) < v['required_engine_version'] then
|
||||||
return false, build_error_with_context(v['context'], "Rules require engine version "..v['required_engine_version']..", but engine version is "..falco_rules.engine_version(rules_mgr))
|
return false, build_error_with_context(v['context'], "Rules require engine version "..v['required_engine_version']..", but engine version is "..falco_rules.engine_version(rules_mgr)), warnings
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif (v['macro']) then
|
elseif (v['macro']) then
|
||||||
|
|
||||||
if (v['macro'] == nil or type(v['macro']) == "table") then
|
if (v['macro'] == nil or type(v['macro']) == "table") then
|
||||||
return false, build_error_with_context(v['context'], "Macro name is empty")
|
return false, build_error_with_context(v['context'], "Macro name is empty"), warnings
|
||||||
end
|
end
|
||||||
|
|
||||||
if v['source'] == nil then
|
if v['source'] == nil then
|
||||||
@@ -310,7 +405,7 @@ function load_rules_doc(rules_mgr, doc, load_state)
|
|||||||
|
|
||||||
for j, field in ipairs({'condition'}) do
|
for j, field in ipairs({'condition'}) do
|
||||||
if (v[field] == nil) then
|
if (v[field] == nil) then
|
||||||
return false, build_error_with_context(v['context'], "Macro must have property "..field)
|
return false, build_error_with_context(v['context'], "Macro must have property "..field), warnings
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -323,7 +418,7 @@ function load_rules_doc(rules_mgr, doc, load_state)
|
|||||||
|
|
||||||
if append then
|
if append then
|
||||||
if state.macros_by_name[v['macro']] == nil then
|
if state.macros_by_name[v['macro']] == nil then
|
||||||
return false, build_error_with_context(v['context'], "Macro " ..v['macro'].. " has 'append' key but no macro by that name already exists")
|
return false, build_error_with_context(v['context'], "Macro " ..v['macro'].. " has 'append' key but no macro by that name already exists"), warnings
|
||||||
end
|
end
|
||||||
|
|
||||||
state.macros_by_name[v['macro']]['condition'] = state.macros_by_name[v['macro']]['condition'] .. " " .. v['condition']
|
state.macros_by_name[v['macro']]['condition'] = state.macros_by_name[v['macro']]['condition'] .. " " .. v['condition']
|
||||||
@@ -338,7 +433,7 @@ function load_rules_doc(rules_mgr, doc, load_state)
|
|||||||
elseif (v['list']) then
|
elseif (v['list']) then
|
||||||
|
|
||||||
if (v['list'] == nil or type(v['list']) == "table") then
|
if (v['list'] == nil or type(v['list']) == "table") then
|
||||||
return false, build_error_with_context(v['context'], "List name is empty")
|
return false, build_error_with_context(v['context'], "List name is empty"), warnings
|
||||||
end
|
end
|
||||||
|
|
||||||
if state.lists_by_name[v['list']] == nil then
|
if state.lists_by_name[v['list']] == nil then
|
||||||
@@ -347,7 +442,7 @@ function load_rules_doc(rules_mgr, doc, load_state)
|
|||||||
|
|
||||||
for j, field in ipairs({'items'}) do
|
for j, field in ipairs({'items'}) do
|
||||||
if (v[field] == nil) then
|
if (v[field] == nil) then
|
||||||
return false, build_error_with_context(v['context'], "List must have property "..field)
|
return false, build_error_with_context(v['context'], "List must have property "..field), warnings
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -360,7 +455,7 @@ function load_rules_doc(rules_mgr, doc, load_state)
|
|||||||
|
|
||||||
if append then
|
if append then
|
||||||
if state.lists_by_name[v['list']] == nil then
|
if state.lists_by_name[v['list']] == nil then
|
||||||
return false, build_error_with_context(v['context'], "List " ..v['list'].. " has 'append' key but no list by that name already exists")
|
return false, build_error_with_context(v['context'], "List " ..v['list'].. " has 'append' key but no list by that name already exists"), warnings
|
||||||
end
|
end
|
||||||
|
|
||||||
for j, elem in ipairs(v['items']) do
|
for j, elem in ipairs(v['items']) do
|
||||||
@@ -373,7 +468,7 @@ function load_rules_doc(rules_mgr, doc, load_state)
|
|||||||
elseif (v['rule']) then
|
elseif (v['rule']) then
|
||||||
|
|
||||||
if (v['rule'] == nil or type(v['rule']) == "table") then
|
if (v['rule'] == nil or type(v['rule']) == "table") then
|
||||||
return false, build_error_with_context(v['context'], "Rule name is empty")
|
return false, build_error_with_context(v['context'], "Rule name is empty"), warnings
|
||||||
end
|
end
|
||||||
|
|
||||||
-- By default, if a rule's condition refers to an unknown
|
-- By default, if a rule's condition refers to an unknown
|
||||||
@@ -386,6 +481,13 @@ function load_rules_doc(rules_mgr, doc, load_state)
|
|||||||
v['source'] = "syscall"
|
v['source'] = "syscall"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Add an empty exceptions property to the rule if not
|
||||||
|
-- defined, but add a warning about defining one
|
||||||
|
if v['exceptions'] == nil then
|
||||||
|
warnings[#warnings + 1] = "Rule "..v['rule']..": consider adding an exceptions property to define supported exceptions fields"
|
||||||
|
v['exceptions'] = {}
|
||||||
|
end
|
||||||
|
|
||||||
-- Possibly append to the condition field of an existing rule
|
-- Possibly append to the condition field of an existing rule
|
||||||
append = false
|
append = false
|
||||||
|
|
||||||
@@ -393,21 +495,100 @@ function load_rules_doc(rules_mgr, doc, load_state)
|
|||||||
append = v['append']
|
append = v['append']
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Validate the contents of the rule exception
|
||||||
|
if next(v['exceptions']) ~= nil then
|
||||||
|
|
||||||
|
-- This validation only applies if append=false. append=true validation is handled below
|
||||||
|
if append == false then
|
||||||
|
|
||||||
|
for _, eitem in ipairs(v['exceptions']) do
|
||||||
|
|
||||||
|
if eitem['name'] == nil then
|
||||||
|
return false, build_error_with_context(v['context'], "Rule exception item must have name property"), warnings
|
||||||
|
end
|
||||||
|
|
||||||
|
if eitem['fields'] == nil then
|
||||||
|
return false, build_error_with_context(v['context'], "Rule exception item "..eitem['name']..": must have fields property with a list of fields"), warnings
|
||||||
|
end
|
||||||
|
|
||||||
|
if eitem['values'] == nil then
|
||||||
|
-- An empty values array is okay
|
||||||
|
eitem['values'] = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Different handling if the fields property is a single item vs a list
|
||||||
|
local valid, err
|
||||||
|
if type(eitem['fields']) == "table" then
|
||||||
|
valid, err = validate_exception_item_multi_fields(eitem, v['context'])
|
||||||
|
else
|
||||||
|
valid, err = validate_exception_item_single_field(eitem, v['context'])
|
||||||
|
end
|
||||||
|
|
||||||
|
if valid == false then
|
||||||
|
return valid, err
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if append then
|
if append then
|
||||||
|
|
||||||
-- For append rules, all you need is the condition
|
-- For append rules, either condition or exceptions must be specified
|
||||||
for j, field in ipairs({'condition'}) do
|
if (v['condition'] == nil and v['exceptions'] == nil) then
|
||||||
if (v[field] == nil) then
|
return false, build_error_with_context(v['context'], "Rule must have exceptions or condition property"), warnings
|
||||||
return false, build_error_with_context(v['context'], "Rule must have property "..field)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if state.rules_by_name[v['rule']] == nil then
|
if state.rules_by_name[v['rule']] == nil then
|
||||||
if state.skipped_rules_by_name[v['rule']] == nil then
|
if state.skipped_rules_by_name[v['rule']] == nil then
|
||||||
return false, build_error_with_context(v['context'], "Rule " ..v['rule'].. " has 'append' key but no rule by that name already exists")
|
return false, build_error_with_context(v['context'], "Rule " ..v['rule'].. " has 'append' key but no rule by that name already exists"), warnings
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
state.rules_by_name[v['rule']]['condition'] = state.rules_by_name[v['rule']]['condition'] .. " " .. v['condition']
|
|
||||||
|
if next(v['exceptions']) ~= nil then
|
||||||
|
|
||||||
|
for _, eitem in ipairs(v['exceptions']) do
|
||||||
|
local name = eitem['name']
|
||||||
|
local fields = eitem['fields']
|
||||||
|
local comps = eitem['comps']
|
||||||
|
|
||||||
|
if name == nil then
|
||||||
|
return false, build_error_with_context(v['context'], "Rule exception item must have name property"), warnings
|
||||||
|
end
|
||||||
|
|
||||||
|
-- You can't append exception fields or comps to a rule
|
||||||
|
if fields ~= nil then
|
||||||
|
return false, build_error_with_context(v['context'], "Can not append exception fields to existing rule, only values"), warnings
|
||||||
|
end
|
||||||
|
|
||||||
|
if comps ~= nil then
|
||||||
|
return false, build_error_with_context(v['context'], "Can not append exception comps to existing rule, only values"), warnings
|
||||||
|
end
|
||||||
|
|
||||||
|
-- You can append values. They are added to the
|
||||||
|
-- corresponding name, if it exists. If no
|
||||||
|
-- exception with that name exists, add a
|
||||||
|
-- warning.
|
||||||
|
if eitem['values'] ~= nil then
|
||||||
|
local found=false
|
||||||
|
for _, reitem in ipairs(state.rules_by_name[v['rule']]['exceptions']) do
|
||||||
|
if reitem['name'] == eitem['name'] then
|
||||||
|
found=true
|
||||||
|
for _, values in ipairs(eitem['values']) do
|
||||||
|
reitem['values'][#reitem['values'] + 1] = values
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if found == false then
|
||||||
|
warnings[#warnings + 1] = "Rule "..v['rule'].." with append=true: no set of fields matching name "..eitem['name']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if v['condition'] ~= nil then
|
||||||
|
state.rules_by_name[v['rule']]['condition'] = state.rules_by_name[v['rule']]['condition'] .. " " .. v['condition']
|
||||||
|
end
|
||||||
|
|
||||||
-- Add the current object to the context of the base rule
|
-- Add the current object to the context of the base rule
|
||||||
state.rules_by_name[v['rule']]['context'] = state.rules_by_name[v['rule']]['context'].."\n"..v['context']
|
state.rules_by_name[v['rule']]['context'] = state.rules_by_name[v['rule']]['context'].."\n"..v['context']
|
||||||
@@ -417,7 +598,7 @@ function load_rules_doc(rules_mgr, doc, load_state)
|
|||||||
|
|
||||||
for j, field in ipairs({'condition', 'output', 'desc', 'priority'}) do
|
for j, field in ipairs({'condition', 'output', 'desc', 'priority'}) do
|
||||||
if (v[field] == nil) then
|
if (v[field] == nil) then
|
||||||
return false, build_error_with_context(v['context'], "Rule must have property "..field)
|
return false, build_error_with_context(v['context'], "Rule must have property "..field), warnings
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -446,16 +627,99 @@ function load_rules_doc(rules_mgr, doc, load_state)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- Remove the context from the table, so the table is exactly what was parsed
|
|
||||||
local context = v['context']
|
local context = v['context']
|
||||||
v['context'] = nil
|
|
||||||
return false, build_error_with_context(context, "Unknown rule object: "..table.tostring(v))
|
arr = build_error_with_context(context, "Unknown top level object: "..table.tostring(v))
|
||||||
|
warnings[#warnings + 1] = arr[1]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return true, ""
|
return true, {}, warnings
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- cond and not ((proc.name=apk and fd.directory=/usr/lib/alpine) or (proc.name=npm and fd.directory=/usr/node/bin) or ...)
|
||||||
|
function build_exception_condition_string_multi_fields(eitem)
|
||||||
|
|
||||||
|
local fields = eitem['fields']
|
||||||
|
local comps = eitem['comps']
|
||||||
|
|
||||||
|
local icond = ""
|
||||||
|
|
||||||
|
for i, values in ipairs(eitem['values']) do
|
||||||
|
|
||||||
|
if #fields ~= #values then
|
||||||
|
return nil, "Exception item "..eitem['name']..": fields and values lists must have equal length"
|
||||||
|
end
|
||||||
|
|
||||||
|
if icond ~= "" then
|
||||||
|
icond=icond.." or "
|
||||||
|
end
|
||||||
|
|
||||||
|
icond=icond.."("
|
||||||
|
|
||||||
|
for k=1,#fields do
|
||||||
|
if k > 1 then
|
||||||
|
icond=icond.." and "
|
||||||
|
end
|
||||||
|
local ival = values[k]
|
||||||
|
local istr = ""
|
||||||
|
|
||||||
|
-- If ival is a table, express it as (titem1, titem2, etc)
|
||||||
|
if type(ival) == "table" then
|
||||||
|
istr = "("
|
||||||
|
for _, item in ipairs(ival) do
|
||||||
|
if istr ~= "(" then
|
||||||
|
istr = istr..", "
|
||||||
|
end
|
||||||
|
istr = istr..quote_item(item)
|
||||||
|
end
|
||||||
|
istr = istr..")"
|
||||||
|
else
|
||||||
|
-- If the corresponding operator is one that works on lists, possibly add surrounding parentheses.
|
||||||
|
if defined_list_comp_operators[comps[k]] then
|
||||||
|
istr = paren_item(ival)
|
||||||
|
else
|
||||||
|
-- Quote the value if not already quoted
|
||||||
|
istr = quote_item(ival)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
icond = icond..fields[k].." "..comps[k].." "..istr
|
||||||
|
end
|
||||||
|
|
||||||
|
icond=icond..")"
|
||||||
|
end
|
||||||
|
|
||||||
|
return icond, nil
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function build_exception_condition_string_single_field(eitem)
|
||||||
|
|
||||||
|
local icond = ""
|
||||||
|
|
||||||
|
for i, value in ipairs(eitem['values']) do
|
||||||
|
|
||||||
|
if icond == "" then
|
||||||
|
icond = "("..eitem['fields'].." "..eitem['comps'].." ("
|
||||||
|
else
|
||||||
|
icond = icond..", "
|
||||||
|
end
|
||||||
|
|
||||||
|
icond = icond..quote_item(value)
|
||||||
|
end
|
||||||
|
|
||||||
|
icond = icond.."))"
|
||||||
|
|
||||||
|
return icond, nil
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns:
|
||||||
|
-- - Load Result: bool
|
||||||
|
-- - required engine version. will be nil when load result is false
|
||||||
|
-- - List of Errors
|
||||||
|
-- - List of Warnings
|
||||||
function load_rules(sinsp_lua_parser,
|
function load_rules(sinsp_lua_parser,
|
||||||
json_lua_parser,
|
json_lua_parser,
|
||||||
rules_content,
|
rules_content,
|
||||||
@@ -466,6 +730,8 @@ function load_rules(sinsp_lua_parser,
|
|||||||
replace_container_info,
|
replace_container_info,
|
||||||
min_priority)
|
min_priority)
|
||||||
|
|
||||||
|
local warnings = {}
|
||||||
|
|
||||||
local load_state = {lines={}, indices={}, cur_item_idx=0, min_priority=min_priority, required_engine_version=0}
|
local load_state = {lines={}, indices={}, cur_item_idx=0, min_priority=min_priority, required_engine_version=0}
|
||||||
|
|
||||||
load_state.lines, load_state.indices = split_lines(rules_content)
|
load_state.lines, load_state.indices = split_lines(rules_content)
|
||||||
@@ -487,36 +753,42 @@ function load_rules(sinsp_lua_parser,
|
|||||||
row = tonumber(row)
|
row = tonumber(row)
|
||||||
col = tonumber(col)
|
col = tonumber(col)
|
||||||
|
|
||||||
return false, build_error(load_state.lines, row, 3, docs)
|
return false, nil, build_error(load_state.lines, row, 3, docs), warnings
|
||||||
end
|
end
|
||||||
|
|
||||||
if docs == nil then
|
if docs == nil then
|
||||||
-- An empty rules file is acceptable
|
-- An empty rules file is acceptable
|
||||||
return true, load_state.required_engine_version
|
return true, load_state.required_engine_version, {}, warnings
|
||||||
end
|
end
|
||||||
|
|
||||||
if type(docs) ~= "table" then
|
if type(docs) ~= "table" then
|
||||||
return false, build_error(load_state.lines, 1, 1, "Rules content is not yaml")
|
return false, nil, build_error(load_state.lines, 1, 1, "Rules content is not yaml"), warnings
|
||||||
end
|
end
|
||||||
|
|
||||||
for docidx, doc in ipairs(docs) do
|
for docidx, doc in ipairs(docs) do
|
||||||
|
|
||||||
if type(doc) ~= "table" then
|
if type(doc) ~= "table" then
|
||||||
return false, build_error(load_state.lines, 1, 1, "Rules content is not yaml")
|
return false, nil, build_error(load_state.lines, 1, 1, "Rules content is not yaml"), warnings
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Look for non-numeric indices--implies that document is not array
|
-- Look for non-numeric indices--implies that document is not array
|
||||||
-- of objects.
|
-- of objects.
|
||||||
for key, val in pairs(doc) do
|
for key, val in pairs(doc) do
|
||||||
if type(key) ~= "number" then
|
if type(key) ~= "number" then
|
||||||
return false, build_error(load_state.lines, 1, 1, "Rules content is not yaml array of objects")
|
return false, nil, build_error(load_state.lines, 1, 1, "Rules content is not yaml array of objects"), warnings
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
res, errstr = load_rules_doc(rules_mgr, doc, load_state)
|
res, errors, doc_warnings = load_rules_doc(rules_mgr, doc, load_state)
|
||||||
|
|
||||||
|
if (doc_warnings ~= nil) then
|
||||||
|
for idx, warning in pairs(doc_warnings) do
|
||||||
|
table.insert(warnings, warning)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if not res then
|
if not res then
|
||||||
return res, errstr
|
return res, nil, errors, warnings
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -538,7 +810,7 @@ function load_rules(sinsp_lua_parser,
|
|||||||
-- the items and expand any references to the items in the list
|
-- the items and expand any references to the items in the list
|
||||||
for i, item in ipairs(v['items']) do
|
for i, item in ipairs(v['items']) do
|
||||||
if (state.lists[item] == nil) then
|
if (state.lists[item] == nil) then
|
||||||
items[#items+1] = item
|
items[#items+1] = quote_item(item)
|
||||||
else
|
else
|
||||||
for i, exp_item in ipairs(state.lists[item].items) do
|
for i, exp_item in ipairs(state.lists[item].items) do
|
||||||
items[#items+1] = exp_item
|
items[#items+1] = exp_item
|
||||||
@@ -556,7 +828,7 @@ function load_rules(sinsp_lua_parser,
|
|||||||
local status, ast = compiler.compile_macro(v['condition'], state.macros, state.lists)
|
local status, ast = compiler.compile_macro(v['condition'], state.macros, state.lists)
|
||||||
|
|
||||||
if status == false then
|
if status == false then
|
||||||
return false, build_error_with_context(v['context'], ast)
|
return false, nil, build_error_with_context(v['context'], ast), warnings
|
||||||
end
|
end
|
||||||
|
|
||||||
if v['source'] == "syscall" then
|
if v['source'] == "syscall" then
|
||||||
@@ -572,6 +844,38 @@ function load_rules(sinsp_lua_parser,
|
|||||||
|
|
||||||
local v = state.rules_by_name[name]
|
local v = state.rules_by_name[name]
|
||||||
|
|
||||||
|
local econd = ""
|
||||||
|
|
||||||
|
-- Turn exceptions into condition strings and add them to each
|
||||||
|
-- rule's condition
|
||||||
|
for _, eitem in ipairs(v['exceptions']) do
|
||||||
|
|
||||||
|
local icond, err
|
||||||
|
if type(eitem['fields']) == "table" then
|
||||||
|
icond, err = build_exception_condition_string_multi_fields(eitem)
|
||||||
|
else
|
||||||
|
icond, err = build_exception_condition_string_single_field(eitem)
|
||||||
|
end
|
||||||
|
|
||||||
|
if err ~= nil then
|
||||||
|
return false, nil, build_error_with_context(v['context'], err), warnings
|
||||||
|
end
|
||||||
|
|
||||||
|
if icond ~= "" then
|
||||||
|
if econd == "" then
|
||||||
|
econd = econd.." and not ("..icond
|
||||||
|
else
|
||||||
|
econd = econd.." or "..icond
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if econd ~= "" then
|
||||||
|
econd=econd..")"
|
||||||
|
|
||||||
|
state.rules_by_name[name]['condition'] = "("..state.rules_by_name[name]['condition']..") "..econd
|
||||||
|
end
|
||||||
|
|
||||||
warn_evttypes = true
|
warn_evttypes = true
|
||||||
if v['warn_evttypes'] ~= nil then
|
if v['warn_evttypes'] ~= nil then
|
||||||
warn_evttypes = v['warn_evttypes']
|
warn_evttypes = v['warn_evttypes']
|
||||||
@@ -581,7 +885,7 @@ function load_rules(sinsp_lua_parser,
|
|||||||
state.macros, state.lists)
|
state.macros, state.lists)
|
||||||
|
|
||||||
if status == false then
|
if status == false then
|
||||||
return false, build_error_with_context(v['context'], filter_ast)
|
return false, nil, build_error_with_context(v['context'], filter_ast), warnings
|
||||||
end
|
end
|
||||||
|
|
||||||
local evtttypes = {}
|
local evtttypes = {}
|
||||||
@@ -631,12 +935,10 @@ function load_rules(sinsp_lua_parser,
|
|||||||
end
|
end
|
||||||
|
|
||||||
if not found then
|
if not found then
|
||||||
if v['skip-if-unknown-filter'] then
|
msg = "rule \""..v['rule'].."\" contains unknown filter "..filter
|
||||||
if verbose then
|
warnings[#warnings + 1] = msg
|
||||||
print("Skipping rule \""..v['rule'].."\" that contains unknown filter "..filter)
|
|
||||||
end
|
if not v['skip-if-unknown-filter'] then
|
||||||
goto next_rule
|
|
||||||
else
|
|
||||||
error("Rule \""..v['rule'].."\" contains unknown filter "..filter)
|
error("Rule \""..v['rule'].."\" contains unknown filter "..filter)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -719,30 +1021,30 @@ function load_rules(sinsp_lua_parser,
|
|||||||
formatter = formats.formatter(v['source'], v['output'])
|
formatter = formats.formatter(v['source'], v['output'])
|
||||||
formats.free_formatter(v['source'], formatter)
|
formats.free_formatter(v['source'], formatter)
|
||||||
else
|
else
|
||||||
return false, build_error_with_context(v['context'], "Unexpected type in load_rule: "..filter_ast.type)
|
return false, nil, build_error_with_context(v['context'], "Unexpected type in load_rule: "..filter_ast.type), warnings
|
||||||
end
|
end
|
||||||
|
|
||||||
::next_rule::
|
::next_rule::
|
||||||
end
|
end
|
||||||
|
|
||||||
if verbose then
|
-- Print info on any dangling lists or macros that were not used anywhere
|
||||||
-- Print info on any dangling lists or macros that were not used anywhere
|
for name, macro in pairs(state.macros) do
|
||||||
for name, macro in pairs(state.macros) do
|
if macro.used == false then
|
||||||
if macro.used == false then
|
msg = "macro "..name.." not refered to by any rule/macro"
|
||||||
print("Warning: macro "..name.." not refered to by any rule/macro")
|
warnings[#warnings + 1] = msg
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
for name, list in pairs(state.lists) do
|
for name, list in pairs(state.lists) do
|
||||||
if list.used == false then
|
if list.used == false then
|
||||||
print("Warning: list "..name.." not refered to by any rule/macro/list")
|
msg = "list "..name.." not refered to by any rule/macro/list"
|
||||||
end
|
warnings[#warnings + 1] = msg
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
io.flush()
|
io.flush()
|
||||||
|
|
||||||
return true, load_state.required_engine_version
|
return true, load_state.required_engine_version, {}, warnings
|
||||||
end
|
end
|
||||||
|
|
||||||
local rule_fmt = "%-50s %s"
|
local rule_fmt = "%-50s %s"
|
||||||
|
|||||||
@@ -14,8 +14,9 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "rules.h"
|
#include "rules.h"
|
||||||
#include "logger.h"
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
@@ -219,6 +220,31 @@ int falco_rules::engine_version(lua_State *ls)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::list<std::string> get_lua_table_values(lua_State *ls, int idx)
|
||||||
|
{
|
||||||
|
std::list<std::string> ret;
|
||||||
|
|
||||||
|
if (lua_isnil(ls, idx)) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushnil(ls); /* first key */
|
||||||
|
while (lua_next(ls, idx-1) != 0) {
|
||||||
|
// key is at index -2, value is at index
|
||||||
|
// -1. We want the values.
|
||||||
|
if (! lua_isstring(ls, -1)) {
|
||||||
|
std::string err = "Non-string value in table of strings";
|
||||||
|
throw falco_exception(err);
|
||||||
|
}
|
||||||
|
ret.push_back(string(lua_tostring(ls, -1)));
|
||||||
|
|
||||||
|
// Remove value, keep key for next iteration
|
||||||
|
lua_pop(ls, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void falco_rules::load_rules(const string &rules_content,
|
void falco_rules::load_rules(const string &rules_content,
|
||||||
bool verbose, bool all_events,
|
bool verbose, bool all_events,
|
||||||
string &extra, bool replace_container_info,
|
string &extra, bool replace_container_info,
|
||||||
@@ -424,7 +450,7 @@ void falco_rules::load_rules(const string &rules_content,
|
|||||||
lua_pushstring(m_ls, extra.c_str());
|
lua_pushstring(m_ls, extra.c_str());
|
||||||
lua_pushboolean(m_ls, (replace_container_info ? 1 : 0));
|
lua_pushboolean(m_ls, (replace_container_info ? 1 : 0));
|
||||||
lua_pushnumber(m_ls, min_priority);
|
lua_pushnumber(m_ls, min_priority);
|
||||||
if(lua_pcall(m_ls, 9, 2, 0) != 0)
|
if(lua_pcall(m_ls, 9, 4, 0) != 0)
|
||||||
{
|
{
|
||||||
const char* lerr = lua_tostring(m_ls, -1);
|
const char* lerr = lua_tostring(m_ls, -1);
|
||||||
|
|
||||||
@@ -433,20 +459,49 @@ void falco_rules::load_rules(const string &rules_content,
|
|||||||
throw falco_exception(err);
|
throw falco_exception(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Either returns (true, required_engine_version), or (false, error string)
|
// Returns:
|
||||||
bool successful = lua_toboolean(m_ls, -2);
|
// Load result: bool
|
||||||
|
// required engine version: will be nil when load result is false
|
||||||
|
// array of errors
|
||||||
|
// array of warnings
|
||||||
|
bool successful = lua_toboolean(m_ls, -4);
|
||||||
|
required_engine_version = lua_tonumber(m_ls, -3);
|
||||||
|
std::list<std::string> errors = get_lua_table_values(m_ls, -2);
|
||||||
|
std::list<std::string> warnings = get_lua_table_values(m_ls, -1);
|
||||||
|
|
||||||
if(successful)
|
// Concatenate errors/warnings
|
||||||
|
std::ostringstream os;
|
||||||
|
if (errors.size() > 0)
|
||||||
{
|
{
|
||||||
required_engine_version = lua_tonumber(m_ls, -1);
|
os << errors.size() << " errors:" << std::endl;
|
||||||
}
|
for(auto err : errors)
|
||||||
else
|
{
|
||||||
{
|
os << err << std::endl;
|
||||||
std::string err = lua_tostring(m_ls, -1);
|
}
|
||||||
throw falco_exception(err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pop(m_ls, 2);
|
if (warnings.size() > 0)
|
||||||
|
{
|
||||||
|
os << warnings.size() << " warnings:" << std::endl;
|
||||||
|
for(auto warn : warnings)
|
||||||
|
{
|
||||||
|
os << warn << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!successful)
|
||||||
|
{
|
||||||
|
throw falco_exception(os.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose && os.str() != "") {
|
||||||
|
// We don't really have a logging callback
|
||||||
|
// from the falco engine, but this would be a
|
||||||
|
// good place to use it.
|
||||||
|
fprintf(stderr, "When reading rules content: %s", os.str().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pop(m_ls, 4);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw falco_exception("No function " + m_lua_load_rules + " found in lua rule module");
|
throw falco_exception("No function " + m_lua_load_rules + " found in lua rule module");
|
||||||
|
|||||||
@@ -816,7 +816,7 @@ int falco_init(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
catch(falco_exception &e)
|
catch(falco_exception &e)
|
||||||
{
|
{
|
||||||
printf("%s%s\n", prefix.c_str(), e.what());
|
printf("%s%s", prefix.c_str(), e.what());
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
printf("%sOk\n", prefix.c_str());
|
printf("%sOk\n", prefix.c_str());
|
||||||
@@ -873,7 +873,15 @@ int falco_init(int argc, char **argv)
|
|||||||
falco_logger::log(LOG_INFO, "Loading rules from file " + filename + ":\n");
|
falco_logger::log(LOG_INFO, "Loading rules from file " + filename + ":\n");
|
||||||
uint64_t required_engine_version;
|
uint64_t required_engine_version;
|
||||||
|
|
||||||
engine->load_rules_file(filename, verbose, all_events, required_engine_version);
|
try {
|
||||||
|
engine->load_rules_file(filename, verbose, all_events, required_engine_version);
|
||||||
|
}
|
||||||
|
catch(falco_exception &e)
|
||||||
|
{
|
||||||
|
std::string prefix = "Could not load rules file " + filename + ": ";
|
||||||
|
|
||||||
|
throw falco_exception(prefix + e.what());
|
||||||
|
}
|
||||||
required_engine_versions[filename] = required_engine_version;
|
required_engine_versions[filename] = required_engine_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1184,8 +1192,8 @@ int falco_init(int argc, char **argv)
|
|||||||
falco_logger::log(LOG_ERR, "Unable to load the driver.\n");
|
falco_logger::log(LOG_ERR, "Unable to load the driver.\n");
|
||||||
}
|
}
|
||||||
open_f(inspector);
|
open_f(inspector);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rethrow_exception(current_exception());
|
rethrow_exception(current_exception());
|
||||||
}
|
}
|
||||||
@@ -1294,7 +1302,7 @@ int falco_init(int argc, char **argv)
|
|||||||
|
|
||||||
if(!trace_filename.empty() && !trace_is_scap)
|
if(!trace_filename.empty() && !trace_is_scap)
|
||||||
{
|
{
|
||||||
#ifndef MINIMAL_BUILD
|
#ifndef MINIMAL_BUILD
|
||||||
read_k8s_audit_trace_file(engine,
|
read_k8s_audit_trace_file(engine,
|
||||||
outputs,
|
outputs,
|
||||||
trace_filename);
|
trace_filename);
|
||||||
|
|||||||
Reference in New Issue
Block a user