Exceptions have been introduced in commit 64a231b962
The feature itself is very useful for more complex environments where
the simple conditions are difficult to handle.
However, many users reported that they find them difficult to understand so
we are doing a rollback of them in the default ruleset in favor of the
syntax without exceptions.
Signed-off-by: Lorenzo Fontana <lo@linux.com>
Whitelist ibm images for connecting to k8s api server
IBM Observability by Sysdig has a vendored sysdig/agent image.
IBM's Kubernetes Service ships with an operator manager. Example:
19:12:45.090908160: Notice Unexpected connection to K8s API Server from
container (command=catalog -namespace ibm-system
-configmapServerImage=registry.ng.bluemix.net/armada-master/configmap-operator-registry:v1.6.1
k8s.ns=ibm-system k8s.pod=catalog-operator-6495d76869-ncl2z
container=4ad7a04fa1e0
image=registry.ng.bluemix.net/armada-master/olm:0.14.1-IKS-1
connection=172.30.108.219:48200->172.21.0.1:443) k8s.ns=ibm-system
k8s.pod=catalog-operator-6495d76869-ncl2z container=4ad7a04fa1e0
IBM's Kubernetes service also ships with a metrics collecting agent
Signed-off-by: Spencer Krum <nibz@spencerkrum.com>
eks:node-manager is an Amazon EKS internal service role that performs specific operations for managed node groups and Fargate.
Reference: https://github.com/awsdocs/amazon-eks-user-guide/blob/master/doc_source/logging-monitoring.md
Related falco log
```
{"output":"10:56:31.181308928: Warning K8s Operation performed by user not in allowed list of users
(user=eks:node-manager target=aws-auth/configmaps verb=get uri=/api/v1/namespaces/kube-system/configmaps/aws-auth?timeout=19s resp=200)","priority":"Warning","rule":"Disallowed K8s User","time":"2021-01-26T10:56:31.181308928Z", "output_fields":
{"jevt.time":"10:56:31.181308928","ka.response.code":"200","ka.target.name":"aws-auth","ka.target.resource":"configmaps","ka.uri":"/api/v1/namespaces/kube-system/configmaps/aws-auth?timeout=19s","ka.user.name":"eks:node-manager","ka.verb":"get"}}
```
Signed-off-by: ismailyenigul <ismailyenigul@gmail.com>
Take advantage of the changes to support exceptions and refactor rules
to use them whenever feasible:
- Define exceptions for every rule. In cases where no practical
exception exists e.g. "K8s <obj> Created/Deleted", define an empty
exception property just to avoid warnings when loading rules.
- Go through all rules and convert macros-used-as-exceptions that
matched against 2-3 filter fields into exceptions. In most cases,
switching from equality (e.g proc.name=nginx) to in (e.g. proc.name
in (nginx)) allowed for better groupings into a smaller set of
exception items.
- In cases where the exception had complex combinations of fields, keep
the macro as is.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
`multipath`, which is run by `systemd-udevd`, writes to
`/etc/multipath/wwids`, `/etc/multipath/bindings` and a few other paths
under `/etc/multipath` as part of its normal operation.
Signed-off-by: Nicolas Marier <nmarier@coveo.com>
Use the right list name in the rule Full K8s Administrative Access--it
was using the nonexistent list admin_k8s_users, so it was just using the
string "admin_k8s_users".
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Like other rules that rely on a process name for exceptions, don't
trigger an event if the process name is missing e.g. "<NA>".
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Also ignore docker programs which would prevent cases where the path is
expressed within the container filesystem (/.bash_history) vs host
filesystem (/var/lib/docker/overlay/.../.bash_history).
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Move the "and not" checks to the end of the rule so all event type
checks are at the front.
Also break into 3 macros to make the rule easier to read.
This fixes https://github.com/falcosecurity/falco/issues/1418.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
It turns out if you read this rules file with falco versions 0.24.0 and
earlier, it can't parse the bare string containing colons:
(Ignore the misleading error context, that's a different problem):
```
Thu Sep 10 10:31:23 2020: Falco initialized with configuration file
/etc/falco/falco.yaml
Thu Sep 10 10:31:23 2020: Loading rules from file
/tmp/k8s_audit_rules.yaml:
Thu Sep 10 10:31:23 2020: Runtime error: found unexpected ':'
---
source: k8s_audit
tags: [k8s]
# In a local/user rules file, you could override this macro to
```
I think the change in 0.25.0 to use a bundled libyaml fixed the problem,
as it also upgraded libyaml to a version that fixed
https://github.com/yaml/libyaml/pull/104.
Work around the problem with earlier falco releases by quoting the colon.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
In some cases, when removing a container, dockerd will itself remove the
entire overlay filesystem, including a shell history file:
---
Shell history had been deleted or renamed (user=root type=unlinkat
command=dockerd -H fd://
... name=/var/lib/docker/overlay2/.../root/.bash_history ..
---
To avoid these FPs, skip paths starting with /var/lib/docker.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Add system:managed-certificate-controller as a system role that can be
modified. Can be changed as a part of upgrades.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Add several images seen in GKE environments that can run in the
kube-system namespace.
Also change the names of the lists to be more specific. The old names
are retained but are kept around for backwards compatibility.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Add a set of images known to run in the host network. Mostly related to
GKE, sometimes plus metrics collection.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Sort the items in the list falco_privileged_images alphabetically
and also separate them into individual lines. Make it easier to note
changes to the entries in the list using git blame.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Previously any write to a file called sources.list would match the
access_repositories condition, even a file /usr/tmp/..../sources.list.
Change the macro so the files in repository_files must be somewhere
below any of repository_directories.
Also allow programs spawned by package management programs to change
these files, using package_mgmt_ancestor_procs.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Let programs spawned by linux-bench (CIS Linux Benchmark program) read
/etc/shadow. Tests in the benchmark check for permissions of the file
and accounts in the contents of the file.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
In some cases, dropped events around the time a new container is started
can result in missing the exec/clone for a process that does a setns to
enter the namespace of a container. Here's an example from an oss
capture:
```
282273 09:01:22.098095673 30 runc:[0:PARENT] (168555) < setns res=0
282283 09:01:22.098138869 30 runc:[0:PARENT] (168555) < setns res=0
282295 09:01:22.098179685 30 runc:[0:PARENT] (168555) < setns res=0
517284 09:01:30.128723777 13 <NA> (168909) < setns res=0
517337 09:01:30.129054963 13 <NA> (168909) < setns res=0
517451 09:01:30.129560037 2 <NA> (168890) < setns res=0
524597 09:01:30.162741004 19 <NA> (168890) < setns res=0
527433 09:01:30.179786170 18 runc:[0:PARENT] (168927) < setns res=0
527448 09:01:30.179852428 18 runc:[0:PARENT] (168927) < setns res=0
535566 09:01:30.232420372 25 nsenter (168938) < setns res=0
537412 09:01:30.246200357 0 nsenter (168941) < setns res=0
554163 09:01:30.347158783 17 nsenter (168950) < setns res=0
659908 09:01:31.064622960 12 runc:[0:PARENT] (169023) < setns res=0
659919 09:01:31.064665759 12 runc:[0:PARENT] (169023) < setns res=0
732062 09:01:31.608297074 4 nsenter (169055) < setns res=0
812985 09:01:32.217527319 6 runc:[0:PARENT] (169077) < setns res=0
812991 09:01:32.217579396 6 runc:[0:PARENT] (169077) < setns res=0
813000 09:01:32.217632211 6 runc:[0:PARENT] (169077) < setns res=0
```
When this happens, it can cause false positives for the "Change thread
namespace" rule as it allows certain process names like "runc",
"containerd", etc to perform setns calls.
Other rules already use the proc_name_exists macro to require that the
process name exists. This change adds proc_name_exists to the Change
Thread Namespace rule as well.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
This update will provide information as to which process uid intitiated the event. This is really important for processes that are started
by a different user name.
Signed-off-by: Chuck Schweizer <chuck.schweizer.lvk2@statefarm.com>
dockerd and docker have "-current" suffix on centos and rhel. This
macro does not match causing false positives on multiple rules
using it
Signed-off-by: Radu Andries <radu@sysdig.com>
Add 'docker.io/falcosecurity/falco' image to 'falco_privileged_images' macro. This preven messages like this when booting up falco :
```
Warning Pod started with privileged container (user=system:serviceaccount:kube-system:daemon-set-controller pod=falco-42brw ns=monitoring images=docker.io/falcosecurity/falco:0.24.0)
```
Signed-off-by: Nicolas Vanheuverzwijn <nicolas.vanheu@gmail.com>
kops 1.17 adds a kube-apiserver-healthcheck user: https://github.com/kubernetes/kops/tree/master/cmd/kube-apiserver-healthcheck
Logs are currently spammed with:
```
{"output":"18:02:15.466580992: Warning K8s Operation performed by user not in allowed list of users (user=kube-apiserver-healthcheck target=<NA>/<NA> verb=get uri=/healthz resp=200)","priority":"Warning","rule":"Disallowed K8s User","time":"2020-06-29T18:02:15.466580992Z", "output_fields": {"jevt.time":"18:02:15.466580992","ka.response.code":"200","ka.target.name":"<NA>","ka.target.resource":"<NA>","ka.uri":"/healthz","ka.user.name":"kube-apiserver-healthcheck","ka.verb":"get"}}
```
Signed-off-by: Antoine Deschênes <antoine.deschenes@equisoft.com>
These application binaries raise events in the `Change thread namespace`
rule as part of their normal operation.
Here are more details regarding each binary :
- `protokube` : See [this](https://github.com/kubernetes/kops/tree/master/protokube)
- `dockerd` : The `dockerd` process name is whitelisted already in this
rule, but not if it is the parent, which will happen if you are doing
docker-in-docker.
- `tini` : See [this](https://github.com/krallin/tini)
- `aws` : This one I noticed because Falco itself uses the AWS CLI to
send events to SNS, which was triggering this rule.
Signed-off-by: Nicolas Marier <nmarier@coveo.com>
While using Falco, I noticed we were getting many events that were
virtually identical to those that were previously filtered out by the
`exexe_running_docker_save` macro, but where the `cmdline` was something
like `exe /var/run/docker/netns/cc5c7b9bb110 all false`. I believe this
is caused by the use of docker-in-docker.
Signed-off-by: Nicolas Marier <nmarier@coveo.com>
A macro like this is useful because configuration management software
may need to run containers with an attached terminal to perform some of
its duties, and users may want to ignore this behavior.
Signed-off-by: Nicolas Marier <nmarier@coveo.com>
This macro is useful to allow binaries to be installed under certain
circumstances. For example, it may be fine to install a binary during a
build in a ci/cd pipeline.
Signed-off-by: Nicolas Marier <nmarier@coveo.com>
Since `evt.arg[1]` does not work for all syscalls, switch to:
- `evt.arg.path` for `rmdir` and `unlink` (used by `remove` macro)
- `evt.arg.name` for `unlinkat` (used by `remove` macro)
- `evt.arg.oldpath/newpath` for `rename` and `renameat` (used by `rename` macro)
That ensures `Modify binary dirs` works properly.
Note that we cannot yet use `renameat2` (not supported by sinsp, see https://github.com/draios/sysdig/issues/1603 )
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
Since the dir's path is found:
- in `evt.arg[1]` for `mkdir`
- but in `evt.arg[2]` for `mkdirat`
switch to `evt.arg.path` to catch both.
That ensures `Mkdir binary dirs` works properly.
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
This macro will be useful because it will make it possible to filter out
events with a higher degree of granularity than is currently possible
for the `Set Setuid or Setgid bit` rule.
For example, if some application is expected to set the setuid or the
setgid bit under a specific condition, like if it's started with a
specific command, then the `user_known_chmod_applications` list is not
enough because we don't want to filter out _all_ events by this
application, only specific ones. This macro allows that.
Signed-off-by: Nicolas Marier <nmarier@coveo.com>
https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler
Example alert:
---
K8s Operation performed by user not in allowed list of
users (user=vpa-recommender target=vpa-recommender/endpoints verb=update
uri=core/v1/namespaces/kube-system/endpoints/vpa-recommender resp=200)
K8s Operation performed by user not in allowed list of
users (user=vpa-updater target=vpa-updater/endpoints verb=update
uri=core/v1/namespaces/kube-system/endpoints/vpa-updater resp=200)
---
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Example event. I'm pretty sure the full file in this case is /etc/lvm/cache:
---
File below /etc opened for writing (user=root command=lvs --noheadings
--readonly --separator=";" -a -o
lv_tags,lv_path,lv_name,vg_name,lv_uuid,lv_size parent=ceph-volume
pcmdline=ceph-volume /usr/sbin/ceph-volume inventory --format json file=/etc/lvm/c...
---
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
"The Azure's NPM is a a daemonset that supports network policies as
defined by the Kubernetes policy specification."
Example event:
---
Log files were tampered (user=root command=azure-npm
file=/var/log/iptables.conf CID1 image=mcr.microsoft.com/containernetworking/azure-npm)
---
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Instead of using the request object to identify service account tokens,
exclude any secrets activity by system users (e.g. users starting with
"system:"). This allows the rules to work on k8s audit events at
Metadata level instead of RequestResponse level.
Also change the example objects for automated tests to ones collected at
Metadata level.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
New rules K8s Secret Created/K8s Secret Deleted detect creating/deleting
secrets, following the pattern of the other "K8s XXX Created/Deleted"
rules. One minor difference is that service account token secrets are
excluded, as those are created automatically as namespaces are created.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
It's useful to ignore some system binaries that use the network under
certain conditions, so this should be overridable by the user.
Signed-off-by: Nicolas Marier <nmarier@coveo.com>
This makes it more convenient to add more allowed procs and many other
rules have a similar mechanism to whitelist certain processes.
Signed-off-by: Nicolas Marier <nmarier@coveo.com>
Sample Falco alert:
```
Shell spawned by untrusted binary (user=git shell=sh parent=puma reactor
cmdline=sh -c pgrep -fl "unicorn.* worker\[.*?\]" pcmdline=puma reactor
gparent=puma ggparent=runsv aname[4]=ru...
```
https://github.com/puma/puma says it is "A Ruby/Rack web server built
for concurrency".
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Sample falco alert:
```
File below /etc opened for writing (user=root command=cp
/run/secrets/kubernetes.io/serviceaccount/ca.crt
/etc/pki/ca-trust/source/anchors/openshift-ca.crt parent=bash
pcmdline=bash -c #!/bin/bash\nset -euo pipefail\n\n# set by the node
image\nunset KUB...
```
The exception is conditioned on containers.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
* Use the user_known_package_manager_in_container_conditions macro in the "Launch Package Management Process in Container" rule
Signed-off-by: Jean-Philippe Lachance <jplachance@coveo.com>
The rule detects the execution of the k8s client tool in a container and
logs it with WARNING priority.
Signed-off-by: David de Torres <detorres.david@gmail.com>
Refactor how JSON event/k8s audit events extract values in two important
ways:
1. An event can now extract multiple values.
2. The extracted value is a class json_event_value instead of a simple
string.
The driver for 1. was that some filtercheck fields like
"ka.req.container.privileged" actually should extract multiple values,
as a pod can have multiple containers and it doesn't make sense to
summarize that down to a single value.
The driver for 2. is that by having an object represent a single
extracted value, you can also hold things like numbers e.g. ports, uids,
gids, etc. and ranges e.g. [0:3]. With an object, you can override
operators ==, <, etc. to do comparisons between the numbers and ranges,
or even set membership tests between extracted numbers and sets of
ranges.
This is really handy for a lot of new fields implemented as a part of
PSP support, where you end up having to check for overlaps between the
paths, images, ports, uids, etc in a K8s Audit Event and the acceptable
values, ranges, path prefixes enumerated in a PSP.
Implementing these changes also involve an overhaul of how aliases are
implemented. Instead of having an optional "formatting" function, where
arguments to the formatting function were expressed as text within the
index, define optional extraction and indexing functions. If an
extraction function is defined, it's responsible for taking the full
json object and calling add_extracted_value() to add values. There's a
default extraction function that uses a list of json_pointers with
automatic iteration over array values returned by a json pointer.
There's still a notion of filter fields supporting indexes--that's
simply handled within the default extraction or custom extraction
function. And for most fields, there won't be a need to write a custom
extraction function simply to implement indexing.
Within a json_event_filter_check object, instead of having a single
extracted value as a string, hold a vector of extracted json_event_value
objects (vector because order matters) and a set of json_event_value
objects (for set comparisons) as m_evalues. Values on the right hand
side of the expression are held as a set m_values.
json_event_filter_check::compare now supports IN/INTERSECTS as set
comparisons. It also supports PMATCH using path_prefix_search objects,
which simplifies checks like ka.req.pod.volumes.hostpath--now they can
be expressed as "ka.req.pod.volumes.hostpath intersects (/proc,
/var/run/docker.sock, /, /etc, /root)" instead of
"ka.req.volume.hostpath[/proc]=true or
ka.req.volume.hostpath[/root]=true or ...".
Define ~10 new filtercheck fields that extract pod properties like
hostIpc, readOnlyRootFilesystem, etc. that are relevant for PSP validation.
As a part of these changes, also clarify the names of filter fields
related to pods to always have a .pod in the name. Furthermore, fields
dealing with containers in a pod always have a .pod.containers prefix in
the name.
Finally, change the comparisons for existing k8s audit rules to use
"intersects" and/or "in" when appropriate instead of a single equality
comparison.
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
Without this, as ecs-agent starts we get a bunch of errors that look
like this (reformatted for readability):
Notice Container with sensitive mount started (
user=root
command=init -- /agent ecs-agent (id=19d4e98bb0dc)
image=amazon/amazon-ecs-agent:latest
mounts=/proc:/host/proc:ro:false:rprivate,$lotsofthings
)
ecs-agent needs those to work properly, so this can cause lots of false
positives when starting a new instance.
Signed-off-by: Felipe Bessa Coelho <fcoelho.9@gmail.com>
If this work as intended PR will automatically get the area labels depending on the files he modified.
In case the user wants it can still apply other areas manually, by slash command, or editing the PR template during the opening of the PR.
Signed-off-by: Leonardo Di Donato <leodidonato@gmail.com>
GKE regularly calls /exec.fifo from both a system level, and within
individual falco pods. As is this triggers errors multiple times every
hour. This change adds /exec.fifo to the expected files below root that
will be called.
Signed-off-by: Jonathan McGowan <jonnymcgow7@gmail.com>