mirror of
https://github.com/falcosecurity/falco.git
synced 2025-06-29 16:17:32 +00:00
Rule updates next (#293)
* Let luajit spawn shells. * Start support for db mgmt programs Add support for db management programs that tend to spawn shells. Starting with two lists mysql_mgmt_binaries/postgres_mgmt_binaries which are combined into db_mgmt_binaries. db_mgmt_binaries is added to both shell spawning rules and the individual programs are removed. * Let apache beam spawn shells The program is "python pipeline.py" but it appears to be related to https://github.com/apache/beam/blob/master/sdks/python/apache_beam/pipeline.py. * Better support for dovecot Allow dovecot to setuid by adding to mail_binaries. Allow the program auth, when run by dovecot, to spawn shells. * Better support for plesk Create a list plesk_binaries and allow them to run shells. Also let them write to files below /etc/sw/keys. * Let strongswan spawn shells. Specifically the program starter. Using the full command line to be more specific. * Let proftpd modify files below /etc. * Let chef binaries write below /etc * Let mandb read sensitive files * Let specific phusion passenger binaries run shells The program is "my_init", which is fairly generic, so capture it by the full command line. * Make git-remote-http more permissive. * Let networkmanager modify /etc/resolv.conf specifically nm-dispatcher * Let hostid open network connections It might perform dns lookups as a part of resolving ip addresses. * Let uwsgi spawn shells * Add docker-runc-cur as a docker binary. truncated version of docker-runc-current. * Add rule for allowed containers New rule Launch Disallowed Container triggers when a container is started that does not match the macro allowed_containers. In the main falco rules file, this macro never matches, so it never triggers. However, in a second rules file the macro allowed_containers could be filled in with the specific images that match. * Also let foreman spawn shells Used by Red Hat Sattelite. * Let confluence run shells. Appears as java program, so look for the classpath. * Make allowed_containers macro more foolproof. In some cases, the container image might not be known/is NULL, so the comparison aganst "dummy-not-allowed-container-image" doesn't work. Replace this with proc.vpid=1, which is in the main rule Launch Disallowed Continer. Ensures it will only trigger when the allowed_containers macro is overridden. * Let tomcat spawn shells. It's java so you need to look at the classpath. * Let pip install software. * Add another yarn command line. * Let add-shell write to /etc/shells.tmp * Let more plesk binaries setuid. * Add imap-login as a mail binary. * Fix plesk writing keys macro Should be testing proc.name, not proc.cmdline. * Let screen read sensitive files. * Add more shell spawners. S99qualys-cloud is the init script, cfn-signal is cloudformation. * Exclude nologin from user mgmt programs. * Let programs run by locales.postins write to /etc It can run scripts like sed to modify files before writing the final file. * Let install4j java progs spawn shells. Again, searching by classpath. * Let some shell cmds be spawned outside containers We had a list known_container_shell_spawn_cmdlines that contained innocuous commandlines, but it only worked for containers. Split this list into container-specific and general commandlines, and add an exception for the general commandlines for the Run Shell Untrusted rule. * Add addl ruby-based passenger spawners Add a different way to identify ruby run by phusion passenger. * Allow bundle ruby cmds to be identififed by name In some cases, bundle runs ruby scripts by direct script name (foo.rb). Also allow that to spawn shells. * Let nginx spawn shells. * Skip setuid rules for containers. For now, entirely skip the setuid rule for containers. Will add back once I can find a way to check for unknown users. * Let PassengerWatchd run shells * Add additional foreman shells Let the direct parent also be scl when the ancestor is tfm-rake,tfm-ruby. * Add additional innocuous command lines. * Also let cron spawn shells in containers Seen when using things like phusion passenger. * Also let run-parts run cmp/cp for sensitive files Might be a case of a missing process but might also be legitimate. * Let erlexec spawn shells. * Add additional innocuous shell cmdlines. * Add suexec as a userexec binary. * Add imap/mailmng-core as mail binaries. Also split list across multiple lines. * Let perl spawn shells when run by cpanm * Let apache_control_ spawn shells * Let ics_start/stop running java spawn shells java is the direct parent, ics_start/stop are ancestors. * Let PassengerAgent setuid. It setuids to nobody. * Let multilog write below /etc if run by supervise * Let bwrap setuid A container setup utility. * Detect writes below /, /root New rule Write below root detects writes either directly below / or anywhere below /root. * Don't let shells directly open network connections In addition to system binaries, don't let shells directly open network connections. Bash has /dev/{tcp,udp} which allows direct connections. * Add additional sensitive mounts. Add additional sensitive mounts, including the docker socket, /, anywhere below /root, or anywhere below /etc. * Let pki-realm write below /etc/pki/realms Appears to be an ansible script. * Let sgdisk write below dev * Let debconf-show read sensitive files. * Additional case for build-related scripts. * Add additional mail binaries. * Let ruby running discourse spawn shells. * Let beam.smp and paster run shells * Temporarily undo shells opening net conns update At some customers, at container create time events are being lost, and for that reason programs spawned by the shell that perform network connections are being misattributed to the shell. * Make the actual sensitive files a list. Make the actual sensitive files used by the sensitive files macro a list so it can be easily extended. * Print mounts in Launch Sensitive Mount Container Add the full list of mounts to the output of Launch Sensitive Mount Container, so it's easy to see which sensitive mount was used. * Add container.image to container-related rules. Helps in diagnosis. * Add sw-engine-kv as a plesk binary. * Allow sa-update to read sensitive files SpamAssassin updater. * Add additional shell spawners. * Allow sumologic secureFiles to run user mgmt progs See https://help.sumologic.com/Send-Data/Installed-Collectors/05Reference-Information-for-Collector-Installation/08Enhanced-File-System-Security-for-Installed-Collectors. * Only consider full mounts of /etc as sensitive A legitimate case is k8s mounting /etc/kubernetes/ssl, which was matching /etc*. The glob matcher we have isn't a full regex so you can't exclude strings, only characters. * Let htpasswd write below /etc Part of nginx * Let pam-auth-update read sensitive files * Let hawkular-metric spawn shells. * Generalize jenkins scripts spawning shells Generalize jenkins_script_sh to jenkins_scripts and add additional cases. * Let php run by assemble spawn shells Better than globally letting php spawn shells. * Add additional setuid binaries. * Add additional package mgmt prog rhsmcertd-worke(r), red hat subscription manager * Add additional yarn cmdlines. * Let dmeventd write below etc. device mapper event daemon. * Let rhsmcertd-worke(r) spawn shells. * Let node spawn bitnami-related shells. * Add user allowed sensitive mounts New macro user_sensitive_mount_containers allows a second rules file to specify containers/images that can perform sensitive mounts. * Add start-stop-daemon as setuid program It has -g/-u args to change gid/uid. Also move some other single setuid programs to the list known_setuid_binaries. * Add additional shell spawners/cmdlines. * Let python running localstack spawn shells. * Add additional chef binaries. * Let fluentd spawn shells. * Don't consider unix_chkpwd to be a user mgmt prog It only checks passwords. * Get setuid for NULL user in container working Reorganize the unknown_user_in_container macro to get it working again in containers. Previously, it was being skipped entirely due to a problem with handling of unknown users, which get returned as NULL. The new macro is known_user_in_container, which tests the user.name against "N/A". It happens that if user.name is NULL, the comparison fails, so it has the same effect as if the string "N/A" were being returned. Any valid user name won't match the string "N/A", so known users will cause the macro to return true. The setuid rule needs an additional check for not container, so add that. * Add exceptions for Write below root Add lists of files/directories that are acceptable to write.
This commit is contained in:
parent
9ec26795c5
commit
ccea09b089
@ -56,6 +56,10 @@
|
||||
- macro: etc_dir
|
||||
condition: fd.name startswith /etc
|
||||
|
||||
# This detects writes immediately below / or any write anywhere below /root
|
||||
- macro: root_dir
|
||||
condition: (fd.directory=/ or fd.name startswith /root)
|
||||
|
||||
- macro: ubuntu_so_dirs
|
||||
condition: >
|
||||
fd.name startswith /lib/x86_64-linux-gnu or
|
||||
@ -78,7 +82,7 @@
|
||||
items: [add-shell, remove-shell]
|
||||
|
||||
- macro: shell_procs
|
||||
condition: proc.name in (shell_binaries)
|
||||
condition: (proc.name in (shell_binaries))
|
||||
|
||||
- list: coreutils_binaries
|
||||
items: [
|
||||
@ -123,7 +127,7 @@
|
||||
items: [setup-backend, dragent, sdchecks]
|
||||
|
||||
- list: docker_binaries
|
||||
items: [docker, dockerd, exe, docker-compose, docker-entrypoi]
|
||||
items: [docker, dockerd, exe, docker-compose, docker-entrypoi, docker-runc-cur]
|
||||
|
||||
- list: k8s_binaries
|
||||
items: [hyperkube, skydns, kube2sky, exechealthz]
|
||||
@ -137,7 +141,13 @@
|
||||
items: [mesos-health-ch, mesos-docker-ex, mesos-agent, mesos-slave, mesos-logrotate, mesos-fetcher, mesos-executor, 3dt]
|
||||
|
||||
- list: phusion_passenger_binaries
|
||||
items: [PassengerAgent]
|
||||
items: [PassengerAgent, PassengerWatchd]
|
||||
|
||||
# A bit longer to avoid the fairly generic my_init.
|
||||
- macro: parent_phusion_passenger_my_init
|
||||
condition: >
|
||||
(proc.pcmdline="my_init -u /sbin/my_init " or
|
||||
proc.pcmdline="my_init -u /sbin/my_init")
|
||||
|
||||
- list: chef_binaries
|
||||
items: [chef-client]
|
||||
@ -148,6 +158,15 @@
|
||||
- list: db_server_binaries
|
||||
items: [mysqld]
|
||||
|
||||
- list: mysql_mgmt_binaries
|
||||
items: [mysql_install_d, mysql_ssl_rsa_s]
|
||||
|
||||
- list: postgres_mgmt_binaries
|
||||
items: [pg_dumpall, pg_ctl]
|
||||
|
||||
- list: db_mgmt_binaries
|
||||
items: [mysql_mgmt_binaries, postgres_mgmt_binaries]
|
||||
|
||||
- list: gitlab_binaries
|
||||
items: [gitlab-shell, gitlab-mon, gitlab-runner-b, git]
|
||||
|
||||
@ -157,7 +176,7 @@
|
||||
# The explicit quotes are needed to avoid the - characters being
|
||||
# interpreted by the filter expression.
|
||||
- list: rpm_binaries
|
||||
items: [dnf, rpm, rpmkey, yum, '"75-system-updat"']
|
||||
items: [dnf, rpm, rpmkey, yum, '"75-system-updat"', rhsmcertd-worke]
|
||||
|
||||
- macro: rpm_procs
|
||||
condition: proc.name in (rpm_binaries)
|
||||
@ -171,7 +190,7 @@
|
||||
# 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]
|
||||
items: [rpm_binaries, deb_binaries, update-alternat, gem, pip]
|
||||
|
||||
- macro: package_mgmt_procs
|
||||
condition: proc.name in (package_mgmt_binaries)
|
||||
@ -185,16 +204,20 @@
|
||||
# A canonical set of processes that run other programs with different
|
||||
# privileges or as a different user.
|
||||
- list: userexec_binaries
|
||||
items: [sudo, su]
|
||||
items: [sudo, su, suexec]
|
||||
|
||||
- list: known_setuid_binaries
|
||||
items: [sshd, dbus-daemon-lau, ping, ping6, critical-stack-]
|
||||
items: [
|
||||
sshd, dbus-daemon-lau, ping, ping6, critical-stack-, pmmcli,
|
||||
filemng, PassengerAgent, bwrap, osdetect, nginxmng, sw-engine-fpm,
|
||||
start-stop-daem
|
||||
]
|
||||
|
||||
- list: user_mgmt_binaries
|
||||
items: [login_binaries, passwd_binaries, shadowutils_binaries]
|
||||
|
||||
- list: dev_creation_binaries
|
||||
items: [blkid, rename_device, update_engine]
|
||||
items: [blkid, rename_device, update_engine, sgdisk]
|
||||
|
||||
- list: aide_wrapper_binaries
|
||||
items: [aide.wrapper, update-aide.con]
|
||||
@ -218,13 +241,17 @@
|
||||
items: [bro, broctl]
|
||||
|
||||
- list: monitoring_binaries
|
||||
items: [icinga2, nrpe, npcd, check_sar_perf., qualys-cloud-ag]
|
||||
items: [icinga2, nrpe, npcd, check_sar_perf., qualys-cloud-ag, S99qualys-cloud]
|
||||
|
||||
- macro: system_procs
|
||||
condition: proc.name in (coreutils_binaries, user_mgmt_binaries)
|
||||
|
||||
- list: mail_binaries
|
||||
items: [sendmail, sendmail-msp, postfix, procmail, exim4, pickup, showq, mailq]
|
||||
items: [
|
||||
sendmail, sendmail-msp, postfix, procmail, exim4,
|
||||
pickup, showq, mailq, dovecot, imap-login, imap,
|
||||
mailmng-core, pop3-login, dovecot-lda
|
||||
]
|
||||
|
||||
- list: sendmail_config_binaries
|
||||
items: [
|
||||
@ -238,10 +265,13 @@
|
||||
- list: keepalived_binaries
|
||||
items: [keepalived]
|
||||
|
||||
- list: sensitive_file_names
|
||||
items: [/etc/shadow, /etc/sudoers, /etc/pam.conf]
|
||||
|
||||
- macro: sensitive_files
|
||||
condition: >
|
||||
fd.name startswith /etc and
|
||||
(fd.name in (/etc/shadow, /etc/sudoers, /etc/pam.conf)
|
||||
(fd.name in (sensitive_file_names)
|
||||
or fd.directory in (/etc/sudoers.d, /etc/pam.d))
|
||||
|
||||
# Indicates that the process is new. Currently detected using time
|
||||
@ -302,6 +332,9 @@
|
||||
- list: sshkit_script_binaries
|
||||
items: [10_etc_sudoers., 10_passwd_group]
|
||||
|
||||
- list: plesk_binaries
|
||||
items: [sw-engine, sw-engine-fpm, sw-engine-kv, filemng, f2bmng]
|
||||
|
||||
# System users that should never log into a system. Consider adding your own
|
||||
# service users (e.g. 'apache' or 'mysqld') here.
|
||||
- macro: system_users
|
||||
@ -319,12 +352,21 @@
|
||||
- macro: ansible_running_python
|
||||
condition: (proc.name in (python, pypy) and proc.cmdline contains ansible)
|
||||
|
||||
- macro: parent_beam_running_python
|
||||
condition: proc.pcmdline="python pipeline.py -c conf.json"
|
||||
|
||||
- macro: parent_strongswan_running_starter
|
||||
condition: proc.pcmdline="starter --daemon charon"
|
||||
|
||||
- macro: python_running_denyhosts
|
||||
condition: >
|
||||
(proc.name=python and
|
||||
(proc.cmdline contains /usr/sbin/denyhosts or
|
||||
proc.cmdline contains /usr/local/bin/denyhosts.py))
|
||||
|
||||
- macro: parent_python_running_localstack
|
||||
condition: (proc.pcmdline startswith "python bin/localstack")
|
||||
|
||||
- macro: parent_python_running_denyhosts
|
||||
condition: >
|
||||
(proc.pname=python and
|
||||
@ -344,8 +386,15 @@
|
||||
(proc.pname=java and proc.pcmdline contains jenkins.war
|
||||
or proc.pcmdline contains /tmp/slave.jar)
|
||||
|
||||
- macro: jenkins_script_sh
|
||||
condition: (proc.pcmdline startswith "script.sh -xe /var/jenkins_home")
|
||||
- macro: parent_cpanm_running_perl
|
||||
condition: (proc.pname=perl and proc.aname[2]=cpanm)
|
||||
|
||||
- macro: ics_running_java
|
||||
condition: (proc.pname=java and proc.aname[3] in (ics_start.sh,ics_stop.sh))
|
||||
|
||||
- macro: jenkins_scripts
|
||||
condition: (proc.pcmdline startswith "script.sh -xe /var/jenkins_home" or
|
||||
proc.cmdline="bash /usr/local/bin/jenkins-slave")
|
||||
|
||||
- macro: parent_java_running_echo
|
||||
condition: (proc.pname=java and proc.cmdline startswith "sh -c echo")
|
||||
@ -365,8 +414,11 @@
|
||||
proc.cmdline startswith "sh -c gcc" or
|
||||
proc.cmdline startswith "sh -c if type gcc" or
|
||||
proc.cmdline startswith "sh -c cd '/var/www/edi/';LC_ALL=en_US.UTF-8 git" or
|
||||
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.pcmdline startswith "node /opt/nodejs/bin/yarn"))
|
||||
proc.pcmdline startswith "node /opt/nodejs/bin/yarn" or
|
||||
proc.pcmdline startswith "node /root/.config/yarn" or
|
||||
proc.pcmdline startswith "node /opt/yarn/bin/yarn.js"))
|
||||
|
||||
- macro: parent_node_running_npm
|
||||
condition: proc.pcmdline startswith "node /usr/local/bin/npm"
|
||||
@ -382,11 +434,21 @@
|
||||
|
||||
- macro: bundle_running_ruby
|
||||
condition: >
|
||||
(proc.pname=ruby and (
|
||||
((proc.pname=ruby or proc.pname contains ".rb") and (
|
||||
proc.aname[2]=bundle or
|
||||
proc.aname[3]=bundle or
|
||||
proc.aname[4]=bundle))
|
||||
|
||||
- macro: assemble_running_php
|
||||
condition: >
|
||||
(proc.pname=php and (
|
||||
proc.aname[2]=assemble or
|
||||
proc.aname[3]=assemble or
|
||||
proc.aname[4]=assemble))
|
||||
|
||||
- macro: node_running_bitnami
|
||||
condition: proc.pname=node and proc.cmdline startswith "sh -c /opt/bitnami"
|
||||
|
||||
# Qualys seems to run a variety of shell subprocesses, at various
|
||||
# levels. This checks at a few levels without the cost of a full
|
||||
# proc.aname, which traverses the full parent heirarchy.
|
||||
@ -397,9 +459,16 @@
|
||||
proc.aname[3]=qualys-cloud-ag or
|
||||
proc.aname[4]=qualys-cloud-ag)
|
||||
|
||||
- macro: run_by_sumologic_securefiles
|
||||
condition: >
|
||||
((proc.cmdline="usermod -a -G sumologic_collector" or
|
||||
proc.cmdline="groupadd sumologic_collector") and
|
||||
(proc.pname=secureFiles.sh and proc.aname[2]=java))
|
||||
|
||||
# Chef is similar.
|
||||
- macro: run_by_chef
|
||||
condition: (proc.aname[2]=chef_command_wr or proc.aname[3]=chef_command_wr)
|
||||
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)
|
||||
|
||||
- macro: run_by_adclient
|
||||
condition: (proc.aname[2]=adclient or proc.aname[3]=adclient or proc.aname[4]=adclient)
|
||||
@ -414,7 +483,15 @@
|
||||
condition: (proc.pname=perl and proc.aname[2]=h2o)
|
||||
|
||||
- macro: run_by_passenger_agent
|
||||
condition: (proc.pname=ruby and proc.aname[2]=PassengerAgent)
|
||||
condition: ((proc.pname=ruby and proc.aname[2]=PassengerAgent) or
|
||||
proc.pcmdline startswith "ruby /usr/share/passenger/helper-scripts/rack-preloader.rb")
|
||||
|
||||
# Also handles running semi-indirectly via scl
|
||||
- macro: run_by_foreman
|
||||
condition: >
|
||||
(user.name=foreman and
|
||||
(proc.pname in (rake, ruby, scl) and proc.aname[5] in (tfm-rake,tfm-ruby)) or
|
||||
(proc.pname=scl and proc.aname[2] in (tfm-rake,tfm-ruby)))
|
||||
|
||||
# As a part of kernel upgrades, dpkg will spawn a perl script with the
|
||||
# name linux-image-N.N. This macro matches that.
|
||||
@ -424,6 +501,33 @@
|
||||
- macro: java_running_sdjagent
|
||||
condition: proc.name=java and proc.cmdline contains sdjagent.jar
|
||||
|
||||
- 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")
|
||||
|
||||
- macro: parent_dovecot_running_auth
|
||||
condition: (proc.pname=auth and proc.aname[2]=dovecot)
|
||||
|
||||
- macro: parent_supervise_running_multilog
|
||||
condition: (proc.name=multilog and proc.pname=supervise)
|
||||
|
||||
- macro: parent_ruby_running_discourse
|
||||
condition: (proc.pcmdline startswith "ruby /var/www/discourse/vendor/bundle/ruby")
|
||||
|
||||
- macro: pki_realm_writing_realms
|
||||
condition: (proc.cmdline startswith "bash /usr/local/lib/pki/pki-realm" and fd.name startswith /etc/pki/realms)
|
||||
|
||||
- macro: htpasswd_writing_passwd
|
||||
condition: (proc.name=htpasswd and fd.name=/etc/nginx/.htpasswd)
|
||||
|
||||
- macro: dmeventd_writing_lvm_archive
|
||||
condition: (proc.name=dmeventd and fd.name startswith /etc/lvm/archive/)
|
||||
|
||||
###############
|
||||
# General Rules
|
||||
###############
|
||||
@ -447,7 +551,16 @@
|
||||
condition: (proc.name=qualys-cloud-ag and fd.name=/etc/qualys/cloud-agent/qagent-log.conf)
|
||||
|
||||
- macro: git_writing_nssdb
|
||||
condition: (proc.cmdline="git-remote-http origin" and fd.directory=/etc/pki/nssdb)
|
||||
condition: (proc.name=git-remote-http and fd.directory=/etc/pki/nssdb)
|
||||
|
||||
- macro: plesk_writing_keys
|
||||
condition: (proc.name in (plesk_binaries) and fd.name startswith /etc/sw/keys)
|
||||
|
||||
- macro: networkmanager_writing_resolv_conf
|
||||
condition: proc.aname[2]=nm-dispatcher and fd.name=/etc/resolv.conf
|
||||
|
||||
- macro: add_shell_writing_shells_tmp
|
||||
condition: (proc.name=add-shell and fd.name=/etc/shells.tmp)
|
||||
|
||||
# Add conditions to this macro (probably in a separate file,
|
||||
# overwriting this macro) to allow for specific combinations of
|
||||
@ -477,7 +590,7 @@
|
||||
gen_resolvconf., update-ca-certi, certbot, runsv,
|
||||
qualys-cloud-ag, locales.postins, nomachine_binaries,
|
||||
adclient, certutil, crlutil)
|
||||
and not proc.pname in (sysdigcloud_binaries, sendmail_config_binaries, hddtemp.postins, sshkit_script_binaries)
|
||||
and not proc.pname in (sysdigcloud_binaries, sendmail_config_binaries, hddtemp.postins, sshkit_script_binaries, locales.postins)
|
||||
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 ansible_running_python
|
||||
@ -488,6 +601,14 @@
|
||||
and not run_by_adclient
|
||||
and not qualys_writing_conf_files
|
||||
and not git_writing_nssdb
|
||||
and not plesk_writing_keys
|
||||
and not networkmanager_writing_resolv_conf
|
||||
and not run_by_chef
|
||||
and not add_shell_writing_shells_tmp
|
||||
and not parent_supervise_running_multilog
|
||||
and not pki_realm_writing_realms
|
||||
and not htpasswd_writing_passwd
|
||||
and not dmeventd_writing_lvm_archive
|
||||
|
||||
- rule: Write below etc
|
||||
desc: an attempt to write to any file below /etc, not in a pipe installer session
|
||||
@ -496,6 +617,22 @@
|
||||
priority: ERROR
|
||||
tags: [filesystem]
|
||||
|
||||
- list: known_root_files
|
||||
items: [/root/.monit.state]
|
||||
|
||||
- list: known_root_directories
|
||||
items: [/root/.oracle_jre_usage]
|
||||
|
||||
- rule: Write below root
|
||||
desc: an attempt to write to any file directly below / or /root
|
||||
condition: >
|
||||
root_dir and evt.dir = < and open_write
|
||||
and not fd.name in (known_root_files)
|
||||
and not fd.directory in (known_root_directories)
|
||||
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
|
||||
tags: [filesystem]
|
||||
|
||||
# Within a fbash session, the severity is lowered to INFO
|
||||
- rule: Write below etc in installer
|
||||
desc: an attempt to write to any file below /etc, in a pipe installer session
|
||||
@ -507,7 +644,7 @@
|
||||
tags: [filesystem]
|
||||
|
||||
- macro: cmp_cp_by_passwd
|
||||
condition: proc.name in (cmp, cp) and proc.pname=passwd
|
||||
condition: proc.name in (cmp, cp) and proc.pname in (passwd, run-parts)
|
||||
|
||||
- rule: Read sensitive file trusted after startup
|
||||
desc: >
|
||||
@ -524,7 +661,8 @@
|
||||
- list: read_sensitive_file_binaries
|
||||
items: [
|
||||
iptables, ps, lsb_release, check-new-relea, dumpe2fs, accounts-daemon, sshd,
|
||||
vsftpd, systemd, mysql_install_d, psql
|
||||
vsftpd, systemd, mysql_install_d, psql, screen, debconf-show, sa-update,
|
||||
pam-auth-update
|
||||
]
|
||||
|
||||
# Add conditions to this macro (probably in a separate file,
|
||||
@ -548,7 +686,8 @@
|
||||
sensitive_files and open_read
|
||||
and not proc.name in (user_mgmt_binaries, userexec_binaries, package_mgmt_binaries,
|
||||
cron_binaries, read_sensitive_file_binaries, shell_binaries, hids_binaries,
|
||||
vpn_binaries, sendmail_config_binaries, nomachine_binaries, sshkit_script_binaries)
|
||||
vpn_binaries, sendmail_config_binaries, nomachine_binaries, sshkit_script_binaries,
|
||||
in.proftpd, mandb)
|
||||
and not cmp_cp_by_passwd
|
||||
and not ansible_running_python
|
||||
and not proc.cmdline contains /usr/bin/mandb
|
||||
@ -642,10 +781,13 @@
|
||||
logrotate, ansible, less, adduser, pycompile, py3compile,
|
||||
pyclean, py3clean, pip, pip2, ansible-playboo, man-db,
|
||||
init, pluto, mkinitramfs, unattended-upgr, watch, sysdig,
|
||||
landscape-sysin, nessusd, PM2, syslog-summary, erl_child_setup,
|
||||
npm, cloud-init, toybox, ceph, hhvm, certbot, mysql_install_d,
|
||||
landscape-sysin, nessusd, PM2, syslog-summary, erl_child_setup, erlexec,
|
||||
npm, cloud-init, toybox, ceph, hhvm, certbot,
|
||||
serf, a2enmod, runsv, supervisord, varnishd, authconfig, tini,
|
||||
timeout, updatedb.findut, mysql_ssl_rsa_s, adclient, systemd-udevd
|
||||
timeout, updatedb.findut, adclient, systemd-udevd,
|
||||
luajit, uwsgi, cfn-signal, apache_control_, beam.smp, paster, postfix-local,
|
||||
nginx_control, mailmng-service, web_statistic_e, statistics_coll, install-info,
|
||||
hawkular-metric, rhsmcertd-worke, parted, amuled, fluentd
|
||||
]
|
||||
|
||||
- rule: Run shell untrusted
|
||||
@ -659,24 +801,36 @@
|
||||
monitoring_binaries, gitlab_binaries, mesos_slave_binaries,
|
||||
keepalived_binaries,
|
||||
needrestart_binaries, phusion_passenger_binaries, chef_binaries, nomachine_binaries,
|
||||
x2go_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 jenkins_script_sh
|
||||
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 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 run_by_foreman
|
||||
and not parent_java_running_tomcat
|
||||
and not parent_java_running_install4j
|
||||
and not parent_cpanm_running_perl
|
||||
and not parent_ruby_running_discourse
|
||||
and not assemble_running_php
|
||||
and not node_running_bitnami
|
||||
and not parent_python_running_localstack
|
||||
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]
|
||||
@ -695,6 +849,15 @@
|
||||
container.image startswith gcr.io/google_containers/kube-proxy or
|
||||
container.image startswith calico/node)
|
||||
|
||||
# Add conditions to this macro (probably in a separate file,
|
||||
# overwriting this macro) to specify additional containers that are
|
||||
# allowed to perform sensitive mounts.
|
||||
#
|
||||
# In this file, it just takes one of the images in trusted_containers
|
||||
# and repeats it.
|
||||
- macro: user_sensitive_mount_containers
|
||||
condition: (container.image startswith sysdig/agent)
|
||||
|
||||
# These containers are ones that are known to spawn lots of
|
||||
# shells. Generally, they are for systems where the container is used
|
||||
# as a packaging mechanism more than for a dedicated microservice.
|
||||
@ -706,12 +869,20 @@
|
||||
- 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
|
||||
output: Privileged container started (user=%user.name command=%proc.cmdline %container.info)
|
||||
output: Privileged container started (user=%user.name command=%proc.cmdline %container.info image=%container.image)
|
||||
priority: INFO
|
||||
tags: [container, cis]
|
||||
|
||||
# For now, only considering a full mount of /etc as
|
||||
# sensitive. Ideally, this would also consider all subdirectories
|
||||
# below /etc as well, but the globbing mechanism used by sysdig
|
||||
# doesn't allow exclusions of a full pattern, only single characters.
|
||||
- macro: sensitive_mount
|
||||
condition: (container.mount.dest[/proc*] != "N/A")
|
||||
condition: (container.mount.dest[/proc*] != "N/A" or
|
||||
container.mount.dest[/var/run/docker.sock] != "N/A" or
|
||||
container.mount.dest[/] != "N/A" or
|
||||
container.mount.dest[/etc] != "N/A" or
|
||||
container.mount.dest[/root*] != "N/A")
|
||||
|
||||
# The steps libcontainer performs to set up the root program for a container are:
|
||||
# - clone + exec self to a program runc:[0:PARENT]
|
||||
@ -731,11 +902,36 @@
|
||||
desc: >
|
||||
Detect the initial process started by a container that has a mount from a sensitive host directory
|
||||
(i.e. /proc). Exceptions are made for known trusted images.
|
||||
condition: evt.type=execve and proc.vpid=1 and container and sensitive_mount and not trusted_containers
|
||||
output: Container with sensitive mount started (user=%user.name command=%proc.cmdline %container.info)
|
||||
condition: >
|
||||
evt.type=execve and proc.vpid=1 and container
|
||||
and sensitive_mount
|
||||
and not trusted_containers
|
||||
and not user_sensitive_mount_containers
|
||||
output: Container with sensitive mount started (user=%user.name command=%proc.cmdline %container.info image=%container.image mounts=%container.mounts)
|
||||
priority: INFO
|
||||
tags: [container, cis]
|
||||
|
||||
# In a local/user rules file, you could override this macro to
|
||||
# explicitly enumerate the container images that you want to run in
|
||||
# your environment. In this main falco rules file, there isn't any way
|
||||
# to know all the containers that can run, so any container is
|
||||
# alllowed, by using a filter that is guaranteed to evaluate to true
|
||||
# (the same proc.vpid=1 that's in the Launch Disallowed Container
|
||||
# rule). In the overridden macro, the condition would look something
|
||||
# like (container.image startswith vendor/container-1 or
|
||||
# container.image startswith vendor/container-2 or ...)
|
||||
|
||||
- macro: allowed_containers
|
||||
condition: (proc.vpid=1)
|
||||
|
||||
- rule: Launch Disallowed Container
|
||||
desc: >
|
||||
Detect the initial process started by a container that is not in a list of allowed containers.
|
||||
condition: evt.type=execve and proc.vpid=1 and container and not allowed_containers
|
||||
output: Container started and not in allowed list (user=%user.name command=%proc.cmdline %container.info image=%container.image)
|
||||
priority: WARNING
|
||||
tags: [container]
|
||||
|
||||
# Anything run interactively by root
|
||||
# - condition: evt.type != switch and user.name = root and proc.name != sshd and interactive
|
||||
# output: "Interactive root (%user.name %proc.name %evt.dir %evt.type %evt.args %fd.name)"
|
||||
@ -763,22 +959,15 @@
|
||||
# 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
|
||||
# fall back to allowing certain command lines.
|
||||
- list: known_container_shell_spawn_cmdlines
|
||||
|
||||
- list: known_shell_spawn_cmdlines
|
||||
items: [
|
||||
'"bash -c curl -f localhost:$API_PORT/admin/healthcheck"',
|
||||
'"sh -c curl http://localhost:6060/debug/vars>/dev/null "',
|
||||
'"sh -c curl http://localhost:6060/debug/vars>/dev/null"',
|
||||
'"sh -c curl http://localhost:6060/debug/vars>/dev/null"',
|
||||
'"sh -c curl http://localhost:6060/debug/vars>/dev/null "',
|
||||
'"sh -c pgrep java && exit 0 || exit 1 "',
|
||||
'"sh -c uname -p 2> /dev/null"',
|
||||
'"sh -c uname -s 2>&1"',
|
||||
'"sh -c uname -r 2>&1"',
|
||||
'"sh -c uname -v 2>&1"',
|
||||
'"sh -c uname -a 2>&1"',
|
||||
'"sh -c ruby -v 2>&1"',
|
||||
'"sh -c echo healthy "',
|
||||
'"sh -c echo alive "',
|
||||
'"sh -c getconf CLK_TCK"',
|
||||
'"sh -c getconf PAGESIZE"',
|
||||
'"sh -c LC_ALL=C LANG=C /sbin/ldconfig -p 2>/dev/null"',
|
||||
@ -793,7 +982,23 @@
|
||||
'"sh -c crontab -l 2"',
|
||||
'"sh -c lsb_release -a"',
|
||||
'"sh -c whoami"',
|
||||
'"sh -c node_modules/.bin/bower-installer"'
|
||||
'"sh -c node_modules/.bin/bower-installer"',
|
||||
'"sh -c /bin/hostname -f 2> /dev/null"',
|
||||
'"sh -c locale -a"',
|
||||
'"sh -c -t -i"'
|
||||
]
|
||||
|
||||
- list: known_container_shell_spawn_cmdlines
|
||||
items: [
|
||||
known_shell_spawn_cmdlines,
|
||||
'"bash -c curl -f localhost:$API_PORT/admin/healthcheck"',
|
||||
'"sh -c curl http://localhost:6060/debug/vars>/dev/null "',
|
||||
'"sh -c curl http://localhost:6060/debug/vars>/dev/null"',
|
||||
'"sh -c curl http://localhost:6060/debug/vars>/dev/null"',
|
||||
'"sh -c curl http://localhost:6060/debug/vars>/dev/null "',
|
||||
'"sh -c pgrep java && exit 0 || exit 1 "',
|
||||
'"sh -c echo healthy "',
|
||||
'"sh -c echo alive "'
|
||||
]
|
||||
|
||||
# This list allows for easy additions to the set of commands allowed
|
||||
@ -825,6 +1030,7 @@
|
||||
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,
|
||||
@ -832,10 +1038,13 @@
|
||||
nomachine_binaries,
|
||||
x2go_binaries,
|
||||
xray_rabbitmq_binaries,
|
||||
monitoring_binaries, gitlab_binaries, initdb, pg_ctl, awk, falco, cron,
|
||||
erl_child_setup, ceph, PM2, pycompile, py3compile, hhvm, npm, mysql_install_d, serf,
|
||||
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, mysql_ssl_rsa_s, logdna-agent, bundle, configure)
|
||||
xrdb, xfce4-session, weave, logdna-agent, bundle, configure, luajit, nginx,
|
||||
beam.smp, paster, postfix-local, hawkular-metric, fluentd)
|
||||
and not trusted_containers
|
||||
and not shell_spawning_containers
|
||||
and not parent_java_running_echo
|
||||
@ -850,8 +1059,20 @@
|
||||
and not run_by_h2o
|
||||
and not run_by_passenger_agent
|
||||
and not parent_java_running_jenkins
|
||||
and not jenkins_script_sh
|
||||
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 ics_running_java
|
||||
and not parent_ruby_running_discourse
|
||||
and not assemble_running_php
|
||||
and not node_running_bitnami
|
||||
and not parent_python_running_localstack
|
||||
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])
|
||||
@ -862,7 +1083,7 @@
|
||||
# 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=systemd
|
||||
condition: (fd.sockfamily = ip and system_procs) and (inbound or outbound) and not proc.name in (systemd, hostid)
|
||||
output: >
|
||||
Known system binary sent/received network traffic
|
||||
(user=%user.name command=%proc.cmdline connection=%fd.name)
|
||||
@ -891,9 +1112,8 @@
|
||||
# container but not on the host. (See
|
||||
# https://github.com/draios/sysdig/issues/954). So in that case, allow
|
||||
# a setuid.
|
||||
|
||||
- macro: unknown_user_in_container
|
||||
condition: (user.name="<NA>" and container)
|
||||
- macro: known_user_in_container
|
||||
condition: (container and user.name != "N/A")
|
||||
|
||||
# sshd, mail programs attempt to setuid to root even when running as non-root. Excluding here to avoid meaningless FPs
|
||||
- rule: Non sudo setuid
|
||||
@ -902,9 +1122,10 @@
|
||||
suing to itself are also excluded, as setuid calls typically involve dropping privileges.
|
||||
condition: >
|
||||
evt.type=setuid and evt.dir=>
|
||||
and not unknown_user_in_container
|
||||
and (known_user_in_container or not container)
|
||||
and not user.name=root and not somebody_becoming_themself
|
||||
and not proc.name in (known_setuid_binaries, userexec_binaries, mail_binaries, docker_binaries, nomachine_binaries)
|
||||
and not proc.name in (known_setuid_binaries, userexec_binaries, mail_binaries, docker_binaries,
|
||||
nomachine_binaries)
|
||||
and not java_running_sdjagent
|
||||
output: >
|
||||
Unexpected setuid call by non-sudo, non-root program (user=%user.name parent=%proc.pname
|
||||
@ -920,12 +1141,13 @@
|
||||
Some innocuous commandlines that don't actually change anything are excluded.
|
||||
condition: >
|
||||
spawned_process and proc.name in (user_mgmt_binaries) and
|
||||
not proc.name in (su, sudo, lastlog) and not container and
|
||||
not proc.name in (su, sudo, lastlog, nologin, unix_chkpwd) and not container and
|
||||
not proc.pname in (cron_binaries, systemd, run-parts) and
|
||||
not proc.cmdline startswith "passwd -S" and
|
||||
not proc.cmdline startswith "useradd -D" and
|
||||
not proc.cmdline startswith "systemd --version" and
|
||||
not run_by_qualys
|
||||
not run_by_qualys and
|
||||
not run_by_sumologic_securefiles
|
||||
output: >
|
||||
User management binary command run outside of container
|
||||
(user=%user.name command=%proc.cmdline parent=%proc.pname gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4])
|
||||
|
Loading…
Reference in New Issue
Block a user