Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added rule to detect LKM module injects using insmod used by rootkits for kernel hooking #1401

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ include(GetFalcoVersion)
set(PACKAGE_NAME "falco")
set(PROBE_NAME "falco")
set(PROBE_DEVICE_NAME "falco")
set(DRIVERS_REPO "https://dl.bintray.com/falcosecurity/driver")
set(DRIVERS_REPO "https://download.falco.org/driver")
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX
/usr
Expand Down
137 changes: 137 additions & 0 deletions proposals/20201025-drivers-storage-s3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# Falco Drivers Storage S3

Supersedes: [20200818-artifacts-storage.md#drivers](20200818-artifacts-storage.md#drivers)

Supersedes: [20200901-artifacts-cleanup.md#drivers](20200901-artifacts-cleanup.md#drivers)

## Introduction

In the past days, as many people probably noticed, Bintray started rate-limiting our users, effectively preventing them from downloading any kernel module, rpm/deb package or any pre-built dependency we host there.

This does not only interrupt the workflow of our users but also the workflow of the contributors, since without bintray most of our container images and CMake files can’t download the dependencies we mirror.

### What is the cause?

We had a spike in adoption apparently, either a user with many nodes or an increased number of users. We don’t know this detail specifically yet because bintray does not give us very fine-grained statistics on this.

This is the 30-days history:

![A spike on driver downloads the last ten days](20201025-drivers-storage-s3_downloads.png)

As you can see, we can only see that they downloaded the latest kernel module driver version, however we can’t see if:

* It’s a single source or many different users

* What is the kernel/OS they are using

### What do we host on Bintray?

* RPM packages: high traffic but very manageable ~90k downloads a month

* Deb packages:low traffic ~5k downloads a month

* Pre-built image Dependencies: low traffic, will eventually disappear in the future

* Kernel modules: very high traffic, 700k downloads in 10 days, this is what is causing the current problems. They are primarily used by users of our container images.

* eBPF probes: low traffic ~5k downloads a month

### Motivations to go to S3 instead of Bintray for the Drivers

Bintray does an excellent service at building the rpm/deb structures for us, however we also use them for S3-like storage for the drivers. We have ten thousand files hosted there and the combinations are infinite.


Before today, we had many issues with storage even without the spike in users we are seeing since the last ten days.

## Context on AWS

Amazon AWS, recently gave credits to the Falco project to operate some parts of the infrastructure on AWS. The CNCF is providing a sub-account we are already using for the migration of the other pieces (like Prow).

## Interactions with other teams and the CNCF

* The setup on the AWS account side already done, this is all technical work.

* We need to open a CNCF service account ticket for the download.falco.org subdomain to point to the S3 bucket we want to use

## The Plan

We want to propose to move the drivers and the container dependencies to S3.

#### Moving means:

* We create a public S3 bucket with [stats enabled](https://docs.aws.amazon.com/AmazonS3/latest/dev/analytics-storage-class.html)

* We attach the bucket to a cloudfront distribution behind the download.falco.org subdomain

* We move the current content keeping the same web server directory structure

* We change the Falco Dockerfiles and driver loader script accordingly

* We update test-infra to push the drivers to S3

* Once we have the drivers in S3, we can ask bintray to relax the limits for this month so that our users are able to download the other packages we keep there. Otherwise they will have to wait until November 1st. We only want to do that after the moving because otherwise we will hit the limits pretty quickly.

#### The repositories we want to move are:

* [https://bintray.com/falcosecurity/driver](https://bintray.com/falcosecurity/driver) will become https://download.falco.org/driver

* [https://bintray.com/falcosecurity/dependencies](https://bintray.com/falcosecurity/dependencies) will become https://download.falco.org/dependencies

#### Changes in Falco

* [Search for bintray ](https://github.com/falcosecurity/falco/search?p=2&q=bintray)on the Falco repo and replace the URL for the CMake and Docker files.

* It’s very important to change the DRIVERS_REPO environment variable [here](https://github.com/falcosecurity/falco/blob/0a33f555eb8e019806b46fea8b80a6302a935421/CMakeLists.txt#L86) - this is what updates the falco-driver-loader scripts that the users and container images use to fetch the module

#### Changes in Test Infra

* We need to use the S3 cli instead of jfrog cli to upload to the s3 bucket after building [here](https://github.com/falcosecurity/test-infra/blob/master/.circleci/config.yml)

* We can probably remove jfrog from that repo since it only deals with drivers and drivers are being put on S3 now

* Instructions on how to setup the S3 directory structure [here](https://falco.org/docs/installation/#install-driver)

* `/$driver_version$/falco_$target$_$kernelrelease$_$kernelversion$.[ko|o]`

#### Changes to Falco website

* Changes should not be necessary, we are not updating the way people install Falco but only the driver. The driver is managed by a script we can change.

## Mitigation and next steps for the users

* **The average users should be good to go now, Bintray raised our limits and we have some room to do this without requiring manual steps on your end**

* **Users that can’t wait for us to have the S3 setup done: **can setup an S3 as driver repo themselves, push the drivers they need to it after compiling them (they can use [Driverkit](https://github.com/falcosecurity/driverkit) for that) Instructions on how to setup the S3 directory structure [here](https://falco.org/docs/installation/#install-driver).

* **Users that can’t wait but don’t want to setup a webserver themselves**: the falco-driver-loader script can also compile the module for you. Make sure to install the kernel-headers on your nodes.

* **Users that can wait** we will approve this document and act on the plan described here by providing the DRIVERS_REPO at [https://download.falco.org/driver](https://download.falco.org/driver) that then you can use

### How to use an alternative DRIVERS_REPO ?

**On bash:**

export DRIVERS_REPO=https://your-url-here

**Docker**

Pass it as environment variable using the docker run flag -e - for example:

docker run -e DRIVERS_REPO=[https://your-url-here](https://your-url-here)

**Kubernetes**

spec:

containers:

- env:

- name: DRIVERS_REPO

value: https://your-url-here

## Release

Next release is on December 1st, we want to rollout a hotfix 0.26.2 release that only contains the updated script before that date so that users don’t get confused and we can just tell them "update Falco" to get the thing working again.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 23 additions & 1 deletion rules/falco_rules.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@
- macro: container_started
condition: >
((evt.type = container or
(evt.type=execve and evt.dir=< and proc.vpid=1)) and
(spawned_process and proc.vpid=1)) and
container.image.repository != incomplete)

- macro: interactive
Expand Down Expand Up @@ -1866,6 +1866,7 @@
- list: falco_privileged_images
items: [
docker.io/calico/node,
calico/node,
docker.io/cloudnativelabs/kube-router,
docker.io/docker/ucp-agent,
docker.io/falcosecurity/falco,
Expand Down Expand Up @@ -3031,6 +3032,17 @@
output: Drift detected (open+create), new executable created in a container (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline filename=%evt.arg.filename name=%evt.arg.name mode=%evt.arg.mode event=%evt.type)
priority: ERROR

# find when a new kernel module is injected

- list: white_listed_modules
items: [""]
- rule: Linux Kernel Module Injection Detected
desc: Detect kernel module was injected (from container).
condition: spawned_process and container and evt.type=execve and proc.name=insmod
output: Linux Kernel Module injection using insmod detected (user=%user.name user_loginuid=%user.loginuid parent_process=%proc.pname module=%proc.args)
priority: WARNING
tags: [process]

- list: c2_server_ip_list
items: []

Expand All @@ -3041,6 +3053,16 @@
priority: WARNING
tags: [network]

- list: white_listed_modules
items: []

- rule: Linux Kernel Module Injection Detected
desc: Detect kernel module was injected (from container).
condition: spawned_process and container and evt.type=execve and proc.name=insmod
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

evt.type=execve is redundant. Can you please remove it?

output: Linux Kernel Module injection using insmod detected (user=%user.name user_loginuid=%user.loginuid parent_process=%proc.pname module=%proc.args)
priority: WARNING
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add tags fields with process

tags: [process]

# Application rules have moved to application_rules.yaml. Please look
# there if you want to enable them by adding to
# falco_rules.local.yaml.
2 changes: 1 addition & 1 deletion rules/k8s_audit_rules.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@
condition: >
kevt
and non_system_user
and ka.user.name in (admin_k8s_users)
and ka.user.name in (full_admin_k8s_users)
and not allowed_full_admin_users
output: K8s Operation performed by full admin user (user=%ka.user.name target=%ka.target.name/%ka.target.resource verb=%ka.verb uri=%ka.uri resp=%ka.response.code)
priority: WARNING
Expand Down
11 changes: 5 additions & 6 deletions userspace/engine/formats.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (C) 2019 The Falco Authors.
Copyright (C) 2020 The Falco Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -24,7 +24,7 @@ sinsp *falco_formats::s_inspector = NULL;
falco_engine *falco_formats::s_engine = NULL;
bool falco_formats::s_json_output = false;
bool falco_formats::s_json_include_output_property = true;
sinsp_evt_formatter_cache *falco_formats::s_formatters = NULL;
std::unique_ptr<sinsp_evt_formatter_cache> falco_formats::s_formatters = NULL;

const static struct luaL_reg ll_falco[] =
{
Expand All @@ -42,10 +42,9 @@ void falco_formats::init(sinsp *inspector,
s_engine = engine;
s_json_output = json_output;
s_json_include_output_property = json_include_output_property;
if(!s_formatters)
{
s_formatters = new sinsp_evt_formatter_cache(s_inspector);
}

// todo(leogr): we should have used std::make_unique, but we cannot since it's not C++14
s_formatters = std::unique_ptr<sinsp_evt_formatter_cache>(new sinsp_evt_formatter_cache(s_inspector));

luaL_openlib(ls, "formats", ll_falco, 0);
}
Expand Down
4 changes: 2 additions & 2 deletions userspace/engine/formats.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (C) 2019 The Falco Authors.
Copyright (C) 2020 The Falco Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -53,7 +53,7 @@ class falco_formats

static sinsp *s_inspector;
static falco_engine *s_engine;
static sinsp_evt_formatter_cache *s_formatters;
static std::unique_ptr<sinsp_evt_formatter_cache> s_formatters;
static bool s_json_output;
static bool s_json_include_output_property;
};
5 changes: 3 additions & 2 deletions userspace/falco/event_drops.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (C) 2019 The Falco Authors.
Copyright (C) 2020 The Falco Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -15,6 +15,7 @@ limitations under the License.
*/

#include "event_drops.h"
#include "falco_common.h"
#include "banned.h" // This raises a compilation error when certain functions are used

syscall_evt_drop_mgr::syscall_evt_drop_mgr():
Expand Down Expand Up @@ -137,7 +138,7 @@ bool syscall_evt_drop_mgr::perform_actions(uint64_t now, scap_stats &delta, bool

case ACT_ALERT:
m_outputs->handle_msg(now,
falco_outputs::PRIORITY_CRITICAL,
falco_common::PRIORITY_CRITICAL,
msg,
rule,
output_fields);
Expand Down
5 changes: 2 additions & 3 deletions userspace/falco/falco.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (C) 2019 The Falco Authors.
Copyright (C) 2020 The Falco Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -762,8 +762,7 @@ int falco_init(int argc, char **argv)
}
}

outputs = new falco_outputs(engine);
outputs->set_inspector(inspector);
outputs = new falco_outputs();

// Some combinations of arguments are not allowed.
if (daemon && pidfilename == "") {
Expand Down
17 changes: 5 additions & 12 deletions userspace/falco/falco_outputs.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (C) 2019 The Falco Authors.
Copyright (C) 2020 The Falco Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -38,8 +38,7 @@ limitations under the License.

using namespace std;

falco_outputs::falco_outputs(falco_engine *engine):
m_falco_engine(engine),
falco_outputs::falco_outputs():
m_initialized(false),
m_buffered(true),
m_json_output(false),
Expand All @@ -64,12 +63,6 @@ void falco_outputs::init(bool json_output,
uint32_t rate, uint32_t max_burst, bool buffered,
bool time_format_iso_8601, string hostname)
{
// The engine must have been given an inspector by now.
if(!m_inspector)
{
throw falco_exception("No inspector provided");
}

m_json_output = json_output;

// Note that falco_formats is already initialized by the engine,
Expand Down Expand Up @@ -123,7 +116,7 @@ void falco_outputs::add_output(falco::outputs::config oc)
throw falco_exception("Output not supported: " + oc.name);
}

oo->init(oc, m_buffered, m_time_format_iso_8601, m_hostname);
oo->init(oc, m_buffered, m_hostname);
m_outputs.push_back(oo);
}

Expand Down Expand Up @@ -203,7 +196,7 @@ void falco_outputs::handle_msg(uint64_t now,
iso8601evttime += time_ns;

jmsg["output"] = msg;
jmsg["priority"] = "Critical";
jmsg["priority"] = falco_common::priority_names[priority];
jmsg["rule"] = rule;
jmsg["time"] = iso8601evttime;
jmsg["output_fields"] = output_fields;
Expand All @@ -216,7 +209,7 @@ void falco_outputs::handle_msg(uint64_t now,
bool first = true;

sinsp_utils::ts_to_string(now, &timestr, false, true);
full_msg = timestr + ": " + falco_common::priority_names[LOG_CRIT] + " " + msg + " (";
full_msg = timestr + ": " + falco_common::priority_names[priority] + " " + msg + " (";
for(auto &pair : output_fields)
{
if(first)
Expand Down
8 changes: 3 additions & 5 deletions userspace/falco/falco_outputs.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (C) 2019 The Falco Authors.
Copyright (C) 2020 The Falco Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -31,10 +31,10 @@ limitations under the License.
// falco output engine. The falco rules engine is implemented by a
// separate class falco_engine.
//
class falco_outputs : public falco_common
class falco_outputs
{
public:
falco_outputs(falco_engine *engine);
falco_outputs();
virtual ~falco_outputs();

void init(bool json_output,
Expand All @@ -61,8 +61,6 @@ class falco_outputs : public falco_common
void reopen_outputs();

private:
falco_engine *m_falco_engine;

bool m_initialized;

std::vector<falco::outputs::abstract_output *> m_outputs;
Expand Down
Loading