Commit Graph

629 Commits

Author SHA1 Message Date
Mark Stemm
185729d5d6 Address feedback from PR
- Instead of having a possibly null string pointer as the argument to
   enable_* and process_event, have wrapper versions that assume a
   default falco ruleset. The default ruleset name is a static member of
   the falco_engine class, and the default ruleset id is created/found
   in the constructor.
 - This makes the whole mechanism simple enough that it doesn't require
   seprarate testing, so remove the capability within falco to read a
   ruleset from the environment and remove automated tests that specify
   a ruleset.
 - Make pattern/tags/ruleset arguments to enable_* functions const.

(I'll squash this down before I commit)
2017-02-10 11:54:30 -08:00
Mark Stemm
0a69fc0c85 Tag existing falco ruleset.
Tag the existing ruleset to group tags in a meaningful way. The added
tags are:

 - filesystem: the rule relates to reading/writing files
 - sofware_mgmt: the rule relates to any software/package management
   tool like rpm, dpkg, etc.
 - process: the rule relates to starting a new process or changing the
   state of a current process.
 - database: the rule relates to databases
 - host: the rule *only* works outside of containers
 - shell: the rule specifically relates to starting shells
 - container: the rule *only* works inside containers
 - cis: the rule is related to the CIS Docker benchmark.
 - users: the rule relates to management of users or changing the
   identity of a running process.
 - network: the rule relates to network activity

Rules can have multiple tags if they relate to multiple of the
above. Rules do not have to have tags, although all the current rules do.
2017-02-08 11:08:37 -08:00
Mark Stemm
88faa7c1e7 Add automated tests for tagged rules
Add automated tests that verify the ability to tag sets of rules,
disable them with -T, and run them with -t, works:

 - New test option disable_tags adds -T <tag> arguments to the falco
   command line, and run_tags adds -t <tag> arguments to the falco command
   line.
 - A new trace file open-multiple-files.scap opens 13 different files,
   and a new rules file has 13 different rules with all combinations of
   the tags a, b, c (both forward and backward), a rule with an empty
   list of tags, a rule with no tags field, and a rule with a completely
   different tag d.

Using the above, add tests for:

 - Both disabling all combations of a, b, c using disable_tags as well as
   run all combinations of a, b, c, using run_tags.
 - Specifying both disabled (-T/-D) and enabled (-t) rules. Not allowed.
 - Specifying a ruleset while having tagged rules enabled, rules based
   on a name disabled, and no particular rules enabled or disabled.
2017-02-08 11:08:36 -08:00
Mark Stemm
a0a6914b6a Add support for tagging rules.
- in lua, look for a tags attribute to each rule. This is passed up in
  add_filter as a tags argument (as a lua table). If not present, an
  empty table is used. The tags table is iterated to populate a set
  of tags as strings, which is passed to add_filter().
- A new method falco_engine::enable_rule_by_tag is similar to
  enable_rule(), but is given a set of tag strings. Any rules containing
  one of the tags is enabled/disabled.
- The list of event types has been changed to a set to more accurately
  reflect its purpose.
- New argument to falco -T allows disabling all rules matching a given
  tag, via enable_rule_by_tag(). It can be provided multiple times.
- New argument to falco -t allows running those rules matching a given
  tag. If provided all rules are first disabled. It can be
  provided multiple times, but can not be combined with -T or
  -D (disable rules by name)
- falco_enging supports the notion of a ruleset. The idea is that you
  can choose a set of rules that are enabled/disabled by using
  enable_rule()/enable_rule_by_tag() in combination with a
  ruleset. Later, in process_event() you include that ruleset and the
  rules you had previously enabled will be run.
- rulsets are provided as strings in enable_rule()/enable_rule_by_tag()
  and as numbers in process_event()--this avoids the overhead of string
  lookups per-event. Ruleset ids are created on the fly as needed. A
  utility method find_ruleset_id() looks up the ruleset id for a given
  name. The default ruleset is NULL string/0 numeric if not provided.
- Although the ruleset is a useful falco engine feature, it isn't that
  important to the falco standalone program, so it's not
  documented. However, you can change the ruleset by providing
  FALCO_RULESET in the environment.
2017-02-08 11:08:36 -08:00
Mark Stemm
df08a80a12 Merge pull request #207 from draios/address-addl-falco-fps
Additional changes to reduce FPs.
2017-02-06 16:46:11 -08:00
Mark Stemm
8a1f62c610 Additional changes to reduce FPs.
- Add flanneld as a privileged container.
 - Add parentheses grouping around many of the "x running y"
   containers. I haven't found this strictly necessary with their
   current use in rules, but this ensures they will be isolated when
   used.
 - Allow denyhosts to spawn shells--it runs iptables to add/remove hosts
   from its deny list.
2017-02-06 15:57:54 -08:00
Mark Stemm
1e205db8aa Use right name for event-generator. 2017-02-03 18:10:34 -08:00
Mark Stemm
3d5789a297 Merge pull request #200 from draios/ndis-hids-etc-rule-updates
Rule updates related to other security products
2017-02-01 17:37:09 -08:00
Mark Stemm
b9d0857362 Rule updates related to other security products
This is a rework of a PR made by @juju4 that had a bunch of additions
related to running other security/monitoring products, including aide,
bro, icinga2, nagios, ansible, etc.

This overlapped a lot with changes I had been making to reduce
noisiness, so rather than have @juju4 deal with the conflicts I took the
changes and made a separate commit with the non-conflicting additions.

A summary of the changes:
 - Add docker-compose as a docker binary.
 - Add showq/critical-stack as setuid binaries.
 - Add lxd binaries
 - Add some additional package management binaries.
 - Add support for host intrustion detection systems like aide.
 - Add support for network intrustion detections systems like bro.
 - Add support for monitoring systems like nagios, icinga2, npcd.
 - Other one-off additions to other lists of mail/etc programs.
2017-02-01 16:25:50 -08:00
Mark Stemm
1afbaba632 Merge pull request #205 from draios/demo-improvements
Demo improvements
2017-02-01 16:24:05 -08:00
Mark Stemm
e0a5034a43 Ensure falco-event-generator actions are detected.
A new trace file falco-event-generator.scap contains the result of
running the falco event generator in docker, via:

docker run --security-opt seccomp=unconfined sysdig/falco-event-generator:latest /usr/local/bin/event_generator --once

Make sure this trace file detects the exact set of events we expect for
each rule. This required adding a new verification method
check_detections_by_rule that finds the per-rule counts and compares
them to the expected counts, which are included in the test description
under the key "detect_counts".

This is the first time a trace file for a test is actually in one of the
downloaded zip files. This means it will be tested twice (one for simple
detect-or-not, once for actual counts).

Adding this test showed a problem with Run shell in container
rule--since sysdig/falco-event-generator startswith sysdig/falco, it was
being treated as a trusted container. Modify the macro
trusted_containers to not allow falco-event-generator to be trusted.
2017-02-01 15:02:44 -08:00
Mark Stemm
6356490b1c Misc demo improvements.
Small changes to improve the use of falco_event_generator with falco:

 - In event_generator, some actions like exec_ls won't trigger
   notifications on their own. So exclude them from -a all.
 - For all actions, print details on what the action will do.
 - For actions that won't result in a falco notification in containers,
   note that in the output.
 - The short version of --once wasn't working, fix the getopt.
 - Explicitly saying -a all wasn't working, fix.
 - Don't rely on an external ruleset in the nodejs docker-compose
   demo--the built in rules are sufficient now.
2017-02-01 14:51:18 -08:00
Mark Stemm
511d0997da Merge pull request #204 from draios/cmake-dependencies
CMakeLists: add dependencies to lyaml project (fix #130)
2017-01-31 14:40:05 -08:00
Riccardo Schirone
6f9f1e4792 CMakeLists: add dependencies to lyaml project 2017-01-31 21:57:26 +00:00
Mark Stemm
c09b6390a3 Merge pull request #202 from draios/more-spurious-alerts
Address more spurious alerts
2017-01-27 12:21:22 -08:00
Mark Stemm
3f2814259a Address more spurious alerts
- Add a second possible location for denyhosts
 - Add PM2 (http://pm2.keymetrics.io/) as a shell spawner.
 - There was a bug in use of ansible_running_python. We actually need
   two variants depending on whether ansible is the parent or current
   process. parent_ansble_running_python is used for Run shell
   untrusted, ansible_running_python is used for other rules.
2017-01-27 11:49:02 -08:00
Mark Stemm
b04bccd1a7 Merge pull request #201 from draios/remove-cchh
Remove cchh image.
2017-01-27 10:14:51 -08:00
Mark Stemm
e21fecf0ef Remove cchh image.
We had added this image while the changes in
https://github.com/draios/falco/pull/177 made it to everyone. This is in
a release now, so we'll remove it from the rule set.
2017-01-27 09:03:25 -08:00
Mark Stemm
ceafeca87e Merge pull request #199 from draios/no-assert-travis-debug
Set -DNDEBUG for travis debug builds.
2017-01-26 10:55:32 -08:00
Mark Stemm
9285aa59c1 Set -DNDEBUG for travis debug builds.
Within the sysdig code there are several ASSERTS() that can occur for
error paths that aren't truly critical, such as:

17:33:52 DEBUG| [stderr] falco: /home/travis/build/draios/sysdig/userspace/libsinsp/parsers.cpp:1657: static void sinsp_parser::parse_openat_dir(sinsp_evt*, char*, int64_t, std::string*): Assertion `false' failed.

Looking at the code, it's not a truly fatal error, just an inability to
find fd information:

----
     if(evt->m_fdinfo == NULL)
     {
             ASSERT(false);
             *sdir = "<UNKNOWN>";
     }
----

When running regression tests in travis, we don't want these ASSERTs to
cause falco to exit.

To allow this, in CMakeLists.txt only set DRAIOS_DEBUG_FLAGS if it
wasn't already set, and in travis's cmake, add -DNDEBUG to
DRAIOS_DEBUG_FLAGS.
2017-01-26 10:12:11 -08:00
Mark Stemm
34e17cb951 Several changes to reduce FPs
Several changes to reduce spurious alerts when managing machines via
ansible:

 - Add ansible_running_python (that is, ansible-spawned python scripts)
   as scripts that can read sensitive files and write below
   /etc. Notably this is the user ansible module.
 - Also add comments to ansible_running_python suggesting users make it
   more strict by specifically naming the root directory for ansible
   scripts.
 - Add pypy as a python variant that can run ansible-related scripts.

Also other changes to reduce FPs:

 - add apt-add-reposit, apt-auto-remova (truncation intentional),
   apt-get, apt, apt-key as package management programs, and add package
   management binaries to the set of shell spawners. The overlapping
   binaries that were in known_shell_spawn_binaries were removed.
 - add passwd_binaries, gpg, insserv, apparmor_parser, update-mime,
   tzdata.{config,postinst}, systemd-machine, and debconf-show to
   the set of binaries that can write below /etc.
 - Add vsftpd as a program that can read sensitive files.
 - Add additional programs (incl. python support programs like pip,
   pycompile) as ones that can spawn shells.
 - Allow privileged containers to spawn shells.
 - Break out the set of files below /dev that are written to with O_CREAT
   into a separate list, and add /dev/random,urandom,console to the list.
 - Add python running denyhosts as a program that can write below /etc.
 - Also add binaries starting with linux-image- as ones that can spawn
   shells. These are perl scripts run as a part of installing
   linux-image-N.N packages.
2017-01-25 08:34:52 -08:00
Mark Stemm
bc83ac18a0 Allow shells spawned by ansible.
Changes to allow shells spawned by ansible. In general this is actually
pretty difficult--on the remote managed machine, ansible performs
actions simply by running python over ssh without any explicit ansible
helper or command line.

One (weak) hint is that the python scripts being run are usually under a
directory with ansible in the name. So use that as the basis for a macro
ansible_running_python. In turn, that macro is used as a negative
condition for the run shell untrusted rule.

This is a pretty fragile and easily exploited condition, so add a note
to the macro saying so.
2017-01-19 15:09:24 -08:00
Mark Stemm
10d0c8f982 Add a local dockerfile variant.
Add a local dockerfile variant that allows creating an image from a
local .deb package.
2017-01-17 10:24:38 -08:00
Mark Stemm
8f53bcbb05 Patch jq 1.5 with a fix for security vulns.
After downloading jq 1.5, apply the changes in
stedolan/jq@8eb1367
by downloading the commit as a patch and applying it. This fixes
CVE-2015-8863.
2017-01-17 10:24:38 -08:00
Mark Stemm
7286b50f4d Update libcurl to 7.52.1.
This fixes a set of ~10 security vulnerabilities.
2017-01-17 10:24:38 -08:00
Mark Stemm
4c60b7c1d2 Update openssl to 1.0.2j.
This fixes a set of ~25 security vulnerabilities.
2017-01-17 10:24:38 -08:00
Mark Stemm
85480f32d6 Avoid FPs resulting from ubuntu weekly cron jobs
Feedback from a falco user:

--
to more findings from last night:

logrotate cronjob (Debian default):

Shell spawned by untrusted binary (user=root shell=sh parent=logrotate cmdline=sh -c invoke-rc.d rsyslog rotate > /dev/null logrotate_script /var/log/syslog)

passwd cronjob (Debian default):

Sensitive file opened for reading by non-trusted program (user=root name=cmp command=cmp -s shadow.bak /etc/shadow file=/etc/shadow)
--

New macro cmp_cp_by_passwd allows cmp/cp to be run by passwd to examine
sensitive files. Add logrotate as a program that can spawn a shell.

Also do some cleanups, moving items to lists and splitting long
single-line conditions into multiple lines.
2017-01-17 09:12:53 -08:00
Luca Marturana
4139370df5
Merge branch 'agent-master' into dev
agent-master went out of sync, probably some rebase/forcepush happened
on dev. Used `git merge -s ours agent-master` here to put all the
commits of agent-master on dev and ignoring anything from agent-master.

So now we can merge from dev to agent-master with fast forward and no
conflicts
2017-01-17 10:58:08 +01:00
Mark Stemm
43d53bb09e Add exechealthz as a k8s binary.
For customers who use
https://github.com/kubernetes/contrib/tree/master/exec-healthz to
perform liveness checking, exechealthz will spawn shells in a
container. Add it to the k8s_binaries list.
2017-01-12 10:32:13 -08:00
Luca Marturana
af3a708251
Improve comment 2017-01-04 18:05:46 +01:00
Mark Stemm
f4bb49f1f5 Add test for truncated outputs.
Add a test that specifically tests truncated outputs. A rule contains an
output field %fd.cport which has no value for an open event. Ensure that
the rule's output has <NA> for the cport and the remainder of the rule's
output is filled in.
2017-01-03 12:58:01 -08:00
Mark Stemm
362a6b7b9a Prefix outputs with * within the engine.
Prefix output strings with * so they are always permissive in the
engine.

In falco outputs, which adds its own prefix, remove any leading * before
adding the custom prefix.
2017-01-03 12:58:01 -08:00
Mark Stemm
77a5429cae Add cchh/sysdig as a trusted container.
Add cchh/sysdig as a trusted container. We'll probably remove this once
the next agent release occurs that has the fix
https://github.com/draios/falco/pull/177.

Also reformat to avoid long lines.
2016-12-30 12:28:02 -08:00
Mark Stemm
9ecdf30314 tests for overriding rules/macros/lists
New tests that test every possible override:

 - Overriding a rule with one that doesn't match
 - Overriding a macro to one that doesn't match
 - Overriding a top level list to a binary that doesn't match
 - Overriding an embedded list to one that doesn't match

In each case, the override results in no longer matching an open by the
program "cat".
2016-12-29 13:32:55 -08:00
Mark Stemm
7c419b6d6b Allow any macro/list/rule to be overridden
Allow any list/macro/rule to be overridden by a subsequent file. The
persistent state that lives across invocations of load_rules are the 3
arrays ordered_{list,macro,rule}_names, which have the
lists/macros/rules in the order in which they first appear, and tables
{rules,macros,lists}_by_name, which maps from a name to a yaml object.

With each call to load_rules, the set of loaded rules is reset and the
state of expanded lists, compiled macros, compiled rules, and rule
metadata are recreated from scratch, using the ordered_*_names arrays
and *_by_name tables. That way, any list/macro/rule can be redefined in
a subsequent file with new values.
2016-12-29 13:32:55 -08:00
Mark Stemm
767f2d5bb4 Add ability to clear loaded rules.
Add the ability to clear the set of loaded rules from lua. It simply
recreates the sinsp_evttype_filter instance m_evttype_filter, which is
now a unique_ptr.
2016-12-29 13:32:55 -08:00
Mark Stemm
3cbf641ded Add confd/fleetctl as acceptable programs.
Add confd as a program that can write files below /etc and fleetctl as a
program that can spawn shells.
2016-12-28 12:38:39 -08:00
Mark Stemm
4ab72d0391 Updating docs for 0.5.0.
New changelog and readme updates.
2016-12-22 12:55:36 -08:00
Jonathan Coetzee
9e933ce5ba Add apt and apt-get as trusted shells
Periodically both apt and apt-get will spawn shells to update success timestamps and motd.

falco-CLA-1.0-signed-off-by: Jonathan Coetzee <jon@thancoetzee.com>
2016-12-22 12:55:36 -08:00
Jonathan Coetzee
c3c6ec67f7 Add systemd as a login binary
SSH'ing into an Ubuntu 16.04 box triggers a bunch of "Sensitive file opened for reading by non-trusted program" errors caused by systemd

falco-CLA-1.0-signed-off-by: Jonathan Coetzee jon@thancoetzee.com
2016-12-22 12:55:36 -08:00
Jonathan Coetzee
9062459669 Add fail2ban-server as trusted binary
fail2ban spawns shells to modify iptables

falco-CLA-1.0-signed-off-by: Jonathan Coetzee <jon@thancoetzee.com>
2016-12-22 12:55:36 -08:00
Mark Stemm
94cef1b541 Revert "Add fail2ban-server as spawn shell trusted binary" 2016-12-22 12:55:36 -08:00
Jonathan Coetzee
dd6b4fd7c0 Add fail2ban-server as spawn shell trusted binary
fail2ban spawns a shell to adjust iptables in order to ban/unban IP addresses.
2016-12-22 12:55:36 -08:00
Mark Stemm
c6953e810b Use sinsp utils version of get time.
sinsp_utils::get_current_time_ns() has the same purpose as
get_epoch_ns(), and now that we're including the token bucket in
falco_engine, it's easy to package the dependency. So use that function
instead.
2016-12-22 12:55:36 -08:00
Mark Stemm
104c99c42e Add rate-limiting for notifications
Add token-bucket based rate limiting for falco notifications.

The token bucket is implemented in token_bucket.cpp (actually in the
engine directory, just to make it easier to include in other
programs). It maintains a current count of tokens (i.e. right to send a
notification). Its main method is claim(), which attemps to claim a
token and returns true if one was claimed successfully. It has a
configurable configurable max burst size and rate. The token bucket
gains "rate" tokens per second, up to a maximum of max_burst tokens.

These parameters are configurable in falco.yaml via the config
options (defaults shown):

outputs:
  rate: 1
  max_burst: 1000

In falco_outputs::handle_event(), try to claim a token, and if
unsuccessful log a debug message and return immediately.
2016-12-22 12:55:36 -08:00
Mark Stemm
f2bfa584e4 Fix misleading variable name.
The second argument to handle_event is actually a rule name, but the
variable was a misleading "level". Fix.
2016-12-22 12:55:36 -08:00
Mark Stemm
6f54a752a2 Make google_containers/kube-proxy a trusted image.
Add google_containers/kube-proxy as a trusted image (can be run
privileged, can mount sensitive filesystems). While our k8s deployments
run kube-proxy via the hyperkube image, evidently it's sometimes run via
its own image.

This is one of the fixes for #156.

Also update the output message for this rule.
2016-12-22 12:55:36 -08:00
Mark Stemm
6c04f53d24 Add log levels.
Previously, log messages had levels, but it only influenced the level
argument passed to syslog(). Now, add the ability to control log level
from falco itself.

New falco.yaml argument "log_level" can be one of the strings
corresponding to the well-known syslog levels, which is converted to a
syslog-style level as integer.

In falco_logger::log(), skip messages below the specified level.
2016-12-22 12:55:36 -08:00
Mark Stemm
db67034338 Cache formatters.
Instead of creating a formatter for each event, cache them and create
them only when needed. A new function output_cleanup cleans up the
cached formatters, and is called in the destructor if init() was called.
2016-12-22 12:55:36 -08:00
Mark Stemm
2a2dcaf25d Modify plotting script to handle drop stats.
New argument --metric, which can be cpu|drops, controls whether to graph
cpu usage or event drop percentage. Titles/axis labels/etc. change
appropriately.
2016-12-22 12:55:36 -08:00