From 653831769f7af819374f15051651eeba5e3ba3c6 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Thu, 16 Nov 2017 17:11:19 -0800 Subject: [PATCH 01/20] 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. --- rules/falco_rules.yaml | 96 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 2 deletions(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index 6ce68f3971c..3176342df2b 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -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] @@ -989,7 +992,84 @@ mysql_upgrade, opkg-cl, vmtoolsd, confd ] +# 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_tomcat + condition: (proc.pname=java and proc.pcmdline contains org.apache.catalina) + +- 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: protected_shell_spawner + condition: > + (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_tomcat + or parent_java_running_datastax) + and (not nginx_starting_nginx) + - 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 protected_shell_spawner + 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: [shell] + +- rule: Run shell untrusted - Old desc: an attempt to spawn a shell by a non-shell program. Exceptions are made for trusted binaries. condition: > spawned_process and not container @@ -1171,6 +1251,18 @@ tags: [users] - rule: Terminal shell in container + 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.pname exists + 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) + priority: NOTICE + tags: [container, shell] + +- rule: Terminal shell in container - Old desc: A shell was spawned by a program in a container with an attached terminal. condition: > spawned_process and container From 98e6ea2746c0d67563aa0bf5ae352372cbc6eb1e Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Thu, 16 Nov 2017 17:58:23 -0800 Subject: [PATCH 02/20] 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. --- docker/event-generator/event_generator.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/docker/event-generator/event_generator.cpp b/docker/event-generator/event_generator.cpp index 3311b6b06df..dd8874c60ca 100644 --- a/docker/event-generator/event_generator.cpp +++ b/docker/event-generator/event_generator.cpp @@ -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 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 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 exclude_from_all_actions = {"exec_ls", "network_activity"}; +set exclude_from_all_actions = {"spawn_shell", "exec_ls", "network_activity"}; void create_symlinks(const char *program) { From bccc8f928e14345b1ec7d00748aef407c847c2f9 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Thu, 16 Nov 2017 18:11:07 -0800 Subject: [PATCH 03/20] Comment out old shell related rules --- rules/falco_rules.yaml | 296 ++++++++++++++++++++--------------------- 1 file changed, 148 insertions(+), 148 deletions(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index 3176342df2b..be014e02352 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1069,66 +1069,66 @@ priority: DEBUG tags: [shell] -- rule: Run shell untrusted - Old - desc: an attempt to spawn a shell by a non-shell program. Exceptions are made for trusted binaries. - condition: > - spawned_process and not container - 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 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_npm_running_node - 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 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 parent_python_running_airflow - and not perl_running_plesk - and not plesk_autoinstaller - and not parent_perl_running_openresty - 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] +# - rule: Run shell untrusted - Old +# desc: an attempt to spawn a shell by a non-shell program. Exceptions are made for trusted binaries. +# condition: > +# spawned_process and not container +# 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 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_npm_running_node +# 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 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 parent_python_running_airflow +# and not perl_running_plesk +# and not plesk_autoinstaller +# and not parent_perl_running_openresty +# 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] - macro: trusted_containers condition: (container.image startswith sysdig/agent or @@ -1262,17 +1262,17 @@ priority: NOTICE tags: [container, shell] -- rule: Terminal shell in container - Old - desc: A shell was spawned by a program in 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) - 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) - priority: NOTICE - tags: [container, shell] +# - rule: Terminal shell in container - Old +# desc: A shell was spawned by a program in 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) +# 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) +# priority: NOTICE +# tags: [container, shell] # For some container types (mesos), there isn't a container image to # work with, and the container name is autogenerated, so there isn't @@ -1354,83 +1354,83 @@ (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, migrate-databas, airflow, bootstrap-qmf-l, - build-qmf-artif, colormake.pl, doxygen, Cypress, lb-controller, vmtoolsd, - haproxy_reload., curator, consul-template, xargs, scl, find, awstats_updatea, - sa-update, mysql_upgrade, opkg-cl, peer-finder, confd, aws) - 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 parent_npm_running_node - 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 parent_java_running_sbt - 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_python_running_airflow - and not parent_docker_start_script - and not parent_java_running_endeca - and not python_mesos_healthcheck - and not python_mesos_marathon_scripting - and not perl_running_plesk - and not parent_rancher_running_healthcheck - and not parent_perl_running_openresty - 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] +# - 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, migrate-databas, airflow, bootstrap-qmf-l, +# build-qmf-artif, colormake.pl, doxygen, Cypress, lb-controller, vmtoolsd, +# haproxy_reload., curator, consul-template, xargs, scl, find, awstats_updatea, +# sa-update, mysql_upgrade, opkg-cl, peer-finder, confd, aws) +# 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 parent_npm_running_node +# 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 parent_java_running_sbt +# 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_python_running_airflow +# and not parent_docker_start_script +# and not parent_java_running_endeca +# and not python_mesos_healthcheck +# and not python_mesos_marathon_scripting +# and not perl_running_plesk +# and not parent_rancher_running_healthcheck +# and not parent_perl_running_openresty +# 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) From 3fe050f571cd7c9ff5a8aaa8fa25a6aef2e4e91c Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Thu, 16 Nov 2017 19:13:48 -0800 Subject: [PATCH 04/20] 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. --- examples/nodejs-bad-rest-api/demo.yml | 4 +--- examples/nodejs-bad-rest-api/run | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) create mode 100755 examples/nodejs-bad-rest-api/run diff --git a/examples/nodejs-bad-rest-api/demo.yml b/examples/nodejs-bad-rest-api/demo.yml index a1f94809d6f..00b45d2c01e 100644 --- a/examples/nodejs-bad-rest-api/demo.yml +++ b/examples/nodejs-bad-rest-api/demo.yml @@ -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: diff --git a/examples/nodejs-bad-rest-api/run b/examples/nodejs-bad-rest-api/run new file mode 100755 index 00000000000..efc6323491b --- /dev/null +++ b/examples/nodejs-bad-rest-api/run @@ -0,0 +1,2 @@ +#!/bin/sh +node server.js From e83444c04f40da6c8599273314a8b8e71d322790 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Fri, 17 Nov 2017 15:02:08 -0800 Subject: [PATCH 05/20] 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. --- rules/falco_rules.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index be014e02352..1ed8e0f2e47 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -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: > From 6f610ed3d916d511a477a40e1ae3d4c42559e39c Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Fri, 17 Nov 2017 15:13:15 -0800 Subject: [PATCH 06/20] 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. --- test/falco_tests.yaml | 2 +- test/falco_traces.yaml.in | 11 ++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/test/falco_tests.yaml b/test/falco_tests.yaml index 485e87fbbc1..f176a9b980d 100644 --- a/test/falco_tests.yaml +++ b/test/falco_tests.yaml @@ -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 diff --git a/test/falco_traces.yaml.in b/test/falco_traces.yaml.in index 10d0c84bb38..1245160c1ed 100644 --- a/test/falco_traces.yaml.in +++ b/test/falco_traces.yaml.in @@ -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 From f213bb60e4b7bcea9766a979017006d1b2e5adde Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Mon, 20 Nov 2017 10:50:48 -0800 Subject: [PATCH 07/20] Allow git binaries to run shells In some cases, these are run below a service runsv so we still need exceptions for them. --- rules/falco_rules.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index 1ed8e0f2e47..783b622258e 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1062,6 +1062,7 @@ and shell_procs and proc.pname exists and protected_shell_spawner + and not proc.pname in (gitlab_binaries) 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] From e8adb279e1616579e4841dc01a4c686821222618 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Mon, 20 Nov 2017 11:10:07 -0800 Subject: [PATCH 08/20] Let consul agent spawn curl for health checks --- rules/falco_rules.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index 783b622258e..d2fa4850f8f 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1040,6 +1040,9 @@ - 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: protected_shell_spawner condition: > (proc.aname in (protected_shell_spawning_binaries) @@ -1063,6 +1066,7 @@ and proc.pname exists and protected_shell_spawner and not proc.pname in (gitlab_binaries) + and not consul_running_curl 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] From 5a85cf1c123fe08a3dc374a2f8babc72b7b9342d Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Mon, 20 Nov 2017 11:30:04 -0800 Subject: [PATCH 09/20] Don't protect tomcat There's enough evidence of people spawning general commands that we can't protect it. --- rules/falco_rules.yaml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index d2fa4850f8f..dcadc128f1b 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -565,9 +565,6 @@ - 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") @@ -1028,9 +1025,6 @@ - macro: parent_java_running_hadoop condition: (proc.pname=java and proc.pcmdline contains org.apache.hadoop) -- macro: parent_java_running_tomcat - condition: (proc.pname=java and proc.pcmdline contains org.apache.catalina) - - macro: parent_java_running_datastax condition: (proc.pname=java and proc.pcmdline contains com.datastax) @@ -1054,7 +1048,6 @@ or parent_java_running_jboss_wildfly or parent_java_running_glassfish or parent_java_running_hadoop - or parent_java_running_tomcat or parent_java_running_datastax) and (not nginx_starting_nginx) From 447cad80b7609a1b0f1c0207fc6c0563f314634a Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Mon, 20 Nov 2017 11:44:07 -0800 Subject: [PATCH 10/20] 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. --- rules/falco_rules.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index dcadc128f1b..7c6e34bc7f2 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1049,7 +1049,6 @@ or parent_java_running_glassfish or parent_java_running_hadoop or parent_java_running_datastax) - and (not nginx_starting_nginx) - rule: Run shell untrusted desc: an attempt to spawn a shell below a non-shell application. Specific applications are monitored. @@ -1058,8 +1057,9 @@ and shell_procs and proc.pname exists and protected_shell_spawner - and not proc.pname in (gitlab_binaries) + and not proc.pname in (gitlab_binaries, erl_child_setup) and not consul_running_curl + and not nginx_starting_nginx 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] From 211ba31811d96bbe05b58c5b11a5b4934a5c89bd Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Mon, 20 Nov 2017 13:54:22 -0800 Subject: [PATCH 11/20] Add additional spawn binaries All off these are either below nginx, httpd, or runsv but should still be allowed to spawn shells. --- rules/falco_rules.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index 7c6e34bc7f2..9bdebb85b74 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1057,7 +1057,8 @@ and shell_procs and proc.pname exists and protected_shell_spawner - and not proc.pname in (gitlab_binaries, erl_child_setup) + and not proc.pname in (gitlab_binaries, cron_binaries, erl_child_setup, exechealthz, PM2, PassengerWatchd) + and not proc.aname in (unicorn_launche) and not consul_running_curl and not nginx_starting_nginx output: > From 1f549db668dd1bc1a111bd08a8309ff26fefe5aa Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Tue, 21 Nov 2017 10:45:40 -0800 Subject: [PATCH 12/20] 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. --- rules/falco_rules.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index 9bdebb85b74..cc05549dad7 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -202,6 +202,9 @@ - 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] @@ -1061,6 +1064,7 @@ and not proc.aname in (unicorn_launche) and not consul_running_curl and not nginx_starting_nginx + and not run_by_package_mgmt_binaries 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] From aaab25573f3559b16a2434f3df118da47c12f627 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Tue, 21 Nov 2017 10:48:15 -0800 Subject: [PATCH 13/20] 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. --- rules/falco_rules.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index cc05549dad7..cd28dd5bdb7 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1040,6 +1040,12 @@ - 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: > (proc.aname in (protected_shell_spawning_binaries) @@ -1065,6 +1071,8 @@ 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 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] From c548ae01d4eda16e89056095f3caa55cf46105f5 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Tue, 21 Nov 2017 10:51:00 -0800 Subject: [PATCH 14/20] 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. --- rules/falco_rules.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index cd28dd5bdb7..ede525812ac 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1066,13 +1066,18 @@ and shell_procs and proc.pname exists and protected_shell_spawner - and not proc.pname in (gitlab_binaries, cron_binaries, erl_child_setup, exechealthz, PM2, PassengerWatchd) + and not proc.pname in (gitlab_binaries, cron_binaries, erl_child_setup, exechealthz, + PM2, PassengerWatchd, c_rehash, svlogd, logrotate, hhvm, serf, + lb-controller) 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 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] From 23fe787352722326fb1eea62615de3005e315f03 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Tue, 21 Nov 2017 10:54:17 -0800 Subject: [PATCH 15/20] 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. --- rules/falco_rules.yaml | 151 ----------------------------------------- 1 file changed, 151 deletions(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index ede525812ac..18b1fbf5fec 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1085,67 +1085,6 @@ priority: DEBUG tags: [shell] -# - rule: Run shell untrusted - Old -# desc: an attempt to spawn a shell by a non-shell program. Exceptions are made for trusted binaries. -# condition: > -# spawned_process and not container -# 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 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_npm_running_node -# 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 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 parent_python_running_airflow -# and not perl_running_plesk -# and not plesk_autoinstaller -# and not parent_perl_running_openresty -# 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] - - macro: trusted_containers condition: (container.image startswith sysdig/agent or (container.image startswith sysdig/falco and @@ -1278,18 +1217,6 @@ priority: NOTICE tags: [container, shell] -# - rule: Terminal shell in container - Old -# desc: A shell was spawned by a program in 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) -# 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) -# priority: NOTICE -# tags: [container, shell] - # For some container types (mesos), there isn't a container image to # work with, and the container name is autogenerated, so there isn't # any stable aspect of the software to work with. In this case, we @@ -1370,84 +1297,6 @@ (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, migrate-databas, airflow, bootstrap-qmf-l, -# build-qmf-artif, colormake.pl, doxygen, Cypress, lb-controller, vmtoolsd, -# haproxy_reload., curator, consul-template, xargs, scl, find, awstats_updatea, -# sa-update, mysql_upgrade, opkg-cl, peer-finder, confd, aws) -# 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 parent_npm_running_node -# 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 parent_java_running_sbt -# 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_python_running_airflow -# and not parent_docker_start_script -# and not parent_java_running_endeca -# and not python_mesos_healthcheck -# and not python_mesos_marathon_scripting -# and not perl_running_plesk -# and not parent_rancher_running_healthcheck -# and not parent_perl_running_openresty -# 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) From 1afa04988e5c47751ef0c0f5d4ca0e627ac60c47 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Tue, 21 Nov 2017 14:20:58 -0800 Subject: [PATCH 16/20] Also exclude based on command lines Add back the exclusions based on command lines, using the existing set of command lines. --- rules/falco_rules.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index 18b1fbf5fec..ff8d7848d22 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1069,6 +1069,7 @@ and not proc.pname in (gitlab_binaries, cron_binaries, erl_child_setup, exechealthz, PM2, PassengerWatchd, c_rehash, svlogd, logrotate, hhvm, serf, lb-controller) + and not proc.cmdline in (known_shell_spawn_cmdlines) and not proc.aname in (unicorn_launche) and not consul_running_curl and not nginx_starting_nginx From e1cb9d24c9bf871a73fb89a900295d13501d3948 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Wed, 22 Nov 2017 09:54:54 -0800 Subject: [PATCH 17/20] 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. --- rules/falco_rules.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index ff8d7848d22..67f997679a1 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1059,6 +1059,10 @@ 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: > @@ -1068,7 +1072,7 @@ and protected_shell_spawner and not proc.pname in (gitlab_binaries, cron_binaries, erl_child_setup, exechealthz, PM2, PassengerWatchd, c_rehash, svlogd, logrotate, hhvm, serf, - lb-controller) + lb-controller, nvidia-installe, runsv, statsite) and not proc.cmdline in (known_shell_spawn_cmdlines) and not proc.aname in (unicorn_launche) and not consul_running_curl From a0786c7165008976b685bd3de951827e92562fbe Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Wed, 22 Nov 2017 09:55:40 -0800 Subject: [PATCH 18/20] Don't trigger on shells spawning shells We'll detect the first shell and not any other shells it spawns. --- rules/falco_rules.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index 67f997679a1..64aa7c42f45 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1070,7 +1070,8 @@ and shell_procs and proc.pname exists and protected_shell_spawner - and not proc.pname in (gitlab_binaries, cron_binaries, erl_child_setup, exechealthz, + and not proc.pname in (shell_binaries, gitlab_binaries, cron_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) From dee9f014db367512af63053a4d0e9a62ea0480f9 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Mon, 27 Nov 2017 23:25:20 -0800 Subject: [PATCH 19/20] 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. --- rules/falco_rules.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index 64aa7c42f45..d4ef264a8ff 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1216,7 +1216,7 @@ condition: > spawned_process and container and shell_procs and proc.tty != 0 - and not proc.pname exists + and (not proc.pname exists or proc.pname startswith "runc:") 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) From 008938bc05889d063f43bf557d4268a787e5ebe8 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Mon, 27 Nov 2017 23:37:57 -0800 Subject: [PATCH 20/20] 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. --- rules/falco_rules.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index d4ef264a8ff..5c35fd6b274 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1163,7 +1163,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: > @@ -1216,7 +1216,7 @@ condition: > spawned_process and container and shell_procs and proc.tty != 0 - and (not proc.pname exists or proc.pname startswith "runc:") + 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)