sg-aks-workshop/cluster-config/falco.yaml

2308 строки
158 KiB
YAML

---
# Source: falco/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: sysdig-falco
namespace: falco
labels:
app: sysdig-falco
chart: "falco-1.1.1"
release: "sysdig-falco"
heritage: "Helm"
data:
falco.yaml: |-
# File(s) or Directories containing Falco rules, loaded at startup.
# The name "rules_file" is only for backwards compatibility.
# If the entry is a file, it will be read directly. If the entry is a directory,
# every file in that directory will be read, in alphabetical order.
#
# falco_rules.yaml ships with the falco package and is overridden with
# every new software version. falco_rules.local.yaml is only created
# if it doesn't exist. If you want to customize the set of rules, add
# your customizations to falco_rules.local.yaml.
#
# The files will be read in the order presented here, so make sure if
# you have overrides they appear in later files.
rules_file:
- /etc/falco/falco_rules.yaml
- /etc/falco/falco_rules.local.yaml
- /etc/falco/k8s_audit_rules.yaml
- /etc/falco/rules.d
# If true, the times displayed in log messages and output messages
# will be in ISO 8601. By default, times are displayed in the local
# time zone, as governed by /etc/localtime.
time_format_iso_8601: false
# Whether to output events in json or text
json_output: false
# When using json output, whether or not to include the "output" property
# itself (e.g. "File below a known binary directory opened for writing
# (user=root ....") in the json output.
json_include_output_property: true
# Send information logs to stderr and/or syslog Note these are *not* security
# notification logs! These are just Falco lifecycle (and possibly error) logs.
log_stderr: true
log_syslog: true
# Minimum log level to include in logs. Note: these levels are
# separate from the priority field of rules. This refers only to the
# log level of falco's internal logging. Can be one of "emergency",
# "alert", "critical", "error", "warning", "notice", "info", "debug".
log_level: info
# Minimum rule priority level to load and run. All rules having a
# priority more severe than this level will be loaded/run. Can be one
# of "emergency", "alert", "critical", "error", "warning", "notice",
# "info", "debug".
priority: debug
# Whether or not output to any of the output channels below is
# buffered. Defaults to false
buffered_outputs: false
# Falco uses a shared buffer between the kernel and userspace to pass
# system call information. When falco detects that this buffer is
# full and system calls have been dropped, it can take one or more of
# the following actions:
# - "ignore": do nothing. If an empty list is provided, ignore is assumed.
# - "log": log a CRITICAL message noting that the buffer was full.
# - "alert": emit a falco alert noting that the buffer was full.
# - "exit": exit falco with a non-zero rc.
#
# The rate at which log/alert messages are emitted is governed by a
# token bucket. The rate corresponds to one message every 30 seconds
# with a burst of 10 messages.
syscall_event_drops:
actions:
- log
- alert
rate: 0.03333
max_burst: 10
# A throttling mechanism implemented as a token bucket limits the
# rate of falco notifications. This throttling is controlled by the following configuration
# options:
# - rate: the number of tokens (i.e. right to send a notification)
# gained per second. Defaults to 1.
# - max_burst: the maximum number of tokens outstanding. Defaults to 1000.
#
# With these defaults, falco could send up to 1000 notifications after
# an initial quiet period, and then up to 1 notification per second
# afterward. It would gain the full burst back after 1000 seconds of
# no activity.
outputs:
rate: 1
max_burst: 1000
# Where security notifications should go.
# Multiple outputs can be enabled.
syslog_output:
enabled: true
# If keep_alive is set to true, the file will be opened once and
# continuously written to, with each output message on its own
# line. If keep_alive is set to false, the file will be re-opened
# for each output message.
#
# Also, the file will be closed and reopened if falco is signaled with
# SIGUSR1.
file_output:
enabled: false
keep_alive: false
filename: ./events.txt
stdout_output:
enabled: true
# Falco contains an embedded webserver that can be used to accept K8s
# Audit Events. These config options control the behavior of that
# webserver. (By default, the webserver is disabled).
#
# The ssl_certificate is a combination SSL Certificate and corresponding
# key contained in a single file. You can generate a key/cert as follows:
#
# $ openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
# $ cat certificate.pem key.pem > falco.pem
# $ sudo cp falco.pem /etc/falco/falco.pem
webserver:
enabled: true
listen_port: 8765
k8s_audit_endpoint: /k8s-audit
ssl_enabled: false
ssl_certificate: /etc/falco/falco.pem
# Possible additional things you might want to do with program output:
# - send to a slack webhook:
# program: "\"jq '{text: .output}' | curl -d @- -X POST https://hooks.slack.com/services/XXX\""
# - logging (alternate method than syslog):
# program: logger -t falco-test
# - send over a network connection:
# program: nc host.example.com 80
# If keep_alive is set to true, the program will be started once and
# continuously written to, with each output message on its own
# line. If keep_alive is set to false, the program will be re-spawned
# for each output message.
#
# Also, the program will be closed and reopened if falco is signaled with
# SIGUSR1.
program_output:
enabled: false
keep_alive: false
program: |
mail -s "Falco Notification" someone@example.com
http_output:
enabled: false
url: http://some.url
application_rules.yaml: |
#
# Copyright (C) 2019 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.
#
- required_engine_version: 2
################################################################
# By default all application-related rules are disabled for
# performance reasons. Depending on the application(s) you use,
# uncomment the corresponding rule definitions for
# application-specific activity monitoring.
################################################################
# Elasticsearch ports
- macro: elasticsearch_cluster_port
condition: fd.sport=9300
- macro: elasticsearch_api_port
condition: fd.sport=9200
- macro: elasticsearch_port
condition: elasticsearch_cluster_port or elasticsearch_api_port
# - rule: Elasticsearch unexpected network inbound traffic
# desc: inbound network traffic to elasticsearch on a port other than the standard ports
# condition: user.name = elasticsearch and inbound and not elasticsearch_port
# output: "Inbound network traffic to Elasticsearch on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Elasticsearch unexpected network outbound traffic
# desc: outbound network traffic from elasticsearch on a port other than the standard ports
# condition: user.name = elasticsearch and outbound and not elasticsearch_cluster_port
# output: "Outbound network traffic from Elasticsearch on unexpected port (connection=%fd.name)"
# priority: WARNING
# ActiveMQ ports
- macro: activemq_cluster_port
condition: fd.sport=61616
- macro: activemq_web_port
condition: fd.sport=8161
- macro: activemq_port
condition: activemq_web_port or activemq_cluster_port
# - rule: Activemq unexpected network inbound traffic
# desc: inbound network traffic to activemq on a port other than the standard ports
# condition: user.name = activemq and inbound and not activemq_port
# output: "Inbound network traffic to ActiveMQ on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Activemq unexpected network outbound traffic
# desc: outbound network traffic from activemq on a port other than the standard ports
# condition: user.name = activemq and outbound and not activemq_cluster_port
# output: "Outbound network traffic from ActiveMQ on unexpected port (connection=%fd.name)"
# priority: WARNING
# Cassandra ports
# https://docs.datastax.com/en/cassandra/2.0/cassandra/security/secureFireWall_r.html
- macro: cassandra_thrift_client_port
condition: fd.sport=9160
- macro: cassandra_cql_port
condition: fd.sport=9042
- macro: cassandra_cluster_port
condition: fd.sport=7000
- macro: cassandra_ssl_cluster_port
condition: fd.sport=7001
- macro: cassandra_jmx_port
condition: fd.sport=7199
- macro: cassandra_port
condition: >
cassandra_thrift_client_port or
cassandra_cql_port or cassandra_cluster_port or
cassandra_ssl_cluster_port or cassandra_jmx_port
# - rule: Cassandra unexpected network inbound traffic
# desc: inbound network traffic to cassandra on a port other than the standard ports
# condition: user.name = cassandra and inbound and not cassandra_port
# output: "Inbound network traffic to Cassandra on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Cassandra unexpected network outbound traffic
# desc: outbound network traffic from cassandra on a port other than the standard ports
# condition: user.name = cassandra and outbound and not (cassandra_ssl_cluster_port or cassandra_cluster_port)
# output: "Outbound network traffic from Cassandra on unexpected port (connection=%fd.name)"
# priority: WARNING
# Couchdb ports
# https://github.com/davisp/couchdb/blob/master/etc/couchdb/local.ini
- macro: couchdb_httpd_port
condition: fd.sport=5984
- macro: couchdb_httpd_ssl_port
condition: fd.sport=6984
# xxx can't tell what clustering ports are used. not writing rules for this
# yet.
# Fluentd ports
- macro: fluentd_http_port
condition: fd.sport=9880
- macro: fluentd_forward_port
condition: fd.sport=24224
# - rule: Fluentd unexpected network inbound traffic
# desc: inbound network traffic to fluentd on a port other than the standard ports
# condition: user.name = td-agent and inbound and not (fluentd_forward_port or fluentd_http_port)
# output: "Inbound network traffic to Fluentd on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Tdagent unexpected network outbound traffic
# desc: outbound network traffic from fluentd on a port other than the standard ports
# condition: user.name = td-agent and outbound and not fluentd_forward_port
# output: "Outbound network traffic from Fluentd on unexpected port (connection=%fd.name)"
# priority: WARNING
# Gearman ports
# http://gearman.org/protocol/
# - rule: Gearman unexpected network outbound traffic
# desc: outbound network traffic from gearman on a port other than the standard ports
# condition: user.name = gearman and outbound and outbound and not fd.sport = 4730
# output: "Outbound network traffic from Gearman on unexpected port (connection=%fd.name)"
# priority: WARNING
# Zookeeper
- macro: zookeeper_port
condition: fd.sport = 2181
# Kafka ports
# - rule: Kafka unexpected network inbound traffic
# desc: inbound network traffic to kafka on a port other than the standard ports
# condition: user.name = kafka and inbound and fd.sport != 9092
# output: "Inbound network traffic to Kafka on unexpected port (connection=%fd.name)"
# priority: WARNING
# Memcached ports
# - rule: Memcached unexpected network inbound traffic
# desc: inbound network traffic to memcached on a port other than the standard ports
# condition: user.name = memcached and inbound and fd.sport != 11211
# output: "Inbound network traffic to Memcached on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Memcached unexpected network outbound traffic
# desc: any outbound network traffic from memcached. memcached never initiates outbound connections.
# condition: user.name = memcached and outbound
# output: "Unexpected Memcached outbound connection (connection=%fd.name)"
# priority: WARNING
# MongoDB ports
- macro: mongodb_server_port
condition: fd.sport = 27017
- macro: mongodb_shardserver_port
condition: fd.sport = 27018
- macro: mongodb_configserver_port
condition: fd.sport = 27019
- macro: mongodb_webserver_port
condition: fd.sport = 28017
# - rule: Mongodb unexpected network inbound traffic
# desc: inbound network traffic to mongodb on a port other than the standard ports
# condition: >
# user.name = mongodb and inbound and not (mongodb_server_port or
# mongodb_shardserver_port or mongodb_configserver_port or mongodb_webserver_port)
# output: "Inbound network traffic to MongoDB on unexpected port (connection=%fd.name)"
# priority: WARNING
# MySQL ports
# - rule: Mysql unexpected network inbound traffic
# desc: inbound network traffic to mysql on a port other than the standard ports
# condition: user.name = mysql and inbound and fd.sport != 3306
# output: "Inbound network traffic to MySQL on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: HTTP server unexpected network inbound traffic
# desc: inbound network traffic to a http server program on a port other than the standard ports
# condition: proc.name in (http_server_binaries) and inbound and fd.sport != 80 and fd.sport != 443
# output: "Inbound network traffic to HTTP Server on unexpected port (connection=%fd.name)"
# priority: WARNING
falco_rules.local.yaml: |
#
# Copyright (C) 2019 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.
#
####################
# Your custom rules!
####################
# Add new rules, like this one
# - rule: The program "sudo" is run in a container
# desc: An event will trigger every time you run sudo in a container
# condition: evt.type = execve and evt.dir=< and container.id != host and proc.name = sudo
# output: "Sudo run in container (user=%user.name %container.info parent=%proc.pname cmdline=%proc.cmdline)"
# priority: ERROR
# tags: [users, container]
# Or override/append to any rule, macro, or list from the Default Rules
falco_rules.yaml: "#\n# Copyright (C) 2019 The Falco Authors.\n#\n#\n# Licensed under
the Apache License, Version 2.0 (the \"License\");\n# you may not use this file
except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#
\ http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable
law or agreed to in writing, software\n# distributed under the License is distributed
on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied.\n# See the License for the specific language governing permissions and\n#
limitations under the License.\n#\n\n# See xxx for details on falco engine and rules
versioning. Currently,\n# this specific rules file is compatible with engine version
0\n# (e.g. falco releases <= 0.13.1), so we'll keep the\n# required_engine_version
lines commented out, so maintain\n# compatibility with older falco releases. With
the first incompatible\n# change to this rules file, we'll uncomment this line and
set it to\n# the falco engine version in use at the time.\n#\n#- required_engine_version:
2\n\n# Currently disabled as read/write are ignored syscalls. The nearly\n# similar
open_write/open_read check for files being opened for\n# reading/writing.\n# - macro:
write\n# condition: (syscall.type=write and fd.type in (file, directory))\n# -
macro: read\n# condition: (syscall.type=read and evt.dir=> and fd.type in (file,
directory))\n\n- macro: open_write\n condition: (evt.type=open or evt.type=openat)
and evt.is_open_write=true and fd.typechar='f' and fd.num>=0\n\n- macro: open_read\n
\ condition: (evt.type=open or evt.type=openat) and evt.is_open_read=true and fd.typechar='f'
and fd.num>=0\n\n- macro: open_directory\n condition: (evt.type=open or evt.type=openat)
and evt.is_open_read=true and fd.typechar='d' and fd.num>=0\n\n- macro: never_true\n
\ condition: (evt.num=0)\n\n- macro: always_true\n condition: (evt.num>=0)\n\n#
In some cases, such as dropped system call events, information about\n# the process
name may be missing. For some rules that really depend\n# on the identity of the
process performing an action such as opening\n# a file, etc., we require that the
process name be known.\n- macro: proc_name_exists\n condition: (proc.name!=\"<NA>\")\n\n-
macro: rename\n condition: evt.type in (rename, renameat)\n- macro: mkdir\n condition:
evt.type in (mkdir, mkdirat)\n- macro: remove\n condition: evt.type in (rmdir,
unlink, unlinkat)\n\n- macro: modify\n condition: rename or remove\n\n- macro:
spawned_process\n condition: evt.type = execve and evt.dir=<\n\n- macro: create_symlink\n
\ condition: evt.type in (symlink, symlinkat) and evt.dir=<\n\n- macro: chmod\n
\ condition: (evt.type in (chmod, fchmod, fchmodat) and evt.dir=<)\n\n# File categories\n-
macro: bin_dir\n condition: fd.directory in (/bin, /sbin, /usr/bin, /usr/sbin)\n\n-
macro: bin_dir_mkdir\n condition: >\n (evt.arg[1] startswith /bin/ or\n evt.arg[1]
startswith /sbin/ or\n evt.arg[1] startswith /usr/bin/ or\n evt.arg[1] startswith
/usr/sbin/)\n\n- macro: bin_dir_rename\n condition: >\n evt.arg[1] startswith
/bin/ or\n evt.arg[1] startswith /sbin/ or\n evt.arg[1] startswith /usr/bin/
or\n evt.arg[1] startswith /usr/sbin/\n\n- macro: etc_dir\n condition: fd.name
startswith /etc/\n\n# This detects writes immediately below / or any write anywhere
below /root\n- macro: root_dir\n condition: ((fd.directory=/ or fd.name startswith
/root) and fd.name contains \"/\")\n\n- list: shell_binaries\n items: [ash, bash,
csh, ksh, sh, tcsh, zsh, dash]\n\n- list: ssh_binaries\n items: [\n sshd, sftp-server,
ssh-agent,\n ssh, scp, sftp,\n ssh-keygen, ssh-keysign, ssh-keyscan, ssh-add\n
\ ]\n\n- list: shell_mgmt_binaries\n items: [add-shell, remove-shell]\n\n- macro:
shell_procs\n condition: proc.name in (shell_binaries)\n\n- list: coreutils_binaries\n
\ items: [\n truncate, sha1sum, numfmt, fmt, fold, uniq, cut, who,\n groups,
csplit, sort, expand, printf, printenv, unlink, tee, chcon, stat,\n basename,
split, nice, \"yes\", whoami, sha224sum, hostid, users, stdbuf,\n base64, unexpand,
cksum, od, paste, nproc, pathchk, sha256sum, wc, test,\n comm, arch, du, factor,
sha512sum, md5sum, tr, runcon, env, dirname,\n tsort, join, shuf, install, logname,
pinky, nohup, expr, pr, tty, timeout,\n tail, \"[\", seq, sha384sum, nl, head,
id, mkfifo, sum, dircolors, ptx, shred,\n tac, link, chroot, vdir, chown, touch,
ls, dd, uname, \"true\", pwd, date,\n chgrp, chmod, mktemp, cat, mknod, sync,
ln, \"false\", rm, mv, cp, echo,\n readlink, sleep, stty, mkdir, df, dir, rmdir,
touch\n ]\n\n# dpkg -L login | grep bin | xargs ls -ld | grep -v '^d' | awk '{print
$9}' | xargs -L 1 basename | tr \"\\\\n\" \",\"\n- list: login_binaries\n items:
[\n login, systemd, '\"(systemd)\"', systemd-logind, su,\n nologin, faillog,
lastlog, newgrp, sg\n ]\n\n# dpkg -L passwd | grep bin | xargs ls -ld | grep
-v '^d' | awk '{print $9}' | xargs -L 1 basename | tr \"\\\\n\" \",\"\n- list: passwd_binaries\n
\ items: [\n shadowconfig, grpck, pwunconv, grpconv, pwck,\n groupmod, vipw,
pwconv, useradd, newusers, cppw, chpasswd, usermod,\n groupadd, groupdel, grpunconv,
chgpasswd, userdel, chage, chsh,\n gpasswd, chfn, expiry, passwd, vigr, cpgr,
adduser, addgroup, deluser, delgroup\n ]\n\n# repoquery -l shadow-utils | grep
bin | xargs ls -ld | grep -v '^d' |\n# awk '{print $9}' | xargs -L 1 basename
| tr \"\\\\n\" \",\"\n- list: shadowutils_binaries\n items: [\n chage, gpasswd,
lastlog, newgrp, sg, adduser, deluser, chpasswd,\n groupadd, groupdel, addgroup,
delgroup, groupmems, groupmod, grpck, grpconv, grpunconv,\n newusers, pwck, pwconv,
pwunconv, useradd, userdel, usermod, vigr, vipw, unix_chkpwd\n ]\n\n- list: sysdigcloud_binaries\n
\ items: [setup-backend, dragent, sdchecks]\n\n- list: docker_binaries\n items:
[docker, dockerd, exe, docker-compose, docker-entrypoi, docker-runc-cur, docker-current,
dockerd-current]\n\n- list: k8s_binaries\n items: [hyperkube, skydns, kube2sky,
exechealthz, weave-net, loopback, bridge, openshift-sdn, openshift]\n\n- list: lxd_binaries\n
\ items: [lxd, lxcfs]\n\n- list: http_server_binaries\n items: [nginx, httpd, httpd-foregroun,
lighttpd, apache, apache2]\n\n- list: db_server_binaries\n items: [mysqld, postgres,
sqlplus]\n\n- list: mysql_mgmt_binaries\n items: [mysql_install_d, mysql_ssl_rsa_s]\n\n-
list: postgres_mgmt_binaries\n items: [pg_dumpall, pg_ctl, pg_lsclusters, pg_ctlcluster]\n\n-
list: db_mgmt_binaries\n items: [mysql_mgmt_binaries, postgres_mgmt_binaries]\n\n-
list: nosql_server_binaries\n items: [couchdb, memcached, redis-server, rabbitmq-server,
mongod]\n\n- list: gitlab_binaries\n items: [gitlab-shell, gitlab-mon, gitlab-runner-b,
git]\n\n- list: interpreted_binaries\n items: [lua, node, perl, perl5, perl6, php,
python, python2, python3, ruby, tcl]\n\n- macro: interpreted_procs\n condition:
>\n (proc.name in (interpreted_binaries))\n\n- macro: server_procs\n condition:
proc.name in (http_server_binaries, db_server_binaries, docker_binaries, sshd)\n\n#
The explicit quotes are needed to avoid the - characters being\n# interpreted by
the filter expression.\n- list: rpm_binaries\n items: [dnf, rpm, rpmkey, yum, '\"75-system-updat\"',
rhsmcertd-worke, subscription-ma,\n repoquery, rpmkeys, rpmq, yum-cron,
yum-config-mana, yum-debug-dump,\n abrt-action-sav, rpmdb_stat, microdnf,
rhn_check, yumdb]\n\n- list: openscap_rpm_binaries\n items: [probe_rpminfo, probe_rpmverify,
probe_rpmverifyfile, probe_rpmverifypackage]\n\n- macro: rpm_procs\n condition:
(proc.name in (rpm_binaries, openscap_rpm_binaries) or proc.name in (salt-minion))\n\n-
list: deb_binaries\n items: [dpkg, dpkg-preconfigu, dpkg-reconfigur, dpkg-divert,
apt, apt-get, aptitude,\n frontend, preinst, add-apt-reposit, apt-auto-remova,
apt-key,\n apt-listchanges, unattended-upgr, apt-add-reposit, apt-config, apt-cache\n
\ ]\n\n# The truncated dpkg-preconfigu is intentional, process names are\n# truncated
at the sysdig level.\n- list: package_mgmt_binaries\n items: [rpm_binaries, deb_binaries,
update-alternat, gem, pip, pip3, sane-utils.post, alternatives, chef-client, apk]\n\n-
macro: package_mgmt_procs\n condition: proc.name in (package_mgmt_binaries)\n\n-
macro: package_mgmt_ancestor_procs\n condition: proc.pname in (package_mgmt_binaries)
or\n proc.aname[2] in (package_mgmt_binaries) or\n proc.aname[3]
in (package_mgmt_binaries) or\n proc.aname[4] in (package_mgmt_binaries)\n\n-
macro: coreos_write_ssh_dir\n condition: (proc.name=update-ssh-keys and fd.name
startswith /home/core/.ssh)\n\n- macro: run_by_package_mgmt_binaries\n condition:
proc.aname in (package_mgmt_binaries, needrestart)\n\n- list: ssl_mgmt_binaries\n
\ items: [ca-certificates]\n\n- list: dhcp_binaries\n items: [dhclient, dhclient-script,
11-dhclient]\n\n# A canonical set of processes that run other programs with different\n#
privileges or as a different user.\n- list: userexec_binaries\n items: [sudo, su,
suexec, critical-stack, dzdo]\n\n- list: known_setuid_binaries\n items: [\n sshd,
dbus-daemon-lau, ping, ping6, critical-stack-, pmmcli,\n filemng, PassengerAgent,
bwrap, osdetect, nginxmng, sw-engine-fpm,\n start-stop-daem\n ]\n\n- list:
user_mgmt_binaries\n items: [login_binaries, passwd_binaries, shadowutils_binaries]\n\n-
list: dev_creation_binaries\n items: [blkid, rename_device, update_engine, sgdisk]\n\n-
list: hids_binaries\n items: [aide, aide.wrapper, update-aide.con, logcheck, syslog-summary,
osqueryd, ossec-syscheckd]\n\n- list: vpn_binaries\n items: [openvpn]\n\n- list:
nomachine_binaries\n items: [nxexec, nxnode.bin, nxserver.bin, nxclient.bin]\n\n-
macro: system_procs\n condition: proc.name in (coreutils_binaries, user_mgmt_binaries)\n\n-
list: mail_binaries\n items: [\n sendmail, sendmail-msp, postfix, procmail,
exim4,\n pickup, showq, mailq, dovecot, imap-login, imap,\n mailmng-core,
pop3-login, dovecot-lda, pop3\n ]\n\n- list: mail_config_binaries\n items: [\n
\ update_conf, parse_mc, makemap_hash, newaliases, update_mk, update_tlsm4,\n
\ update_db, update_mc, ssmtp.postinst, mailq, postalias, postfix.config.,\n postfix.config,
postfix-script, postconf\n ]\n\n- list: sensitive_file_names\n items: [/etc/shadow,
/etc/sudoers, /etc/pam.conf, /etc/security/pwquality.conf]\n\n- list: sensitive_directory_names\n
\ items: [/, /etc, /etc/, /root, /root/]\n\n- macro: sensitive_files\n condition:
>\n fd.name startswith /etc and\n (fd.name in (sensitive_file_names)\n or
fd.directory in (/etc/sudoers.d, /etc/pam.d))\n\n# Indicates that the process is
new. Currently detected using time\n# since process was started, using a threshold
of 5 seconds.\n- macro: proc_is_new\n condition: proc.duration <= 5000000000\n\n#
Network\n- macro: inbound\n condition: >\n (((evt.type in (accept,listen) and
evt.dir=<) or\n (evt.type in (recvfrom,recvmsg) and evt.dir=< and\n fd.l4proto
!= tcp and fd.connected=false and fd.name_changed=true)) and\n (fd.typechar
= 4 or fd.typechar = 6) and\n (fd.ip != \"0.0.0.0\" and fd.net != \"127.0.0.0/8\")
and\n (evt.rawres >= 0 or evt.res = EINPROGRESS))\n\n# RFC1918 addresses were
assigned for private network usage\n- list: rfc_1918_addresses\n items: ['\"10.0.0.0/8\"',
'\"172.16.0.0/12\"', '\"192.168.0.0/16\"']\n\n- macro: outbound\n condition: >\n
\ (((evt.type = connect and evt.dir=<) or\n (evt.type in (sendto,sendmsg)
and evt.dir=< and\n fd.l4proto != tcp and fd.connected=false and fd.name_changed=true))
and\n (fd.typechar = 4 or fd.typechar = 6) and\n (fd.ip != \"0.0.0.0\" and
fd.net != \"127.0.0.0/8\" and not fd.snet in (rfc_1918_addresses)) and\n (evt.rawres
>= 0 or evt.res = EINPROGRESS))\n\n# Very similar to inbound/outbound, but combines
the tests together\n# for efficiency.\n- macro: inbound_outbound\n condition: >\n
\ (((evt.type in (accept,listen,connect) and evt.dir=<)) or\n (fd.typechar
= 4 or fd.typechar = 6) and\n (fd.ip != \"0.0.0.0\" and fd.net != \"127.0.0.0/8\")
and\n (evt.rawres >= 0 or evt.res = EINPROGRESS))\n\n- macro: ssh_port\n condition:
fd.sport=22\n\n# In a local/user rules file, you could override this macro to\n#
enumerate the servers for which ssh connections are allowed. For\n# example, you
might have a ssh gateway host for which ssh connections\n# are allowed.\n#\n# In
the main falco rules file, there isn't any way to know the\n# specific hosts for
which ssh access is allowed, so this macro just\n# repeats ssh_port, which effectively
allows ssh from all hosts. In\n# the overridden macro, the condition would look
something like\n# \"fd.sip=\"a.b.c.d\" or fd.sip=\"e.f.g.h\" or ...\"\n- macro:
allowed_ssh_hosts\n condition: ssh_port\n\n- rule: Disallowed SSH Connection\n
\ desc: Detect any new ssh connection to a host other than those in an allowed group
of hosts\n condition: (inbound_outbound) and ssh_port and not allowed_ssh_hosts\n
\ output: Disallowed SSH Connection (command=%proc.cmdline connection=%fd.name user=%user.name
container_id=%container.id image=%container.image.repository)\n priority: NOTICE\n
\ tags: [network, mitre_remote_service]\n\n# These rules and supporting macros are
more of an example for how to\n# use the fd.*ip and fd.*ip.name fields to match
connection\n# information against ips, netmasks, and complete domain names.\n#\n#
To use this rule, you should modify consider_all_outbound_conns and\n# populate
allowed_{source,destination}_{ipaddrs,networks,domains} with the\n# values that
make sense for your environment.\n- macro: consider_all_outbound_conns\n condition:
(never_true)\n\n# Note that this can be either individual IPs or netmasks\n- list:
allowed_outbound_destination_ipaddrs\n items: ['\"127.0.0.1\"', '\"8.8.8.8\"']\n\n-
list: allowed_outbound_destination_networks\n items: ['\"127.0.0.1/8\"']\n\n- list:
allowed_outbound_destination_domains\n items: [google.com, www.yahoo.com]\n\n-
rule: Unexpected outbound connection destination\n desc: Detect any outbound connection
to a destination outside of an allowed set of ips, networks, or domain names\n condition:
>\n consider_all_outbound_conns and outbound and not\n ((fd.sip in (allowed_outbound_destination_ipaddrs))
or\n (fd.snet in (allowed_outbound_destination_networks)) or\n (fd.sip.name
in (allowed_outbound_destination_domains)))\n output: Disallowed outbound connection
destination (command=%proc.cmdline connection=%fd.name user=%user.name container_id=%container.id
image=%container.image.repository)\n priority: NOTICE\n tags: [network]\n\n- macro:
consider_all_inbound_conns\n condition: (never_true)\n\n- list: allowed_inbound_source_ipaddrs\n
\ items: ['\"127.0.0.1\"']\n\n- list: allowed_inbound_source_networks\n items:
['\"127.0.0.1/8\"', '\"10.0.0.0/8\"']\n\n- list: allowed_inbound_source_domains\n
\ items: [google.com]\n\n- rule: Unexpected inbound connection source\n desc: Detect
any inbound connection from a source outside of an allowed set of ips, networks,
or domain names\n condition: >\n consider_all_inbound_conns and inbound and
not\n ((fd.cip in (allowed_inbound_source_ipaddrs)) or\n (fd.cnet in (allowed_inbound_source_networks))
or\n (fd.cip.name in (allowed_inbound_source_domains)))\n output: Disallowed
inbound connection source (command=%proc.cmdline connection=%fd.name user=%user.name
container_id=%container.id image=%container.image.repository)\n priority: NOTICE\n
\ tags: [network]\n\n- list: bash_config_filenames\n items: [.bashrc, .bash_profile,
.bash_history, .bash_login, .bash_logout, .inputrc, .profile]\n\n- list: bash_config_files\n
\ items: [/etc/profile, /etc/bashrc]\n\n# Covers both csh and tcsh\n- list: csh_config_filenames\n
\ items: [.cshrc, .login, .logout, .history, .tcshrc, .cshdirs]\n\n- list: csh_config_files\n
\ items: [/etc/csh.cshrc, /etc/csh.login]\n\n- list: zsh_config_filenames\n items:
[.zshenv, .zprofile, .zshrc, .zlogin, .zlogout]\n\n- list: shell_config_filenames\n
\ items: [bash_config_filenames, csh_config_filenames, zsh_config_filenames]\n\n-
list: shell_config_files\n items: [bash_config_files, csh_config_files]\n\n- list:
shell_config_directories\n items: [/etc/zsh]\n\n- rule: Modify Shell Configuration
File\n desc: Detect attempt to modify shell configuration files\n condition: >\n
\ open_write and\n (fd.filename in (shell_config_filenames) or\n fd.name
in (shell_config_files) or\n fd.directory in (shell_config_directories))\n and
not proc.name in (shell_binaries)\n and not exe_running_docker_save\n output:
>\n a shell configuration file has been modified (user=%user.name command=%proc.cmdline
pcmdline=%proc.pcmdline file=%fd.name container_id=%container.id image=%container.image.repository)\n
\ priority:\n WARNING\n tag: [file, mitre_persistence]\n\n# This rule is not
enabled by default, as there are many legitimate\n# readers of shell config files.
If you want to enable it, modify the\n# following macro.\n\n- macro: consider_shell_config_reads\n
\ condition: (never_true)\n\n- rule: Read Shell Configuration File\n desc: Detect
attempts to read shell configuration files by non-shell programs\n condition: >\n
\ open_read and\n consider_shell_config_reads and\n (fd.filename in (shell_config_filenames)
or\n fd.name in (shell_config_files) or\n fd.directory in (shell_config_directories))
and\n (not proc.name in (shell_binaries))\n output: >\n a shell configuration
file was read by a non-shell program (user=%user.name command=%proc.cmdline file=%fd.name
container_id=%container.id image=%container.image.repository)\n priority:\n WARNING\n
\ tag: [file, mitre_discovery]\n\n- macro: consider_all_cron_jobs\n condition:
(never_true)\n\n- rule: Schedule Cron Jobs\n desc: Detect cron jobs scheduled\n
\ condition: >\n consider_all_cron_jobs and\n ((open_write and fd.name startswith
/etc/cron) or\n (spawned_process and proc.name = \"crontab\"))\n output: >\n
\ Cron jobs were scheduled to run (user=%user.name command=%proc.cmdline\n file=%fd.name
container_id=%container.id container_name=%container.name image=%container.image.repository:%container.image.tag)\n
\ priority:\n NOTICE\n tag: [file, mitre_persistence]\n\n# Use this to test
whether the event occurred within a container.\n\n# When displaying container information
in the output field, use\n# %container.info, without any leading term (file=%fd.name\n#
%container.info user=%user.name, and not file=%fd.name\n# container=%container.info
user=%user.name). The output will change\n# based on the context and whether or
not -pk/-pm/-pc was specified on\n# the command line.\n- macro: container\n condition:
(container.id != host)\n\n- macro: container_started\n condition: >\n ((evt.type
= container or\n (evt.type=execve and evt.dir=< and proc.vpid=1)) and\n container.image.repository
!= incomplete)\n\n- macro: interactive\n condition: >\n ((proc.aname=sshd and
proc.name != sshd) or\n proc.name=systemd-logind or proc.name=login)\n\n- list:
cron_binaries\n items: [anacron, cron, crond, crontab]\n\n# https://github.com/liske/needrestart\n-
list: needrestart_binaries\n items: [needrestart, 10-dpkg, 20-rpm, 30-pacman]\n\n#
Possible scripts run by sshkit\n- list: sshkit_script_binaries\n items: [10_etc_sudoers.,
10_passwd_group]\n\n- list: plesk_binaries\n items: [sw-engine, sw-engine-fpm,
sw-engine-kv, filemng, f2bmng]\n\n# System users that should never log into a system.
Consider adding your own\n# service users (e.g. 'apache' or 'mysqld') here.\n- macro:
system_users\n condition: user.name in (bin, daemon, games, lp, mail, nobody, sshd,
sync, uucp, www-data)\n\n# These macros will be removed soon. Only keeping them
to maintain\n# compatiblity with some widely used rules files.\n# Begin Deprecated\n-
macro: parent_ansible_running_python\n condition: (proc.pname in (python, pypy,
python3) and proc.pcmdline contains ansible)\n\n- macro: parent_bro_running_python\n
\ condition: (proc.pname=python and proc.cmdline contains /usr/share/broctl)\n\n-
macro: parent_python_running_denyhosts\n condition: >\n (proc.cmdline startswith
\"denyhosts.py /usr/bin/denyhosts.py\" or\n (proc.pname=python and\n (proc.pcmdline
contains /usr/sbin/denyhosts or\n proc.pcmdline contains /usr/local/bin/denyhosts.py)))\n\n-
macro: parent_python_running_sdchecks\n condition: >\n (proc.pname in (python,
python2.7) and\n (proc.pcmdline contains /opt/draios/bin/sdchecks))\n\n- macro:
python_running_sdchecks\n condition: >\n (proc.name in (python, python2.7) and\n
\ (proc.cmdline contains /opt/draios/bin/sdchecks))\n\n- macro: parent_linux_image_upgrade_script\n
\ condition: proc.pname startswith linux-image-\n\n- macro: parent_java_running_echo\n
\ condition: (proc.pname=java and proc.cmdline startswith \"sh -c echo\")\n\n- macro:
parent_scripting_running_builds\n condition: >\n (proc.pname in (php,php5-fpm,php-fpm7.1,python,ruby,ruby2.3,ruby2.1,node,conda)
and (\n proc.cmdline startswith \"sh -c git\" or\n proc.cmdline startswith
\"sh -c date\" or\n proc.cmdline startswith \"sh -c /usr/bin/g++\" or\n proc.cmdline
startswith \"sh -c /usr/bin/gcc\" or\n proc.cmdline startswith \"sh -c gcc\"
or\n proc.cmdline startswith \"sh -c if type gcc\" or\n proc.cmdline
startswith \"sh -c cd '/var/www/edi/';LC_ALL=en_US.UTF-8 git\" or\n proc.cmdline
startswith \"sh -c /var/www/edi/bin/sftp.sh\" or\n proc.cmdline startswith
\"sh -c /usr/src/app/crxlsx/bin/linux/crxlsx\" or\n proc.cmdline startswith
\"sh -c make parent\" or\n proc.cmdline startswith \"node /jenkins/tools\"
or\n proc.cmdline startswith \"sh -c '/usr/bin/node'\" or\n proc.cmdline
startswith \"sh -c stty -a |\" or\n proc.pcmdline startswith \"node /opt/nodejs/bin/yarn\"
or\n proc.pcmdline startswith \"node /usr/local/bin/yarn\" or\n proc.pcmdline
startswith \"node /root/.config/yarn\" or\n proc.pcmdline startswith \"node
/opt/yarn/bin/yarn.js\"))\n\n\n- macro: httpd_writing_ssl_conf\n condition: >\n
\ (proc.pname=run-httpd and\n (proc.cmdline startswith \"sed -ri\" or proc.cmdline
startswith \"sed -i\") and\n (fd.name startswith /etc/httpd/conf.d/ or fd.name
startswith /etc/httpd/conf))\n\n- macro: userhelper_writing_etc_security\n condition:
(proc.name=userhelper and fd.name startswith /etc/security)\n\n- macro: parent_Xvfb_running_xkbcomp\n
\ condition: (proc.pname=Xvfb and proc.cmdline startswith 'sh -c \"/usr/bin/xkbcomp\"')\n\n-
macro: parent_nginx_running_serf\n condition: (proc.pname=nginx and proc.cmdline
startswith \"sh -c serf\")\n\n- macro: parent_node_running_npm\n condition: (proc.pcmdline
startswith \"node /usr/local/bin/npm\" or\n proc.pcmdline startswith
\"node /usr/local/nodejs/bin/npm\" or\n proc.pcmdline startswith \"node
/opt/rh/rh-nodejs6/root/usr/bin/npm\")\n\n- macro: parent_java_running_sbt\n condition:
(proc.pname=java and proc.pcmdline contains sbt-launch.jar)\n\n- list: known_container_shell_spawn_cmdlines\n
\ items: []\n\n- list: known_shell_spawn_binaries\n items: []\n\n## End Deprecated\n\n-
macro: ansible_running_python\n condition: (proc.name in (python, pypy, python3)
and proc.cmdline contains ansible)\n\n- macro: python_running_chef\n condition:
(proc.name=python and (proc.cmdline contains yum-dump.py or proc.cmdline=\"python
/usr/bin/chef-monitor.py\"))\n\n- macro: python_running_denyhosts\n condition:
>\n (proc.name=python and\n (proc.cmdline contains /usr/sbin/denyhosts or\n
\ proc.cmdline contains /usr/local/bin/denyhosts.py))\n\n# Qualys seems to run
a variety of shell subprocesses, at various\n# levels. This checks at a few levels
without the cost of a full\n# proc.aname, which traverses the full parent heirarchy.\n-
macro: run_by_qualys\n condition: >\n (proc.pname=qualys-cloud-ag or\n proc.aname[2]=qualys-cloud-ag
or\n proc.aname[3]=qualys-cloud-ag or\n proc.aname[4]=qualys-cloud-ag)\n\n-
macro: run_by_sumologic_securefiles\n condition: >\n ((proc.cmdline=\"usermod
-a -G sumologic_collector\" or\n proc.cmdline=\"groupadd sumologic_collector\")
and\n (proc.pname=secureFiles.sh and proc.aname[2]=java))\n\n- macro: run_by_yum\n
\ condition: ((proc.pname=sh and proc.aname[2]=yum) or\n (proc.aname[2]=sh
and proc.aname[3]=yum))\n\n- macro: run_by_ms_oms\n condition: >\n (proc.aname[3]
startswith omsagent- or\n proc.aname[3] startswith scx-)\n\n- macro: run_by_google_accounts_daemon\n
\ condition: >\n (proc.aname[1] startswith google_accounts or\n proc.aname[2]
startswith google_accounts or\n proc.aname[3] startswith google_accounts)\n\n#
Chef is similar.\n- macro: run_by_chef\n condition: (proc.aname[2]=chef_command_wr
or proc.aname[3]=chef_command_wr or\n proc.aname[2]=chef-client or
proc.aname[3]=chef-client or\n proc.name=chef-client)\n\n- macro: run_by_adclient\n
\ condition: (proc.aname[2]=adclient or proc.aname[3]=adclient or proc.aname[4]=adclient)\n\n-
macro: run_by_centrify\n condition: (proc.aname[2]=centrify or proc.aname[3]=centrify
or proc.aname[4]=centrify)\n\n- macro: run_by_puppet\n condition: (proc.aname[2]=puppet
or proc.aname[3]=puppet)\n\n# Also handles running semi-indirectly via scl\n- macro:
run_by_foreman\n condition: >\n (user.name=foreman and\n (proc.pname in
(rake, ruby, scl) and proc.aname[5] in (tfm-rake,tfm-ruby)) or\n (proc.pname=scl
and proc.aname[2] in (tfm-rake,tfm-ruby)))\n\n- macro: java_running_sdjagent\n condition:
proc.name=java and proc.cmdline contains sdjagent.jar\n\n- macro: kubelet_running_loopback\n
\ condition: (proc.pname=kubelet and proc.name=loopback)\n\n- macro: python_mesos_marathon_scripting\n
\ condition: (proc.pcmdline startswith \"python3 /marathon-lb/marathon_lb.py\")\n\n-
macro: splunk_running_forwarder\n condition: (proc.pname=splunkd and proc.cmdline
startswith \"sh -c /opt/splunkforwarder\")\n\n- macro: parent_supervise_running_multilog\n
\ condition: (proc.name=multilog and proc.pname=supervise)\n\n- macro: supervise_writing_status\n
\ condition: (proc.name in (supervise,svc) and fd.name startswith \"/etc/sb/\")\n\n-
macro: pki_realm_writing_realms\n condition: (proc.cmdline startswith \"bash /usr/local/lib/pki/pki-realm\"
and fd.name startswith /etc/pki/realms)\n\n- macro: htpasswd_writing_passwd\n condition:
(proc.name=htpasswd and fd.name=/etc/nginx/.htpasswd)\n\n- macro: lvprogs_writing_conf\n
\ condition: >\n (proc.name in (dmeventd,lvcreate,pvscan) and\n (fd.name
startswith /etc/lvm/archive or\n fd.name startswith /etc/lvm/backup or\n fd.name
startswith /etc/lvm/cache))\n\n- macro: ovsdb_writing_openvswitch\n condition:
(proc.name=ovsdb-server and fd.directory=/etc/openvswitch)\n\n- macro: perl_running_plesk\n
\ condition: (proc.cmdline startswith \"perl /opt/psa/admin/bin/plesk_agent_manager\"
or\n proc.pcmdline startswith \"perl /opt/psa/admin/bin/plesk_agent_manager\")\n\n-
macro: perl_running_updmap\n condition: (proc.cmdline startswith \"perl /usr/bin/updmap\")\n\n-
macro: perl_running_centrifydc\n condition: (proc.cmdline startswith \"perl /usr/share/centrifydc\")\n\n-
macro: runuser_reading_pam\n condition: (proc.name=runuser and fd.directory=/etc/pam.d)\n\n-
macro: parent_ucf_writing_conf\n condition: (proc.pname=ucf and proc.aname[2]=frontend)\n\n-
macro: consul_template_writing_conf\n condition: >\n ((proc.name=consul-template
and fd.name startswith /etc/haproxy) or\n (proc.name=reload.sh and proc.aname[2]=consul-template
and fd.name startswith /etc/ssl))\n\n- macro: countly_writing_nginx_conf\n condition:
(proc.cmdline startswith \"nodejs /opt/countly/bin\" and fd.name startswith /etc/nginx)\n\n-
list: ms_oms_binaries\n items: [omi.postinst, omsconfig.posti, scx.postinst, omsadmin.sh,
omiagent]\n\n- macro: ms_oms_writing_conf\n condition: >\n ((proc.name in (omiagent,omsagent,in_heartbeat_r*,omsadmin.sh,PerformInventor)\n
\ or proc.pname in (ms_oms_binaries)\n or proc.aname[2] in (ms_oms_binaries))\n
\ and (fd.name startswith /etc/opt/omi or fd.name startswith /etc/opt/microsoft/omsagent))\n\n-
macro: ms_scx_writing_conf\n condition: (proc.name in (GetLinuxOS.sh) and fd.name
startswith /etc/opt/microsoft/scx)\n\n- macro: azure_scripts_writing_conf\n condition:
(proc.pname startswith \"bash /var/lib/waagent/\" and fd.name startswith /etc/azure)\n\n-
macro: azure_networkwatcher_writing_conf\n condition: (proc.name in (NetworkWatcherA)
and fd.name=/etc/init.d/AzureNetworkWatcherAgent)\n\n- macro: couchdb_writing_conf\n
\ condition: (proc.name=beam.smp and proc.cmdline contains couchdb and fd.name startswith
/etc/couchdb)\n\n- macro: update_texmf_writing_conf\n condition: (proc.name=update-texmf
and fd.name startswith /etc/texmf)\n\n- macro: slapadd_writing_conf\n condition:
(proc.name=slapadd and fd.name startswith /etc/ldap)\n\n- macro: openldap_writing_conf\n
\ condition: (proc.pname=run-openldap.sh and fd.name startswith /etc/openldap)\n\n-
macro: ucpagent_writing_conf\n condition: (proc.name=apiserver and container.image.repository=docker/ucp-agent
and fd.name=/etc/authorization_config.cfg)\n\n- macro: iscsi_writing_conf\n condition:
(proc.name=iscsiadm and fd.name startswith /etc/iscsi)\n\n- macro: istio_writing_conf\n
\ condition: (proc.name=pilot-agent and fd.name startswith /etc/istio)\n\n- macro:
symantec_writing_conf\n condition: >\n ((proc.name=symcfgd and fd.name startswith
/etc/symantec) or\n (proc.name=navdefutil and fd.name=/etc/symc-defutils.conf))\n\n-
macro: liveupdate_writing_conf\n condition: (proc.cmdline startswith \"java LiveUpdate\"
and fd.name in (/etc/liveupdate.conf, /etc/Product.Catalog.JavaLiveUpdate))\n\n-
macro: rancher_agent\n condition: (proc.name=agent and container.image.repository
contains \"rancher/agent\")\n\n- macro: rancher_network_manager\n condition: (proc.name=rancher-bridge
and container.image.repository contains \"rancher/network-manager\")\n\n- macro:
sosreport_writing_files\n condition: >\n (proc.name=urlgrabber-ext- and proc.aname[3]=sosreport
and\n (fd.name startswith /etc/pkt/nssdb or fd.name startswith /etc/pki/nssdb))\n\n-
macro: pkgmgmt_progs_writing_pki\n condition: >\n (proc.name=urlgrabber-ext-
and proc.pname in (yum, yum-cron, repoquery) and\n (fd.name startswith /etc/pkt/nssdb
or fd.name startswith /etc/pki/nssdb))\n\n- macro: update_ca_trust_writing_pki\n
\ condition: (proc.pname=update-ca-trust and proc.name=trust and fd.name startswith
/etc/pki)\n\n- macro: brandbot_writing_os_release\n condition: proc.name=brandbot
and fd.name=/etc/os-release\n\n- macro: selinux_writing_conf\n condition: (proc.name
in (semodule,genhomedircon,sefcontext_comp) and fd.name startswith /etc/selinux)\n\n-
list: veritas_binaries\n items: [vxconfigd, sfcache, vxclustadm, vxdctl, vxprint,
vxdmpadm, vxdisk, vxdg, vxassist, vxtune]\n\n- macro: veritas_driver_script\n condition:
(proc.cmdline startswith \"perl /opt/VRTSsfmh/bin/mh_driver.pl\")\n\n- macro: veritas_progs\n
\ condition: (proc.name in (veritas_binaries) or veritas_driver_script)\n\n- macro:
veritas_writing_config\n condition: (veritas_progs and (fd.name startswith /etc/vx
or fd.name startswith /etc/opt/VRTS or fd.name startswith /etc/vom))\n\n- macro:
nginx_writing_conf\n condition: (proc.name in (nginx,nginx-ingress-c,nginx-ingress)
and (fd.name startswith /etc/nginx or fd.name startswith /etc/ingress-controller))\n\n-
macro: nginx_writing_certs\n condition: >\n (((proc.name=openssl and proc.pname=nginx-launch.sh)
or proc.name=nginx-launch.sh) and fd.name startswith /etc/nginx/certs)\n\n- macro:
chef_client_writing_conf\n condition: (proc.pcmdline startswith \"chef-client /opt/gitlab\"
and fd.name startswith /etc/gitlab)\n\n- macro: centrify_writing_krb\n condition:
(proc.name in (adjoin,addns) and fd.name startswith /etc/krb5)\n\n- macro: cockpit_writing_conf\n
\ condition: >\n ((proc.pname=cockpit-kube-la or proc.aname[2]=cockpit-kube-la)\n
\ and fd.name startswith /etc/cockpit)\n\n- macro: ipsec_writing_conf\n condition:
(proc.name=start-ipsec.sh and fd.directory=/etc/ipsec)\n\n- macro: exe_running_docker_save\n
\ condition: >\n proc.name = \"exe\"\n and proc.cmdline contains \"/var/lib/docker\"\n
\ and proc.pname in (dockerd, docker)\n\n# Ideally we'd have a length check here
as well but sysdig\n# filterchecks don't have operators like len()\n- macro: sed_temporary_file\n
\ condition: (proc.name=sed and fd.name startswith \"/etc/sed\")\n\n- macro: python_running_get_pip\n
\ condition: (proc.cmdline startswith \"python get-pip.py\")\n\n- macro: python_running_ms_oms\n
\ condition: (proc.cmdline startswith \"python /var/lib/waagent/\")\n\n- macro:
gugent_writing_guestagent_log\n condition: (proc.name=gugent and fd.name=GuestAgent.log)\n\n-
macro: dse_writing_tmp\n condition: (proc.name=dse-entrypoint and fd.name=/root/tmp__)\n\n-
macro: zap_writing_state\n condition: (proc.name=java and proc.cmdline contains
\"jar /zap\" and fd.name startswith /root/.ZAP)\n\n- macro: airflow_writing_state\n
\ condition: (proc.name=airflow and fd.name startswith /root/airflow)\n\n- macro:
rpm_writing_root_rpmdb\n condition: (proc.name=rpm and fd.directory=/root/.rpmdb)\n\n-
macro: maven_writing_groovy\n condition: (proc.name=java and proc.cmdline contains
\"classpath /usr/local/apache-maven\" and fd.name startswith /root/.groovy)\n\n-
macro: chef_writing_conf\n condition: (proc.name=chef-client and fd.name startswith
/root/.chef)\n\n- macro: kubectl_writing_state\n condition: (proc.name in (kubectl,oc)
and fd.name startswith /root/.kube)\n\n- macro: java_running_cassandra\n condition:
(proc.name=java and proc.cmdline contains \"cassandra.jar\")\n\n- macro: cassandra_writing_state\n
\ condition: (java_running_cassandra and fd.directory=/root/.cassandra)\n\n# Istio\n-
macro: galley_writing_state\n condition: (proc.name=galley and fd.name in (known_istio_files))\n\n-
list: known_istio_files\n items: [/healthready, /healthliveness]\n\n- macro: calico_writing_state\n
\ condition: (proc.name=kube-controller and fd.name startswith /status.json and
k8s.pod.name startswith calico)\n\n- macro: calico_writing_envvars\n condition:
(proc.name=start_runit and fd.name startswith \"/etc/envvars\" and container.image.repository
endswith \"calico/node\")\n\n- list: repository_files\n items: [sources.list]\n\n-
list: repository_directories\n items: [/etc/apt/sources.list.d, /etc/yum.repos.d]\n\n-
macro: access_repositories\n condition: (fd.filename in (repository_files) or fd.directory
in (repository_directories))\n\n- macro: modify_repositories\n condition: (evt.arg.newpath
pmatch (repository_directories))\n\n- rule: Update Package Repository\n desc: Detect
package repositories get updated\n condition: >\n ((open_write and access_repositories)
or (modify and modify_repositories))\n and not package_mgmt_procs\n and not
exe_running_docker_save\n output: >\n Repository files get updated (user=%user.name
command=%proc.cmdline pcmdline=%proc.pcmdline file=%fd.name newpath=%evt.arg.newpath
container_id=%container.id image=%container.image.repository)\n priority:\n NOTICE\n
\ tags: [filesystem, mitre_persistence]\n\n- rule: Write below binary dir\n desc:
an attempt to write to any file below a set of binary directories\n condition:
>\n bin_dir and evt.dir = < and open_write\n and not package_mgmt_procs\n
\ and not exe_running_docker_save\n and not python_running_get_pip\n and
not python_running_ms_oms\n output: >\n File below a known binary directory
opened for writing (user=%user.name\n command=%proc.cmdline file=%fd.name parent=%proc.pname
pcmdline=%proc.pcmdline gparent=%proc.aname[2] container_id=%container.id image=%container.image.repository)\n
\ priority: ERROR\n tags: [filesystem, mitre_persistence]\n\n# If you'd like to
generally monitor a wider set of directories on top\n# of the ones covered by the
rule Write below binary dir, you can use\n# the following rule and lists.\n\n- list:
monitored_directories\n items: [/boot, /lib, /lib64, /usr/lib, /usr/local/lib,
/usr/local/sbin, /usr/local/bin, /root/.ssh, /etc/cardserver]\n\n# Until https://github.com/draios/sysdig/pull/1153,
which fixes\n# https://github.com/draios/sysdig/issues/1152, is widely available,\n#
we can't use glob operators to match pathnames. Until then, we do a\n# looser check
to match ssh directories.\n# When fixed, we will use \"fd.name glob '/home/*/.ssh/*'\"\n-
macro: user_ssh_directory\n condition: (fd.name startswith '/home' and fd.name
contains '.ssh')\n\n# google_accounts_(daemon)\n- macro: google_accounts_daemon_writing_ssh\n
\ condition: (proc.name=google_accounts and user_ssh_directory)\n\n- macro: cloud_init_writing_ssh\n
\ condition: (proc.name=cloud-init and user_ssh_directory)\n\n- macro: mkinitramfs_writing_boot\n
\ condition: (proc.pname in (mkinitramfs, update-initramf) and fd.directory=/boot)\n\n-
macro: monitored_dir\n condition: >\n (fd.directory in (monitored_directories)\n
\ or user_ssh_directory)\n and not mkinitramfs_writing_boot\n\n# Add conditions
to this macro (probably in a separate file,\n# overwriting this macro) to allow
for specific combinations of\n# programs writing below monitored directories.\n#\n#
Its default value is an expression that always is false, which\n# becomes true when
the \"not ...\" in the rule is applied.\n- macro: user_known_write_monitored_dir_conditions\n
\ condition: (never_true)\n\n- rule: Write below monitored dir\n desc: an attempt
to write to any file below a set of binary directories\n condition: >\n evt.dir
= < and open_write and monitored_dir\n and not package_mgmt_procs\n and not
coreos_write_ssh_dir\n and not exe_running_docker_save\n and not python_running_get_pip\n
\ and not python_running_ms_oms\n and not google_accounts_daemon_writing_ssh\n
\ and not cloud_init_writing_ssh\n and not user_known_write_monitored_dir_conditions\n
\ output: >\n File below a monitored directory opened for writing (user=%user.name\n
\ command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline
gparent=%proc.aname[2] container_id=%container.id image=%container.image.repository)\n
\ priority: ERROR\n tags: [filesystem, mitre_persistence]\n\n# This rule is disabled
by default as many system management tools\n# like ansible, etc can read these files/paths.
Enable it using this macro.\n\n- macro: consider_ssh_reads\n condition: (never_true)\n\n-
rule: Read ssh information\n desc: Any attempt to read files below ssh directories
by non-ssh programs\n condition: >\n (consider_ssh_reads and\n (open_read
or open_directory) and\n (user_ssh_directory or fd.name startswith /root/.ssh)
and\n (not proc.name in (ssh_binaries)))\n output: >\n ssh-related file/directory
read by non-ssh program (user=%user.name\n command=%proc.cmdline file=%fd.name
parent=%proc.pname pcmdline=%proc.pcmdline container_id=%container.id image=%container.image.repository)\n
\ priority: ERROR\n tags: [filesystem, mitre_discovery]\n\n- list: safe_etc_dirs\n
\ items: [/etc/cassandra, /etc/ssl/certs/java, /etc/logstash, /etc/nginx/conf.d,
/etc/container_environment, /etc/hrmconfig, /etc/fluent/configs.d]\n\n- macro: fluentd_writing_conf_files\n
\ condition: (proc.name=start-fluentd and fd.name in (/etc/fluent/fluent.conf, /etc/td-agent/td-agent.conf))\n\n-
macro: qualys_writing_conf_files\n condition: (proc.name=qualys-cloud-ag and fd.name=/etc/qualys/cloud-agent/qagent-log.conf)\n\n-
macro: git_writing_nssdb\n condition: (proc.name=git-remote-http and fd.directory=/etc/pki/nssdb)\n\n-
macro: plesk_writing_keys\n condition: (proc.name in (plesk_binaries) and fd.name
startswith /etc/sw/keys)\n\n- macro: plesk_install_writing_apache_conf\n condition:
(proc.cmdline startswith \"bash -hB /usr/lib/plesk-9.0/services/webserver.apache
configure\"\n and fd.name=\"/etc/apache2/apache2.conf.tmp\")\n\n- macro:
plesk_running_mktemp\n condition: (proc.name=mktemp and proc.aname[3] in (plesk_binaries))\n\n-
macro: networkmanager_writing_resolv_conf\n condition: proc.aname[2]=nm-dispatcher
and fd.name=/etc/resolv.conf\n\n- macro: add_shell_writing_shells_tmp\n condition:
(proc.name=add-shell and fd.name=/etc/shells.tmp)\n\n- macro: duply_writing_exclude_files\n
\ condition: (proc.name=touch and proc.pcmdline startswith \"bash /usr/bin/duply\"
and fd.name startswith \"/etc/duply\")\n\n- macro: xmlcatalog_writing_files\n condition:
(proc.name=update-xmlcatal and fd.directory=/etc/xml)\n\n- macro: datadog_writing_conf\n
\ condition: ((proc.cmdline startswith \"python /opt/datadog-agent\" or\n proc.cmdline
startswith \"entrypoint.sh /entrypoint.sh datadog start\" or\n proc.cmdline
startswith \"agent.py /opt/datadog-agent\")\n and fd.name startswith
\"/etc/dd-agent\")\n\n- macro: rancher_writing_conf\n condition: ((proc.name in
(healthcheck, lb-controller, rancher-dns)) and\n (container.image.repository
contains \"rancher/healthcheck\" or\n container.image.repository contains
\"rancher/lb-service-haproxy\" or\n container.image.repository contains
\"rancher/dns\") and\n (fd.name startswith \"/etc/haproxy\" or fd.name
startswith \"/etc/rancher-dns\"))\n\n- macro: rancher_writing_root\n condition:
(proc.name=rancher-metadat and\n (container.image.repository contains
\"rancher/metadata\" or container.image.repository contains \"rancher/lb-service-haproxy\")
and\n fd.name startswith \"/answers.json\")\n\n- macro: checkpoint_writing_state\n
\ condition: (proc.name=checkpoint and\n container.image.repository
contains \"coreos/pod-checkpointer\" and\n fd.name startswith \"/etc/kubernetes\")\n\n-
macro: jboss_in_container_writing_passwd\n condition: >\n ((proc.cmdline=\"run-java.sh
/opt/jboss/container/java/run/run-java.sh\"\n or proc.cmdline=\"run-java.sh
/opt/run-java/run-java.sh\")\n and container\n and fd.name=/etc/passwd)\n\n-
macro: curl_writing_pki_db\n condition: (proc.name=curl and fd.directory=/etc/pki/nssdb)\n\n-
macro: haproxy_writing_conf\n condition: ((proc.name in (update-haproxy-,haproxy_reload.)
or proc.pname in (update-haproxy-,haproxy_reload,haproxy_reload.))\n and
(fd.name=/etc/openvpn/client.map or fd.name startswith /etc/haproxy))\n\n- macro:
java_writing_conf\n condition: (proc.name=java and fd.name=/etc/.java/.systemPrefs/.system.lock)\n\n-
macro: rabbitmq_writing_conf\n condition: (proc.name=rabbitmq-server and fd.directory=/etc/rabbitmq)\n\n-
macro: rook_writing_conf\n condition: (proc.name=toolbox.sh and container.image.repository=rook/toolbox\n
\ and fd.directory=/etc/ceph)\n\n- macro: httpd_writing_conf_logs\n
\ condition: (proc.name=httpd and fd.name startswith /etc/httpd/)\n\n- macro: mysql_writing_conf\n
\ condition: >\n ((proc.name in (start-mysql.sh, run-mysqld) or proc.pname=start-mysql.sh)
and\n (fd.name startswith /etc/mysql or fd.directory=/etc/my.cnf.d))\n\n- macro:
redis_writing_conf\n condition: >\n (proc.name in (run-redis, redis-launcher.)
and fd.name=/etc/redis.conf or fd.name startswith /etc/redis)\n\n- macro: openvpn_writing_conf\n
\ condition: (proc.name in (openvpn,openvpn-entrypo) and fd.name startswith /etc/openvpn)\n\n-
macro: php_handlers_writing_conf\n condition: (proc.name=php_handlers_co and fd.name=/etc/psa/php_versions.json)\n\n-
macro: sed_writing_temp_file\n condition: >\n ((proc.aname[3]=cron_start.sh
and fd.name startswith /etc/security/sed) or\n (proc.name=sed and (fd.name startswith
/etc/apt/sources.list.d/sed or\n fd.name startswith /etc/apt/sed
or\n fd.name startswith /etc/apt/apt.conf.d/sed)))\n\n-
macro: cron_start_writing_pam_env\n condition: (proc.cmdline=\"bash /usr/sbin/start-cron\"
and fd.name=/etc/security/pam_env.conf)\n\n# In some cases dpkg-reconfigur runs
commands that modify /etc. Not\n# putting the full set of package management programs
yet.\n- macro: dpkg_scripting\n condition: (proc.aname[2] in (dpkg-reconfigur,
dpkg-preconfigu))\n\n- macro: ufw_writing_conf\n condition: (proc.name=ufw and
fd.directory=/etc/ufw)\n\n- macro: calico_writing_conf\n condition: >\n (proc.name
= calico-node and fd.name startswith /etc/calico)\n\n- macro: prometheus_conf_writing_conf\n
\ condition: (proc.name=prometheus-conf and fd.name startswith /etc/prometheus/config_out)\n\n-
macro: openshift_writing_conf\n condition: (proc.name=oc and fd.name startswith
/etc/origin/node)\n\n- macro: keepalived_writing_conf\n condition: (proc.name=keepalived
and fd.name=/etc/keepalived/keepalived.conf)\n\n- macro: etcd_manager_updating_dns\n
\ condition: (container and proc.name=etcd-manager and fd.name=/etc/hosts)\n\n-
macro: automount_using_mtab\n condition: (proc.pname = automount and fd.name startswith
/etc/mtab)\n\n# Add conditions to this macro (probably in a separate file,\n# overwriting
this macro) to allow for specific combinations of\n# programs writing below specific
directories below\n# /etc. fluentd_writing_conf_files is a good example to follow,
as it\n# specifies both the program doing the writing as well as the specific\n#
files it is allowed to modify.\n#\n# In this file, it just takes one of the programs
in the base macro\n# and repeats it.\n\n- macro: user_known_write_etc_conditions\n
\ condition: proc.name=confd\n\n# This is a placeholder for user to extend the whitelist
for write below etc rule\n- macro: user_known_write_below_etc_activities\n condition:
(never_true)\n\n- macro: write_etc_common\n condition: >\n etc_dir and evt.dir
= < and open_write\n and proc_name_exists\n and not proc.name in (passwd_binaries,
shadowutils_binaries, sysdigcloud_binaries,\n package_mgmt_binaries,
ssl_mgmt_binaries, dhcp_binaries,\n dev_creation_binaries,
shell_mgmt_binaries,\n mail_config_binaries,\n sshkit_script_binaries,\n
\ ldconfig.real, ldconfig, confd, gpg, insserv,\n apparmor_parser,
update-mime, tzdata.config, tzdata.postinst,\n systemd,
systemd-machine, systemd-sysuser,\n debconf-show, rollerd,
bind9.postinst, sv,\n gen_resolvconf., update-ca-certi,
certbot, runsv,\n qualys-cloud-ag, locales.postins, nomachine_binaries,\n
\ adclient, certutil, crlutil, pam-auth-update, parallels_insta,\n
\ openshift-launc, update-rc.d, puppet)\n and not proc.pname
in (sysdigcloud_binaries, mail_config_binaries, hddtemp.postins, sshkit_script_binaries,
locales.postins, deb_binaries, dhcp_binaries)\n and not fd.name pmatch (safe_etc_dirs)\n
\ and not fd.name in (/etc/container_environment.sh, /etc/container_environment.json,
/etc/motd, /etc/motd.svc)\n and not sed_temporary_file\n and not exe_running_docker_save\n
\ and not ansible_running_python\n and not python_running_denyhosts\n and
not fluentd_writing_conf_files\n and not user_known_write_etc_conditions\n and
not run_by_centrify\n and not run_by_adclient\n and not qualys_writing_conf_files\n
\ and not git_writing_nssdb\n and not plesk_writing_keys\n and not plesk_install_writing_apache_conf\n
\ and not plesk_running_mktemp\n and not networkmanager_writing_resolv_conf\n
\ and not run_by_chef\n and not add_shell_writing_shells_tmp\n and not duply_writing_exclude_files\n
\ and not xmlcatalog_writing_files\n and not parent_supervise_running_multilog\n
\ and not supervise_writing_status\n and not pki_realm_writing_realms\n and
not htpasswd_writing_passwd\n and not lvprogs_writing_conf\n and not ovsdb_writing_openvswitch\n
\ and not datadog_writing_conf\n and not curl_writing_pki_db\n and not haproxy_writing_conf\n
\ and not java_writing_conf\n and not dpkg_scripting\n and not parent_ucf_writing_conf\n
\ and not rabbitmq_writing_conf\n and not rook_writing_conf\n and not php_handlers_writing_conf\n
\ and not sed_writing_temp_file\n and not cron_start_writing_pam_env\n and
not httpd_writing_conf_logs\n and not mysql_writing_conf\n and not openvpn_writing_conf\n
\ and not consul_template_writing_conf\n and not countly_writing_nginx_conf\n
\ and not ms_oms_writing_conf\n and not ms_scx_writing_conf\n and not azure_scripts_writing_conf\n
\ and not azure_networkwatcher_writing_conf\n and not couchdb_writing_conf\n
\ and not update_texmf_writing_conf\n and not slapadd_writing_conf\n and
not symantec_writing_conf\n and not liveupdate_writing_conf\n and not sosreport_writing_files\n
\ and not selinux_writing_conf\n and not veritas_writing_config\n and not
nginx_writing_conf\n and not nginx_writing_certs\n and not chef_client_writing_conf\n
\ and not centrify_writing_krb\n and not cockpit_writing_conf\n and not
ipsec_writing_conf\n and not httpd_writing_ssl_conf\n and not userhelper_writing_etc_security\n
\ and not pkgmgmt_progs_writing_pki\n and not update_ca_trust_writing_pki\n
\ and not brandbot_writing_os_release\n and not redis_writing_conf\n and
not openldap_writing_conf\n and not ucpagent_writing_conf\n and not iscsi_writing_conf\n
\ and not istio_writing_conf\n and not ufw_writing_conf\n and not calico_writing_conf\n
\ and not calico_writing_envvars\n and not prometheus_conf_writing_conf\n and
not openshift_writing_conf\n and not keepalived_writing_conf\n and not rancher_writing_conf\n
\ and not checkpoint_writing_state\n and not jboss_in_container_writing_passwd\n
\ and not etcd_manager_updating_dns\n and not user_known_write_below_etc_activities\n
\ and not automount_using_mtab\n\n- rule: Write below etc\n desc: an attempt
to write to any file below /etc\n condition: write_etc_common\n output: \"File
below /etc opened for writing (user=%user.name 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)\"\n
\ priority: ERROR\n tags: [filesystem, mitre_persistence]\n\n- list: known_root_files\n
\ items: [/root/.monit.state, /root/.auth_tokens, /root/.bash_history, /root/.ash_history,
/root/.aws/credentials,\n /root/.viminfo.tmp, /root/.lesshst, /root/.bzr.log,
/root/.gitconfig.lock, /root/.babel.json, /root/.localstack,\n /root/.node_repl_history,
/root/.mongorc.js, /root/.dbshell, /root/.augeas/history, /root/.rnd, /root/.wget-hsts,
/health, /exec.fifo]\n\n- list: known_root_directories\n items: [/root/.oracle_jre_usage,
/root/.ssh, /root/.subversion, /root/.nami]\n\n- macro: known_root_conditions\n
\ condition: (fd.name startswith /root/orcexec.\n or fd.name startswith
/root/.m2\n or fd.name startswith /root/.npm\n or fd.name
startswith /root/.pki\n or fd.name startswith /root/.ivy2\n or
fd.name startswith /root/.config/Cypress\n or fd.name startswith /root/.config/pulse\n
\ or fd.name startswith /root/.config/configstore\n or
fd.name startswith /root/jenkins/workspace\n or fd.name startswith
/root/.jenkins\n or fd.name startswith /root/.cache\n or
fd.name startswith /root/.sbt\n or fd.name startswith /root/.java\n
\ or fd.name startswith /root/.glide\n or fd.name startswith
/root/.sonar\n or fd.name startswith /root/.v8flag\n or
fd.name startswith /root/infaagent\n or fd.name startswith /root/.local/lib/python\n
\ or fd.name startswith /root/.pm2\n or fd.name startswith
/root/.gnupg\n or fd.name startswith /root/.pgpass\n or
fd.name startswith /root/.theano\n or fd.name startswith /root/.gradle\n
\ or fd.name startswith /root/.android\n or fd.name startswith
/root/.ansible\n or fd.name startswith /root/.crashlytics\n or
fd.name startswith /root/.dbus\n or fd.name startswith /root/.composer\n
\ or fd.name startswith /root/.gconf\n or fd.name startswith
/root/.nv\n or fd.name startswith /root/.local/share/jupyter\n or
fd.name startswith /root/oradiag_root\n or fd.name startswith /root/workspace\n
\ or fd.name startswith /root/jvm\n or fd.name startswith
/root/.node-gyp)\n\n# Add conditions to this macro (probably in a separate file,\n#
overwriting this macro) to allow for specific combinations of\n# programs writing
below specific directories below\n# / or /root.\n#\n# In this file, it just takes
one of the condition in the base macro\n# and repeats it.\n- macro: user_known_write_root_conditions\n
\ condition: fd.name=/root/.bash_history\n\n# This is a placeholder for user to
extend the whitelist for write below root rule\n- macro: user_known_write_below_root_activities\n
\ condition: (never_true)\n\n- rule: Write below root\n desc: an attempt to write
to any file directly below / or /root\n condition: >\n root_dir and evt.dir
= < and open_write\n and not fd.name in (known_root_files)\n and not fd.directory
in (known_root_directories)\n and not exe_running_docker_save\n and not gugent_writing_guestagent_log\n
\ and not dse_writing_tmp\n and not zap_writing_state\n and not airflow_writing_state\n
\ and not rpm_writing_root_rpmdb\n and not maven_writing_groovy\n and not
chef_writing_conf\n and not kubectl_writing_state\n and not cassandra_writing_state\n
\ and not galley_writing_state\n and not calico_writing_state\n and not
rancher_writing_root\n and not known_root_conditions\n and not user_known_write_root_conditions\n
\ and not user_known_write_below_root_activities\n output: \"File below / or
/root opened for writing (user=%user.name command=%proc.cmdline parent=%proc.pname
file=%fd.name program=%proc.name container_id=%container.id image=%container.image.repository)\"\n
\ priority: ERROR\n tags: [filesystem, mitre_persistence]\n\n- macro: cmp_cp_by_passwd\n
\ condition: proc.name in (cmp, cp) and proc.pname in (passwd, run-parts)\n\n- rule:
Read sensitive file trusted after startup\n desc: >\n an attempt to read any
sensitive file (e.g. files containing user/password/authentication\n information)
by a trusted program after startup. Trusted programs might read these files\n at
startup to load initial state, but not afterwards.\n condition: sensitive_files
and open_read and server_procs and not proc_is_new and proc.name!=\"sshd\"\n output:
>\n Sensitive file opened for reading by trusted program after startup (user=%user.name\n
\ command=%proc.cmdline parent=%proc.pname file=%fd.name parent=%proc.pname gparent=%proc.aname[2]
container_id=%container.id image=%container.image.repository)\n priority: WARNING\n
\ tags: [filesystem, mitre_credential_access]\n\n- list: read_sensitive_file_binaries\n
\ items: [\n iptables, ps, lsb_release, check-new-relea, dumpe2fs, accounts-daemon,
sshd,\n vsftpd, systemd, mysql_install_d, psql, screen, debconf-show, sa-update,\n
\ pam-auth-update, pam-config, /usr/sbin/spamd, polkit-agent-he, lsattr, file,
sosreport,\n scxcimservera, adclient, rtvscand, cockpit-session, userhelper,
ossec-syscheckd\n ]\n\n# Add conditions to this macro (probably in a separate
file,\n# overwriting this macro) to allow for specific combinations of\n# programs
accessing sensitive files.\n# fluentd_writing_conf_files is a good example to follow,
as it\n# specifies both the program doing the writing as well as the specific\n#
files it is allowed to modify.\n#\n# In this file, it just takes one of the macros
in the base rule\n# and repeats it.\n\n- macro: user_read_sensitive_file_conditions\n
\ condition: cmp_cp_by_passwd\n\n- rule: Read sensitive file untrusted\n desc:
>\n an attempt to read any sensitive file (e.g. files containing user/password/authentication\n
\ information). Exceptions are made for known trusted programs.\n condition:
>\n sensitive_files and open_read\n and proc_name_exists\n and not proc.name
in (user_mgmt_binaries, userexec_binaries, package_mgmt_binaries,\n cron_binaries,
read_sensitive_file_binaries, shell_binaries, hids_binaries,\n vpn_binaries,
mail_config_binaries, nomachine_binaries, sshkit_script_binaries,\n in.proftpd,
mandb, salt-minion, postgres_mgmt_binaries)\n and not cmp_cp_by_passwd\n and
not ansible_running_python\n and not proc.cmdline contains /usr/bin/mandb\n and
not run_by_qualys\n and not run_by_chef\n and not run_by_google_accounts_daemon\n
\ and not user_read_sensitive_file_conditions\n and not perl_running_plesk\n
\ and not perl_running_updmap\n and not veritas_driver_script\n and not
perl_running_centrifydc\n and not runuser_reading_pam\n output: >\n Sensitive
file opened for reading by non-trusted program (user=%user.name program=%proc.name\n
\ command=%proc.cmdline file=%fd.name parent=%proc.pname gparent=%proc.aname[2]
ggparent=%proc.aname[3] gggparent=%proc.aname[4] container_id=%container.id image=%container.image.repository)\n
\ priority: WARNING\n tags: [filesystem, mitre_credential_access, mitre_discovery]\n\n-
macro: amazon_linux_running_python_yum\n condition: >\n (proc.name = python
and\n proc.pcmdline = \"python -m amazon_linux_extras system_motd\" and\n proc.cmdline
startswith \"python -c import yum;\")\n\n# Only let rpm-related programs write to
the rpm database\n- rule: Write below rpm database\n desc: an attempt to write
to the rpm database by any non-rpm related program\n condition: >\n fd.name
startswith /var/lib/rpm and open_write\n and not rpm_procs\n and not ansible_running_python\n
\ and not python_running_chef\n and not exe_running_docker_save\n and not
amazon_linux_running_python_yum\n output: \"Rpm database opened for writing by
a non-rpm program (command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline
container_id=%container.id image=%container.image.repository)\"\n priority: ERROR\n
\ tags: [filesystem, software_mgmt, mitre_persistence]\n\n- macro: postgres_running_wal_e\n
\ condition: (proc.pname=postgres and proc.cmdline startswith \"sh -c envdir /etc/wal-e.d/env
/usr/local/bin/wal-e\")\n\n- macro: redis_running_prepost_scripts\n condition:
(proc.aname[2]=redis-server and (proc.cmdline contains \"redis-server.post-up.d\"
or proc.cmdline contains \"redis-server.pre-up.d\"))\n\n- macro: rabbitmq_running_scripts\n
\ condition: >\n (proc.pname=beam.smp and\n (proc.cmdline startswith \"sh
-c exec ps\" or\n proc.cmdline startswith \"sh -c exec inet_gethost\" or\n proc.cmdline=
\"sh -s unix:cmd\" or\n proc.cmdline= \"sh -c exec /bin/sh -s unix:cmd 2>&1\"))\n\n-
macro: rabbitmqctl_running_scripts\n condition: (proc.aname[2]=rabbitmqctl and
proc.cmdline startswith \"sh -c \")\n\n- macro: run_by_appdynamics\n condition:
(proc.pname=java and proc.pcmdline startswith \"java -jar -Dappdynamics\")\n\n-
rule: DB program spawned process\n desc: >\n a database-server related program
spawned a new process other than itself.\n This shouldn\\'t occur and is a follow
on from some SQL injection attacks.\n condition: >\n proc.pname in (db_server_binaries)\n
\ and spawned_process\n and not proc.name in (db_server_binaries)\n and
not postgres_running_wal_e\n output: >\n Database-related program spawned process
other than itself (user=%user.name\n program=%proc.cmdline parent=%proc.pname
container_id=%container.id image=%container.image.repository)\n priority: NOTICE\n
\ tags: [process, database, mitre_execution]\n\n- rule: Modify binary dirs\n desc:
an attempt to modify any file below a set of binary directories.\n condition: (bin_dir_rename)
and modify and not package_mgmt_procs and not exe_running_docker_save\n output:
>\n File below known binary directory renamed/removed (user=%user.name command=%proc.cmdline\n
\ pcmdline=%proc.pcmdline operation=%evt.type file=%fd.name %evt.args container_id=%container.id
image=%container.image.repository)\n priority: ERROR\n tags: [filesystem, mitre_persistence]\n\n-
rule: Mkdir binary dirs\n desc: an attempt to create a directory below a set of
binary directories.\n condition: mkdir and bin_dir_mkdir and not package_mgmt_procs\n
\ output: >\n Directory below known binary directory created (user=%user.name\n
\ command=%proc.cmdline directory=%evt.arg.path container_id=%container.id image=%container.image.repository)\n
\ priority: ERROR\n tags: [filesystem, mitre_persistence]\n\n# This list allows
for easy additions to the set of commands allowed\n# to change thread namespace
without having to copy and override the\n# entire change thread namespace rule.\n-
list: user_known_change_thread_namespace_binaries\n items: []\n\n- macro: user_known_change_thread_namespace_activities\n
\ condition: (never_true)\n\n- list: network_plugin_binaries\n items: [aws-cni,
azure-vnet]\n\n- macro: calico_node\n condition: (container.image.repository endswith
calico/node and proc.name=calico-node)\n\n- macro: weaveworks_scope\n condition:
(container.image.repository endswith weaveworks/scope and proc.name=scope)\n\n-
rule: Change thread namespace\n desc: >\n an attempt to change a program/thread\\'s
namespace (commonly done\n as a part of creating a container) by calling setns.\n
\ condition: >\n evt.type = setns\n and not proc.name in (docker_binaries,
k8s_binaries, lxd_binaries, sysdigcloud_binaries,\n sysdig,
nsenter, calico, oci-umount, network_plugin_binaries)\n and not proc.name in
(user_known_change_thread_namespace_binaries)\n and not proc.name startswith
\"runc\"\n and not proc.cmdline startswith \"containerd\"\n and not proc.pname
in (sysdigcloud_binaries)\n and not python_running_sdchecks\n and not java_running_sdjagent\n
\ and not kubelet_running_loopback\n and not rancher_agent\n and not rancher_network_manager\n
\ and not calico_node\n and not weaveworks_scope\n and not user_known_change_thread_namespace_activities\n
\ output: >\n Namespace change (setns) by unexpected program (user=%user.name
command=%proc.cmdline\n parent=%proc.pname %container.info container_id=%container.id
image=%container.image.repository)\n priority: NOTICE\n tags: [process]\n\n# The
binaries in this list and their descendents are *not* allowed\n# spawn shells. This
includes the binaries spawning shells directly as\n# well as indirectly. For example,
apache -> php/perl for\n# mod_{php,perl} -> some shell is also not allowed, because
the shell\n# has apache as an ancestor.\n\n- list: protected_shell_spawning_binaries\n
\ items: [\n http_server_binaries, db_server_binaries, nosql_server_binaries,
mail_binaries,\n fluentd, flanneld, splunkd, consul, smbd, runsv, PM2\n ]\n\n-
macro: parent_java_running_zookeeper\n condition: (proc.pname=java and proc.pcmdline
contains org.apache.zookeeper.server)\n\n- macro: parent_java_running_kafka\n condition:
(proc.pname=java and proc.pcmdline contains kafka.Kafka)\n\n- macro: parent_java_running_elasticsearch\n
\ condition: (proc.pname=java and proc.pcmdline contains org.elasticsearch.bootstrap.Elasticsearch)\n\n-
macro: parent_java_running_activemq\n condition: (proc.pname=java and proc.pcmdline
contains activemq.jar)\n\n- macro: parent_java_running_cassandra\n condition: (proc.pname=java
and (proc.pcmdline contains \"-Dcassandra.config.loader\" or proc.pcmdline contains
org.apache.cassandra.service.CassandraDaemon))\n\n- macro: parent_java_running_jboss_wildfly\n
\ condition: (proc.pname=java and proc.pcmdline contains org.jboss)\n\n- macro:
parent_java_running_glassfish\n condition: (proc.pname=java and proc.pcmdline contains
com.sun.enterprise.glassfish)\n\n- macro: parent_java_running_hadoop\n condition:
(proc.pname=java and proc.pcmdline contains org.apache.hadoop)\n\n- macro: parent_java_running_datastax\n
\ condition: (proc.pname=java and proc.pcmdline contains com.datastax)\n\n- macro:
nginx_starting_nginx\n condition: (proc.pname=nginx and proc.cmdline contains \"/usr/sbin/nginx
-c /etc/nginx/nginx.conf\")\n\n- macro: nginx_running_aws_s3_cp\n condition: (proc.pname=nginx
and proc.cmdline startswith \"sh -c /usr/local/bin/aws s3 cp\")\n\n- macro: consul_running_net_scripts\n
\ condition: (proc.pname=consul and (proc.cmdline startswith \"sh -c curl\" or proc.cmdline
startswith \"sh -c nc\"))\n\n- macro: consul_running_alert_checks\n condition:
(proc.pname=consul and proc.cmdline startswith \"sh -c /bin/consul-alerts\")\n\n-
macro: serf_script\n condition: (proc.cmdline startswith \"sh -c serf\")\n\n- macro:
check_process_status\n condition: (proc.cmdline startswith \"sh -c kill -0 \")\n\n#
In some cases, you may want to consider node processes run directly\n# in containers
as protected shell spawners. Examples include using\n# pm2-docker or pm2 start some-app.js
--no-daemon-mode as the direct\n# entrypoint of the container, and when the node
app is a long-lived\n# server using something like express.\n#\n# However, there
are other uses of node related to build pipelines for\n# which node is not really
a server but instead a general scripting\n# tool. In these cases, shells are very
likely and in these cases you\n# don't want to consider node processes protected
shell spawners.\n#\n# We have to choose one of these cases, so we consider node
processes\n# as unprotected by default. If you want to consider any node process\n#
run in a container as a protected shell spawner, override the below\n# macro to
remove the \"never_true\" clause, which allows it to take effect.\n- macro: possibly_node_in_container\n
\ condition: (never_true and (proc.pname=node and proc.aname[3]=docker-containe))\n\n#
Similarly, you may want to consider any shell spawned by apache\n# tomcat as suspect.
The famous apache struts attack (CVE-2017-5638)\n# could be exploited to do things
like spawn shells.\n#\n# However, many applications *do* use tomcat to run arbitrary
shells,\n# as a part of build pipelines, etc.\n#\n# Like for node, we make this
case opt-in.\n- macro: possibly_parent_java_running_tomcat\n condition: (never_true
and proc.pname=java and proc.pcmdline contains org.apache.catalina.startup.Bootstrap)\n\n-
macro: protected_shell_spawner\n condition: >\n (proc.aname in (protected_shell_spawning_binaries)\n
\ or parent_java_running_zookeeper\n or parent_java_running_kafka\n or parent_java_running_elasticsearch\n
\ or parent_java_running_activemq\n or parent_java_running_cassandra\n or
parent_java_running_jboss_wildfly\n or parent_java_running_glassfish\n or
parent_java_running_hadoop\n or parent_java_running_datastax\n or possibly_parent_java_running_tomcat\n
\ or possibly_node_in_container)\n\n- list: mesos_shell_binaries\n items: [mesos-docker-ex,
mesos-slave, mesos-health-ch]\n\n# Note that runsv is both in protected_shell_spawner
and the\n# exclusions by pname. This means that runsv can itself spawn shells\n#
(the ./run and ./finish scripts), but the processes runsv can not\n# spawn shells.\n-
rule: Run shell untrusted\n desc: an attempt to spawn a shell below a non-shell
application. Specific applications are monitored.\n condition: >\n spawned_process\n
\ and shell_procs\n and proc.pname exists\n and protected_shell_spawner\n
\ and not proc.pname in (shell_binaries, gitlab_binaries, cron_binaries, user_known_shell_spawn_binaries,\n
\ needrestart_binaries,\n mesos_shell_binaries,\n
\ erl_child_setup, exechealthz,\n PM2,
PassengerWatchd, c_rehash, svlogd, logrotate, hhvm, serf,\n lb-controller,
nvidia-installe, runsv, statsite, erlexec)\n and not proc.cmdline in (known_shell_spawn_cmdlines)\n
\ and not proc.aname in (unicorn_launche)\n and not consul_running_net_scripts\n
\ and not consul_running_alert_checks\n and not nginx_starting_nginx\n and
not nginx_running_aws_s3_cp\n and not run_by_package_mgmt_binaries\n and not
serf_script\n and not check_process_status\n and not run_by_foreman\n and
not python_mesos_marathon_scripting\n and not splunk_running_forwarder\n and
not postgres_running_wal_e\n and not redis_running_prepost_scripts\n and not
rabbitmq_running_scripts\n and not rabbitmqctl_running_scripts\n and not run_by_appdynamics\n
\ and not user_shell_container_exclusions\n output: >\n Shell spawned by untrusted
binary (user=%user.name shell=%proc.name parent=%proc.pname\n cmdline=%proc.cmdline
pcmdline=%proc.pcmdline gparent=%proc.aname[2] ggparent=%proc.aname[3]\n aname[4]=%proc.aname[4]
aname[5]=%proc.aname[5] aname[6]=%proc.aname[6] aname[7]=%proc.aname[7] container_id=%container.id
image=%container.image.repository)\n priority: DEBUG\n tags: [shell, mitre_execution]\n\n-
macro: allowed_openshift_registry_root\n condition: >\n (container.image.repository
startswith openshift3/ or\n container.image.repository startswith registry.redhat.io/openshift3/
or\n container.image.repository startswith registry.access.redhat.com/openshift3/)\n\n#
Source: https://docs.openshift.com/enterprise/3.2/install_config/install/disconnected_install.html\n-
macro: openshift_image\n condition: >\n (allowed_openshift_registry_root and\n
\ (container.image.repository endswith /logging-deployment or\n container.image.repository
endswith /logging-elasticsearch or\n container.image.repository endswith /logging-kibana
or\n container.image.repository endswith /logging-fluentd or\n container.image.repository
endswith /logging-auth-proxy or\n container.image.repository endswith /metrics-deployer
or\n container.image.repository endswith /metrics-hawkular-metrics or\n container.image.repository
endswith /metrics-cassandra or\n container.image.repository endswith /metrics-heapster
or\n container.image.repository endswith /ose-haproxy-router or\n container.image.repository
endswith /ose-deployer or\n container.image.repository endswith /ose-sti-builder
or\n container.image.repository endswith /ose-docker-builder or\n container.image.repository
endswith /ose-pod or\n container.image.repository endswith /ose-node or\n
\ container.image.repository endswith /ose-docker-registry or\n container.image.repository
endswith /prometheus-node-exporter or\n container.image.repository endswith
/image-inspector))\n\n# These images are allowed both to run with --privileged and
to mount\n# sensitive paths from the host filesystem.\n#\n# NOTE: This list is only
provided for backwards compatibility with\n# older local falco rules files that
may have been appending to\n# trusted_images. To make customizations, it's better
to add images to\n# either privileged_images or falco_sensitive_mount_images.\n-
list: trusted_images\n items: []\n\n# NOTE: This macro is only provided for backwards
compatibility with\n# older local falco rules files that may have been appending
to\n# trusted_images. To make customizations, it's better to add containers to\n#
user_trusted_containers, user_privileged_containers or user_sensitive_mount_containers.\n-
macro: trusted_containers\n condition: (container.image.repository in (trusted_images))\n\n#
Add conditions to this macro (probably in a separate file,\n# overwriting this macro)
to specify additional containers that are\n# trusted and therefore allowed to run
privileged *and* with sensitive\n# mounts.\n#\n# Like trusted_images, this is deprecated
in favor of\n# user_privileged_containers and user_sensitive_mount_containers and\n#
is only provided for backwards compatibility.\n#\n# In this file, it just takes
one of the images in trusted_containers\n# and repeats it.\n- macro: user_trusted_containers\n
\ condition: (container.image.repository endswith sysdig/agent)\n\n- list: sematext_images\n
\ items: [docker.io/sematext/sematext-agent-docker, docker.io/sematext/agent, docker.io/sematext/logagent,\n
\ registry.access.redhat.com/sematext/sematext-agent-docker,\n registry.access.redhat.com/sematext/agent,\n
\ registry.access.redhat.com/sematext/logagent]\n\n# These container images
are allowed to run with --privileged\n- list: falco_privileged_images\n items:
[\n docker.io/sysdig/agent, docker.io/sysdig/falco, docker.io/sysdig/sysdig,\n
\ gcr.io/google_containers/kube-proxy, docker.io/calico/node, quay.io/calico/node,\n
\ docker.io/rook/toolbox, docker.io/cloudnativelabs/kube-router, docker.io/mesosphere/mesos-slave,\n
\ docker.io/docker/ucp-agent, sematext_images, k8s.gcr.io/kube-proxy\n ]\n\n-
macro: falco_privileged_containers\n condition: (openshift_image or\n user_trusted_containers
or\n container.image.repository in (trusted_images) or\n container.image.repository
in (falco_privileged_images) or\n container.image.repository startswith
istio/proxy_ or\n container.image.repository startswith quay.io/sysdig)\n\n#
Add conditions to this macro (probably in a separate file,\n# overwriting this macro)
to specify additional containers that are\n# allowed to run privileged\n#\n# In
this file, it just takes one of the images in falco_privileged_images\n# and repeats
it.\n- macro: user_privileged_containers\n condition: (container.image.repository
endswith sysdig/agent)\n\n- list: rancher_images\n items: [\n rancher/network-manager,
rancher/dns, rancher/agent,\n rancher/lb-service-haproxy, rancher/metadata, rancher/healthcheck\n
\ ]\n\n# These container images are allowed to mount sensitive paths from the\n#
host filesystem.\n- list: falco_sensitive_mount_images\n items: [\n docker.io/sysdig/agent,
docker.io/sysdig/falco, docker.io/sysdig/sysdig,\n gcr.io/google_containers/hyperkube,\n
\ gcr.io/google_containers/kube-proxy, docker.io/calico/node,\n docker.io/rook/toolbox,
docker.io/cloudnativelabs/kube-router, docker.io/consul,\n docker.io/datadog/docker-dd-agent,
docker.io/datadog/agent, docker.io/docker/ucp-agent, docker.io/gliderlabs/logspout,\n
\ docker.io/netdata/netdata, docker.io/google/cadvisor, docker.io/prom/node-exporter,\n
\ amazon/amazon-ecs-agent\n ]\n\n- macro: falco_sensitive_mount_containers\n
\ condition: (user_trusted_containers or\n container.image.repository
in (trusted_images) or\n container.image.repository in (falco_sensitive_mount_images)
or\n container.image.repository startswith quay.io/sysdig)\n\n# These
container images are allowed to run with hostnetwork=true\n- list: falco_hostnetwork_images\n
\ items: []\n\n# Add conditions to this macro (probably in a separate file,\n# overwriting
this macro) to specify additional containers that are\n# allowed to perform sensitive
mounts.\n#\n# In this file, it just takes one of the images in falco_sensitive_mount_images\n#
and repeats it.\n- macro: user_sensitive_mount_containers\n condition: (container.image.repository
= docker.io/sysdig/agent)\n\n- rule: Launch Privileged Container\n desc: Detect
the initial process started in a privileged container. Exceptions are made for known
trusted images.\n condition: >\n container_started and container\n and container.privileged=true\n
\ and not falco_privileged_containers\n and not user_privileged_containers\n
\ output: Privileged container started (user=%user.name command=%proc.cmdline %container.info
image=%container.image.repository:%container.image.tag)\n priority: INFO\n tags:
[container, cis, mitre_privilege_escalation, mitre_lateral_movement]\n\n# For now,
only considering a full mount of /etc as\n# sensitive. Ideally, this would also
consider all subdirectories\n# below /etc as well, but the globbing mechanism used
by sysdig\n# doesn't allow exclusions of a full pattern, only single characters.\n-
macro: sensitive_mount\n condition: (container.mount.dest[/proc*] != \"N/A\" or\n
\ container.mount.dest[/var/run/docker.sock] != \"N/A\" or\n container.mount.dest[/var/run/crio/crio.sock]
!= \"N/A\" or\n container.mount.dest[/var/lib/kubelet] != \"N/A\" or\n
\ container.mount.dest[/var/lib/kubelet/pki] != \"N/A\" or\n container.mount.dest[/]
!= \"N/A\" or\n container.mount.dest[/home/admin] != \"N/A\" or\n container.mount.dest[/etc]
!= \"N/A\" or\n container.mount.dest[/etc/kubernetes] != \"N/A\" or\n
\ container.mount.dest[/etc/kubernetes/manifests] != \"N/A\" or\n container.mount.dest[/root*]
!= \"N/A\")\n\n# The steps libcontainer performs to set up the root program for
a container are:\n# - clone + exec self to a program runc:[0:PARENT]\n# - clone
a program runc:[1:CHILD] which sets up all the namespaces\n# - clone a second program
runc:[2:INIT] + exec to the root program.\n# The parent of runc:[2:INIT] is runc:0:PARENT]\n#
As soon as 1:CHILD is created, 0:PARENT exits, so there's a race\n# where at the
time 2:INIT execs the root program, 0:PARENT might have\n# already exited, or
might still be around. So we handle both.\n# We also let runc:[1:CHILD] count as
the parent process, which can occur\n# when we lose events and lose track of state.\n\n-
macro: container_entrypoint\n condition: (not proc.pname exists or proc.pname in
(runc:[0:PARENT], runc:[1:CHILD], runc, docker-runc, exe, docker-runc-cur))\n\n-
rule: Launch Sensitive Mount Container\n desc: >\n Detect the initial process
started by a container that has a mount from a sensitive host directory\n (i.e.
/proc). Exceptions are made for known trusted images.\n condition: >\n container_started
and container\n and sensitive_mount\n and not falco_sensitive_mount_containers\n
\ and not user_sensitive_mount_containers\n output: Container with sensitive
mount started (user=%user.name command=%proc.cmdline %container.info image=%container.image.repository:%container.image.tag
mounts=%container.mounts)\n priority: INFO\n tags: [container, cis, mitre_lateral_movement]\n\n#
In a local/user rules file, you could override this macro to\n# explicitly enumerate
the container images that you want to run in\n# your environment. In this main falco
rules file, there isn't any way\n# to know all the containers that can run, so any
container is\n# allowed, by using a filter that is guaranteed to evaluate to true.\n#
In the overridden macro, the condition would look something like\n# (container.image.repository
= vendor/container-1 or\n# container.image.repository = vendor/container-2 or ...)\n\n-
macro: allowed_containers\n condition: (container.id exists)\n\n- rule: Launch
Disallowed Container\n desc: >\n Detect the initial process started by a container
that is not in a list of allowed containers.\n condition: container_started and
container and not allowed_containers\n output: Container started and not in allowed
list (user=%user.name command=%proc.cmdline %container.info image=%container.image.repository:%container.image.tag)\n
\ priority: WARNING\n tags: [container, mitre_lateral_movement]\n\n# Anything run
interactively by root\n# - condition: evt.type != switch and user.name = root and
proc.name != sshd and interactive\n# output: \"Interactive root (%user.name %proc.name
%evt.dir %evt.type %evt.args %fd.name)\"\n# priority: WARNING\n\n- rule: System
user interactive\n desc: an attempt to run interactive commands by a system (i.e.
non-login) user\n condition: spawned_process and system_users and interactive\n
\ output: \"System user ran an interactive command (user=%user.name command=%proc.cmdline
container_id=%container.id image=%container.image.repository)\"\n priority: INFO\n
\ tags: [users, mitre_remote_access_tools]\n\n- rule: Terminal shell in container\n
\ desc: A shell was used as the entrypoint/exec point into a container with an attached
terminal.\n condition: >\n spawned_process and container\n and shell_procs
and proc.tty != 0\n and container_entrypoint\n output: >\n A shell was spawned
in a container with an attached terminal (user=%user.name %container.info\n shell=%proc.name
parent=%proc.pname cmdline=%proc.cmdline terminal=%proc.tty container_id=%container.id
image=%container.image.repository)\n priority: NOTICE\n tags: [container, shell,
mitre_execution]\n\n# For some container types (mesos), there isn't a container
image to\n# work with, and the container name is autogenerated, so there isn't\n#
any stable aspect of the software to work with. In this case, we\n# fall back to
allowing certain command lines.\n\n- list: known_shell_spawn_cmdlines\n items:
[\n '\"sh -c uname -p 2> /dev/null\"',\n '\"sh -c uname -s 2>&1\"',\n '\"sh
-c uname -r 2>&1\"',\n '\"sh -c uname -v 2>&1\"',\n '\"sh -c uname -a 2>&1\"',\n
\ '\"sh -c ruby -v 2>&1\"',\n '\"sh -c getconf CLK_TCK\"',\n '\"sh -c getconf
PAGESIZE\"',\n '\"sh -c LC_ALL=C LANG=C /sbin/ldconfig -p 2>/dev/null\"',\n '\"sh
-c LANG=C /sbin/ldconfig -p 2>/dev/null\"',\n '\"sh -c /sbin/ldconfig -p 2>/dev/null\"',\n
\ '\"sh -c stty -a 2>/dev/null\"',\n '\"sh -c stty -a < /dev/tty\"',\n '\"sh
-c stty -g < /dev/tty\"',\n '\"sh -c node index.js\"',\n '\"sh -c node index\"',\n
\ '\"sh -c node ./src/start.js\"',\n '\"sh -c node app.js\"',\n '\"sh -c
node -e \\\"require(''nan'')\\\"\"',\n '\"sh -c node -e \\\"require(''nan'')\\\")\"',\n
\ '\"sh -c node $NODE_DEBUG_OPTION index.js \"',\n '\"sh -c crontab -l 2\"',\n
\ '\"sh -c lsb_release -a\"',\n '\"sh -c lsb_release -is 2>/dev/null\"',\n
\ '\"sh -c whoami\"',\n '\"sh -c node_modules/.bin/bower-installer\"',\n '\"sh
-c /bin/hostname -f 2> /dev/null\"',\n '\"sh -c locale -a\"',\n '\"sh -c -t
-i\"',\n '\"sh -c openssl version\"',\n '\"bash -c id -Gn kafadmin\"',\n '\"sh
-c /bin/sh -c ''date +%%s''\"'\n ]\n\n# This list allows for easy additions to
the set of commands allowed\n# to run shells in containers without having to without
having to copy\n# and override the entire run shell in container macro. Once\n#
https://github.com/draios/falco/issues/255 is fixed this will be a\n# bit easier,
as someone could append of any of the existing lists.\n- list: user_known_shell_spawn_binaries\n
\ items: []\n\n# This macro allows for easy additions to the set of commands allowed\n#
to run shells in containers without having to override the entire\n# rule. Its default
value is an expression that always is false, which\n# becomes true when the \"not
...\" in the rule is applied.\n- macro: user_shell_container_exclusions\n condition:
(never_true)\n\n- macro: login_doing_dns_lookup\n condition: (proc.name=login and
fd.l4proto=udp and fd.sport=53)\n\n# sockfamily ip is to exclude certain processes
(like 'groups') that communicate on unix-domain sockets\n# systemd can listen on
ports to launch things like sshd on demand\n- rule: System procs network activity\n
\ desc: any network activity performed by system binaries that are not expected
to send or receive any network traffic\n condition: >\n (fd.sockfamily = ip
and (system_procs or proc.name in (shell_binaries)))\n and (inbound_outbound)\n
\ and not proc.name in (systemd, hostid, id)\n and not login_doing_dns_lookup\n
\ output: >\n Known system binary sent/received network traffic\n (user=%user.name
command=%proc.cmdline connection=%fd.name container_id=%container.id image=%container.image.repository)\n
\ priority: NOTICE\n tags: [network, mitre_exfiltration]\n\n# When filled in, this
should look something like:\n# (proc.env contains \"HTTP_PROXY=http://my.http.proxy.com
\")\n# The trailing space is intentional so avoid matching on prefixes of\n# the
actual proxy.\n- macro: allowed_ssh_proxy_env\n condition: (always_true)\n\n- list:
http_proxy_binaries\n items: [curl, wget]\n\n- macro: http_proxy_procs\n condition:
(proc.name in (http_proxy_binaries))\n\n- rule: Program run with disallowed http
proxy env\n desc: An attempt to run a program with a disallowed HTTP_PROXY environment
variable\n condition: >\n spawned_process and\n http_proxy_procs and\n not
allowed_ssh_proxy_env and\n proc.env icontains HTTP_PROXY\n output: >\n Program
run with disallowed HTTP_PROXY environment variable\n (user=%user.name command=%proc.cmdline
env=%proc.env parent=%proc.pname container_id=%container.id image=%container.image.repository)\n
\ priority: NOTICE\n tags: [host, users]\n\n# In some environments, any attempt
by a interpreted program (perl,\n# python, ruby, etc) to listen for incoming connections
or perform\n# outgoing connections might be suspicious. These rules are not\n# enabled
by default, but you can modify the following macros to\n# enable them.\n\n- macro:
consider_interpreted_inbound\n condition: (never_true)\n\n- macro: consider_interpreted_outbound\n
\ condition: (never_true)\n\n- rule: Interpreted procs inbound network activity\n
\ desc: Any inbound network activity performed by any interpreted program (perl,
python, ruby, etc.)\n condition: >\n (inbound and consider_interpreted_inbound\n
\ and interpreted_procs)\n output: >\n Interpreted program received/listened
for network traffic\n (user=%user.name command=%proc.cmdline connection=%fd.name
container_id=%container.id image=%container.image.repository)\n priority: NOTICE\n
\ tags: [network, mitre_exfiltration]\n\n- rule: Interpreted procs outbound network
activity\n desc: Any outbound network activity performed by any interpreted program
(perl, python, ruby, etc.)\n condition: >\n (outbound and consider_interpreted_outbound\n
\ and interpreted_procs)\n output: >\n Interpreted program performed outgoing
network connection\n (user=%user.name command=%proc.cmdline connection=%fd.name
container_id=%container.id image=%container.image.repository)\n priority: NOTICE\n
\ tags: [network, mitre_exfiltration]\n\n- list: openvpn_udp_ports\n items: [1194,
1197, 1198, 8080, 9201]\n\n- list: l2tp_udp_ports\n items: [500, 1701, 4500, 10000]\n\n-
list: statsd_ports\n items: [8125]\n\n- list: ntp_ports\n items: [123]\n\n# Some
applications will connect a udp socket to an address only to\n# test connectivity.
Assuming the udp connect works, they will follow\n# up with a tcp connect that actually
sends/receives data.\n#\n# With that in mind, we listed a few commonly seen ports
here to avoid\n# some false positives. In addition, we make the main rule opt-in,
so\n# it's disabled by default.\n\n- list: test_connect_ports\n items: [0, 9, 80,
3306]\n\n- macro: do_unexpected_udp_check\n condition: (never_true)\n\n- list:
expected_udp_ports\n items: [53, openvpn_udp_ports, l2tp_udp_ports, statsd_ports,
ntp_ports, test_connect_ports]\n\n- macro: expected_udp_traffic\n condition: fd.port
in (expected_udp_ports)\n\n- rule: Unexpected UDP Traffic\n desc: UDP traffic not
on port 53 (DNS) or other commonly used ports\n condition: (inbound_outbound) and
do_unexpected_udp_check and fd.l4proto=udp and not expected_udp_traffic\n output:
>\n Unexpected UDP Traffic Seen\n (user=%user.name command=%proc.cmdline connection=%fd.name
proto=%fd.l4proto evt=%evt.type %evt.args container_id=%container.id image=%container.image.repository)\n
\ priority: NOTICE\n tags: [network, mitre_exfiltration]\n\n# With the current
restriction on system calls handled by falco\n# (e.g. excluding read/write/sendto/recvfrom/etc,
this rule won't\n# trigger).\n# - rule: Ssh error in syslog\n# desc: any ssh errors
(failed logins, disconnects, ...) sent to syslog\n# condition: syslog and ssh_error_message
and evt.dir = <\n# output: \"sshd sent error message to syslog (error=%evt.buffer)\"\n#
\ priority: WARNING\n\n- macro: somebody_becoming_themself\n condition: ((user.name=nobody
and evt.arg.uid=nobody) or\n (user.name=www-data and evt.arg.uid=www-data)
or\n (user.name=_apt and evt.arg.uid=_apt) or\n (user.name=postfix
and evt.arg.uid=postfix) or\n (user.name=pki-agent and evt.arg.uid=pki-agent)
or\n (user.name=pki-acme and evt.arg.uid=pki-acme) or\n (user.name=nfsnobody
and evt.arg.uid=nfsnobody) or\n (user.name=postgres and evt.arg.uid=postgres))\n\n-
macro: nrpe_becoming_nagios\n condition: (proc.name=nrpe and evt.arg.uid=nagios)\n\n#
In containers, the user name might be for a uid that exists in the\n# container
but not on the host. (See\n# https://github.com/draios/sysdig/issues/954). So in
that case, allow\n# a setuid.\n- macro: known_user_in_container\n condition: (container
and user.name != \"N/A\")\n\n# Add conditions to this macro (probably in a separate
file,\n# overwriting this macro) to allow for specific combinations of\n# programs
changing users by calling setuid.\n#\n# In this file, it just takes one of the condition
in the base macro\n# and repeats it.\n- macro: user_known_non_sudo_setuid_conditions\n
\ condition: user.name=root\n\n# sshd, mail programs attempt to setuid to root even
when running as non-root. Excluding here to avoid meaningless FPs\n- rule: Non sudo
setuid\n desc: >\n an attempt to change users by calling setuid. sudo/su are
excluded. users \"root\" and \"nobody\"\n suing to itself are also excluded,
as setuid calls typically involve dropping privileges.\n condition: >\n evt.type=setuid
and evt.dir=>\n and (known_user_in_container or not container)\n and not user.name=root\n
\ and not somebody_becoming_themself\n and not proc.name in (known_setuid_binaries,
userexec_binaries, mail_binaries, docker_binaries,\n nomachine_binaries)\n
\ and not proc.name startswith \"runc:\"\n and not java_running_sdjagent\n
\ and not nrpe_becoming_nagios\n and not user_known_non_sudo_setuid_conditions\n
\ output: >\n Unexpected setuid call by non-sudo, non-root program (user=%user.name
cur_uid=%user.uid parent=%proc.pname\n command=%proc.cmdline uid=%evt.arg.uid
container_id=%container.id image=%container.image.repository)\n priority: NOTICE\n
\ tags: [users, mitre_privilege_escalation]\n\n- rule: User mgmt binaries\n desc:
>\n activity by any programs that can manage users, passwords, or permissions.
sudo and su are excluded.\n Activity in containers is also excluded--some containers
create custom users on top\n of a base linux distribution at startup.\n Some
innocuous commandlines that don't actually change anything are excluded.\n condition:
>\n spawned_process and proc.name in (user_mgmt_binaries) and\n not proc.name
in (su, sudo, lastlog, nologin, unix_chkpwd) and not container and\n not proc.pname
in (cron_binaries, systemd, systemd.postins, udev.postinst, run-parts) and\n not
proc.cmdline startswith \"passwd -S\" and\n not proc.cmdline startswith \"useradd
-D\" and\n not proc.cmdline startswith \"systemd --version\" and\n not run_by_qualys
and\n not run_by_sumologic_securefiles and\n not run_by_yum and\n not run_by_ms_oms
and\n not run_by_google_accounts_daemon\n output: >\n User management binary
command run outside of container\n (user=%user.name command=%proc.cmdline parent=%proc.pname
gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4])\n priority:
NOTICE\n tags: [host, users, mitre_persistence]\n\n- list: allowed_dev_files\n
\ items: [\n /dev/null, /dev/stdin, /dev/stdout, /dev/stderr,\n /dev/random,
/dev/urandom, /dev/console, /dev/kmsg\n ]\n\n# (we may need to add additional
checks against false positives, see:\n# https://bugs.launchpad.net/ubuntu/+source/rkhunter/+bug/86153)\n-
rule: Create files below dev\n desc: creating any files below /dev other than known
programs that manage devices. Some rootkits hide files in /dev.\n condition: >\n
\ fd.directory = /dev and\n (evt.type = creat or (evt.type = open and evt.arg.flags
contains O_CREAT))\n and not proc.name in (dev_creation_binaries)\n and not
fd.name in (allowed_dev_files)\n and not fd.name startswith /dev/tty\n output:
\"File created below /dev by untrusted program (user=%user.name command=%proc.cmdline
file=%fd.name container_id=%container.id image=%container.image.repository)\"\n
\ priority: ERROR\n tags: [filesystem, mitre_persistence]\n\n\n# In a local/user
rules file, you could override this macro to\n# explicitly enumerate the container
images that you want to allow\n# access to EC2 metadata. In this main falco rules
file, there isn't\n# any way to know all the containers that should have access,
so any\n# container is alllowed, by repeating the \"container\" macro. In the\n#
overridden macro, the condition would look something like\n# (container.image.repository
= vendor/container-1 or\n# container.image.repository = vendor/container-2 or ...)\n-
macro: ec2_metadata_containers\n condition: container\n\n# On EC2 instances, 169.254.169.254
is a special IP used to fetch\n# metadata about the instance. It may be desirable
to prevent access\n# to this IP from containers.\n- rule: Contact EC2 Instance Metadata
Service From Container\n desc: Detect attempts to contact the EC2 Instance Metadata
Service from a container\n condition: outbound and fd.sip=\"169.254.169.254\" and
container and not ec2_metadata_containers\n output: Outbound connection to EC2
instance metadata service (command=%proc.cmdline connection=%fd.name %container.info
image=%container.image.repository:%container.image.tag)\n priority: NOTICE\n tags:
[network, aws, container, mitre_discovery]\n\n\n# This rule is not enabled by default,
since this rule is for cloud environment(GCP, AWS and Azure) only.\n# If you want
to enable this rule, overwrite the first macro,\n# And you can filter the container
that you want to allow access to metadata by overwriting the second macro.\n- macro:
consider_metadata_access\n condition: (never_true)\n\n- macro: user_known_metadata_access\n
\ condition: (k8s.ns.name = \"kube-system\")\n\n# On GCP, AWS and Azure, 169.254.169.254
is a special IP used to fetch\n# metadata about the instance. The metadata could
be used to get credentials by attackers.\n- rule: Contact cloud metadata service
from container\n desc: Detect attempts to contact the Cloud Instance Metadata Service
from a container\n condition: outbound and fd.sip=\"169.254.169.254\" and container
and consider_metadata_access and not user_known_metadata_access\n output: Outbound
connection to cloud instance metadata service (command=%proc.cmdline connection=%fd.name
%container.info image=%container.image.repository:%container.image.tag)\n priority:
NOTICE\n tags: [network, container, mitre_discovery]\n\n\n# In a local/user rules
file, list the namespace or container images that are\n# allowed to contact the
K8s API Server from within a container. This\n# might cover cases where the K8s
infrastructure itself is running\n# within a container.\n- macro: k8s_containers\n
\ condition: >\n (container.image.repository in (gcr.io/google_containers/hyperkube-amd64,\n
\ gcr.io/google_containers/kube2sky, sysdig/agent, sysdig/falco,\n sysdig/sysdig,
falcosecurity/falco) or (k8s.ns.name = \"kube-system\"))\n\n- macro: k8s_api_server\n
\ condition: (fd.sip.name=\"kubernetes.default.svc.cluster.local\")\n\n- rule: Contact
K8S API Server From Container\n desc: Detect attempts to contact the K8S API Server
from a container\n condition: evt.type=connect and evt.dir=< and (fd.typechar=4
or fd.typechar=6) and container and not k8s_containers and k8s_api_server\n output:
Unexpected connection to K8s API Server from container (command=%proc.cmdline %container.info
image=%container.image.repository:%container.image.tag connection=%fd.name)\n priority:
NOTICE\n tags: [network, k8s, container, mitre_discovery]\n\n# In a local/user
rules file, list the container images that are\n# allowed to contact NodePort services
from within a container. This\n# might cover cases where the K8s infrastructure
itself is running\n# within a container.\n#\n# By default, all containers are allowed
to contact NodePort services.\n- macro: nodeport_containers\n condition: container\n\n-
rule: Unexpected K8s NodePort Connection\n desc: Detect attempts to use K8s NodePorts
from a container\n condition: (inbound_outbound) and fd.sport >= 30000 and fd.sport
<= 32767 and container and not nodeport_containers\n output: Unexpected K8s NodePort
Connection (command=%proc.cmdline connection=%fd.name container_id=%container.id
image=%container.image.repository)\n priority: NOTICE\n tags: [network, k8s, container,
mitre_port_knocking]\n\n- list: network_tool_binaries\n items: [nc, ncat, nmap,
dig, tcpdump, tshark, ngrep, telnet, mitmproxy, socat]\n\n- macro: network_tool_procs\n
\ condition: (proc.name in (network_tool_binaries))\n\n# In a local/user rules file,
create a condition that matches legitimate uses\n# of a package management process
inside a container.\n#\n# For example:\n# - macro: user_known_package_manager_in_container\n#
\ condition: proc.cmdline=\"dpkg -l\"\n- macro: user_known_package_manager_in_container\n
\ condition: (never_true)\n\n# Container is supposed to be immutable. Package management
should be done in building the image.\n- rule: Launch Package Management Process
in Container\n desc: Package management process ran inside container\n condition:
>\n spawned_process\n and container\n and user.name != \"_apt\"\n and
package_mgmt_procs\n and not package_mgmt_ancestor_procs\n and not user_known_package_manager_in_container\n
\ output: >\n Package management process launched in container (user=%user.name\n
\ command=%proc.cmdline container_id=%container.id container_name=%container.name
image=%container.image.repository:%container.image.tag)\n priority: ERROR\n tags:
[process, mitre_persistence]\n\n- rule: Netcat Remote Code Execution in Container\n
\ desc: Netcat Program runs inside container that allows remote code execution\n
\ condition: >\n spawned_process and container and\n ((proc.name = \"nc\"
and (proc.args contains \"-e\" or proc.args contains \"-c\")) or\n (proc.name
= \"ncat\" and (proc.args contains \"--sh-exec\" or proc.args contains \"--exec\"
or proc.args contains \"-e \"\n or proc.args contains
\"-c \" or proc.args contains \"--lua-exec\"))\n )\n output: >\n Netcat runs
inside container that allows remote code execution (user=%user.name\n command=%proc.cmdline
container_id=%container.id container_name=%container.name image=%container.image.repository:%container.image.tag)\n
\ priority: WARNING\n tags: [network, process, mitre_execution]\n\n- rule: Launch
Suspicious Network Tool in Container\n desc: Detect network tools launched inside
container\n condition: >\n spawned_process and container and network_tool_procs\n
\ output: >\n Network tool launched in container (user=%user.name command=%proc.cmdline
parent_process=%proc.pname\n container_id=%container.id container_name=%container.name
image=%container.image.repository:%container.image.tag)\n priority: NOTICE\n tags:
[network, process, mitre_discovery, mitre_exfiltration]\n\n# This rule is not enabled
by default, as there are legitimate use\n# cases for these tools on hosts. If you
want to enable it, modify the\n# following macro.\n- macro: consider_network_tools_on_host\n
\ condition: (never_true)\n\n- rule: Launch Suspicious Network Tool on Host\n desc:
Detect network tools launched on the host\n condition: >\n spawned_process and\n
\ not container and\n consider_network_tools_on_host and\n network_tool_procs\n
\ output: >\n Network tool launched on host (user=%user.name command=%proc.cmdline
parent_process=%proc.pname)\n priority: NOTICE\n tags: [network, process, mitre_discovery,
mitre_exfiltration]\n\n- list: grep_binaries\n items: [grep, egrep, fgrep]\n\n-
macro: grep_commands\n condition: (proc.name in (grep_binaries))\n\n# a less restrictive
search for things that might be passwords/ssh/user etc.\n- macro: grep_more\n condition:
(never_true)\n\n- macro: private_key_or_password\n condition: >\n (proc.args
icontains \"BEGIN PRIVATE\" or\n proc.args icontains \"BEGIN RSA PRIVATE\" or\n
\ proc.args icontains \"BEGIN DSA PRIVATE\" or\n proc.args icontains \"BEGIN
EC PRIVATE\" or\n (grep_more and\n (proc.args icontains \" pass \" or\n
\ proc.args icontains \" ssh \" or\n proc.args icontains \" user \"))\n
\ )\n\n- rule: Search Private Keys or Passwords\n desc: >\n Detect grep private
keys or passwords activity.\n condition: >\n (spawned_process and\n ((grep_commands
and private_key_or_password) or\n (proc.name = \"find\" and (proc.args contains
\"id_rsa\" or proc.args contains \"id_dsa\")))\n )\n output: >\n Grep private
keys or passwords activities found\n (user=%user.name command=%proc.cmdline container_id=%container.id
container_name=%container.name\n image=%container.image.repository:%container.image.tag)\n
\ priority:\n WARNING\n tags: [process, mitre_credential_access]\n\n- list:
log_directories\n items: [/var/log, /dev/log]\n\n- list: log_files\n items: [syslog,
auth.log, secure, kern.log, cron, user.log, dpkg.log, last.log, yum.log, access_log,
mysql.log, mysqld.log]\n\n- macro: access_log_files\n condition: (fd.directory
in (log_directories) or fd.filename in (log_files))\n\n# a placeholder for whitelist
log files that could be cleared. Recommend the macro as (fd.name startswith \"/var/log/app1*\")\n-
macro: allowed_clear_log_files\n condition: (never_true)\n\n- macro: trusted_logging_images\n
\ condition: (container.image.repository endswith \"splunk/fluentd-hec\" or\n container.image.repository
endswith \"fluent/fluentd-kubernetes-daemonset\")\n\n- rule: Clear Log Activities\n
\ desc: Detect clearing of critical log files\n condition: >\n open_write and\n
\ access_log_files and\n evt.arg.flags contains \"O_TRUNC\" and\n not trusted_logging_images
and\n not allowed_clear_log_files\n output: >\n Log files were tampered (user=%user.name
command=%proc.cmdline file=%fd.name container_id=%container.id image=%container.image.repository)\n
\ priority:\n WARNING\n tags: [file, mitre_defense_evasion]\n\n- list: data_remove_commands\n
\ items: [shred, mkfs, mke2fs]\n\n- macro: clear_data_procs\n condition: (proc.name
in (data_remove_commands))\n\n- rule: Remove Bulk Data from Disk\n desc: Detect
process running to clear bulk data from disk\n condition: spawned_process and clear_data_procs\n
\ output: >\n Bulk data has been removed from disk (user=%user.name command=%proc.cmdline
file=%fd.name container_id=%container.id image=%container.image.repository)\n priority:\n
\ WARNING\n tags: [process, mitre_persistence]\n\n- rule: Delete or rename shell
history\n desc: Detect shell history deletion\n condition: >\n (modify and
(\n evt.arg.name contains \"bash_history\" or\n evt.arg.name contains
\"zsh_history\" or\n evt.arg.name contains \"fish_read_history\" or\n evt.arg.name
endswith \"fish_history\" or\n evt.arg.oldpath contains \"bash_history\" or\n
\ evt.arg.oldpath contains \"zsh_history\" or\n evt.arg.oldpath contains
\"fish_read_history\" or\n evt.arg.oldpath endswith \"fish_history\" or\n evt.arg.path
contains \"bash_history\" or\n evt.arg.path contains \"zsh_history\" or\n evt.arg.path
contains \"fish_read_history\" or\n evt.arg.path endswith \"fish_history\"))
or\n (open_write and (\n fd.name contains \"bash_history\" or\n fd.name
contains \"zsh_history\" or\n fd.name contains \"fish_read_history\" or\n fd.name
endswith \"fish_history\") and evt.arg.flags contains \"O_TRUNC\")\n output: >\n
\ Shell history had been deleted or renamed (user=%user.name type=%evt.type command=%proc.cmdline
fd.name=%fd.name name=%evt.arg.name path=%evt.arg.path oldpath=%evt.arg.oldpath
%container.info)\n priority:\n WARNING\n tag: [process, mitre_defense_evation]\n\n#
This rule is deprecated and will/should never be triggered. Keep it here for backport
compatibility.\n# Rule Delete or rename shell history is the preferred rule to use
now.\n- rule: Delete Bash History\n desc: Detect bash history deletion\n condition:
>\n ((spawned_process and proc.name in (shred, rm, mv) and proc.args contains
\"bash_history\") or \n (open_write and fd.name contains \"bash_history\" and
evt.arg.flags contains \"O_TRUNC\"))\n output: >\n Shell history had been deleted
or renamed (user=%user.name type=%evt.type command=%proc.cmdline fd.name=%fd.name
name=%evt.arg.name path=%evt.arg.path oldpath=%evt.arg.oldpath %container.info)\n
\ priority:\n WARNING\n tag: [process, mitre_defense_evation]\n\n- macro: consider_all_chmods\n
\ condition: (always_true)\n\n- list: user_known_chmod_applications\n items: [hyperkube,
kubelet]\n\n- rule: Set Setuid or Setgid bit\n desc: >\n When the setuid or
setgid bits are set for an application,\n this means that the application will
run with the privileges of the owning user or group respectively.\n Detect setuid
or setgid bits set via chmod\n condition: >\n consider_all_chmods and chmod
and (evt.arg.mode contains \"S_ISUID\" or evt.arg.mode contains \"S_ISGID\")\n and
not proc.name in (user_known_chmod_applications)\n and not exe_running_docker_save\n
\ output: >\n Setuid or setgid bit is set via chmod (fd=%evt.arg.fd filename=%evt.arg.filename
mode=%evt.arg.mode user=%user.name process=%proc.name\n command=%proc.cmdline
container_id=%container.id container_name=%container.name image=%container.image.repository:%container.image.tag)\n
\ priority:\n NOTICE\n tag: [process, mitre_persistence]\n\n- list: exclude_hidden_directories\n
\ items: [/root/.cassandra]\n\n# To use this rule, you should modify consider_hidden_file_creation.\n-
macro: consider_hidden_file_creation\n condition: (never_true)\n\n- rule: Create
Hidden Files or Directories\n desc: Detect hidden files or directories created\n
\ condition: >\n (consider_hidden_file_creation and (\n (modify and evt.arg.newpath
contains \"/.\") or\n (mkdir and evt.arg.path contains \"/.\") or\n (open_write
and evt.arg.flags contains \"O_CREAT\" and fd.name contains \"/.\" and not fd.name
pmatch (exclude_hidden_directories)))\n )\n output: >\n Hidden file or directory
created (user=%user.name command=%proc.cmdline\n file=%fd.name newpath=%evt.arg.newpath
container_id=%container.id container_name=%container.name image=%container.image.repository:%container.image.tag)\n
\ priority:\n NOTICE\n tag: [file, mitre_persistence]\n\n- list: remote_file_copy_binaries\n
\ items: [rsync, scp, sftp, dcp]\n\n- macro: remote_file_copy_procs\n condition:
(proc.name in (remote_File_copy_binaries))\n\n- rule: Launch Remote File Copy Tools
in Container\n desc: Detect remote file copy tools launched in container\n condition:
>\n spawned_process and container and remote_file_copy_procs\n output: >\n Remote
file copy tool launched in container (user=%user.name command=%proc.cmdline parent_process=%proc.pname\n
\ container_id=%container.id container_name=%container.name image=%container.image.repository:%container.image.tag)\n
\ priority: NOTICE\n tags: [network, process, mitre_lateral_movement, mitre_exfiltration]\n\n-
rule: Create Symlink Over Sensitive Files\n desc: Detect symlink created over sensitive
files\n condition: >\n create_symlink and\n (evt.arg.target in (sensitive_file_names)
or evt.arg.target in (sensitive_directory_names))\n output: >\n Symlinks created
over senstivie files (user=%user.name command=%proc.cmdline target=%evt.arg.target
linkpath=%evt.arg.linkpath parent_process=%proc.pname)\n priority: NOTICE\n tags:
[file, mitre_exfiltration]\n\n- list: miner_ports\n items: [\n 25, 3333,
3334, 3335, 3336, 3357, 4444,\n 5555, 5556, 5588, 5730, 6099, 6666, 7777,\n
\ 7778, 8000, 8001, 8008, 8080, 8118, 8333,\n 8888, 8899, 9332, 9999,
14433, 14444,\n 45560, 45700\n ]\n\n- list: miner_domains\n items: [\n
\ \"asia1.ethpool.org\",\"ca.minexmr.com\",\n \"cn.stratum.slushpool.com\",\"de.minexmr.com\",\n
\ \"eth-ar.dwarfpool.com\",\"eth-asia.dwarfpool.com\",\n \"eth-asia1.nanopool.org\",\"eth-au.dwarfpool.com\",\n
\ \"eth-au1.nanopool.org\",\"eth-br.dwarfpool.com\",\n \"eth-cn.dwarfpool.com\",\"eth-cn2.dwarfpool.com\",\n
\ \"eth-eu.dwarfpool.com\",\"eth-eu1.nanopool.org\",\n \"eth-eu2.nanopool.org\",\"eth-hk.dwarfpool.com\",\n
\ \"eth-jp1.nanopool.org\",\"eth-ru.dwarfpool.com\",\n \"eth-ru2.dwarfpool.com\",\"eth-sg.dwarfpool.com\",\n
\ \"eth-us-east1.nanopool.org\",\"eth-us-west1.nanopool.org\",\n \"eth-us.dwarfpool.com\",\"eth-us2.dwarfpool.com\",\n
\ \"eu.stratum.slushpool.com\",\"eu1.ethermine.org\",\n \"eu1.ethpool.org\",\"fr.minexmr.com\",\n
\ \"mine.moneropool.com\",\"mine.xmrpool.net\",\n \"pool.minexmr.com\",\"pool.monero.hashvault.pro\",\n
\ \"pool.supportxmr.com\",\"sg.minexmr.com\",\n \"sg.stratum.slushpool.com\",\"stratum-eth.antpool.com\",\n
\ \"stratum-ltc.antpool.com\",\"stratum-zec.antpool.com\",\n \"stratum.antpool.com\",\"us-east.stratum.slushpool.com\",\n
\ \"us1.ethermine.org\",\"us1.ethpool.org\",\n \"us2.ethermine.org\",\"us2.ethpool.org\",\n
\ \"xmr-asia1.nanopool.org\",\"xmr-au1.nanopool.org\",\n \"xmr-eu1.nanopool.org\",\"xmr-eu2.nanopool.org\",\n
\ \"xmr-jp1.nanopool.org\",\"xmr-us-east1.nanopool.org\",\n \"xmr-us-west1.nanopool.org\",\"xmr.crypto-pool.fr\",\n
\ \"xmr.pool.minergate.com\"\n ]\n\n- list: https_miner_domains\n items:
[\n \"ca.minexmr.com\",\n \"cn.stratum.slushpool.com\",\n \"de.minexmr.com\",\n
\ \"fr.minexmr.com\",\n \"mine.moneropool.com\",\n \"mine.xmrpool.net\",\n
\ \"pool.minexmr.com\",\n \"sg.minexmr.com\",\n \"stratum-eth.antpool.com\",\n
\ \"stratum-ltc.antpool.com\",\n \"stratum-zec.antpool.com\",\n \"stratum.antpool.com\",\n
\ \"xmr.crypto-pool.fr\"\n ]\n\n- list: http_miner_domains\n items: [\n \"ca.minexmr.com\",\n
\ \"de.minexmr.com\",\n \"fr.minexmr.com\",\n \"mine.moneropool.com\",\n
\ \"mine.xmrpool.net\",\n \"pool.minexmr.com\",\n \"sg.minexmr.com\",\n
\ \"xmr.crypto-pool.fr\"\n ]\n\n# Add rule based on crypto mining IOCs\n- macro:
minerpool_https\n condition: (fd.sport=\"443\" and fd.sip.name in (https_miner_domains))\n\n-
macro: minerpool_http\n condition: (fd.sport=\"80\" and fd.sip.name in (http_miner_domains))\n\n-
macro: minerpool_other\n condition: (fd.sport in (miner_ports) and fd.sip.name
in (miner_domains))\n\n- macro: net_miner_pool\n condition: (evt.type in (sendto,
sendmsg) and evt.dir=< and ((minerpool_http) or (minerpool_https) or (minerpool_other)))\n\n-
rule: Detect outbound connections to common miner pool ports\n desc: Miners typically
connect to miner pools on common ports.\n condition: net_miner_pool\n output:
Outbound connection to IP/Port flagged by cryptoioc.ch (command=%proc.cmdline port=%fd.rport
ip=%fd.rip container=%container.info image=%container.image.repository)\n priority:
CRITICAL\n tags: [network, mitre_execution]\n\n- rule: Detect crypto miners using
the Stratum protocol\n desc: Miners typically specify the mining pool to connect
to with a URI that begins with 'stratum+tcp'\n condition: spawned_process and proc.cmdline
contains \"stratum+tcp\"\n output: Possible miner running (command=%proc.cmdline
container=%container.info image=%container.image.repository)\n priority: CRITICAL\n
\ tags: [process, mitre_execution]\n\n- list: k8s_client_binaries\n items: [docker,
kubectl, crictl]\n\n# Whitelist for known docker client binaries run inside container\n#
- k8s.gcr.io/fluentd-gcp-scaler in GCP/GKE \n- macro: user_known_k8s_client_container\n
\ condition: (k8s.ns.name=\"kube-system\" and container.image.repository=k8s.gcr.io/fluentd-gcp-scaler)\n
\ \n- rule: The docker client is executed in a container\n desc: Detect a k8s client
tool executed inside a container\n condition: spawned_process and container and
not user_known_k8s_client_container and proc.name in (k8s_client_binaries)\n output:
\"Docker or kubernetes client executed in container (user=%user.name %container.info
parent=%proc.pname cmdline=%proc.cmdline image=%container.image.repository:%container.image.tag)\"\n
\ priority: WARNING\n tags: [container, mitre_execution]\n\n\n# This rule is not
enabled by default, as there are legitimate use\n# cases for raw packet. If you
want to enable it, modify the\n# following macro.\n- macro: consider_packet_socket_communication\n
\ condition: (never_true)\n\n- list: user_known_packet_socket_binaries\n items:
[]\n\n- rule: Packet socket created in container\n desc: Detect new packet socket
at the device driver (OSI Layer 2) level in a container. Packet socket could be
used to do ARP Spoofing by attacker.\n condition: evt.type=socket and evt.arg[0]=AF_PACKET
and consider_packet_socket_communication and container and not proc.name in (user_known_packet_socket_binaries)\n
\ output: Packet socket was created in a container (user=%user.name command=%proc.cmdline
socket_info=%evt.args container_id=%container.id container_name=%container.name
image=%container.image.repository:%container.image.tag)\n priority: NOTICE\n tags:
[network, mitre_discovery]\n \n\n# Application rules have moved to application_rules.yaml.
Please look\n# there if you want to enable them by adding to\n# falco_rules.local.yaml.\n"
k8s_audit_rules.yaml: |
#
# Copyright (C) 2019 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.
#
- required_engine_version: 2
# Like always_true/always_false, but works with k8s audit events
- macro: k8s_audit_always_true
condition: (jevt.rawtime exists)
- macro: k8s_audit_never_true
condition: (jevt.rawtime=0)
# Generally only consider audit events once the response has completed
- list: k8s_audit_stages
items: ["ResponseComplete"]
# Generally exclude users starting with "system:"
- macro: non_system_user
condition: (not ka.user.name startswith "system:")
# This macro selects the set of Audit Events used by the below rules.
- macro: kevt
condition: (jevt.value[/stage] in (k8s_audit_stages))
- macro: kevt_started
condition: (jevt.value[/stage]=ResponseStarted)
# If you wish to restrict activity to a specific set of users, override/append to this list.
# users created by kops are included
- list: allowed_k8s_users
items: ["minikube", "minikube-user", "kubelet", "kops", "admin", "kube", "kube-proxy"]
- rule: Disallowed K8s User
desc: Detect any k8s operation by users outside of an allowed set of users.
condition: kevt and non_system_user and not ka.user.name in (allowed_k8s_users)
output: K8s Operation performed by user not in allowed list of users (user=%ka.user.name target=%ka.target.name/%ka.target.resource verb=%ka.verb uri=%ka.uri resp=%ka.response.code)
priority: WARNING
source: k8s_audit
tags: [k8s]
# In a local/user rules file, you could override this macro to
# explicitly enumerate the container images that you want to run in
# your environment. In this main falco rules file, there isn't any way
# to know all the containers that can run, so any container is
# allowed, by using the always_true macro. In the overridden macro, the condition
# would look something like (ka.req.pod.containers.image.repository in (my-repo/my-image))
- macro: allowed_k8s_containers
condition: (k8s_audit_always_true)
- macro: response_successful
condition: (ka.response.code startswith 2)
- macro: kcreate
condition: ka.verb=create
- macro: kmodify
condition: (ka.verb in (create,update,patch))
- macro: kdelete
condition: ka.verb=delete
- macro: pod
condition: ka.target.resource=pods and not ka.target.subresource exists
- macro: pod_subresource
condition: ka.target.resource=pods and ka.target.subresource exists
- macro: deployment
condition: ka.target.resource=deployments
- macro: service
condition: ka.target.resource=services
- macro: configmap
condition: ka.target.resource=configmaps
- macro: namespace
condition: ka.target.resource=namespaces
- macro: serviceaccount
condition: ka.target.resource=serviceaccounts
- macro: clusterrole
condition: ka.target.resource=clusterroles
- macro: clusterrolebinding
condition: ka.target.resource=clusterrolebindings
- macro: role
condition: ka.target.resource=roles
- macro: health_endpoint
condition: ka.uri=/healthz
- rule: Create Disallowed Pod
desc: >
Detect an attempt to start a pod with a container image outside of a list of allowed images.
condition: kevt and pod and kcreate and not allowed_k8s_containers
output: Pod started with container not in allowed list (user=%ka.user.name pod=%ka.resp.name ns=%ka.target.namespace images=%ka.req.pod.containers.image)
priority: WARNING
source: k8s_audit
tags: [k8s]
- rule: Create Privileged Pod
desc: >
Detect an attempt to start a pod with a privileged container
condition: kevt and pod and kcreate and ka.req.pod.containers.privileged intersects (true) and not ka.req.pod.containers.image.repository in (falco_privileged_images)
output: Pod started with privileged container (user=%ka.user.name pod=%ka.resp.name ns=%ka.target.namespace images=%ka.req.pod.containers.image)
priority: WARNING
source: k8s_audit
tags: [k8s]
- macro: sensitive_vol_mount
condition: >
(ka.req.pod.volumes.hostpath intersects (/proc, /var/run/docker.sock, /, /etc, /root, /var/run/crio/crio.sock, /home/admin, /var/lib/kubelet, /var/lib/kubelet/pki, /etc/kubernetes, /etc/kubernetes/manifests))
- rule: Create Sensitive Mount Pod
desc: >
Detect an attempt to start a pod with a volume from a sensitive host directory (i.e. /proc).
Exceptions are made for known trusted images.
condition: kevt and pod and kcreate and sensitive_vol_mount and not ka.req.pod.containers.image.repository in (falco_sensitive_mount_images)
output: Pod started with sensitive mount (user=%ka.user.name pod=%ka.resp.name ns=%ka.target.namespace images=%ka.req.pod.containers.image volumes=%jevt.value[/requestObject/spec/volumes])
priority: WARNING
source: k8s_audit
tags: [k8s]
# Corresponds to K8s CIS Benchmark 1.7.4
- rule: Create HostNetwork Pod
desc: Detect an attempt to start a pod using the host network.
condition: kevt and pod and kcreate and ka.req.pod.host_network intersects (true) and not ka.req.pod.containers.image.repository in (falco_hostnetwork_images)
output: Pod started using host network (user=%ka.user.name pod=%ka.resp.name ns=%ka.target.namespace images=%ka.req.pod.containers.image)
priority: WARNING
source: k8s_audit
tags: [k8s]
- rule: Create NodePort Service
desc: >
Detect an attempt to start a service with a NodePort service type
condition: kevt and service and kcreate and ka.req.service.type=NodePort
output: NodePort Service Created (user=%ka.user.name service=%ka.target.name ns=%ka.target.namespace ports=%ka.req.service.ports)
priority: WARNING
source: k8s_audit
tags: [k8s]
- macro: contains_private_credentials
condition: >
(ka.req.configmap.obj contains "aws_access_key_id" or
ka.req.configmap.obj contains "aws-access-key-id" or
ka.req.configmap.obj contains "aws_s3_access_key_id" or
ka.req.configmap.obj contains "aws-s3-access-key-id" or
ka.req.configmap.obj contains "password" or
ka.req.configmap.obj contains "passphrase")
- rule: Create/Modify Configmap With Private Credentials
desc: >
Detect creating/modifying a configmap containing a private credential (aws key, password, etc.)
condition: kevt and configmap and kmodify and contains_private_credentials
output: K8s configmap with private credential (user=%ka.user.name verb=%ka.verb configmap=%ka.req.configmap.name config=%ka.req.configmap.obj)
priority: WARNING
source: k8s_audit
tags: [k8s]
# Corresponds to K8s CIS Benchmark, 1.1.1.
- rule: Anonymous Request Allowed
desc: >
Detect any request made by the anonymous user that was allowed
condition: kevt and ka.user.name=system:anonymous and ka.auth.decision!=reject and not health_endpoint
output: Request by anonymous user allowed (user=%ka.user.name verb=%ka.verb uri=%ka.uri reason=%ka.auth.reason))
priority: WARNING
source: k8s_audit
tags: [k8s]
# Roughly corresponds to K8s CIS Benchmark, 1.1.12. In this case,
# notifies an attempt to exec/attach to a privileged container.
# Ideally, we'd add a more stringent rule that detects attaches/execs
# to a privileged pod, but that requires the engine for k8s audit
# events to be stateful, so it could know if a container named in an
# attach request was created privileged or not. For now, we have a
# less severe rule that detects attaches/execs to any pod.
- rule: Attach/Exec Pod
desc: >
Detect any attempt to attach/exec to a pod
condition: kevt_started and pod_subresource and kcreate and ka.target.subresource in (exec,attach)
output: Attach/Exec to pod (user=%ka.user.name pod=%ka.target.name ns=%ka.target.namespace action=%ka.target.subresource command=%ka.uri.param[command])
priority: NOTICE
source: k8s_audit
tags: [k8s]
# In a local/user rules fie, you can append to this list to add additional allowed namespaces
- list: allowed_namespaces
items: [kube-system, kube-public, default]
- rule: Create Disallowed Namespace
desc: Detect any attempt to create a namespace outside of a set of known namespaces
condition: kevt and namespace and kcreate and not ka.target.name in (allowed_namespaces)
output: Disallowed namespace created (user=%ka.user.name ns=%ka.target.name)
priority: WARNING
source: k8s_audit
tags: [k8s]
# Detect any new pod created in the kube-system namespace
- rule: Pod Created in Kube Namespace
desc: Detect any attempt to create a pod in the kube-system or kube-public namespaces
condition: kevt and pod and kcreate and ka.target.namespace in (kube-system, kube-public)
output: Pod created in kube namespace (user=%ka.user.name pod=%ka.resp.name ns=%ka.target.namespace images=%ka.req.pod.containers.image)
priority: WARNING
source: k8s_audit
tags: [k8s]
# Detect creating a service account in the kube-system/kube-public namespace
- rule: Service Account Created in Kube Namespace
desc: Detect any attempt to create a serviceaccount in the kube-system or kube-public namespaces
condition: kevt and serviceaccount and kcreate and ka.target.namespace in (kube-system, kube-public)
output: Service account created in kube namespace (user=%ka.user.name serviceaccount=%ka.target.name ns=%ka.target.namespace)
priority: WARNING
source: k8s_audit
tags: [k8s]
# Detect any modify/delete to any ClusterRole starting with
# "system:". "system:coredns" is excluded as changes are expected in
# normal operation.
- rule: System ClusterRole Modified/Deleted
desc: Detect any attempt to modify/delete a ClusterRole/Role starting with system
condition: kevt and (role or clusterrole) and (kmodify or kdelete) and (ka.target.name startswith "system:") and ka.target.name!="system:coredns"
output: System ClusterRole/Role modified or deleted (user=%ka.user.name role=%ka.target.name ns=%ka.target.namespace action=%ka.verb)
priority: WARNING
source: k8s_audit
tags: [k8s]
# Detect any attempt to create a ClusterRoleBinding to the cluster-admin user
# (exapand this to any built-in cluster role that does "sensitive" things)
- rule: Attach to cluster-admin Role
desc: Detect any attempt to create a ClusterRoleBinding to the cluster-admin user
condition: kevt and clusterrolebinding and kcreate and ka.req.binding.role=cluster-admin
output: Cluster Role Binding to cluster-admin role (user=%ka.user.name subject=%ka.req.binding.subjects)
priority: WARNING
source: k8s_audit
tags: [k8s]
- rule: ClusterRole With Wildcard Created
desc: Detect any attempt to create a Role/ClusterRole with wildcard resources or verbs
condition: kevt and (role or clusterrole) and kcreate and (ka.req.role.rules.resources intersects ("*") or ka.req.role.rules.verbs intersects ("*"))
output: Created Role/ClusterRole with wildcard (user=%ka.user.name role=%ka.target.name rules=%ka.req.role.rules)
priority: WARNING
source: k8s_audit
tags: [k8s]
- macro: writable_verbs
condition: >
(ka.req.role.rules.verbs intersects (create, update, patch, delete, deletecollection))
- rule: ClusterRole With Write Privileges Created
desc: Detect any attempt to create a Role/ClusterRole that can perform write-related actions
condition: kevt and (role or clusterrole) and kcreate and writable_verbs
output: Created Role/ClusterRole with write privileges (user=%ka.user.name role=%ka.target.name rules=%ka.req.role.rules)
priority: NOTICE
source: k8s_audit
tags: [k8s]
- rule: ClusterRole With Pod Exec Created
desc: Detect any attempt to create a Role/ClusterRole that can exec to pods
condition: kevt and (role or clusterrole) and kcreate and ka.req.role.rules.resources intersects ("pods/exec")
output: Created Role/ClusterRole with pod exec privileges (user=%ka.user.name role=%ka.target.name rules=%ka.req.role.rules)
priority: WARNING
source: k8s_audit
tags: [k8s]
# The rules below this point are less discriminatory and generally
# represent a stream of activity for a cluster. If you wish to disable
# these events, modify the following macro.
- macro: consider_activity_events
condition: (k8s_audit_always_true)
- macro: kactivity
condition: (kevt and consider_activity_events)
- rule: K8s Deployment Created
desc: Detect any attempt to create a deployment
condition: (kactivity and kcreate and deployment and response_successful)
output: K8s Deployment Created (user=%ka.user.name deployment=%ka.target.name ns=%ka.target.namespace resp=%ka.response.code decision=%ka.auth.decision reason=%ka.auth.reason)
priority: INFO
source: k8s_audit
tags: [k8s]
- rule: K8s Deployment Deleted
desc: Detect any attempt to delete a deployment
condition: (kactivity and kdelete and deployment and response_successful)
output: K8s Deployment Deleted (user=%ka.user.name deployment=%ka.target.name ns=%ka.target.namespace resp=%ka.response.code decision=%ka.auth.decision reason=%ka.auth.reason)
priority: INFO
source: k8s_audit
tags: [k8s]
- rule: K8s Service Created
desc: Detect any attempt to create a service
condition: (kactivity and kcreate and service and response_successful)
output: K8s Service Created (user=%ka.user.name service=%ka.target.name ns=%ka.target.namespace resp=%ka.response.code decision=%ka.auth.decision reason=%ka.auth.reason)
priority: INFO
source: k8s_audit
tags: [k8s]
- rule: K8s Service Deleted
desc: Detect any attempt to delete a service
condition: (kactivity and kdelete and service and response_successful)
output: K8s Service Deleted (user=%ka.user.name service=%ka.target.name ns=%ka.target.namespace resp=%ka.response.code decision=%ka.auth.decision reason=%ka.auth.reason)
priority: INFO
source: k8s_audit
tags: [k8s]
- rule: K8s ConfigMap Created
desc: Detect any attempt to create a configmap
condition: (kactivity and kcreate and configmap and response_successful)
output: K8s ConfigMap Created (user=%ka.user.name configmap=%ka.target.name ns=%ka.target.namespace resp=%ka.response.code decision=%ka.auth.decision reason=%ka.auth.reason)
priority: INFO
source: k8s_audit
tags: [k8s]
- rule: K8s ConfigMap Deleted
desc: Detect any attempt to delete a configmap
condition: (kactivity and kdelete and configmap and response_successful)
output: K8s ConfigMap Deleted (user=%ka.user.name configmap=%ka.target.name ns=%ka.target.namespace resp=%ka.response.code decision=%ka.auth.decision reason=%ka.auth.reason)
priority: INFO
source: k8s_audit
tags: [k8s]
- rule: K8s Namespace Created
desc: Detect any attempt to create a namespace
condition: (kactivity and kcreate and namespace and response_successful)
output: K8s Namespace Created (user=%ka.user.name namespace=%ka.target.name resp=%ka.response.code decision=%ka.auth.decision reason=%ka.auth.reason)
priority: INFO
source: k8s_audit
tags: [k8s]
- rule: K8s Namespace Deleted
desc: Detect any attempt to delete a namespace
condition: (kactivity and non_system_user and kdelete and namespace and response_successful)
output: K8s Namespace Deleted (user=%ka.user.name namespace=%ka.target.name resp=%ka.response.code decision=%ka.auth.decision reason=%ka.auth.reason)
priority: INFO
source: k8s_audit
tags: [k8s]
- rule: K8s Serviceaccount Created
desc: Detect any attempt to create a service account
condition: (kactivity and kcreate and serviceaccount and response_successful)
output: K8s Serviceaccount Created (user=%ka.user.name user=%ka.target.name ns=%ka.target.namespace resp=%ka.response.code decision=%ka.auth.decision reason=%ka.auth.reason)
priority: INFO
source: k8s_audit
tags: [k8s]
- rule: K8s Serviceaccount Deleted
desc: Detect any attempt to delete a service account
condition: (kactivity and kdelete and serviceaccount and response_successful)
output: K8s Serviceaccount Deleted (user=%ka.user.name user=%ka.target.name ns=%ka.target.namespace resp=%ka.response.code decision=%ka.auth.decision reason=%ka.auth.reason)
priority: INFO
source: k8s_audit
tags: [k8s]
- rule: K8s Role/Clusterrole Created
desc: Detect any attempt to create a cluster role/role
condition: (kactivity and kcreate and (clusterrole or role) and response_successful)
output: K8s Cluster Role Created (user=%ka.user.name role=%ka.target.name rules=%ka.req.role.rules resp=%ka.response.code decision=%ka.auth.decision reason=%ka.auth.reason)
priority: INFO
source: k8s_audit
tags: [k8s]
- rule: K8s Role/Clusterrole Deleted
desc: Detect any attempt to delete a cluster role/role
condition: (kactivity and kdelete and (clusterrole or role) and response_successful)
output: K8s Cluster Role Deleted (user=%ka.user.name role=%ka.target.name resp=%ka.response.code decision=%ka.auth.decision reason=%ka.auth.reason)
priority: INFO
source: k8s_audit
tags: [k8s]
- rule: K8s Role/Clusterrolebinding Created
desc: Detect any attempt to create a clusterrolebinding
condition: (kactivity and kcreate and clusterrolebinding and response_successful)
output: K8s Cluster Role Binding Created (user=%ka.user.name binding=%ka.target.name subjects=%ka.req.binding.subjects role=%ka.req.binding.role resp=%ka.response.code decision=%ka.auth.decision reason=%ka.auth.reason)
priority: INFO
source: k8s_audit
tags: [k8s]
- rule: K8s Role/Clusterrolebinding Deleted
desc: Detect any attempt to delete a clusterrolebinding
condition: (kactivity and kdelete and clusterrolebinding and response_successful)
output: K8s Cluster Role Binding Deleted (user=%ka.user.name binding=%ka.target.name resp=%ka.response.code decision=%ka.auth.decision reason=%ka.auth.reason)
priority: INFO
source: k8s_audit
tags: [k8s]
# This rule generally matches all events, and as a result is disabled
# by default. If you wish to enable these events, modify the
# following macro.
# condition: (jevt.rawtime exists)
- macro: consider_all_events
condition: (k8s_audit_never_true)
- macro: kall
condition: (kevt and consider_all_events)
- rule: All K8s Audit Events
desc: Match all K8s Audit Events
condition: kall
output: K8s Audit Event received (user=%ka.user.name verb=%ka.verb uri=%ka.uri obj=%jevt.obj)
priority: DEBUG
source: k8s_audit
tags: [k8s]
---
# Source: falco/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: sysdig-falco
namespace: falco
labels:
app: sysdig-falco
chart: "falco-1.1.1"
release: "sysdig-falco"
heritage: "Helm"
---
# Source: falco/templates/clusterrole.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: sysdig-falco
labels:
app: sysdig-falco
chart: "falco-1.1.1"
release: "sysdig-falco"
heritage: "Helm"
rules:
- apiGroups:
- extensions
- ""
resources:
- nodes
- namespaces
- pods
- replicationcontrollers
- replicasets
- services
- daemonsets
- deployments
- events
- configmaps
verbs:
- get
- list
- watch
- nonResourceURLs:
- /healthz
- /healthz/*
verbs:
- get
---
# Source: falco/templates/clusterrolebinding.yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: sysdig-falco
labels:
app: sysdig-falco
chart: "falco-1.1.1"
release: "sysdig-falco"
heritage: "Helm"
subjects:
- kind: ServiceAccount
name: sysdig-falco
namespace: falco
roleRef:
kind: ClusterRole
name: sysdig-falco
apiGroup: rbac.authorization.k8s.io
---
# Source: falco/templates/auditservice.yaml
kind: Service
apiVersion: v1
metadata:
name: sysdig-falco-audit-service
namespace: falco
labels:
app: sysdig-falco
chart: "falco-1.1.1"
release: "sysdig-falco"
heritage: "Helm"
spec:
selector:
app: sysdig-falco
clusterIP:
ports:
- protocol: TCP
port: 8765
---
# Source: falco/templates/daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: sysdig-falco
namespace: falco
labels:
app: sysdig-falco
chart: "falco-1.1.1"
release: "sysdig-falco"
heritage: "Helm"
spec:
selector:
matchLabels:
app: sysdig-falco
role: security
template:
metadata:
name: sysdig-falco
labels:
app: sysdig-falco
role: security
annotations:
checksum/config: e37b20f6c02ad1fbdcc65e430d3e137786a9dd139a62378418587e57f6fda77a
checksum/rules: 01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b
spec:
serviceAccountName: sysdig-falco
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/master
containers:
- name: falco
image: docker.io/falcosecurity/falco:0.19.0
imagePullPolicy: IfNotPresent
resources:
limits:
cpu: 200m
memory: 1024Mi
requests:
cpu: 100m
memory: 512Mi
securityContext:
privileged: true
args:
- /usr/bin/falco
- --cri
- /host/run/containerd/containerd.sock
- -K
- /var/run/secrets/kubernetes.io/serviceaccount/token
- -k
- "https://$(KUBERNETES_SERVICE_HOST)"
- -pk
env:
volumeMounts:
- mountPath: /host/var/run/docker.sock
name: docker-socket
- mountPath: /host/run/containerd/containerd.sock
name: containerd-socket
- mountPath: /host/dev
name: dev-fs
readOnly: true
- mountPath: /host/proc
name: proc-fs
readOnly: true
- mountPath: /host/boot
name: boot-fs
readOnly: true
- mountPath: /host/lib/modules
name: lib-modules
readOnly: true
- mountPath: /host/usr
name: usr-fs
readOnly: true
- mountPath: /dev/shm
name: dshm
- mountPath: /etc/falco
name: config-volume
volumes:
- name: dshm
emptyDir:
medium: Memory
- name: docker-socket
hostPath:
path: /var/run/docker.sock
- name: containerd-socket
hostPath:
path: /run/containerd/containerd.sock
- name: dev-fs
hostPath:
path: /dev
- name: proc-fs
hostPath:
path: /proc
- name: boot-fs
hostPath:
path: /boot
- name: lib-modules
hostPath:
path: /lib/modules
- name: usr-fs
hostPath:
path: /usr
- name: config-volume
configMap:
name: sysdig-falco
items:
- key: falco.yaml
path: falco.yaml
- key: falco_rules.yaml
path: falco_rules.yaml
- key: falco_rules.local.yaml
path: falco_rules.local.yaml
- key: application_rules.yaml
path: rules.available/application_rules.yaml
updateStrategy:
type: RollingUpdate