Compare commits

...

10 Commits

Author SHA1 Message Date
Brett Bertocci
19db7890b3 Merge branch 'dev' into agent-master 2018-01-11 17:25:47 -08:00
Michael Ducy
cef147708a Update K8S Daemon Set for RBAC & ConfigMap (#309)
* Update K8S Daemon Set for RBAC & ConfigMap

* Fix typo in command
2017-12-20 22:58:20 -05:00
Mark Stemm
1c9f86bdd8 Merge branch 'dev' into agent-master 2017-12-13 13:35:57 -08:00
Mark Stemm
db0d913acc Rule updates vdec (#307)
* 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.
2017-12-11 22:34:50 -08:00
Luca Marturana
e0458cba67 Merge branch 'dev' into agent-master 2017-12-04 11:18:18 +01:00
Mark Stemm
af564f17a6 Add ability to override shell spawning binaries (#304)
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.
2017-12-01 12:30:04 -08:00
Mark Stemm
cd2b210fe3 Merge branch 'dev' into agent-master 2017-11-28 09:18:58 -08:00
Mark Stemm
d6d975e28c Refactor shell rules (#301)
* 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.
2017-11-28 07:04:37 -08:00
Luca Marturana
5ac3e7d074 Merge branch 'dev' into agent-master 2017-11-21 12:18:56 +01:00
Mark Stemm
60af4166de Rule updates vnov (#300)
* 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.
2017-11-16 12:12:31 -08:00
13 changed files with 647 additions and 338 deletions

View File

@@ -1,3 +1,4 @@
/etc/falco/falco.yaml
/etc/falco/falco_rules.yaml
/etc/falco/application_rules.yaml
/etc/falco/falco_rules.local.yaml

View File

@@ -50,6 +50,8 @@ void usage(char *program)
printf(" then read a sensitive file\n");
printf(" write_rpm_database Write to files below /var/lib/rpm\n");
printf(" spawn_shell Run a shell (bash)\n");
printf(" Used by spawn_shell_under_httpd below\n");
printf(" spawn_shell_under_httpd Run a shell (bash) under a httpd process\n");
printf(" db_program_spawn_process As a database program, try to spawn\n");
printf(" another program\n");
printf(" modify_binary_dirs Modify a file below /bin\n");
@@ -64,7 +66,7 @@ void usage(char *program)
printf(" non_sudo_setuid Setuid as a non-root user\n");
printf(" create_files_below_dev Create files below /dev\n");
printf(" exec_ls execve() the program ls\n");
printf(" (used by user_mgmt_binaries below)\n");
printf(" (used by user_mgmt_binaries, db_program_spawn_process)\n");
printf(" user_mgmt_binaries Become the program \"vipw\", which triggers\n");
printf(" rules related to user management programs\n");
printf(" exfiltration Read /etc/shadow and send it via udp to a\n");
@@ -230,9 +232,14 @@ void spawn_shell() {
}
}
void spawn_shell_under_httpd() {
printf("Becoming the program \"httpd\" and then spawning a shell\n");
respawn("./httpd", "spawn_shell", "0");
}
void db_program_spawn_process() {
printf("Becoming the program \"mysql\" and then spawning a shell\n");
respawn("./mysqld", "spawn_shell", "0");
printf("Becoming the program \"mysql\" and then running ls\n");
respawn("./mysqld", "exec_ls", "0");
}
void modify_binary_dirs() {
@@ -360,6 +367,7 @@ map<string, action_t> defined_actions = {{"write_binary_dir", write_binary_dir},
{"read_sensitive_file_after_startup", read_sensitive_file_after_startup},
{"write_rpm_database", write_rpm_database},
{"spawn_shell", spawn_shell},
{"spawn_shell_under_httpd", spawn_shell_under_httpd},
{"db_program_spawn_process", db_program_spawn_process},
{"modify_binary_dirs", modify_binary_dirs},
{"mkdir_binary_dirs", mkdir_binary_dirs},
@@ -375,7 +383,7 @@ map<string, action_t> defined_actions = {{"write_binary_dir", write_binary_dir},
// Some actions don't directly result in suspicious behavior. These
// actions are excluded from the ones run with -a all.
set<string> exclude_from_all_actions = {"exec_ls", "network_activity"};
set<string> exclude_from_all_actions = {"spawn_shell", "exec_ls", "network_activity"};
void create_symlinks(const char *program)
{

View File

@@ -1,5 +1,92 @@
# Example K8s Services for Falco
# Example Kubernetes Daemon Sets for Sysdig Falco
The yaml file in this directory installs the following:
- Open Source Falco, as a DaemonSet. Falco is configured to communicate with the K8s API server via its service account, and changes its output to be K8s-friendly. It also sends to a slack webhook for the `#demo-falco-alerts` channel on our [public slack](https://sysdig.slack.com/messages/demo-falco-alerts/).
- The [Falco Event Generator](https://github.com/draios/falco/wiki/Generating-Sample-Events), as a deployment that ensures it runs on exactly 1 node.
This directory gives you the required YAML files to stand up Sysdig Falco on Kubernetes as a Daemon Set. This will result in a Falco Pod being deployed to each node, and thus the ability to monitor any running containers for abnormal behavior.
The two options are provided to deploy a Daemon Set:
- `k8s-with-rbac` - This directory provides a definition to deploy a Daemon Set on Kubernetes with RBAC enabled.
- `k8s-without-rbac` - This directory provides a definition to deploy a Daemon Set on Kubernetes without RBAC enabled.
Also provided:
- `falco-event-generator-deployment.yaml` - A Kubernetes Deployment to generate sample events. This is useful for testing, but note it will generate a large number of events.
## Deploying to Kubernetes with RBAC enabled
Since v1.8 RBAC has been available in Kubernetes, and running with RBAC enabled is considered the best practice. The `k8s-with-rbac` directory provides the YAML to create a Service Account for Falco, as well as the ClusterRoles and bindings to grant the appropriate permissions to the Service Account.
```
k8s-using-daemonset$ kubectl create -f k8s-with-rbac/falco-account.yaml
serviceaccount "falco-account" created
clusterrole "falco-cluster-role" created
clusterrolebinding "falco-cluster-role-binding" created
k8s-using-daemonset$
```
The Daemon Set also relies on a Kubernetes ConfigMap to store the Falco configuration and make the configuration available to the Falco Pods. This allows you to manage custom configuration without rebuilding and redeploying the underlying Pods. In order to create the ConfigMap you'll need to first need to copy the required configuration from their location in this GitHub repo to the `k8s-with-rbac/falco-config/` directory. Any modification of the configuration should be performed on these copies rather than the original files.
```
k8s-using-daemonset$ cp ../../falco.yaml k8s-with-rbac/falco-config/
k8s-using-daemonset$ cp ../../rules/falco_rules.* k8s-with-rbac/falco-config/
```
If you want to send Falco alerts to a Slack channel, you'll want to modify the `falco.yaml` file to point to your Slack webhook. For more information on getting a webhook URL for your Slack team, refer to the [Slack documentation](https://api.slack.com/incoming-webhooks). Add the below to the bottom of the `falco.yaml` config file you just copied to enable Slack messages.
```
program_output:
enabled: true
keep_alive: false
program: "jq '{text: .output}' | curl -d @- -X POST https://hooks.slack.com/services/see_your_slack_team/apps_settings_for/a_webhook_url"
```
You will also need to enable JSON output. Find the `json_output: false` setting in the `falco.yaml` file and change it to read `json_output: true`. Any custom rules for your environment can be added to into the `falco_rules.local.yaml` file and they will be picked up by Falco at start time. You can now create the ConfigMap in Kubernetes.
```
k8s-using-daemonset$ kubectl create configmap falco-config --from-file=k8s-with-rbac/falco-config
configmap "falco-config" created
k8s-using-daemonset$
```
Now that we have the requirements for our Daemon Set in place, we can create our Daemon Set.
```
k8s-using-daemonset$ kubectl create -f k8s-with-rbac/falco-daemonset-configmap.yaml
daemonset "falco" created
k8s-using-daemonset$
```
## Deploying to Kubernetes without RBAC enabled
If you are running Kubernetes with Legacy Authorization enabled, you can use `kubectl` to deploy the Daemon Set provided in the `k8s-without-rbac` directory. The example provides the ability to post messages to a Slack channel via a webhook. For more information on getting a webhook URL for your Slack team, refer to the [Slack documentation](https://api.slack.com/incoming-webhooks). Modify the [`args`](https://github.com/draios/falco/blob/dev/examples/k8s-using-daemonset/falco-daemonset.yaml#L21) passed to the Falco container to point to the appropriate URL for your webhook.
```
k8s-using-daemonset$ kubectl create -f k8s-without-rbac/falco-daemonset.yaml
```
## Verifying the installation
In order to test that Falco is working correctly, you can launch a shell in a Pod. You should see a message in your Slack channel (if configured), or in the logs of the Falco pod.
```
k8s-using-daemonset$ kubectl get pods
NAME READY STATUS RESTARTS AGE
falco-74htl 1/1 Running 0 13h
falco-fqz2m 1/1 Running 0 13h
falco-sgjfx 1/1 Running 0 13h
k8s-using-daemonset$ kubectl exec -it falco-74htl bash
root@falco-74htl:/# exit
k8s-using-daemonset$ kubectl logs falco-74htl
{"output":"17:48:58.590038385: Notice A shell was spawned in a container with an attached terminal (user=root k8s.pod=falco-74htl container=a98c2aa8e670 shell=bash parent=<NA> cmdline=bash terminal=34816)","priority":"Notice","rule":"Terminal shell in container","time":"2017-12-20T17:48:58.590038385Z", "output_fields": {"container.id":"a98c2aa8e670","evt.time":1513792138590038385,"k8s.pod.name":"falco-74htl","proc.cmdline":"bash ","proc.name":"bash","proc.pname":null,"proc.tty":34816,"user.name":"root"}}
k8s-using-daemonset$
```
Alternatively, you can deploy the [Falco Event Generator](https://github.com/draios/falco/wiki/Generating-Sample-Events) deployement to have events automatically generated. Please note that this Deployment will generate a large number of events.
```
k8s-using-daemonset$ kubectl create -f falco-event-generator-deployment.yaml \
&& sleep 1 \
&& kubectl delete -f falco-event-generator-deployment.yaml
deployment "falco-event-generator-deployment" created
deployment "falco-event-generator-deployment" deleted
k8s-using-daemonset$
```

View File

@@ -0,0 +1,29 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: falco-account
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: falco-cluster-role
rules:
- apiGroups: ["extensions",""]
resources: ["nodes","namespaces","pods","replicationcontrollers","services","events","configmaps"]
verbs: ["get","list","watch"]
- nonResourceURLs: ["/healthz", "/healthz/*"]
verbs: ["get"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: falco-cluster-role-binding
namespace: default
subjects:
- kind: ServiceAccount
name: falco-account
namespace: default
roleRef:
kind: ClusterRole
name: falco-cluster-role
apiGroup: rbac.authorization.k8s.io

View File

@@ -0,0 +1,65 @@
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: falco
labels:
name: falco-daemonset
app: demo
spec:
template:
metadata:
labels:
name: falco
app: demo
role: security
spec:
serviceAccount: falco-account
containers:
- name: falco
image: sysdig/falco:latest
securityContext:
privileged: true
args: [ "/usr/bin/falco", "-K", "/var/run/secrets/kubernetes.io/serviceaccount/token", "-k", "https://kubernetes", "-pk"]
volumeMounts:
- mountPath: /host/var/run/docker.sock
name: docker-socket
readOnly: true
- mountPath: /host/dev
name: dev-fs
readOnly: true
- mountPath: /host/proc
name: proc-fs
readOnly: true
- mountPath: /host/boot
name: boot-fs
readOnly: true
- mountPath: /host/lib/modules
name: lib-modules
readOnly: true
- mountPath: /host/usr
name: usr-fs
readOnly: true
- mountPath: /etc/falco
name: falco-config
volumes:
- name: docker-socket
hostPath:
path: /var/run/docker.sock
- name: dev-fs
hostPath:
path: /dev
- name: proc-fs
hostPath:
path: /proc
- name: boot-fs
hostPath:
path: /boot
- name: lib-modules
hostPath:
path: /lib/modules
- name: usr-fs
hostPath:
path: /usr
- name: falco-config
configMap:
name: falco-config

View File

@@ -18,7 +18,7 @@ spec:
image: sysdig/falco:latest
securityContext:
privileged: true
args: [ "/usr/bin/falco", "-K", "/var/run/secrets/kubernetes.io/serviceaccount/token", "-k", "https://kubernetes", "-pk", "-o", "json_output=true", "-o", "program_output.enabled=true", "-o", "program_output.program=jq '{text: .output}' | curl -d @- -X POST https://hooks.slack.com/services/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"]
args: [ "/usr/bin/falco", "-K", "/var/run/secrets/kubernetes.io/serviceaccount/token", "-k", "https://kubernetes", "-pk", "-o", "json_output=true", "-o", "program_output.enabled=true", "-o", "program_output.program=jq '{text: .output}' | curl -d @- -X POST https://hooks.slack.com/services/see_your_slack_team/apps_settings_for/a_webhook_url"]
volumeMounts:
- mountPath: /host/var/run/docker.sock
name: docker-socket

View File

@@ -1,9 +1,7 @@
# Owned by software vendor, serving install-software.sh.
express_server:
container_name: express_server
image: node:latest
working_dir: /usr/src/app
command: bash -c "npm install && node server.js"
command: bash -c "apt-get -y update && apt-get -y install runit && npm install && runsv /usr/src/app"
ports:
- "8181:8181"
volumes:

View File

@@ -0,0 +1,2 @@
#!/bin/sh
node server.js

View File

@@ -5,6 +5,7 @@ endif()
if(NOT DEFINED FALCO_RULES_DEST_FILENAME)
set(FALCO_RULES_DEST_FILENAME "falco_rules.yaml")
set(FALCO_LOCAL_RULES_DEST_FILENAME "falco_rules.local.yaml")
set(FALCO_APP_RULES_DEST_FILENAME "application_rules.yaml")
endif()
if(DEFINED FALCO_COMPONENT)
@@ -17,6 +18,9 @@ install(FILES falco_rules.local.yaml
COMPONENT "${FALCO_COMPONENT}"
DESTINATION "${FALCO_ETC_DIR}"
RENAME "${FALCO_LOCAL_RULES_DEST_FILENAME}")
# Intentionally *not* installing application_rules.yaml. Not needed
# when falco is embedded in other projects.
else()
install(FILES falco_rules.yaml
DESTINATION "${FALCO_ETC_DIR}"
@@ -25,5 +29,9 @@ install(FILES falco_rules.yaml
install(FILES falco_rules.local.yaml
DESTINATION "${FALCO_ETC_DIR}"
RENAME "${FALCO_LOCAL_RULES_DEST_FILENAME}")
install(FILES application_rules.yaml
DESTINATION "${FALCO_ETC_DIR}"
RENAME "${FALCO_APP_RULES_DEST_FILENAME}")
endif()

View File

@@ -0,0 +1,169 @@
################################################################
# By default all application-related rules are disabled for
# performance reasons. Depending on the application(s) you use,
# uncomment the corresponding rule definitions for
# application-specific activity monitoring.
################################################################
# Elasticsearch ports
- macro: elasticsearch_cluster_port
condition: fd.sport=9300
- macro: elasticsearch_api_port
condition: fd.sport=9200
- macro: elasticsearch_port
condition: elasticsearch_cluster_port or elasticsearch_api_port
# - rule: Elasticsearch unexpected network inbound traffic
# desc: inbound network traffic to elasticsearch on a port other than the standard ports
# condition: user.name = elasticsearch and inbound and not elasticsearch_port
# output: "Inbound network traffic to Elasticsearch on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Elasticsearch unexpected network outbound traffic
# desc: outbound network traffic from elasticsearch on a port other than the standard ports
# condition: user.name = elasticsearch and outbound and not elasticsearch_cluster_port
# output: "Outbound network traffic from Elasticsearch on unexpected port (connection=%fd.name)"
# priority: WARNING
# ActiveMQ ports
- macro: activemq_cluster_port
condition: fd.sport=61616
- macro: activemq_web_port
condition: fd.sport=8161
- macro: activemq_port
condition: activemq_web_port or activemq_cluster_port
# - rule: Activemq unexpected network inbound traffic
# desc: inbound network traffic to activemq on a port other than the standard ports
# condition: user.name = activemq and inbound and not activemq_port
# output: "Inbound network traffic to ActiveMQ on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Activemq unexpected network outbound traffic
# desc: outbound network traffic from activemq on a port other than the standard ports
# condition: user.name = activemq and outbound and not activemq_cluster_port
# output: "Outbound network traffic from ActiveMQ on unexpected port (connection=%fd.name)"
# priority: WARNING
# Cassandra ports
# https://docs.datastax.com/en/cassandra/2.0/cassandra/security/secureFireWall_r.html
- macro: cassandra_thrift_client_port
condition: fd.sport=9160
- macro: cassandra_cql_port
condition: fd.sport=9042
- macro: cassandra_cluster_port
condition: fd.sport=7000
- macro: cassandra_ssl_cluster_port
condition: fd.sport=7001
- macro: cassandra_jmx_port
condition: fd.sport=7199
- macro: cassandra_port
condition: >
cassandra_thrift_client_port or
cassandra_cql_port or cassandra_cluster_port or
cassandra_ssl_cluster_port or cassandra_jmx_port
# - rule: Cassandra unexpected network inbound traffic
# desc: inbound network traffic to cassandra on a port other than the standard ports
# condition: user.name = cassandra and inbound and not cassandra_port
# output: "Inbound network traffic to Cassandra on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Cassandra unexpected network outbound traffic
# desc: outbound network traffic from cassandra on a port other than the standard ports
# condition: user.name = cassandra and outbound and not (cassandra_ssl_cluster_port or cassandra_cluster_port)
# output: "Outbound network traffic from Cassandra on unexpected port (connection=%fd.name)"
# priority: WARNING
# Couchdb ports
# https://github.com/davisp/couchdb/blob/master/etc/couchdb/local.ini
- macro: couchdb_httpd_port
condition: fd.sport=5984
- macro: couchdb_httpd_ssl_port
condition: fd.sport=6984
# xxx can't tell what clustering ports are used. not writing rules for this
# yet.
# Fluentd ports
- macro: fluentd_http_port
condition: fd.sport=9880
- macro: fluentd_forward_port
condition: fd.sport=24224
# - rule: Fluentd unexpected network inbound traffic
# desc: inbound network traffic to fluentd on a port other than the standard ports
# condition: user.name = td-agent and inbound and not (fluentd_forward_port or fluentd_http_port)
# output: "Inbound network traffic to Fluentd on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Tdagent unexpected network outbound traffic
# desc: outbound network traffic from fluentd on a port other than the standard ports
# condition: user.name = td-agent and outbound and not fluentd_forward_port
# output: "Outbound network traffic from Fluentd on unexpected port (connection=%fd.name)"
# priority: WARNING
# Gearman ports
# http://gearman.org/protocol/
# - rule: Gearman unexpected network outbound traffic
# desc: outbound network traffic from gearman on a port other than the standard ports
# condition: user.name = gearman and outbound and outbound and not fd.sport = 4730
# output: "Outbound network traffic from Gearman on unexpected port (connection=%fd.name)"
# priority: WARNING
# Zookeeper
- macro: zookeeper_port
condition: fd.sport = 2181
# Kafka ports
# - rule: Kafka unexpected network inbound traffic
# desc: inbound network traffic to kafka on a port other than the standard ports
# condition: user.name = kafka and inbound and fd.sport != 9092
# output: "Inbound network traffic to Kafka on unexpected port (connection=%fd.name)"
# priority: WARNING
# Memcached ports
# - rule: Memcached unexpected network inbound traffic
# desc: inbound network traffic to memcached on a port other than the standard ports
# condition: user.name = memcached and inbound and fd.sport != 11211
# output: "Inbound network traffic to Memcached on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Memcached unexpected network outbound traffic
# desc: any outbound network traffic from memcached. memcached never initiates outbound connections.
# condition: user.name = memcached and outbound
# output: "Unexpected Memcached outbound connection (connection=%fd.name)"
# priority: WARNING
# MongoDB ports
- macro: mongodb_server_port
condition: fd.sport = 27017
- macro: mongodb_shardserver_port
condition: fd.sport = 27018
- macro: mongodb_configserver_port
condition: fd.sport = 27019
- macro: mongodb_webserver_port
condition: fd.sport = 28017
# - rule: Mongodb unexpected network inbound traffic
# desc: inbound network traffic to mongodb on a port other than the standard ports
# condition: >
# user.name = mongodb and inbound and not (mongodb_server_port or
# mongodb_shardserver_port or mongodb_configserver_port or mongodb_webserver_port)
# output: "Inbound network traffic to MongoDB on unexpected port (connection=%fd.name)"
# priority: WARNING
# MySQL ports
# - rule: Mysql unexpected network inbound traffic
# desc: inbound network traffic to mysql on a port other than the standard ports
# condition: user.name = mysql and inbound and fd.sport != 3306
# output: "Inbound network traffic to MySQL on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: HTTP server unexpected network inbound traffic
# desc: inbound network traffic to a http server program on a port other than the standard ports
# condition: proc.name in (http_server_binaries) and inbound and fd.sport != 80 and fd.sport != 443
# output: "Inbound network traffic to HTTP Server on unexpected port (connection=%fd.name)"
# priority: WARNING

View File

@@ -41,10 +41,10 @@
- macro: bin_dir_mkdir
condition: >
evt.arg[0] startswith /bin/ or
evt.arg[0] startswith /sbin/ or
evt.arg[0] startswith /usr/bin/ or
evt.arg[0] startswith /usr/sbin/
(evt.arg[1] startswith /bin/ or
evt.arg[1] startswith /sbin/ or
evt.arg[1] startswith /usr/bin/ or
evt.arg[1] startswith /usr/sbin/)
- macro: bin_dir_rename
condition: >
@@ -54,7 +54,7 @@
evt.arg[1] startswith /usr/sbin/
- macro: etc_dir
condition: fd.name startswith /etc
condition: fd.name startswith /etc/
# This detects writes immediately below / or any write anywhere below /root
- macro: root_dir
@@ -156,10 +156,10 @@
items: [chef-client]
- list: http_server_binaries
items: [nginx, httpd, httpd-foregroun, lighttpd]
items: [nginx, httpd, httpd-foregroun, lighttpd, apache, apache2]
- list: db_server_binaries
items: [mysqld]
items: [mysqld, postgres, sqlplus]
- list: mysql_mgmt_binaries
items: [mysql_install_d, mysql_ssl_rsa_s]
@@ -170,6 +170,9 @@
- list: db_mgmt_binaries
items: [mysql_mgmt_binaries, postgres_mgmt_binaries]
- list: nosql_server_binaries
items: [couchdb, memcached, redis-server, rabbitmq-server, mongod]
- list: gitlab_binaries
items: [gitlab-shell, gitlab-mon, gitlab-runner-b, git]
@@ -180,7 +183,7 @@
# interpreted by the filter expression.
- list: rpm_binaries
items: [dnf, rpm, rpmkey, yum, '"75-system-updat"', rhsmcertd-worke, subscription-ma,
repoquery, rpmkeys]
repoquery, rpmkeys, rpmq]
- macro: rpm_procs
condition: proc.name in (rpm_binaries)
@@ -194,11 +197,14 @@
# The truncated dpkg-preconfigu is intentional, process names are
# truncated at the sysdig level.
- list: package_mgmt_binaries
items: [rpm_binaries, deb_binaries, update-alternat, gem, pip]
items: [rpm_binaries, deb_binaries, update-alternat, gem, pip, sane-utils.post]
- macro: package_mgmt_procs
condition: proc.name in (package_mgmt_binaries)
- macro: run_by_package_mgmt_binaries
condition: proc.aname in (package_mgmt_binaries, needrestart)
- list: ssl_mgmt_binaries
items: [ca-certificates]
@@ -236,7 +242,7 @@
items: [nxexec, nxnode.bin, nxserver.bin, nxclient.bin]
- list: x2go_binaries
items: [x2gosuspend-age, x2goagent]
items: [x2gosuspend-age, x2goagent, x2gomountdirs]
- list: nids_binaries
items: [bro, broctl]
@@ -251,7 +257,7 @@
items: [
sendmail, sendmail-msp, postfix, procmail, exim4,
pickup, showq, mailq, dovecot, imap-login, imap,
mailmng-core, pop3-login, dovecot-lda
mailmng-core, pop3-login, dovecot-lda, pop3
]
- list: mail_config_binaries
@@ -354,6 +360,9 @@
- macro: ansible_running_python
condition: (proc.name in (python, pypy) and proc.cmdline contains ansible)
- macro: chef_running_yum_dump
condition: (proc.name=python and proc.cmdline contains yum-dump.py)
- macro: parent_beam_running_python
condition: proc.pcmdline="python pipeline.py -c conf.json"
@@ -372,6 +381,9 @@
- macro: parent_python_running_zookeeper
condition: (proc.pcmdline startswith "python /usr/local/bin/cub")
- macro: parent_python_running_airflow
condition: (proc.pname in (python,/usr/bin/python) and proc.cmdline startswith "bash -c airflow")
- macro: parent_docker_start_script
condition: (proc.pcmdline="start.sh /opt/docker/conf/start.sh")
@@ -391,8 +403,11 @@
- macro: parent_java_running_jenkins
condition: >
(proc.pname=java and proc.pcmdline contains jenkins.war
or proc.pcmdline contains /tmp/slave.jar)
(proc.pname=java and
(proc.pcmdline contains jenkins.war or
proc.pcmdline contains "-cp /jenkins/maven" or
proc.pcmdline contains /tmp/slave.jar or
proc.pcmdline contains /mnt/mesos/sandbox/slave.jar))
- macro: parent_java_running_maven
condition: >
@@ -414,6 +429,8 @@
- macro: jenkins_scripts
condition: (proc.pcmdline startswith "script.sh -xe /var/jenkins_home" or
proc.pcmdline startswith "node /jenkins/workspace" or
proc.pcmdline startswith "python /home/jenkins/workspace" or
proc.cmdline="bash /usr/local/bin/jenkins-slave")
- macro: parent_java_running_echo
@@ -437,6 +454,9 @@
proc.cmdline startswith "sh -c /var/www/edi/bin/sftp.sh" or
proc.cmdline startswith "sh -c /usr/src/app/crxlsx/bin/linux/crxlsx" or
proc.cmdline startswith "sh -c make parent" or
proc.cmdline startswith "node /jenkins/tools" or
proc.cmdline startswith "sh -c '/usr/bin/node'" or
proc.cmdline startswith "sh -c stty -a |" or
proc.pcmdline startswith "node /opt/nodejs/bin/yarn" or
proc.pcmdline startswith "node /usr/local/bin/yarn" or
proc.pcmdline startswith "node /root/.config/yarn" or
@@ -450,6 +470,9 @@
proc.pcmdline startswith "node /usr/local/nodejs/bin/npm" or
proc.pcmdline startswith "node /opt/rh/rh-nodejs6/root/usr/bin/npm")
- macro: parent_npm_running_node
condition: (proc.pname=node and proc.aname[2]=npm)
- macro: parent_nginx_running_serf
condition: (proc.pname=nginx and proc.cmdline startswith "sh -c serf")
@@ -459,6 +482,9 @@
- macro: mysql_image_running_healthcheck
condition: container.image=mysql and proc.cmdline="sh -c /healthcheck.sh"
- macro: parent_rancher_running_healthcheck
condition: (proc.pname=healthcheck and (proc.aname[2]=tini or proc.aname[3]=tini))
- macro: bundle_running_ruby
condition: >
((proc.pname in (ruby,ruby2.1) or proc.pname contains ".rb") and (
@@ -504,7 +530,8 @@
# Chef is similar.
- macro: run_by_chef
condition: (proc.aname[2]=chef_command_wr or proc.aname[3]=chef_command_wr or
proc.aname[2]=chef-client or proc.aname[3]=chef-client)
proc.aname[2]=chef-client or proc.aname[3]=chef-client or
proc.name=chef-client)
- macro: run_by_adclient
condition: (proc.aname[2]=adclient or proc.aname[3]=adclient or proc.aname[4]=adclient)
@@ -521,7 +548,8 @@
- macro: run_by_passenger_agent
condition: ((proc.pname=ruby and proc.aname[2]=PassengerAgent) or
proc.pcmdline startswith "ruby /usr/share/passenger/helper-scripts/rack-preloader.rb" or
proc.pcmdline startswith "ruby /usr/local/bundle/bin/passenger")
proc.pcmdline startswith "ruby /usr/local/bundle/bin/passenger" or
proc.pcmdline startswith "ruby /usr/local/bin/passenger")
# Also handles running semi-indirectly via scl
- macro: run_by_foreman
@@ -541,12 +569,12 @@
- macro: java_running_sdjagent
condition: proc.name=java and proc.cmdline contains sdjagent.jar
- macro: kubelet_running_loopback
condition: (proc.pname=kubelet and proc.name=loopback)
- macro: parent_java_running_confluence
condition: (proc.pname=java and proc.pcmdline contains "-classpath /opt/atlassian/confluence")
- macro: parent_java_running_tomcat
condition: (proc.pname=java and proc.pcmdline contains "-classpath /usr/local/tomcat")
- macro: parent_java_running_install4j
condition: (proc.pname=java and proc.pcmdline contains "-classpath i4jruntime.jar")
@@ -556,6 +584,9 @@
- macro: python_mesos_healthcheck
condition: (proc.pcmdline startswith "python /mesoshealthcheck.py")
- macro: python_mesos_marathon_scripting
condition: (proc.pcmdline startswith "python3 /marathon-lb/marathon_lb.py")
- macro: parent_running_datastax
condition: ((proc.pname=java and proc.pcmdline contains "-jar datastax-agent") or
(proc.pcmdline startswith "nodetool /opt/dse/bin/"))
@@ -566,6 +597,9 @@
- macro: parent_supervise_running_multilog
condition: (proc.name=multilog and proc.pname=supervise)
- macro: supervise_writing_status
condition: (proc.name in (supervise,svc) and fd.name startswith "/etc/sb/")
- macro: parent_ruby_running_discourse
condition: (proc.pcmdline startswith "ruby /var/www/discourse/vendor/bundle/ruby")
@@ -584,13 +618,35 @@
- macro: ovsdb_writing_openvswitch
condition: (proc.name=ovsdb-server and fd.directory=/etc/openvswitch)
- macro: perl_running_plesk
condition: (proc.cmdline startswith "perl /opt/psa/admin/bin/plesk_agent_manager" or
proc.pcmdline startswith "perl /opt/psa/admin/bin/plesk_agent_manager")
- macro: plesk_autoinstaller
condition: (proc.pname=autoinstaller and proc.aname[2]=sw-engine)
- macro: parent_perl_running_openresty
condition: (proc.pcmdline startswith "perl /usr/local/openresty/bin")
- macro: parent_ucf_writing_conf
condition: (proc.pname=ucf and fd.name startswith "/etc/gconf")
- macro: consul_template_writing_conf
condition: (proc.name=consul-template and fd.name startswith /etc/haproxy)
- macro: countly_writing_nginx_conf
condition: (proc.cmdline startswith "nodejs /opt/countly/bin" and fd.name startswith /etc/nginx)
- macro: exe_running_docker_save
condition: (container and proc.cmdline startswith "exe /var/lib/docker" and proc.pname in (dockerd, docker))
###############
# General Rules
###############
- rule: Write below binary dir
desc: an attempt to write to any file below a set of binary directories
condition: bin_dir and evt.dir = < and open_write and not package_mgmt_procs
condition: bin_dir and evt.dir = < and open_write and not package_mgmt_procs and not exe_running_docker_save
output: >
File below a known binary directory opened for writing (user=%user.name
command=%proc.cmdline file=%fd.name)
@@ -632,19 +688,48 @@
condition: (proc.name=update-xmlcatal and fd.directory=/etc/xml)
- macro: datadog_writing_conf
condition: (proc.cmdline startswith "python /opt/datadog-agent"
condition: ((proc.cmdline startswith "python /opt/datadog-agent" or
proc.cmdline startswith "entrypoint.sh /entrypoint.sh datadog start" or
proc.cmdline startswith "agent.py /opt/datadog-agent")
and fd.name startswith "/etc/dd-agent")
- macro: curl_writing_pki_db
condition: (proc.name=curl and fd.directory=/etc/pki/nssdb)
- macro: haproxy_writing_conf
condition: ((proc.name=update-haproxy- or proc.pname=update-haproxy-)
and fd.name in (/etc/openvpn/client.map, /etc/haproxy/client.map-))
condition: ((proc.name in (update-haproxy-,haproxy_reload.) or proc.pname=update-haproxy-)
and fd.name=/etc/openvpn/client.map or fd.directory=/etc/haproxy)
- macro: java_writing_conf
condition: (proc.name=java and fd.name=/etc/.java/.systemPrefs/.system.lock)
- macro: rabbitmq_writing_conf
condition: (proc.name=rabbitmq-server and fd.directory=/etc/rabbitmq)
- macro: rook_writing_conf
condition: (proc.name=toolbox.sh and container.image startswith rook/toolbox
and fd.directory=/etc/ceph)
- macro: httpd_writing_conf_logs
condition: (proc.name=httpd and fd.name startswith /etc/httpd/)
- macro: mysql_writing_conf
condition: ((proc.name=start-mysql.sh or proc.pname=start-mysql.sh) and fd.name startswith /etc/mysql)
- macro: openvpn_writing_conf
condition: (proc.name=openvpn and fd.directory=/etc/openvpn)
- macro: php_handlers_writing_conf
condition: (proc.name=php_handlers_co and fd.name=/etc/psa/php_versions.json)
- macro: cron_sed_writing_temp_file
condition: (proc.aname[3]=cron_start.sh and fd.name startswith /etc/security/sed)
# In some cases dpkg-reconfigur runs commands that modify /etc. Not
# putting the full set of package management programs yet.
- macro: dpkg_scripting
condition: (proc.aname[2] in (dpkg-reconfigur, dpkg-preconfigu))
# Add conditions to this macro (probably in a separate file,
# overwriting this macro) to allow for specific combinations of
# programs writing below specific directories below
@@ -674,9 +759,10 @@
qualys-cloud-ag, locales.postins, nomachine_binaries,
adclient, certutil, crlutil, pam-auth-update, parallels_insta,
openshift-launc)
and not proc.pname in (sysdigcloud_binaries, mail_config_binaries, hddtemp.postins, sshkit_script_binaries, locales.postins)
and not proc.pname in (sysdigcloud_binaries, mail_config_binaries, hddtemp.postins, sshkit_script_binaries, locales.postins, deb_binaries)
and not fd.name pmatch (safe_etc_dirs)
and not fd.name in (/etc/container_environment.sh, /etc/container_environment.json, /etc/motd, /etc/motd.svc)
and not exe_running_docker_save
and not ansible_running_python
and not python_running_denyhosts
and not fluentd_writing_conf_files
@@ -694,6 +780,7 @@
and not duply_writing_exclude_files
and not xmlcatalog_writing_files
and not parent_supervise_running_multilog
and not supervise_writing_status
and not pki_realm_writing_realms
and not htpasswd_writing_passwd
and not dmeventd_writing_lvm_archive
@@ -702,6 +789,17 @@
and not curl_writing_pki_db
and not haproxy_writing_conf
and not java_writing_conf
and not dpkg_scripting
and not parent_ucf_writing_conf
and not rabbitmq_writing_conf
and not rook_writing_conf
and not php_handlers_writing_conf
and not cron_sed_writing_temp_file
and not httpd_writing_conf_logs
and not mysql_writing_conf
and not openvpn_writing_conf
and not consul_template_writing_conf
and not countly_writing_nginx_conf
- rule: Write below etc
desc: an attempt to write to any file below /etc, not in a pipe installer session
@@ -711,13 +809,26 @@
tags: [filesystem]
- list: known_root_files
items: [/root/.monit.state]
items: [/root/.monit.state, /root/.auth_tokens, /root/.bash_history, /root/.aws/credentials,
/root/.viminfo.tmp, /root/.lesshst, /root/.bzr.log, /root/.gitconfig.lock]
- list: known_root_directories
items: [/root/.oracle_jre_usage, /root/.java/.userPrefs, /root/.ssh, /root/.cache]
items: [/root/.oracle_jre_usage, /root/.ssh]
- macro: known_root_conditions
condition: (fd.name startswith /root/orcexec.)
condition: (fd.name startswith /root/orcexec.
or fd.name startswith /root/.m2
or fd.name startswith /root/.npm
or fd.name startswith /root/.pki
or fd.name startswith /root/.ivy2
or fd.name startswith /root/.config/Cypress
or fd.name startswith /root/.config/pulse
or fd.name startswith /root/jenkins/workspace
or fd.name startswith /root/.jenkins
or fd.name startswith /root/.cache
or fd.name startswith /root/.sbt
or fd.name startswith /root/.java
or fd.name startswith /root/.sonar)
- rule: Write below root
desc: an attempt to write to any file directly below / or /root
@@ -725,6 +836,7 @@
root_dir and evt.dir = < and open_write
and not fd.name in (known_root_files)
and not fd.directory in (known_root_directories)
and not exe_running_docker_save
and not known_root_conditions
output: "File below / or /root opened for writing (user=%user.name command=%proc.cmdline parent=%proc.pname file=%fd.name name=%proc.name)"
priority: ERROR
@@ -791,6 +903,7 @@
and not run_by_qualys
and not run_by_chef
and not user_read_sensitive_file_conditions
and not perl_running_plesk
output: >
Sensitive file opened for reading by non-trusted program (user=%user.name name=%proc.name
command=%proc.cmdline file=%fd.name parent=%proc.pname gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4])
@@ -800,7 +913,7 @@
# Only let rpm-related programs write to the rpm database
- rule: Write below rpm database
desc: an attempt to write to the rpm database by any non-rpm related program
condition: fd.name startswith /var/lib/rpm and open_write and not rpm_procs and not ansible_running_python
condition: fd.name startswith /var/lib/rpm and open_write and not rpm_procs and not ansible_running_python and not chef_running_yum_dump
output: "Rpm database opened for writing by a non-rpm program (command=%proc.cmdline file=%fd.name)"
priority: ERROR
tags: [filesystem, software_mgmt]
@@ -864,6 +977,7 @@
and not proc.name startswith "runc:"
and not proc.pname in (sysdigcloud_binaries)
and not java_running_sdjagent
and not kubelet_running_loopback
output: >
Namespace change (setns) by unexpected program (user=%user.name command=%proc.cmdline
parent=%proc.pname %container.info)
@@ -886,64 +1000,109 @@
nginx_control, mailmng-service, web_statistic_e, statistics_coll, install-info,
hawkular-metric, rhsmcertd-worke, parted, amuled, fluentd, x2gormforward,
parallels_insta, salt-minion, dnsmng, update-inetd, pum_worker, awstats_buildst,
tsvuln, 50plesk-daily, grubby, chkconfig, dracut-install, rhnsd, find, consul
tsvuln, 50plesk-daily, grubby, chkconfig, dracut-install, rhnsd, find, consul,
doxygen, Cypress, consul-template, xargs, scl, awstats_updatea, sa-update,
mysql_upgrade, opkg-cl, vmtoolsd, confd
]
- rule: Run shell untrusted
desc: an attempt to spawn a shell by a non-shell program. Exceptions are made for trusted binaries.
# The binaries in this list and their descendents are *not* allowed
# spawn shells. This includes the binaries spawning shells directly as
# well as indirectly. For example, apache -> php/perl for
# mod_{php,perl} -> some shell is also not allowed, because the shell
# has apache as an ancestor.
- list: protected_shell_spawning_binaries
items: [
http_server_binaries, db_server_binaries, nosql_server_binaries, mail_binaries,
fluentd, flanneld, splunkd, consul, runsv
]
- macro: parent_java_running_zookeeper
condition: (proc.pname=java and proc.pcmdline contains org.apache.zookeeper.server)
- macro: parent_java_running_kafka
condition: (proc.pname=java and proc.pcmdline contains kafka.Kafka)
- macro: parent_java_running_elasticsearch
condition: (proc.pname=java and proc.pcmdline contains org.elasticsearch.bootstrap.Elasticsearch)
- macro: parent_java_running_activemq
condition: (proc.pname=java and proc.pcmdline contains activemq.jar)
- macro: parent_java_running_cassandra
condition: (proc.pname=java and proc.pcmdline contains org.apache.cassandra.service.CassandraDaemon)
- macro: parent_java_running_jboss_wildfly
condition: (proc.pname=java and proc.pcmdline contains org.jboss)
- macro: parent_java_running_glassfish
condition: (proc.pname=java and proc.pcmdline contains com.sun.enterprise.glassfish)
- macro: parent_java_running_hadoop
condition: (proc.pname=java and proc.pcmdline contains org.apache.hadoop)
- macro: parent_java_running_datastax
condition: (proc.pname=java and proc.pcmdline contains com.datastax)
- macro: parent_java_running_sumologic
condition: (proc.pname=java and proc.pcmdline contains com.sumologic)
- macro: nginx_starting_nginx
condition: (proc.pname=nginx and proc.cmdline contains "/usr/sbin/nginx -c /etc/nginx/nginx.conf")
- macro: consul_running_curl
condition: (proc.pname=consul and proc.cmdline startswith "sh -c curl")
- macro: serf_script
condition: (proc.cmdline startswith "sh -c serf")
- macro: check_process_status
condition: (proc.cmdline startswith "sh -c kill -0 ")
- macro: protected_shell_spawner
condition: >
spawned_process and not container
(proc.aname in (protected_shell_spawning_binaries)
or parent_java_running_zookeeper
or parent_java_running_kafka
or parent_java_running_elasticsearch
or parent_java_running_activemq
or parent_java_running_cassandra
or parent_java_running_jboss_wildfly
or parent_java_running_glassfish
or parent_java_running_hadoop
or parent_java_running_datastax)
# Note that runsv is both in protected_shell_spawner and the
# exclusions by pname. This means that runsv can itself spawn shells
# (the ./run and ./finish scripts), but the processes runsv can not
# spawn shells.
- rule: Run shell untrusted
desc: an attempt to spawn a shell below a non-shell application. Specific applications are monitored.
condition: >
spawned_process
and shell_procs
and proc.pname exists
and not proc.pname in (cron_binaries, shell_binaries, make_binaries, known_shell_spawn_binaries, docker_binaries,
k8s_binaries, package_mgmt_binaries, aide_wrapper_binaries, nids_binaries,
monitoring_binaries, gitlab_binaries, mesos_slave_binaries,
keepalived_binaries,
needrestart_binaries, phusion_passenger_binaries, chef_binaries, nomachine_binaries,
x2go_binaries, db_mgmt_binaries, plesk_binaries)
and not parent_ansible_running_python
and not parent_bro_running_python
and not parent_python_running_denyhosts
and not parent_python_running_sdchecks
and not parent_linux_image_upgrade_script
and not parent_java_running_jenkins
and protected_shell_spawner
and not proc.pname in (shell_binaries, gitlab_binaries, cron_binaries, user_known_shell_spawn_binaries,
erl_child_setup, exechealthz,
PM2, PassengerWatchd, c_rehash, svlogd, logrotate, hhvm, serf,
lb-controller, nvidia-installe, runsv, statsite)
and not proc.cmdline in (known_shell_spawn_cmdlines)
and not jenkins_scripts
and not parent_java_running_echo
and not parent_scripting_running_builds
and not makefile_perl
and not parent_Xvfb_running_xkbcomp
and not parent_nginx_running_serf
and not parent_node_running_npm
and not parent_java_running_sbt
and not parent_beam_running_python
and not parent_strongswan_running_starter
and not run_by_chef
and not run_by_puppet
and not run_by_adclient
and not run_by_centrify
and not parent_dovecot_running_auth
and not proc.aname in (unicorn_launche)
and not consul_running_curl
and not nginx_starting_nginx
and not run_by_package_mgmt_binaries
and not serf_script
and not check_process_status
and not run_by_foreman
and not run_by_openshift
and not parent_java_running_tomcat
and not parent_java_running_install4j
and not parent_java_running_endeca
and not parent_running_datastax
and not parent_java_running_appdynamics
and not parent_cpanm_running_perl
and not parent_ruby_running_discourse
and not parent_ruby_running_pups
and not assemble_running_php
and not node_running_bitnami
and not node_running_threatstack
and not parent_python_running_localstack
and not parent_python_running_zookeeper
and not python_mesos_marathon_scripting
and not user_shell_container_exclusions
output: >
Shell spawned by untrusted binary (user=%user.name shell=%proc.name parent=%proc.pname
cmdline=%proc.cmdline pcmdline=%proc.pcmdline gparent=%proc.aname[2] ggparent=%proc.aname[3]
gggparent=%proc.aname[4] ggggparent=%proc.aname[5])
priority: DEBUG
tags: [host, shell]
tags: [shell]
- macro: trusted_containers
condition: (container.image startswith sysdig/agent or
@@ -954,7 +1113,17 @@
container.image startswith gcr.io/google_containers/hyperkube or
container.image startswith quay.io/coreos/flannel or
container.image startswith gcr.io/google_containers/kube-proxy or
container.image startswith calico/node)
container.image startswith calico/node or
container.image startswith rook/toolbox)
# Add conditions to this macro (probably in a separate file,
# overwriting this macro) to specify additional containers that are
# trusted and therefore allowed to run privileged.
#
# In this file, it just takes one of the images in trusted_containers
# and repeats it.
- macro: user_trusted_containers
condition: (container.image startswith sysdig/agent)
# Add conditions to this macro (probably in a separate file,
# overwriting this macro) to specify additional containers that are
@@ -975,7 +1144,11 @@
- rule: Launch Privileged Container
desc: Detect the initial process started in a privileged container. Exceptions are made for known trusted images.
condition: evt.type=execve and proc.vpid=1 and container and container.privileged=true and not trusted_containers
condition: >
evt.type=execve and proc.vpid=1 and container
and container.privileged=true
and not trusted_containers
and not user_trusted_containers
output: Privileged container started (user=%user.name command=%proc.cmdline %container.info image=%container.image)
priority: INFO
tags: [container, cis]
@@ -1003,7 +1176,7 @@
# when we lose events and lose track of state.
- macro: container_entrypoint
condition: (not proc.pname exists or proc.pname in (runc:[0:PARENT], runc:[1:CHILD], docker-runc))
condition: (not proc.pname exists or proc.pname in (runc:[0:PARENT], runc:[1:CHILD], docker-runc, exe))
- rule: Launch Sensitive Mount Container
desc: >
@@ -1052,11 +1225,11 @@
tags: [users]
- rule: Terminal shell in container
desc: A shell was spawned by a program in a container with an attached terminal.
desc: A shell was used as the entrypoint/exec point into a container with an attached terminal.
condition: >
spawned_process and container
and shell_procs and proc.tty != 0
and not proc.cmdline in (known_shell_spawn_cmdlines)
and container_entrypoint
output: >
A shell was spawned in a container with an attached terminal (user=%user.name %container.info
shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline terminal=%proc.tty)
@@ -1116,7 +1289,10 @@
'"bash /opt/docker/bin/lar"',
'"bash /opt/docker/bin/irs"',
'"bash /opt/docker/bin/brs"',
'"bash /opt/docker/bin/hdi"'
'"bash /opt/docker/bin/hdi"',
'"bash /opt/docker/bin/hdi "',
'"bash /home/entrypoint.sh"',
'"bash /tmp/bootstrap.sh"'
]
# This list allows for easy additions to the set of commands allowed
@@ -1124,7 +1300,7 @@
# and override the entire run shell in container macro. Once
# https://github.com/draios/falco/issues/255 is fixed this will be a
# bit easier, as someone could append of any of the existing lists.
- list: user_known_container_shell_spawn_binaries
- list: user_known_shell_spawn_binaries
items: []
# This macro allows for easy additions to the set of commands allowed
@@ -1140,79 +1316,18 @@
(proc.pname=node and (proc.pcmdline contains /var/www/edi/process.js or
proc.pcmdline contains "sh -c /var/www/edi/bin/sftp.sh"))
- rule: Run shell in container
desc: a shell was spawned by a non-shell program in a container. Container entrypoints are excluded.
condition: >
spawned_process and container
and shell_procs
and not container_entrypoint
and not proc.pname in (shell_binaries, make_binaries, docker_binaries, k8s_binaries, package_mgmt_binaries,
lxd_binaries, mesos_slave_binaries, aide_wrapper_binaries, nids_binaries,
cron_binaries,
user_known_container_shell_spawn_binaries,
needrestart_binaries,
phusion_passenger_binaries,
chef_binaries,
nomachine_binaries,
x2go_binaries,
db_mgmt_binaries,
plesk_binaries,
monitoring_binaries, gitlab_binaries, initdb, awk, falco, cron,
erl_child_setup, erlexec, ceph, PM2, pycompile, py3compile, hhvm, npm, serf,
runsv, supervisord, varnishd, crond, logrotate, timeout, tini,
xrdb, xfce4-session, weave, logdna-agent, bundle, configure, luajit, nginx,
beam.smp, paster, postfix-local, hawkular-metric, fluentd, x2gormforward,
"[celeryd:", flock, nsrun, consul)
and not trusted_containers
and not shell_spawning_containers
and not parent_java_running_echo
and not parent_scripting_running_builds
and not makefile_perl
and not parent_Xvfb_running_xkbcomp
and not mysql_image_running_healthcheck
and not parent_nginx_running_serf
and not proc.cmdline in (known_container_shell_spawn_cmdlines)
and not parent_node_running_npm
and not user_shell_container_exclusions
and not node_running_edi_dynamodb
and not run_by_h2o
and not run_by_passenger_agent
and not parent_java_running_jenkins
and not parent_java_running_maven
and not parent_java_running_appdynamics
and not python_running_es_curator
and not parent_beam_running_python
and not jenkins_scripts
and not bundle_running_ruby
and not parent_dovecot_running_auth
and not parent_strongswan_running_starter
and not parent_phusion_passenger_my_init
and not parent_java_running_confluence
and not parent_java_running_tomcat
and not parent_java_running_install4j
and not parent_running_datastax
and not ics_running_java
and not parent_ruby_running_discourse
and not parent_ruby_running_pups
and not assemble_running_php
and not node_running_bitnami
and not node_running_threatstack
and not parent_python_running_localstack
and not parent_python_running_zookeeper
and not parent_docker_start_script
and not parent_java_running_endeca
and not python_mesos_healthcheck
output: >
Shell spawned in a container other than entrypoint (user=%user.name %container.info image=%container.image
shell=%proc.name pcmdline=%proc.pcmdline cmdline=%proc.cmdline parent=%proc.pname gparent=%proc.aname[2] ggparent=%proc.aname[3])
priority: DEBUG
tags: [container, shell]
- macro: login_doing_dns_lookup
condition: (proc.name=login and fd.l4proto=udp and fd.sport=53)
# sockfamily ip is to exclude certain processes (like 'groups') that communicate on unix-domain sockets
# systemd can listen on ports to launch things like sshd on demand
- rule: System procs network activity
desc: any network activity performed by system binaries that are not expected to send or receive any network traffic
condition: (fd.sockfamily = ip and system_procs) and (inbound or outbound) and not proc.name in (systemd, hostid)
condition: >
(fd.sockfamily = ip and system_procs)
and (inbound or outbound)
and not proc.name in (systemd, hostid)
and not login_doing_dns_lookup
output: >
Known system binary sent/received network traffic
(user=%user.name command=%proc.cmdline connection=%fd.name)
@@ -1356,172 +1471,6 @@
# Application-Related Rules
###########################
################################################################
# By default all application-related rules are disabled for
# performance reasons. Depending on the application(s) you use,
# uncomment the corresponding rule definitions for
# application-specific activity monitoring.
################################################################
# Moved to application_rules.yaml. Please look there if you want to
# enable them by adding to falco_rules.local.yaml.
# Elasticsearch ports
- macro: elasticsearch_cluster_port
condition: fd.sport=9300
- macro: elasticsearch_api_port
condition: fd.sport=9200
- macro: elasticsearch_port
condition: elasticsearch_cluster_port or elasticsearch_api_port
# - rule: Elasticsearch unexpected network inbound traffic
# desc: inbound network traffic to elasticsearch on a port other than the standard ports
# condition: user.name = elasticsearch and inbound and not elasticsearch_port
# output: "Inbound network traffic to Elasticsearch on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Elasticsearch unexpected network outbound traffic
# desc: outbound network traffic from elasticsearch on a port other than the standard ports
# condition: user.name = elasticsearch and outbound and not elasticsearch_cluster_port
# output: "Outbound network traffic from Elasticsearch on unexpected port (connection=%fd.name)"
# priority: WARNING
# ActiveMQ ports
- macro: activemq_cluster_port
condition: fd.sport=61616
- macro: activemq_web_port
condition: fd.sport=8161
- macro: activemq_port
condition: activemq_web_port or activemq_cluster_port
# - rule: Activemq unexpected network inbound traffic
# desc: inbound network traffic to activemq on a port other than the standard ports
# condition: user.name = activemq and inbound and not activemq_port
# output: "Inbound network traffic to ActiveMQ on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Activemq unexpected network outbound traffic
# desc: outbound network traffic from activemq on a port other than the standard ports
# condition: user.name = activemq and outbound and not activemq_cluster_port
# output: "Outbound network traffic from ActiveMQ on unexpected port (connection=%fd.name)"
# priority: WARNING
# Cassandra ports
# https://docs.datastax.com/en/cassandra/2.0/cassandra/security/secureFireWall_r.html
- macro: cassandra_thrift_client_port
condition: fd.sport=9160
- macro: cassandra_cql_port
condition: fd.sport=9042
- macro: cassandra_cluster_port
condition: fd.sport=7000
- macro: cassandra_ssl_cluster_port
condition: fd.sport=7001
- macro: cassandra_jmx_port
condition: fd.sport=7199
- macro: cassandra_port
condition: >
cassandra_thrift_client_port or
cassandra_cql_port or cassandra_cluster_port or
cassandra_ssl_cluster_port or cassandra_jmx_port
# - rule: Cassandra unexpected network inbound traffic
# desc: inbound network traffic to cassandra on a port other than the standard ports
# condition: user.name = cassandra and inbound and not cassandra_port
# output: "Inbound network traffic to Cassandra on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Cassandra unexpected network outbound traffic
# desc: outbound network traffic from cassandra on a port other than the standard ports
# condition: user.name = cassandra and outbound and not (cassandra_ssl_cluster_port or cassandra_cluster_port)
# output: "Outbound network traffic from Cassandra on unexpected port (connection=%fd.name)"
# priority: WARNING
# Couchdb ports
# https://github.com/davisp/couchdb/blob/master/etc/couchdb/local.ini
- macro: couchdb_httpd_port
condition: fd.sport=5984
- macro: couchdb_httpd_ssl_port
condition: fd.sport=6984
# xxx can't tell what clustering ports are used. not writing rules for this
# yet.
# Fluentd ports
- macro: fluentd_http_port
condition: fd.sport=9880
- macro: fluentd_forward_port
condition: fd.sport=24224
# - rule: Fluentd unexpected network inbound traffic
# desc: inbound network traffic to fluentd on a port other than the standard ports
# condition: user.name = td-agent and inbound and not (fluentd_forward_port or fluentd_http_port)
# output: "Inbound network traffic to Fluentd on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Tdagent unexpected network outbound traffic
# desc: outbound network traffic from fluentd on a port other than the standard ports
# condition: user.name = td-agent and outbound and not fluentd_forward_port
# output: "Outbound network traffic from Fluentd on unexpected port (connection=%fd.name)"
# priority: WARNING
# Gearman ports
# http://gearman.org/protocol/
# - rule: Gearman unexpected network outbound traffic
# desc: outbound network traffic from gearman on a port other than the standard ports
# condition: user.name = gearman and outbound and outbound and not fd.sport = 4730
# output: "Outbound network traffic from Gearman on unexpected port (connection=%fd.name)"
# priority: WARNING
# Zookeeper
- macro: zookeeper_port
condition: fd.sport = 2181
# Kafka ports
# - rule: Kafka unexpected network inbound traffic
# desc: inbound network traffic to kafka on a port other than the standard ports
# condition: user.name = kafka and inbound and fd.sport != 9092
# output: "Inbound network traffic to Kafka on unexpected port (connection=%fd.name)"
# priority: WARNING
# Memcached ports
# - rule: Memcached unexpected network inbound traffic
# desc: inbound network traffic to memcached on a port other than the standard ports
# condition: user.name = memcached and inbound and fd.sport != 11211
# output: "Inbound network traffic to Memcached on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Memcached unexpected network outbound traffic
# desc: any outbound network traffic from memcached. memcached never initiates outbound connections.
# condition: user.name = memcached and outbound
# output: "Unexpected Memcached outbound connection (connection=%fd.name)"
# priority: WARNING
# MongoDB ports
- macro: mongodb_server_port
condition: fd.sport = 27017
- macro: mongodb_shardserver_port
condition: fd.sport = 27018
- macro: mongodb_configserver_port
condition: fd.sport = 27019
- macro: mongodb_webserver_port
condition: fd.sport = 28017
# - rule: Mongodb unexpected network inbound traffic
# desc: inbound network traffic to mongodb on a port other than the standard ports
# condition: >
# user.name = mongodb and inbound and not (mongodb_server_port or
# mongodb_shardserver_port or mongodb_configserver_port or mongodb_webserver_port)
# output: "Inbound network traffic to MongoDB on unexpected port (connection=%fd.name)"
# priority: WARNING
# MySQL ports
# - rule: Mysql unexpected network inbound traffic
# desc: inbound network traffic to mysql on a port other than the standard ports
# condition: user.name = mysql and inbound and fd.sport != 3306
# output: "Inbound network traffic to MySQL on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: HTTP server unexpected network inbound traffic
# desc: inbound network traffic to a http server program on a port other than the standard ports
# condition: proc.name in (http_server_binaries) and inbound and fd.sport != 80 and fd.sport != 443
# output: "Inbound network traffic to HTTP Server on unexpected port (connection=%fd.name)"
# priority: WARNING

View File

@@ -319,7 +319,7 @@ trace_files: !mux
detect_counts:
- "Write below binary dir": 1
- "Read sensitive file untrusted": 3
- "Run shell in container": 1
- "Run shell untrusted": 1
- "Write below rpm database": 1
- "Write below etc": 1
- "System procs network activity": 1

View File

@@ -43,11 +43,11 @@ traces: !mux
falco-event-generator:
trace_file: traces-positive/falco-event-generator.scap
detect: True
detect_level: [ERROR, WARNING, INFO, NOTICE]
detect_level: [ERROR, WARNING, INFO, NOTICE, DEBUG]
detect_counts:
- "Write below binary dir": 1
- "Read sensitive file untrusted": 3
- "Run shell in container": 1
- "Run shell untrusted": 1
- "Write below rpm database": 1
- "Write below etc": 1
- "System procs network activity": 1
@@ -146,13 +146,6 @@ traces: !mux
detect_counts:
- "Run shell untrusted": 1
shell-in-container:
trace_file: traces-positive/shell-in-container.scap
detect: True
detect_level: DEBUG
detect_counts:
- "Run shell in container": 1
system-binaries-network-activity:
trace_file: traces-positive/system-binaries-network-activity.scap
detect: True