* Add additional rpm writing programs
rhn_check, yumdb.
* Add 11-dhclient as a dhcp binary
* Let runuser read below pam
It reads those files to check permissions.
* Let chef write to /root/.chef*
Some deployments write directly below /root.
* Refactor openshift privileged images
Rework how openshift images are handled:
Many customers deploy to a private registry, which would normally
involve duplicating the image list for the new registry. Now, split the
image prefix search (e.g. <host>/openshift3) from the check of the image
name. The prefix search is in allowed_openshift_registry_root, and can
be easily overridden to add a new private registry hostname. The image
list check is in openshift_image, is conditioned on
allowed_openshift_registry_root, and does a contains search instead of a
prefix match.
Also try to get a more comprehensive set of possible openshift3 images,
using online docs as a guide.
* Also let sdchecks directly setns
A new macro python_running_sdchecks is similar to
parent_python_running_sdchecks but works on the process itself.
Add this as an exception to Change thread namespace.
* Use correct copyright years.
Also include the start year.
* Improve copyright notices.
Use the proper start year instead of just 2018.
Add the right owner Draios dba Sysdig.
Add copyright notices to some files that were missing them.
Replace references to GNU Public License to Apache license in:
- COPYING file
- README
- all source code below falco
- rules files
- rules and code below test directory
- code below falco directory
- entrypoint for docker containers (but not the Dockerfiles)
I didn't generally add copyright notices to all the examples files, as
they aren't core falco. If they did refer to the gpl I changed them to
apache.
* Add dpkg-divert as a debian package mgmt program.
* Add pip3 as a package mgmt program.
* Let ucpagent write config
Since the name is fairly generic (apiserver), require that it runs in a
container with image docker/ucp-agent.
* Let iscsi admin programs write config
* Add parent to some output strings
Will aid in addressing false positives.
* Let update-ca-trust write to pki files
* Add additional root writing programs
- zap: web application security tool
- airflow: apache app for managing data pipelines
- rpm can sometimes write below /root/.rpmdb
- maven can write groovy files
* Expand redis etc files
Additional program redis-launcher.(sh) and path /etc/redis.
* Add additional root directories
/root/workspace could be used by jenkins, /root/oradiag_root could be
used by Oracle 11 SQL*Net.
* Add pam-config as an auth program
* Add additional trusted containers
openshift image inspector, alternate name for datadog agent, docker ucp
agent, gliderlabs logspout.
* Add microdnf as a rpm binary.
https://github.com/rpm-software-management/microdnf
* Let coreos update-ssh-keys write /home/core/.ssh
* Allow additional writes below /etc/iscsi
Allow any path starting with /etc/iscsi.
* Add additional /root write paths
Additional files, with /root/workspace changing from a directory to a
path prefix.
* Add additional openshift trusted container.
* Also allow grandparents for ms_oms_writing_conf
In some cases the program spawns intermediate shells, for example:
07:15:30.756713513: Error File below /etc opened for writing (user= command=StatusReport.sh /opt/microsoft/omsconfig/Scripts/StatusReport.sh D34448EA-363A-42C2-ACE0-ACD6C1514CF1 EndTime parent=sh pcmdline=sh -c /opt/microsoft/omsconfig/Scripts/StatusReport.sh D34448EA-363A-42C2-ACE0-ACD6C1514CF1 EndTime file=/etc/opt/omi/conf/omsconfig/last_statusreport program=StatusReport.sh gparent=omiagent ggparent=omiagent gggparent=omiagent) k8s.pod= container=host k8s.pod= container=host
This should fix#387.
* Add alternatives as a binary dir writer
It can set symlinks below binary dirs.
* Let userhelper read sens.files/write below /etc
Part of usermode package, can be used by oVirt.
* Let package mgmt progs urlgrabber pki files
Some package management programs run urlgrabber-ext-{down} to update pki
files.
* Add additional root directory
for Jupyter-notebook
* Let brandbot write to /etc/os-release
Used on centos
* Add an additional veritas conf directory.
Also /etc/opt/VRTS...
* Let appdynamics spawn shells
Java, so we look at parent cmdline.
* Add more ancestors to output
In an attempt to track down the source of some additional shell
spawners, add additional parents.
* Let chef write below bin dirs/rpm database
Rename an existing macro chef_running_yum_dump to python_running_chef
and add additional variants.
Also add chef-client as a package management binary.
* Remove dangling macro.
No longer in use.
* Add additional volume mgmt progs
Add pvscan as a volume management program and add an additional
directory below /etc. Also rename the macro to make it more generic.
* Let openldap write below /etc/openldap
Only program is run-openldap.sh for now.
* Add additional veritas directory
Also /etc/vom.
* Let sed write /etc/sedXXXXX files
These are often seen in install scrips for rpm/deb packages. The test
only checks for /etc/sed, as we don't have anything like a regex match
or glob operator.
* Let dse (DataStax Search) write to /root
Only file is /root/tmp__.
* Add additional mysql programs and directories
Add run-mysqld and /etc/my.cnf.d directory.
* Let redis write its config below /etc.
* Let id program open network connections
Seen using port 111 (sun-rpc, but really user lookups).
* Opt-in rule for protecting tomcat shell spawns
Some users want to consider any shell spawned by tomcat suspect for
example, protecting against the famous apache struts attack
CVE-2017-5638, while others do not.
Split the difference by adding a macro
possibly_parent_java_running_tomcat, but disabling it by default.
* added ossec-syscheckd to read_sensitive_file_binaries
* Add "Write below monitored directory"
Take the technique used by "Write below binary dir", and make it more
general, expanding to a list of "monitored directories". This contains
common directories like /boot, /lib, etc.
It has a small workaround to look for home ssh directories without using
the glob operator, which has a pending fix in
https://github.com/draios/sysdig/pull/1153.
* Fix FPs
Move monitored_dir to after evt type checks and allow mkinitramfs to
write below /boot
* Addl boot writers.
* Improve compatibility with falco 0.9.0
Temporarily remove some rules features that are not compatible with
falco 0.9.0. We'll release a new falco soon, after which we'll add these
rules features back.
* Disable the unexpected udp traffic rule by default
Some applications will connect a udp socket to an address only to
test connectivity. Assuming the udp connect works, they will follow
up with a tcp connect that actually sends/receives data.
This occurs often enough that we don't want to update the Unexpected UDP
Traffic rule by default, so add a macro do_unexpected_udp_check which is
set to never_true. To opt-in, override the macro to use the condition
always_true.
* added new command lines for rabbitMQ
* added httpd_writing_ssl_conf macro and add it to write_etc_common
* modified httpd_writing_ssl_conf to add additional files
* added additional command to httpd_writing_ssl_conf
* Wrap condition
Wrap condition with folded style.
* Consolidate test connect ports into one list
There were several exceptions for apps that do a udp connect on an
address simply to see if it works, folllowed by a tcp connect that
actually sends/receives data.
Unify these exceptions into a single list test_connect_ports, and add
port 9 (discard, used by dockerd).
* Add Rule for unexpected udp traffic
New rule Unexpected UDP Traffic checks for udp traffic not on a list of
expected ports. Currently blocked on
https://github.com/draios/falco/issues/308.
* Add sendto/recvfrom in inbound/outbound macros
Expand the inbound/outbound macros to handle sendfrom/recvto events, so
they can work on unconnected udp sockets. In order to avoid a flood of
events, they also depend on fd.name_changed to only consider
sendto/recvfrom when the connection tuple changes.
Also make the check for protocol a positive check for udp instead of not tcp,
to avoid a warning about event type filters potentially appearing before
a negative condition. This makes filtering rules by event type easier.
This depends on https://github.com/draios/sysdig/pull/1052.
* Add additional restrictions for inbound/outbound
- only look for fd.name_changed on unconnected sockets.
- skip connections where both ips are 0.0.0.0 or localhost network.
- only look for successful or non-blocking actions that are in progress
* Add a combined inbound/outbound macro
Add a combined inbound/outbound macro so you don't have to do all the
other net/result related tests more than once.
* Fix evt generator for new in/outbound restrictions
The new rules skip localhost, so instead connect a udp socket to a
non-local port. That still triggers the inbound/outbound macros.
* Address FPs in regression tests
In some cases, an app may make a udp connection to an address with a
port of 0, or to an address with an application's port, before making a
tcp connection that actually sends/receives traffic. Allow these
connects.
Also, check both the server and client port and only consider the
traffic unexpected if neither port is in range.
* Also check evt.abspath in "Modify binary dirs" rule
For unlinkat evt.arg[1] is not the path of the file/dir removed.
* Monitor renameat too in "Modify binary dirs" rule
* Add ability to read rules files from directories
When the argument to -r <path> or an entry in falco.yaml's rules_file
list is a directory, read all files in the directory and add them to the
rules file list. The files in the directory are sorted alphabetically
before being added to the list.
The installed falco adds directories /etc/falco/rules.available and
/etc/falco/rules.d and moves /etc/falco/application_rules.yaml to
/etc/falco/rules.available. /etc/falco/rules.d is empty, but the idea is
that admins can symlink to /etc/falco/rules.available for applications
they want to enable.
This will make it easier to add application-specific rulesets that
admins can opt-in to.
* Unit test for reading rules from directory
Copy the rules/trace file from the test multiple_rules to a new test
rules_directory. The rules files are in rules/rules_dir/{000,001}*.yaml,
and the test uses a rules_file argument of rules_dir. Ensure that the
same events are detected.
* add common fluentd command, let docker modify
Add a common fluentd command, and let docker operations modify bin dir
* Add abrt-action-sav(...) as a rpm program
https://linux.die.net/man/1/abrt-action-save-package-data
* Add etc writers for more ms-on-linux svcs
Microsoft SCX and Azure Network Watcher Agent.
* Let nginx write its own config.
* Let chef-managed gitlab write gitlab config
* Let docker container fsen outside of containers
The docker process can also be outside of a container when doing actions
like docker save, etc, so drop the docker requirement.
* Expand the set of haproxy configs.
Let the parent process also be haproxy_reload and add an additional
directory.
* Add an additional node-related file below /root
For node cli.
* Let adclient read sensitive files
Active Directory Client.
* Let mesos docker executor write shells
* Add additional privileged containers.
A few more openshift-related containers and datadog.
* Add a kafka admin command line as allowed shell
In this case, run by cassandra
* Add additional ignored root directories
gradle and crashlytics
* Add back mesos shell spawning binaries back
This list will be limited only to those binaries known to spawn
shells. Add mesos-slave/mesos-health-ch.
* Add addl trusted containers
Consul and mesos-slave.
* Add additional config writers for sosreport
Can also write files below /etc/pki/nssdb.
* Expand selinux config progs
Rename macro to selinux_writing_conf and add additional programs.
* Let rtvscand read sensitive files
Symantec av cli program.
* Let nginx-launch write its own certificates
Sometimes directly, sometimes by invoking openssl.
* Add addl haproxy config writers
Also allow the general prefix /etc/haproxy.
* Add additional root files.
Mongodb-related.
* Add additional rpm binaries
rpmdb_stat
* Let python running get-pip.py modify binary files
Used as a part of directly running get-pip.py.
* Let centrify scripts read sensitive files
Scripts start with /usr/share/centrifydc
* Let centrify progs write krb info
Specifically, adjoin and addns.
* Let ansible run below /root/.ansible
* Let ms oms-run progs manage users
The parent process is generally omsagent-<version> or scx-<version.
* Combine & expand omiagent/omsagent macros
Combine the two macros into a single ms_oms_writing_conf and add both
direct and parent binaries.
* Let python scripts rltd to ms oms write binaries
Python scripts below /var/lib/waagent.
* Let google accounts daemon modify users
Parent process is google_accounts(_daemon).
* Let update-rc.d modify files below /etc
* Let dhcp binaries write indirectly to etc
This allows them to run programs like sed, cp, etc.
* Add istio as a trusted container.
* Add addl user management progs
Related to post-install steps for systemd/udev.
* Let azure-related scripts write below etc
Directory is /etc/azure, scripts are below /var/lib/waagent.
* Let cockpit write its config
http://www.cockpit-project.org/
* Add openshift's cassandra as a trusted container
* Let ipsec write config
Related to strongswan (https://strongswan.org/).
* Let consul-template write to addl /etc files
It may spawn intermediate shells and write below /etc/ssl.
* Add openvpn-entrypo(int) as an openvpn program
Also allow subdirectories below /etc/openvpn.
* Add additional files/directories below /root
* Add cockpit-session as a sensitive file reader
* Add puppet macro back
Still used in some people's user rules files.
* Rename name= to program=
Some users pointed out that name= was ambiguous, especially when the
event includes files being acted upon. Change to program=.
* Also let omiagent run progs that write oms config
It can run things like python scripts.
* Allow writes below /root/.android
* Let OMS agent for linux write config
Programs are omiagent/omsagent/PerformInventor/in_heartbeat_r* and files
are below /etc/opt/omi and /etc/opt/microsoft/omsagent.
* Handle really long classpath lines for cassandra
Some cassandra cmdlines are so long the classpath truncates the cmdline
before the actual entry class gets named. In those cases also look for
cassandra-specific config options.
* Let postgres binaries read sensitive files
Also add a couple of postgres cluster management programs.
* Add apt-add-reposit(ory) as a debian mgmt program
* Add addl info to debug writing sensitive files
Add parent/grandparent process info.
* Requrire root directory files to contain /
In some cases, a file below root might be detected but the file itself
has no directory component at all. This might be a bug with dropped
events. Make the test more strict by requiring that the file actually
contains a "/".
* Let updmap read sensitive files
Part of texlive (https://www.tug.org/texlive/)
* For selected rules, require proc name to exist
Some rules such as reading sensitive files and writing below etc have
many exceptions that depend on the process name. In very busy
environments, system call events might end up being dropped, which
causes the process name to be missing.
In these cases, we'll let the sensitive file read/write below etc to
occur. That's handled by a macro proc_name_exists, which ensures that
proc.name is not "<NA>" (the placeholder when it doesn't exist).
* Let ucf write generally below /etc
ucf is a general purpose config copying program, so let it generally
write below /etc, as long as it in turn is run by the apt program
"frontend".
* Add new conf writers for couchdb/texmf/slapadd
Each has specific subdirectories below /etc
* Let sed write to addl temp files below /etc
Let sed write to additional temporary files (some directory + "sed")
below /etc. All generally related to package installation scripts.
* Let rabbitmq(ctl) spawn limited shells
Let rabbitmq spawn limited shells that perform read-only tasks like
reading processes/ifaces.
Let rabbitmqctl generally spawn shells.
* Let redis run startup/shutdown scripts
Let redis run specific startup/shutdown scripts that trigger at
start/stop. They generally reside below /etc/redis, but just looking for
the names redis-server.{pre,post}-up in the commandline.
* Let erlexec spawn shells
https://github.com/saleyn/erlexec, "Execute and control OS processes
from Erlang/OTP."
* Handle updated trace files
As a part of these changes, we updated some of the positive trace files
to properly include a process name. These newer trace files have
additional opens, so update the expected event counts to match.
* Let yum-debug-dump write to rpm database
* Additional config writers
Symantec AV for Linux, sosreport, semodule (selinux), all with their
config files.
* Tidy up comments a bit.
* Try protecting node apps again
Try improving coverage of run shell untrusted by looking for shells
below node processes again. Want to see how many FPs this causes before
fully committing to it.
* Let node run directly by docker count as a service
Generally, we don't want to consider all uses of node as a service wrt
spawned shells. But we might be able to consider node run directly by
docker as a "service". So add that to protected_shell_spawner.
* Also add PM2 as a protected shell spawner
This should handle cases where PM2 manages node apps.
* Remove dangling macros/lists
Do a pass over the set of macros/lists, removing most of those that are
no longer referred to by any macro/list. The bulk of the macros/lists
were related to the rule Run Shell Untrusted, which was refactored to
only detect shells run below specific programs. With that change, many
of these exceptions were no longer neeeded.
* Add a "never_true" macro
Add a never_true macro that will never match any event. Useful if you
want to disable a rule/macro/etc.
* Add missing case to write_below_etc
Add the macro veritas_writing_config to write_below_etc, which was
mistakenly not added before.
* Make tracking shells spawned by node optional
The change to generally consider node run directly in a container as a
protected shell spawner was too permissive, causing false
positives. However, there are some deployments that want to track shells
spawned by node as suspect. To address this, create a macro
possibly_node_in_container which defaults to never matching (via the
never_true) macro. In a user rules file, you can override the macro to
remove the never_true clause, reverting to the old behavior.
* Add some dangling macros/lists back
Some macros/lists are still referred to by some widely used user rules
files, so add them back temporarily.
* Add additional allowed files below root.
These are related to node.js apps.
* Let yum-config-mana(ger) write to rpm database.
* Let gugent write to (root) + GuestAgent.log
vRA7 Guest Agent writes to GuestAgent.log with a cwd of root.
* Let cron-start write to pam_env.conf
* Add additional root files and directories
All seen in legitimate cases.
* Let nginx run aws s3 cp
Possibly seen as a part of consul deployments and/or openresty.
* Add rule for disallowed ssh connections
New rule "Disallowed SSH Connection" detects ssh connection attempts
other than those allowed by the macro allowed_ssh_hosts. The default
version of the macro allows any ssh connection, so the rule never
triggers by default.
The macro could be overridden in a local/user rules file, though.
* Detect contacting NodePort svcs in containers
New rule "Unexpected K8s NodePort Connection" detects attempts to
contact K8s NodePort services (i.e. ports >=30000) from within
containers.
It requires overridding a macro nodeport_containers which specifies a
set of containers that are allowed to use these port ranges. By default
every container is allowed.
* Remove remaining fbash references.
No longer relevant after all the installer rules were removed.
* Detect contacting EC2 metadata svc from containers
Add a rule that detects attempts to contact the ec2 metadata service
from containers. By default, the rule does not trigger unless a list of
explicitly allowed containers is provided.
* Detect contacting K8S API Server from container
New rule "Contact K8S API Server From Container" looks for connections
to the K8s API Server. The ip/port for the K8s API Server is in the
macro k8s_api_server and contains an ip/port that's not likely to occur
in practice, so the rule is effectively disabled by default.
* Additional rpm writers, root directories
salt-minion can also touch the rpm database, and some node packages
write below /root/.config/configstore.
* Add smbd as a protected shell spawner.
It's a server-like program.
* Also handle .ash_history
default shell for alpine linux
* Add exceptions for veritas
Let many veritas programs write below /etc/vx.
Let one veritas-related perl script read sensitive files.
* Allow postgres to run wal-e
https://github.com/wal-e/wal-e, archiving program for postgres.
* Let consul (agent) run addl scripts
Also let consul (agent, but the distinction is in the command line args)
to run nc in addition to curl. Also rename the macro.
* Let postgres setuid to itself
Let postgres setuid to itself. Seen by archiving programs like wal-e.
* Also allow consul to run alert check scripts
"sh -c /bin/consul-alerts watch checks --alert-addr 0.0.0.0:9000 ..."
* Add additional privileged containers.
Openshift's logging support containers generally run privileged.
* Let addl progs write below /etc/lvm
Add lvcreate as a program that can write below /etc/lvm and rename the
macro to lvprogs_writing_lvm_archive.
* Let glide write below root
https://glide.sh/, package management for go.
* Let sosreport read sensitive files.
* Let scom server read sensitive files.
Microsoft System Center Operations Manager (SCOM).
* Let kube-router run privileged.
https://github.com/cloudnativelabs/kube-router
* Let needrestart_binaries spawns shells
Was included in prior version of shell rules, adding back.
* Let splunk spawn shells below /opt/splunkforwarder
* Add yum-cron as a rpm binary
* Add a different way to run denyhosts.
Strange that the program is denyhosts.py but observed in actual
environments.
* Let nrpe setuid to nagios.
* Also let postgres run wal-e wrt shells
Previously added as an exception for db program spawned process, need to
add as an exception for run shell untrusted.
* Remove installer shell-related rules
They aren't used that often and removing them cleans up space for new
rules we want to add soon.
* Let kubelet running loopback spawn shells
Seen by @JPLachance, thanks for the heads up!
* Let docker's "exe" broadly write to files.
As a part of some docker commands like "docker save", etc, the program
exe can write from files on the host filesystem /var/lib/docker/... to a
variety of files within the container.
Allow this via a macro exe_running_docker_save that checks the
commandline as well as the parent and use it as an exclusion for the
write below binary dir/root/etc rules.
* Let chef perform more tasks
- Let chef-client generally read sensitive files and write below /etc.
- Let python running a chef script yum-dump.py write the rpm database.
Rename user_known_container_shell_spawn_binaries to
user_known_shell_spawn_binaries (the container distinction doesn't exist
any longer) and add it as an exception for run shell untrusted.
That way others can easily exclude shell spawning programs in a second
rules file.
* Refactor shell rules to avoid FPs.
Refactoring the shell related rules to avoid FPs. Instead of considering
all shells suspicious and trying to carve out exceptions for the
legitimate uses of shells, only consider shells spawned below certain
processes suspicious.
The set of processes is a collection of commonly used web servers,
databases, nosql document stores, mail programs, message queues, process
monitors, application servers, etc.
Also, runsv is also considered a top level process that denotes a
service. This allows a way for more flexible servers like ad-hoc nodejs
express apps, etc to denote themselves as a full server process.
* Update event generator to reflect new shell rules
spawn_shell is now a silent action. its replacement is
spawn_shell_under_httpd, which respawns itself as httpd and then runs a
shell.
db_program_spawn_binaries now runs ls instead of a shell so it only
matches db_program_spawn_process.
* Comment out old shell related rules
* Modify nodejs example to work w/ new shell rules
Start the express server using runit's runsv, which allows falco to
consider any shells run by it as suspicious.
* Use the updated argument for mkdir
In https://github.com/draios/sysdig/pull/757 the path argument for mkdir
moved to the second argument. This only became visible in the unit tests
once the trace files were updated to reflect the other shell rule
changes--the trace files had the old format.
* Update unit tests for shell rules changes
Shell in container doesn't exist any longer and its functionality has
been subsumed by run shell untrusted.
* Allow git binaries to run shells
In some cases, these are run below a service runsv so we still need
exceptions for them.
* Let consul agent spawn curl for health checks
* Don't protect tomcat
There's enough evidence of people spawning general commands that we
can't protect it.
* Reorder exceptions, add rabbitmq exception
Move the nginx exception to the main rule instead of the
protected_shell_spawner macro. Also add erl_child_setup (related to
rabbitmq) as an allowed shell spawner.
* Add additional spawn binaries
All off these are either below nginx, httpd, or runsv but should still
be allowed to spawn shells.
* Exclude shells when ancestor is a pkg mgmt binary
Skip shells when any process ancestor (parent, gparent, etc) is a
package management binary. This includes the program needrestart. This
is a deep search but should prevent a lot of other more detailed
exceptions trying to find the specific scripts run as a part of
installations.
* Skip shells related to serf
Serf is a service discovery tool and can in some cases be spawned by
apache/nginx. Also allow shells that are just checking the status of
pids via kill -0.
* Add several exclusions back
Add several exclusions back from the shell in container rule. These are
all allowed shell spawns that happen to be below
nginx/fluentd/apache/etc.
* Remove commented-out rules
This saves space as well as cleanup. I haven't yet removed the
macros/lists used by these rules and not used anywhere else. I'll do
that cleanup in a separate step.
* Also exclude based on command lines
Add back the exclusions based on command lines, using the existing set
of command lines.
* Add addl exclusions for shells
Of note is runsv, which means it can directly run shells (the ./run and
./finish scripts), but the things it runs can not.
* Don't trigger on shells spawning shells
We'll detect the first shell and not any other shells it spawns.
* Allow "runc:" parents to count as a cont entrypnt
In some cases, the initial process for a container can have a parent
"runc:[0:PARENT]", so also allow those cases to count as a container
entrypoint.
* Use container_entrypoint macro
Use the container_entrypoint macro to denote entering a container and
also allow exe to be one of the processes that's the parent of an
entrypoint.
* Let supervisor write more generally below /etc
* Let perl+plesk scripts run shells/write below etc
* Allow spaces after some cmdlines
* Add additional shell spawner.
* Add addl package mgmt binaries.
* Add addl cases for java + jenkins
Addl jar files to consider.
* Add addl jenkins-related cmdlines
Mostly related to node scripts run by jenkins
* Let python running some mesos tasks spawn shells
In this case marathon run by python
* Let ucf write below etc
Only below /etc/gconf for now.
* Let dpkg-reconfigur indirectly write below /etc
It may run programs that modify files below /etc
* Add files/dirs/prefixes for writes below root
Build a set of acceptable files/dirs/prefixes for writes below
/root. Mostly triggered by apps that run directly as root.
* Add addl shell spawn binaries.
* Also let java + sbt spawn shells in containers
Not seen only at host level
* Make sure the file below etc is /etc/
Make sure the file below /etc is really below the directory etc aka
/etc/xxx. Otherwise it would match a file /etcfoo.
* Let rancher healthcheck spawn shells
The name healthcheck is relatively innocuous so also look at the parent
process.
* Add addl shell container shell spawn binaries
* Add addl x2go binaries
* Let rabbitq write its config files
* Let rook write below /etc
toolbox.sh is fairly generic so add a condition based on the image name.
* Let consul-template spawn shells
* Add rook/toolbox as a trusted container
Their github pages recommend running privileged.
* Add addl mail binary that can setuid
* Let plesk autoinstaller spawn shells
The name autoinstaller is fairly generic so also look at the parent.
* Let php handlers write its config
* Let addl pkg-* binary write to /etc indirectly
* Add additional shell spawning binaries.
* Add ability to specify user trusted containers
New macro user_trusted_containers allows a user-provided set of
containers that are trusted and are allowed to run privileged.
* If npm runs node, let node spawn shells
* Let python run airflow via a shell.
* Add addl passenger commandlines (for shells)
* Add addl ways datadog can be run
* Let find run shells in containers.
* Add rpmq as a rpm binary
* Let httpd write below /etc/httpd/
* Let awstats/sa-update spawn shells
* Add container entrypoint as a shell
Some images have an extra shell level for image entrypoints.
* Add an additional jenkins commandline
* Let mysql write its config
* Let openvpn write its config
* Add addl root dirs/files
Also move /root/.java to be a general prefix.
* Let mysql_upgrade/opkg-cl spawn shells
* Allow login to perform dns lookups
With run with -h <host> to specify a remote host, some versions of login
will do a dns lookup to try to resolve the host.
* Let consul-template write haproxy config.
* Also let mysql indirectly edit its config
It might spawn a program to edit the config in addition to directly.
* Allow certain sed temp files below /etc/
* Allow debian binaries to indirectly write to /etc
They may spawn programs like sed, touch, etc to change files below /etc.
* Add additional root file
* Let rancher healthcheck be run more indirectly
The grandparent as well as parent of healthcheck can be tini.
* Add more cases for haproxy writing config
Allow more files as well as more scripts to update the config.
* Let vmtoolsd spawn shells on the host
* Add an additional innocuous entrypoint shell
* Let peer-finder (mongodb) spawn shells
* Split application rules to separate file.
Move the contents of application rules, which have never been enabled by
default, to a separate file. It's only installed in the mail falco packages.
* Add more build-related command lines
* Let perl running openresty spawn shells
* Let countly write nginx config
* Let confd spawn shells
* Also let aws spawn shells in containers.
The terminal shell in container rule has always been less permissive
than the other shell rules, mostly because we expect terminal-attached
shells to be less common. However, they might run innocuous commands,
especially from scripting languages like python. So allow the innocuous
commands to run.
* Let luajit spawn shells.
* Start support for db mgmt programs
Add support for db management programs that tend to spawn
shells. Starting with two lists
mysql_mgmt_binaries/postgres_mgmt_binaries which are combined into
db_mgmt_binaries. db_mgmt_binaries is added to both shell spawning rules
and the individual programs are removed.
* Let apache beam spawn shells
The program is "python pipeline.py" but it appears to be related to
https://github.com/apache/beam/blob/master/sdks/python/apache_beam/pipeline.py.
* Better support for dovecot
Allow dovecot to setuid by adding to mail_binaries.
Allow the program auth, when run by dovecot, to spawn shells.
* Better support for plesk
Create a list plesk_binaries and allow them to run shells.
Also let them write to files below /etc/sw/keys.
* Let strongswan spawn shells.
Specifically the program starter. Using the full command line to be more
specific.
* Let proftpd modify files below /etc.
* Let chef binaries write below /etc
* Let mandb read sensitive files
* Let specific phusion passenger binaries run shells
The program is "my_init", which is fairly generic, so capture it by the
full command line.
* Make git-remote-http more permissive.
* Let networkmanager modify /etc/resolv.conf
specifically nm-dispatcher
* Let hostid open network connections
It might perform dns lookups as a part of resolving ip addresses.
* Let uwsgi spawn shells
* Add docker-runc-cur as a docker binary.
truncated version of docker-runc-current.
* Add rule for allowed containers
New rule Launch Disallowed Container triggers when a container is
started that does not match the macro allowed_containers. In the main
falco rules file, this macro never matches, so it never
triggers. However, in a second rules file the macro allowed_containers
could be filled in with the specific images that match.
* Also let foreman spawn shells
Used by Red Hat Sattelite.
* Let confluence run shells.
Appears as java program, so look for the classpath.
* Make allowed_containers macro more foolproof.
In some cases, the container image might not be known/is NULL, so the
comparison aganst "dummy-not-allowed-container-image" doesn't work.
Replace this with proc.vpid=1, which is in the main rule Launch
Disallowed Continer. Ensures it will only trigger when the
allowed_containers macro is overridden.
* Let tomcat spawn shells.
It's java so you need to look at the classpath.
* Let pip install software.
* Add another yarn command line.
* Let add-shell write to /etc/shells.tmp
* Let more plesk binaries setuid.
* Add imap-login as a mail binary.
* Fix plesk writing keys macro
Should be testing proc.name, not proc.cmdline.
* Let screen read sensitive files.
* Add more shell spawners.
S99qualys-cloud is the init script, cfn-signal is cloudformation.
* Exclude nologin from user mgmt programs.
* Let programs run by locales.postins write to /etc
It can run scripts like sed to modify files before writing the final
file.
* Let install4j java progs spawn shells.
Again, searching by classpath.
* Let some shell cmds be spawned outside containers
We had a list known_container_shell_spawn_cmdlines that contained
innocuous commandlines, but it only worked for containers.
Split this list into container-specific and general commandlines, and
add an exception for the general commandlines for the Run Shell
Untrusted rule.
* Add addl ruby-based passenger spawners
Add a different way to identify ruby run by phusion passenger.
* Allow bundle ruby cmds to be identififed by name
In some cases, bundle runs ruby scripts by direct script
name (foo.rb). Also allow that to spawn shells.
* Let nginx spawn shells.
* Skip setuid rules for containers.
For now, entirely skip the setuid rule for containers. Will add back
once I can find a way to check for unknown users.
* Let PassengerWatchd run shells
* Add additional foreman shells
Let the direct parent also be scl when the ancestor is tfm-rake,tfm-ruby.
* Add additional innocuous command lines.
* Also let cron spawn shells in containers
Seen when using things like phusion passenger.
* Also let run-parts run cmp/cp for sensitive files
Might be a case of a missing process but might also be legitimate.
* Let erlexec spawn shells.
* Add additional innocuous shell cmdlines.
* Add suexec as a userexec binary.
* Add imap/mailmng-core as mail binaries.
Also split list across multiple lines.
* Let perl spawn shells when run by cpanm
* Let apache_control_ spawn shells
* Let ics_start/stop running java spawn shells
java is the direct parent, ics_start/stop are ancestors.
* Let PassengerAgent setuid.
It setuids to nobody.
* Let multilog write below /etc if run by supervise
* Let bwrap setuid
A container setup utility.
* Detect writes below /, /root
New rule Write below root detects writes either directly below / or
anywhere below /root.
* Don't let shells directly open network connections
In addition to system binaries, don't let shells directly open network
connections. Bash has /dev/{tcp,udp} which allows direct connections.
* Add additional sensitive mounts.
Add additional sensitive mounts, including the docker socket, /,
anywhere below /root, or anywhere below /etc.
* Let pki-realm write below /etc/pki/realms
Appears to be an ansible script.
* Let sgdisk write below dev
* Let debconf-show read sensitive files.
* Additional case for build-related scripts.
* Add additional mail binaries.
* Let ruby running discourse spawn shells.
* Let beam.smp and paster run shells
* Temporarily undo shells opening net conns update
At some customers, at container create time events are being lost, and
for that reason programs spawned by the shell that perform network
connections are being misattributed to the shell.
* Make the actual sensitive files a list.
Make the actual sensitive files used by the sensitive files macro a list
so it can be easily extended.
* Print mounts in Launch Sensitive Mount Container
Add the full list of mounts to the output of Launch Sensitive Mount
Container, so it's easy to see which sensitive mount was used.
* Add container.image to container-related rules.
Helps in diagnosis.
* Add sw-engine-kv as a plesk binary.
* Allow sa-update to read sensitive files
SpamAssassin updater.
* Add additional shell spawners.
* Allow sumologic secureFiles to run user mgmt progs
See https://help.sumologic.com/Send-Data/Installed-Collectors/05Reference-Information-for-Collector-Installation/08Enhanced-File-System-Security-for-Installed-Collectors.
* Only consider full mounts of /etc as sensitive
A legitimate case is k8s mounting /etc/kubernetes/ssl, which was
matching /etc*. The glob matcher we have isn't a full regex so you can't
exclude strings, only characters.
* Let htpasswd write below /etc
Part of nginx
* Let pam-auth-update read sensitive files
* Let hawkular-metric spawn shells.
* Generalize jenkins scripts spawning shells
Generalize jenkins_script_sh to jenkins_scripts and add additional
cases.
* Let php run by assemble spawn shells
Better than globally letting php spawn shells.
* Add additional setuid binaries.
* Add additional package mgmt prog
rhsmcertd-worke(r), red hat subscription manager
* Add additional yarn cmdlines.
* Let dmeventd write below etc.
device mapper event daemon.
* Let rhsmcertd-worke(r) spawn shells.
* Let node spawn bitnami-related shells.
* Add user allowed sensitive mounts
New macro user_sensitive_mount_containers allows a second rules file to
specify containers/images that can perform sensitive mounts.
* Add start-stop-daemon as setuid program
It has -g/-u args to change gid/uid.
Also move some other single setuid programs to the list
known_setuid_binaries.
* Add additional shell spawners/cmdlines.
* Let python running localstack spawn shells.
* Add additional chef binaries.
* Let fluentd spawn shells.
* Don't consider unix_chkpwd to be a user mgmt prog
It only checks passwords.
* Get setuid for NULL user in container working
Reorganize the unknown_user_in_container macro to get it working again
in containers. Previously, it was being skipped entirely due to a
problem with handling of unknown users, which get returned as NULL.
The new macro is known_user_in_container, which tests the user.name
against "N/A". It happens that if user.name is NULL, the comparison
fails, so it has the same effect as if the string "N/A" were being
returned. Any valid user name won't match the string "N/A", so known
users will cause the macro to return true.
The setuid rule needs an additional check for not container, so add that.
* Add exceptions for Write below root
Add lists of files/directories that are acceptable to write.
Work around https://github.com/draios/sysdig/issues/954, which relates
to not always knowing the proper user name in containers, by not running
the rule when in a container and the user name is "<NA>". This won't
address cases where the uid from inside the container maps to a user
name outside the container that is different than the user inside the
container, but it will help a bit.
Add crlutil as a program that can modify below etc.
Let centrify programs modify below etc.
Add more info for writes below etc to track etc writers through scripts.
Increase the level of debugging for shells.
Add more run_by_xxx macros for h2o/phusion passenger. Handles cases
where the ancestor has a name, but the direct parent is a general
scripting language like ruby/perl/etc.
New macro run_by_chef is similar to run_by_qualys in that it looks in
various places in the process heirarchy. Use that macro to allow writes
below etc. Will probably add in more places soon.
Qualys seems to run a variety of shell subprocesses, at various
levels. Add a macro run_by_qualys that checks at a few levels without
the cost of a full proc.aname, which traverses the full parent
heirarchy.
Add a macro user_shell_container_exclusions that allows a second rules
file to easily extend the shelll in container rule without overriding
the entire rule.
Also add an exclusion node_running_edi_dynamodb which can be used for
that macro.
Add more specific controls of files below /etc, allowing specific
combinations of programs and files:
- start-fluentd can write to /etc/fluent/fluent.conf
- locales.postins can write to /etc/locale.gen
Use pmatch, which compares a file against a set of prefix paths, instead
of fd.directory. This allows the directories in safe_etc_dirs to be a
prefix of a file instead of just the directory containing a file.
Move entrypoint detection to its own macro. Also consider something the
entrypoint if its parent is runc:[0:PARENT]. There's a race where
runc:[0:PARENT] exits in parallel with the root program being execd, so
the parent might not exist or might have this name.
Combine parent_php_running_builds and parent_ruby_running_gcc into a
single parent_scripting_running_builds which handles the general case of
some script running some make/compilation related program. Also add some
build-related command line prefixes.
Allow supervisor-related programs to spawn shells and access sensitive
files.
Allow sendmail config binaries to write below etc directly (their
children already could).
Add some directories related to phusion (system-as-a-container).
For a few rules add parent programs in the output so it's easier to
diagnose the context for an event.
Let varnishd spawn shells.
- Move qualys-cloud-ag to the monitoring_binaries list
- Add a new list sendmail_config_binaries containing programs that can
modify files.
- Make parent_php_running_git a bit more generic for
parent_php_running_builds and add some additional sub-commands.
- Allow several combinations of scripting programs (ruby, python, etc.)
to run other build-ish commands.
- Let mysql_install_d(b) spawn shells and access sensitive files.
- Let qualys-cloud-ag(ent) spawn shells
- Add a few additional innocuous commandlines
- Let postfix setuid to itself
A new (empty) list user_known_container_shell_spawn_binaries allows
additional files to add additional programs that are allowed to spawn
shells in containers.
Add additional shell spawning command lines.
Allow package management binaries in containers--lots of people seem to
do it. Also allow pycompile/py3compile.
I need to refactor the shell spawners to more clearly isolate shell
spawners that we don't want to occur in a container from ones that can
run both inside and outside of a container.
These changes allow for a local rules file that will be preserved across
upgrades and allows the main rules file to be overwritten across upgrades.
- Move all config/rules files below /etc/falco/
- Add a "local rules" file /etc/falco/falco_rules.local.yaml. The intent
is that it contains modifications/deltas to the main rules file
/etc/falco/falco_rules.yaml. The main falco_rules.yaml should be
treated as immutable.
- All config files are flagged so they are not overwritten on upgrade.
- Change the handling of the config item "rules_file" in falco.yaml to
allow a list of files. By default, this list contains:
[/etc/falco/falco_rules.yaml, /etc/falco/falco_rules.local.yaml].
Also change rpm/debian packaging to ensure that the above files are
preserved across upgrades:
- Use relative paths for share/bin dirs. This ensures that when packaged
as rpms they won't be flagged as config files.
- Add CMAKE_INSTALL_PREFIX to FALCO_ENGINE_LUA_DIR now that it's relative.
- In debian packaging, flag
/etc/falco/{falco.yaml,falco_rules.yaml,falco_rules.local.yaml} as
conffiles. That way they are preserved across upgrades if modified.
- In rpm packaging when using cmake, any files installed with an
absolute path are automatically flagged as %config. The only files
directly installed are now the config files, so that addresses the problem.
Add CMAKE_INSTALL_PREFIX to lua dir.
* Updates from beta customers.
- add anacron as a cron program
* Reorganize package management binaries
Split package_management_binaries into two separate lists rpm_binaries
and deb_binaries. unattended-upgr is common to both worlds so it's still
in package_management_binaries.
Also change Write below rpm database to use rpm_binaries instead of its
own list.
Also add 75-system-updat (truncated) as a shell spawner.
* Add rules for jenkins
Add rules that allow jenkins to spawn shells, both in containers and
directly on the host.
Also handle jenkins slaves that run /tmp/slave.jar.
* Allow npm to run shells.
Not yet allowing node to run shells itself, although we want to add
something to reduce node-related FPs.
* Allow urlgrabber/git-remote to access /etc
urlgrabber and git-remote both try to access the RHEL nss database,
containing shared certificates. I may change this in a more general way
by changing open_read/open_write to only look for successful opens.
* Only look for successful open_read/open_writes
Change the macros open_read/open_write to only trigger on successful
opens (when fd.num > 0). This is a pretty big change to behavior, but
is more intuitive.
This required a small update to the open counts for a couple of unit
tests, but otherwise they still all passed with this change.
* Allow rename_device to write below /dev
Part of udev.
* Allow cloud-init to spawn shells.
Part of https://cloud-init.io/
* Allow python to run a shell that runs sdchecks
sdchecks is a part of the sysdig monitor agent.
* Allow dev creation binaries to write below etc.
Specifically this includes blkid and /etc/blkid/blkid.tab.
* Allow git binaries to spawn shells.
They were already allowed to run shells in a container.
* Add /dev/kmsg as an allowed /dev file
Allows userspace programs to write to kernel log.
* Allow other make programs to spawn shells.
Also allow gmake/cmake to spawn shells and put them in their own list
make_binaries.
* Add better mesos support.
Mesos slaves appear to be in a container due to their cgroup and can run
programs mesos-health-check/mesos-docker-exec to monitor the containers
on the slave, so allow them to run shells.
Add mesos-agent, mesos-logrotate, mesos-fetch as shell spawners both in
and out of containers.
Add gen_resolvconf. (short for gen_resolvconf.py) as a program that can
write to /etc.
Add toybox (used by mesos, part of http://landley.net/toybox/about.html)
as a shell spawner.
* systemd can listen on network ports.
Systemd can listen on network ports to launch daemons on demand, so
allow it to perform network activity.
* Let docker binaries setuid.
Let docker binaries setuid and add docker-entrypoi (truncation
intentional) to the set of docker binaries.
* Change cis-related rules to be less noisy
Change the two cis-related falco rules "File Open by Privileged
Container" and "Sensitive Mount by Container" to be less noisy. We found
in practice that tracking every open still results in too many falco
notifications.
For now, change the rules to only track the initial process start in the
container by looking for vpid=1. This should result in only triggering
when a privileged/sensitive mount container is started. This is slightly
less coverage but is far less noisy.
* Add quay.io/sysdig as trusted containers
These are used for sysdig cloud onpremise deployments.
* Add gitlab-runner-b(uild) as a gitlab binary.
Add gitlab-runner-b (truncated gitlab-runner-build) as a gitlab binary.
* Add ceph as a shell spawner.
Also allow ceph to spawn shells in a container.
* Allow some shells by command line.
For some mesos containers, where the container doesn't have an image and
is just a tarball in a cgroup/namespace, we don't have any image to work
with. In those cases, allow specific command lines.
* Allow user 'nobody' to setuid.
Allow the user nobody to setuid. This depends on the user nobody being
set up in the first place to have no access, but that should be an ok
assumption.
* Additional allowed shell commandlines
* Add additional shells.
* Allow multiple users to become themself.
Add rule somebody_becoming_themself that handles cases of nobody and
www-data trying to setuid to themself. The sysdig filter language
doesn't support template/variable values to allow "user.name=X and
evt.arg.uid=X for a given X", so we have to enumerate the users.
* More known spawn command lines
* Let make binaries be run in containers.
Some CI/CD pipelines build in containers.
* Add additional shell spawning command lines
* Add additional apt program apt-listchanges.
* Add gitlab-ce as shell spawning container.
* Allow PM2 to spawn shells in containers.
Was already in the general list, seen in some customers, so adding to
the in containers list.
* Clean up pass to fix long lines.
Take a pass through the rules making sure each line is < 120 characters.
* Change tests for privileged container rules.
Change unit tests to reflect the new privileged/sensitive mount
container rules that only detect container launch.
Review the priorities used by each rule and try to use a consistent set
that uses more of the possible priorities. The general guidelines I used
were:
- If a rule is related to a write of state (i.e. filesystem, etc.),
its priority is ERROR.
- If a rule is related to an unauthorized read of state (i.e. reading
sensitive filees, etc.), its priority is WARNING.
- If a rule is related to unexpected behavior (spawning an unexpected
shell in a container, opening an unexpected network connection, etc.), its priority
is NOTICE.
- If a rule is related to behaving against good practices (unexpected
privileged containers, containers with sensitive mounts, running
interactive commands as root), its priority is INFO.
One exception is that the most FP-prone rule (Run shell untrusted) has a
priority of DEBUG.
Allow the sysdig cloud agent to call setns to collect java process
metrics.
We've also seen cases where some of the intermediate processes created
below runc appear to call setns. It appears that this only should happen
if some events (like the execve that spawns the intermediate processes)
are lost, but just to be safe allow processes starting with "runc:" to
call setns.
Add a new falco rule "Terminal shell in container" that looks for shells
spawned in a container with an attached terminal. This is similar to the
existing "Run shell in container" rule, but doesn't have as many
exceptions as we expect this to be even less rare.
- Sometimes systemd changes its process name to '(systemd)', probably
for a forked daemon process. Add that version to login_binaries.
- Add sv (part of runit) as a program that can write below /etc.
- Allow all /dev/tty* files by moving /dev/tty from the list to a
"startswith /dev/tty" condition.
Tag the existing ruleset to group tags in a meaningful way. The added
tags are:
- filesystem: the rule relates to reading/writing files
- sofware_mgmt: the rule relates to any software/package management
tool like rpm, dpkg, etc.
- process: the rule relates to starting a new process or changing the
state of a current process.
- database: the rule relates to databases
- host: the rule *only* works outside of containers
- shell: the rule specifically relates to starting shells
- container: the rule *only* works inside containers
- cis: the rule is related to the CIS Docker benchmark.
- users: the rule relates to management of users or changing the
identity of a running process.
- network: the rule relates to network activity
Rules can have multiple tags if they relate to multiple of the
above. Rules do not have to have tags, although all the current rules do.
- Add flanneld as a privileged container.
- Add parentheses grouping around many of the "x running y"
containers. I haven't found this strictly necessary with their
current use in rules, but this ensures they will be isolated when
used.
- Allow denyhosts to spawn shells--it runs iptables to add/remove hosts
from its deny list.
This is a rework of a PR made by @juju4 that had a bunch of additions
related to running other security/monitoring products, including aide,
bro, icinga2, nagios, ansible, etc.
This overlapped a lot with changes I had been making to reduce
noisiness, so rather than have @juju4 deal with the conflicts I took the
changes and made a separate commit with the non-conflicting additions.
A summary of the changes:
- Add docker-compose as a docker binary.
- Add showq/critical-stack as setuid binaries.
- Add lxd binaries
- Add some additional package management binaries.
- Add support for host intrustion detection systems like aide.
- Add support for network intrustion detections systems like bro.
- Add support for monitoring systems like nagios, icinga2, npcd.
- Other one-off additions to other lists of mail/etc programs.
A new trace file falco-event-generator.scap contains the result of
running the falco event generator in docker, via:
docker run --security-opt seccomp=unconfined sysdig/falco-event-generator:latest /usr/local/bin/event_generator --once
Make sure this trace file detects the exact set of events we expect for
each rule. This required adding a new verification method
check_detections_by_rule that finds the per-rule counts and compares
them to the expected counts, which are included in the test description
under the key "detect_counts".
This is the first time a trace file for a test is actually in one of the
downloaded zip files. This means it will be tested twice (one for simple
detect-or-not, once for actual counts).
Adding this test showed a problem with Run shell in container
rule--since sysdig/falco-event-generator startswith sysdig/falco, it was
being treated as a trusted container. Modify the macro
trusted_containers to not allow falco-event-generator to be trusted.
- Add a second possible location for denyhosts
- Add PM2 (http://pm2.keymetrics.io/) as a shell spawner.
- There was a bug in use of ansible_running_python. We actually need
two variants depending on whether ansible is the parent or current
process. parent_ansble_running_python is used for Run shell
untrusted, ansible_running_python is used for other rules.
We had added this image while the changes in
https://github.com/draios/falco/pull/177 made it to everyone. This is in
a release now, so we'll remove it from the rule set.
Several changes to reduce spurious alerts when managing machines via
ansible:
- Add ansible_running_python (that is, ansible-spawned python scripts)
as scripts that can read sensitive files and write below
/etc. Notably this is the user ansible module.
- Also add comments to ansible_running_python suggesting users make it
more strict by specifically naming the root directory for ansible
scripts.
- Add pypy as a python variant that can run ansible-related scripts.
Also other changes to reduce FPs:
- add apt-add-reposit, apt-auto-remova (truncation intentional),
apt-get, apt, apt-key as package management programs, and add package
management binaries to the set of shell spawners. The overlapping
binaries that were in known_shell_spawn_binaries were removed.
- add passwd_binaries, gpg, insserv, apparmor_parser, update-mime,
tzdata.{config,postinst}, systemd-machine, and debconf-show to
the set of binaries that can write below /etc.
- Add vsftpd as a program that can read sensitive files.
- Add additional programs (incl. python support programs like pip,
pycompile) as ones that can spawn shells.
- Allow privileged containers to spawn shells.
- Break out the set of files below /dev that are written to with O_CREAT
into a separate list, and add /dev/random,urandom,console to the list.
- Add python running denyhosts as a program that can write below /etc.
- Also add binaries starting with linux-image- as ones that can spawn
shells. These are perl scripts run as a part of installing
linux-image-N.N packages.
Changes to allow shells spawned by ansible. In general this is actually
pretty difficult--on the remote managed machine, ansible performs
actions simply by running python over ssh without any explicit ansible
helper or command line.
One (weak) hint is that the python scripts being run are usually under a
directory with ansible in the name. So use that as the basis for a macro
ansible_running_python. In turn, that macro is used as a negative
condition for the run shell untrusted rule.
This is a pretty fragile and easily exploited condition, so add a note
to the macro saying so.
Feedback from a falco user:
--
to more findings from last night:
logrotate cronjob (Debian default):
Shell spawned by untrusted binary (user=root shell=sh parent=logrotate cmdline=sh -c invoke-rc.d rsyslog rotate > /dev/null logrotate_script /var/log/syslog)
passwd cronjob (Debian default):
Sensitive file opened for reading by non-trusted program (user=root name=cmp command=cmp -s shadow.bak /etc/shadow file=/etc/shadow)
--
New macro cmp_cp_by_passwd allows cmp/cp to be run by passwd to examine
sensitive files. Add logrotate as a program that can spawn a shell.
Also do some cleanups, moving items to lists and splitting long
single-line conditions into multiple lines.
Add cchh/sysdig as a trusted container. We'll probably remove this once
the next agent release occurs that has the fix
https://github.com/draios/falco/pull/177.
Also reformat to avoid long lines.
Periodically both apt and apt-get will spawn shells to update success timestamps and motd.
falco-CLA-1.0-signed-off-by: Jonathan Coetzee <jon@thancoetzee.com>
SSH'ing into an Ubuntu 16.04 box triggers a bunch of "Sensitive file opened for reading by non-trusted program" errors caused by systemd
falco-CLA-1.0-signed-off-by: Jonathan Coetzee jon@thancoetzee.com
Add google_containers/kube-proxy as a trusted image (can be run
privileged, can mount sensitive filesystems). While our k8s deployments
run kube-proxy via the hyperkube image, evidently it's sometimes run via
its own image.
This is one of the fixes for #156.
Also update the output message for this rule.
Make sure falco doesn't detect the things draios-agent does as
suspicious. It's possible that you might run open source falco alongside
sysdig cloud.
App checks spawned by sysdig cloud binaries might also change namespace,
so also allow children of sysdigcloud binaries to call setns.
Add a new list k8s_binaries and allow those binaries to do things like
setns/spawn shells. It's not the case that all of these binaries
actually do these things, but keeping it as a single list makes
management easier.
Copy handling of -pk/-pm/-pc/-k/-m arguments from sysdig. All of the
relevant code was already in the inspector so that was easy.
The information from k8s/mesos/containers is used in two ways:
- In rule outputs, if the format string contains %container.info, that
is replaced with the value from -pk/-pm/-pc, if one of those options
was provided. If no option was provided, %container.info is replaced
with a generic %container.name (id=%container.id) instead.
- If the format string does not contain %container.info, and one of
-pk/-pm/-pc was provided, that is added to the end of the formatting
string.
- If -p was specified with a general value (i.e. not
kubernetes/mesos/container), the value is simply added to the end and
any %container.info is replaced with the generic value.
The new privileged falco rule was noisy when running kubernetes, which
can run privileged. Add it to the trusted_containers list.
Also eliminate a couple spurious warnings related to spawning shells in
containers.
New rule 'File Open by Privileged Container' triggers when a container
that is running privileged opens a file.
New rule 'Sensitive Mount by Container' triggers when a container that
has a sensitive mount opens a file. Currently, a sensitive mount is a
mount of /proc.
This depends on https://github.com/draios/sysdig/pull/655.
Falco itself spawns a shell when using program notifications, so add
falco to the set of trusted programs. (Also add some other programs like
make, awk, configure, that are run while building).
New variable FALCO_RULES_DEST_FILENAME allows the rules file to be
installed with a different filename. Not set in the falco repo, but in
the agent repo it's installed as falco_rules.default.yaml.
Improve ruleset after using with falco event_generator:
- Instead of assuming all shells are bash, add a list shell_binaries
and macro shell_procs, and replace references to bash with
shell_procs. This revealed some other programs that can spawn shells.
- Add "login" as an interactive command. systemd-login isn't in alpine
linux, which is the linux distro used for the container.
- Move read_sensitive_file_untrusted before
read_sensitive_file_trusted_after_startup, so it can hit first.
Docker 1.12 split docker into docker and dockerd, so add dockerd as a
docker binary. Also be consistent about using docker_binares instead of
just references to docker.
Also add ldconfig as a program that can write to files below /etc.
Move the c++ and lua code implementing falco engine/falco common to its
own directory userspace/engine. It's compiled as a static library
libfalco_engine.a, and has its own CMakeLists.txt so it can be included
by other projects.
The engine's CMakeLists.txt has a add_subdirectory for the falco rules
directory, so including the engine also builds the rules.
The variables you need to set to use the engine's CMakeLists.txt are:
- CMAKE_INSTALL_PREFIX: the root directory below which everything is
installed.
- FALCO_ETC_DIR: where to install the rules file.
- FALCO_SHARE_DIR: where to install lua code, relative to the
- install/package root.
- LUAJIT_INCLUDE: where to find header files for lua.
- FALCO_SINSP_LIBRARY: the library containing sinsp code. It will be
- considered a dependency of the engine.
- LPEG_LIB/LYAML_LIB/LIBYAML_LIB: locations for third-party libraries.
- FALCO_COMPONENT: if set, will be included as a part of any install()
commands.
Instead of specifying /usr/share/falco in config_falco_*.h.in, use
CMAKE_INSTALL_PREFIX and FALCO_SHARE_DIR.
The lua code for the engine has also moved, so the two lua source
directories (userspace/engine/lua and userspace/falco/lua) need to be
available separately via falco_common, so make it an argument to
falco_common::init.
As a part of making it easy to include in another project, also clean up
LPEG build/defs. Modify build-lpeg to add a PREFIX argument to allow for
object files/libraries being in an alternate location, and when building
lpeg, put object files in a build/ subdirectory.
In modify_binary_dirs, move the bin_dir_rename check before modify,
which is just a bunch of evt.type checks and is handled by evttype
filters.
Change create_files_below_dev to put the directory check first.
- Move evt.type checks to the front of rules. This is necessary to avoid
warnings now that event types are automatically extracted during rule
parsing and used to bind each rule with a specific set of events.
- Explicitly specify open for O_CREAT. With the change to event-specific
filters, it's necessary to associate a search for O_CREAT with
evt.type=open.
Make changes to rules to improve performance and reduce FPs:
- Rely on https://github.com/draios/sysdig/pull/610 that allows
specifying an open/openat for reading/writing without having to search
through all the flags individually.
- For a two-item list (open, openat), and thinking ahead to
https://github.com/draios/sysdig/pull/624, check the event type
individually instead of as a set membership test, which is a bit
faster.
- Switch to consistently using evt.type instead of syscall.type.
- Move positive tests like etc_dir, bin_dir, sensitive_files,
proc.sname, etc., which are most likely to not succeed, to the
beginning of rules, so they have a greater chance to cause the rest of
the rule to be skipped, which saves time.
- Using exim as a mail program--exim also can suid to root.
- add a new macro for ssl management binaries and allow them to write
below /etc and read sensitive files.
- add a new macro for dhcp client binaries and allow them to write below
/etc.
- Add exe (docker-related program) as a program that can set a namespace
using setns.
- Don't count /dev/tty as an important file under /dev.
https://github.com/draios/sysdig/pull/623 adds support for a startswith
operator to allow for string prefix matching. Modify the parser to
recognize that operator, and use that operator for rules that really
want to check the beginning of a pathname, directory, etc. to make them
faster and avoid FPs.
Once sysdig adds support for handling "in (...)" filter expressions as
set membership tests, it will be advantageous to combine lists of items
together into a single list so they can all be checked in a single set
membership test.
This commit adds support for a new yaml item type "list" containing a
field "name" and field "items" containing a list of items. These are
represented as a yaml list, which allows yaml to handle some of the
initial parsing with the list items maintained natively in lua.
Allow lists to contain list references by expanding any references to
the items in the list, before storing the list items in
state.lists.
When parsing macro or rule conditions, replace all references to a list
name with the list items as a comma separated string.
Modify the falco rules to switch to lists whenever possible. The
new convention is to use the suffix _binaries for lists of program names
and _procs for macros that define a filter expression using the list.
Adding docker-compose based example of man-in-the-middle attack against
installation scripts and how it can be detected using sysdig falco.
The docker-compose environment starts a good web server, compromised
nginx installation, evil web server, and a copy of sysdig falco. The
README walks through the process of compromising a client by using curl
http://localhost/get-software.sh | bash and detecting the compromise
using ./fbash.
The fbash program included in this example fixes https://github.com/draios/falco/issues/46.
Add additional rules related to using pipe installers within a fbash
session:
- Modify write_etc to only trigger if *not* in a fbash session. There's
a new rule write_etc_installer which has the same conditions when in
a fbash session, logging at INFO severity.
- A new rule write_rpm_database warns if any non package management
program tries to write below /var/lib/rpm.
- Add a new warning if any program below a fbash session tries to open
an outbound network connection on ports other than http(s) and dns.
- Add INFO level messages when programs in a fbash session try to run
package management binaries (rpm,yum,etc) or service
management (systemctl,chkconfig,etc) binaries.
In order to test these new INFO level rules, make up a third class of
trace files traces-info.zip containing trace files that should result in
info-level messages.
To differentiate warning and info level detection, add an attribute to
the multiplex file "detect_level", which is "Warning" for the files in
traces-positive and "Info" for the files in traces-info. Modify
falco_test.py to look specifically for a non-zero count for the given
detect_level.
Doing this exposed a bug in the way the level-specific counts were being
recorded--they were keeping counts by level name, not number. Fix that.
Update fbash rules to use proc.sname instead of proc.aname and to rely
on sessions instead of process ancestors.
I also wanted to add details on the address/port being listened to but
that's blocked on https://github.com/draios/falco/issues/86.
Along with this change, there are new positive trace files
installer-bash-starts-network-server.scap and
installer-bash-starts-session.scap that test these updated rules.
Do another round of rule cleanups now that we have a larger set of
positive and negative trace files to work with. Outside of this commit,
there are now trace files for all the positive rules, a docker-compose
startup and teardown, and some trace files from the sysdig cloud staging
environment.
Also add a script that runs sysdig with a filter that removes all the
syscalls not handled by falco as well as a few other high-volume,
low-information syscalls. This script was used to create the staging
environment trace files.
Notable rule changes:
- The direction for write_binary_dir/write_etc needs to be exit instead
of enter, as the bin_dir clause works on the file descriptor returned
by the open/openat call.
- Add login as a trusted binary that can read sensitive files (occurs
for direct console logins).
- sshd can read sensitive files well after startup, so exclude it from
the set of binaries that can trigger
read_sensitive_file_trusted_after_startup.
- limit run_shell_untrusted to non-containers.
- Disable the ssh_error_syslog rule for now. With the current
restriction on system calls (no read/write/sendto/recvfrom/etc), you
won't see the ssh error messages. Nevertheless, add a string to look
for to indicate ssh errors and add systemd's true location for the
syslog device.
- Sshd attemps to setuid even when it's not running as root, so exclude
it from the set of binaries to monitor for now.
- Let programs that are direct decendants of systemd spawn user
management tasks for now.
- Temporarily disable the EACCESS rule. This rule is exposing a bug in
sysdig in debug mode, https://github.com/draios/sysdig/issues/598. The
rule is also pretty noisy so I'll keep it disabled until the sysdig bug
is fixed.
- The etc_dir and bin_dir macros both have the problem that they match
pathnames with /etc/, /bin/, etc in the middle of the path, as sysdig
doesn't have a "begins with" comparison. Add notes for that.
- Change spawn_process to spawned_process to indicate that it's for the
exit side of the execve. Also use it in a few places that were
looking for the same conditions without any macro.
- Get rid of adduser_binaries and fold any programs not already present
into shadowutils_binaries.
- Add new groups sysdigcloud_binaries and sysdigcloud_binaries_parent
and add them as exceptions for write_etc/write_binary_dir.
- Add yum as a package management binary and add it as an exception to
write_etc/write_binary_dir.
- Change how db_program_spawned_process works. Since all of the useful
information is on the exit side of the event, you can't really add a
condition based on the process being new. Isntead, have the rule
check for a non-database-related program being spawned by a
database-related program.
- Allow dragent to run shells.
- Add sendmail, sendmail-msp as a program that attempts to setuid.
- Some of the *_binaries macros that were based on dpkg -L accidentally
contained directories in addition to end files. Trim those.
- Add systemd-logind as a login_binary.
- Add unix_chkpwd as a shadowutils_binary.
- Add parentheses around any macros that group items using or. I found
this necessary when the macro is used in the middle of a list of and
conditions.
- Break out system_binaries into a new subset user_mgmt_binaries
containing login_, passwd_, and shadowutils_ binaries. That way you
don't have to pull in all of system_binaries when looking for
sensisitive files or user management activity.
- Rename fs-bash to fbash, thinking ahead to its more likely name.
We found during testing that rules without syscall/event conditions are
slower than other rules, so take a pass over the existing set of rules
ensuring that whenever possible they have a condition. The changes are:
- Only process executions by interactive users are monitored
- Only look at connect/listen/etc for system binaries performing
network activity
- Only monitor process executions when monitoring user management
programs.
Also comment out all application rules by default so users can opt-in
for the applications they use instead of getting a lot of application
monitoring they may not need. Add a note stating they're all disabled by
default and can be re-enabled as needed.
Finally, remove some less common applications where we haven't done live
testing.
These 3 changes, along with those in
https://github.com/draios/sysdig/pull/592, result in a significant
performance increase on busy servers.
For rules where evt.args had useful information but too much
information, add back specific values that have just the useful argument
from the event:
- spawned shells contain the commandline--it's the exit half of the
exec event so the current commandline is what was exec()d to.
- setuid contains the uid being switched to.
While I was testing these, I had a couple of other fixes:
- In the spawn shells rule, only track execve events so you don't catch
clone() events that precede an exec.
- in spawn_process only consider the exit half of the exec event.
A new macro package_mgmt_binaries includes dpkg and rpm. Those programs
are allowed to create directories and modify files below binary
directories. I'm not adding them to other trusted sets for now, though.
Try to clean up the language of the existing rule set, expanding the
output when possible, removing %evt.dir in most cases.
There is one substantive change: the mkdir half of modify_binary_dirs
was split out into its own rule mkdir_binary_dirs.
Add name and description fields to all rules. The name field is actually
a field called 'rule', which corresponds to the 'macro' field for
macros.
Within the rule loader, the state changes slightly. There are two
indices into the set of rules 'rules_by_name' and
'rules_by_idx' (formerly 'outputs'). They both now contain the original
table from the yaml parse. One field 'level' is added which is the
priority mapped to a number.
Get rid of the notion of default priority or output. Every rule must now
provide both.
Go through all current rules and add names and descriptions.
Update rules to reduce FPs after running against some real-world
environments with and without containers. Summary of changes:
- Too many processes read /etc/passwd--it's world-readable and a
side-effect of getpwent. Switch to /etc/shadow instead.
- Add a mail_binaries group. This wasn't directly used, but it may be
handy for other rules and goes along with the changes in #54.
- not_cron was the only macro expressing a negative, so switch it to be
a positive 'cron'. Also add crond as a cron process.
- add dragent to the set of programs that can call setns.
- For the shell detection rules, change them to only look for the
specific exec/clone event rather than all follow-on activity. Also
allow docker to spawn shell scripts--this is required for entrypoints
that use the shell instead of a direct exec. Also add a few
additional programs that can spawn shells.
- In containers, shells are allowed as long as the parent process is
docker or bash. Like the outside of container case, only the initial
clone/exec is detected.
- Fix a typo Sytem -> System.
- Change the chmod rule to only protect imporant/sensitive files. I saw
lots of "regular" files being chmod()ed.
- Change the setuid test to allow root to setuid to anything, rather
than listing a bunch of programs run as root that drop privileges.
- Allow running su/sudo in containers. Some containers add users from a
base linux distribution before running.
This will detect the result of some sql injection attacks where the
injected query tries to spawn a process.
We don't include web servers in this list for now due to things like
mod_perl, mod_php, etc. Maybe we can add it once we make exceptions for
those modules.
Add back detection for mysql and sensitive files that was removed in the
previous commit. A new macro proc_is_new adds a condition on how long a
process has been running.
A new rule triggers if the process is not new and tries to open a
sensitive file. This handles cases like mysql, where it *does* read
/etc/passwd on startup but shouldn't really open it afterward.
Add some new groups of binary programs as macros and start using them in
the set of rules:
- docker_binaries: docker and exe (which is a temporary process name
for processes like docker-proxy)
- http_server_binaries: httpd, nginx, and similar
- db_server_binaries: mysql for now, we'll add more later
- server_binaries: all of the above
- userexec_binaries: sudo and su.
Start using these groups in the rules. Most of the time, changing from
the inline lists of processes to macros was a no-op. There are some
actual changes, though:
- docker and exe are now allowed to read 'sensitive' files. They may
not actually do so, but it's not really harmful.
- lighttpd is now allowed to read 'sensitive' files, via inclusion in
http_server_binaries.
- su, lighttpd, and docker can now setuid.
- http-foreground is included as a http server wrt non-port 80/443 ports.
I'm going to use these macros in some of the following rules.
This actually prevents detection of mysql reading sensitive files, which
is one of the demo scenarios (sql injection). I plan on adding this
detection back in the next commit.
Make changes to falco_rules.yaml to make sure they work on the demo
scenarios without too many false positives. The specific changes are:
- Add /etc/ld.so.cache as an allowed shared library to open.
- Comment out the shared library check for now--there are lots of
locations below /usr/lib for things like python, perl, etc and I want
to get a fuller categorization first.
- Add a few additional parent processes that can spawn shells, write
sensitive files, and call setuid. Also allow bash shells with no
parent to spawn shells. We may want to disallow this but I suspect a
better place to detect is the parent-less bash shell becoming a
session leader.
- Add rules for fs-bash (falco-safe bash), which is used in the curl
<url> | bash installer demo. The idea is that fs-bash has restrictions
on what it and child proceses can do.
- Add trailing '/' characters to path names in bin_dir_* so paths like
/tmp/binary don't accidentally match '/bin'
Note that as process names are truncated to 15 characters, long process
names like 'httpd-foregroun' are intentionally truncated.
The ignored syscalls in macros were:
- write: renamed to open_write to make its weaker resolution more
apparent. Checks for open with any flag that could change a file.
- read: renamed to open_read. Checks for open with any read flag.
- sendto: I couldn't think of any way to replace this, so I simply
removed it with a comment.
I kept the original read/write macros commented out with a note that
they use ignored syscalls.
I have not tested these changes yet other than verifying that falco
starts properly.
As pointed out by Loris, timestamping output messages should be a
responsibility of the output/collection system.
So as a first step towards this, add timestamps automatically for output
formats, and remove them from rules.