mirror of
https://github.com/falcosecurity/falco.git
synced 2026-04-02 18:12:15 +00:00
Compare commits
41 Commits
new/plugin
...
embeddable
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c3fe8a4e7 | ||
|
|
5787dfa098 | ||
|
|
2434942bdc | ||
|
|
2f7b72d670 | ||
|
|
50e8da1049 | ||
|
|
5c398bd396 | ||
|
|
efbe887d6e | ||
|
|
7dcbeb1f44 | ||
|
|
93667f2d3e | ||
|
|
b5b1763d09 | ||
|
|
d6690313a0 | ||
|
|
98ce88f7ef | ||
|
|
9ff8099501 | ||
|
|
7db4778f55 | ||
|
|
7f761ade4b | ||
|
|
84257912e0 | ||
|
|
9bc942c654 | ||
|
|
8216b435cb | ||
|
|
78f710c706 | ||
|
|
1dd97c1b6f | ||
|
|
3ef5716fa2 | ||
|
|
64102078c7 | ||
|
|
9703853da8 | ||
|
|
96403fa275 | ||
|
|
acd5422b55 | ||
|
|
099c79ddde | ||
|
|
0f24448d18 | ||
|
|
1b63ad1aed | ||
|
|
b268d4d6c3 | ||
|
|
684a5d85ff | ||
|
|
58cea0c5e7 | ||
|
|
38ebc61808 | ||
|
|
535db19991 | ||
|
|
abe46a19a0 | ||
|
|
96fc8d1a27 | ||
|
|
ad82f66be3 | ||
|
|
c60fac9e34 | ||
|
|
35dc315390 | ||
|
|
62c995f309 | ||
|
|
3432551295 | ||
|
|
09e1604fe0 |
@@ -13,7 +13,7 @@ jobs:
|
|||||||
command: apk update
|
command: apk update
|
||||||
- run:
|
- run:
|
||||||
name: Install build dependencies
|
name: Install build dependencies
|
||||||
command: apk add g++ gcc cmake cmake make ncurses-dev git bash perl linux-headers autoconf automake m4 libtool elfutils-dev libelf-static patch binutils
|
command: apk add g++ gcc cmake cmake make git bash perl linux-headers autoconf automake m4 libtool elfutils-dev libelf-static patch binutils
|
||||||
- run:
|
- run:
|
||||||
name: Prepare project
|
name: Prepare project
|
||||||
command: |
|
command: |
|
||||||
@@ -60,7 +60,7 @@ jobs:
|
|||||||
command: apt update -y
|
command: apt update -y
|
||||||
- run:
|
- run:
|
||||||
name: Install dependencies
|
name: Install dependencies
|
||||||
command: DEBIAN_FRONTEND=noninteractive apt install libjq-dev libncurses-dev libyaml-cpp-dev libelf-dev cmake build-essential git -y
|
command: DEBIAN_FRONTEND=noninteractive apt install libjq-dev libyaml-cpp-dev libelf-dev cmake build-essential git -y
|
||||||
- run:
|
- run:
|
||||||
name: Prepare project
|
name: Prepare project
|
||||||
command: |
|
command: |
|
||||||
@@ -92,7 +92,7 @@ jobs:
|
|||||||
command: apt update -y
|
command: apt update -y
|
||||||
- run:
|
- run:
|
||||||
name: Install dependencies
|
name: Install dependencies
|
||||||
command: DEBIAN_FRONTEND=noninteractive apt install libssl-dev libyaml-dev libncurses-dev libc-ares-dev libprotobuf-dev protobuf-compiler libjq-dev libyaml-cpp-dev libgrpc++-dev protobuf-compiler-grpc rpm libelf-dev cmake build-essential libcurl4-openssl-dev linux-headers-generic clang llvm git -y
|
command: DEBIAN_FRONTEND=noninteractive apt install libssl-dev libyaml-dev libc-ares-dev libprotobuf-dev protobuf-compiler libjq-dev libyaml-cpp-dev libgrpc++-dev protobuf-compiler-grpc rpm libelf-dev cmake build-essential libcurl4-openssl-dev linux-headers-generic clang llvm git -y
|
||||||
- run:
|
- run:
|
||||||
name: Prepare project
|
name: Prepare project
|
||||||
command: |
|
command: |
|
||||||
@@ -124,7 +124,7 @@ jobs:
|
|||||||
command: apt update -y
|
command: apt update -y
|
||||||
- run:
|
- run:
|
||||||
name: Install dependencies
|
name: Install dependencies
|
||||||
command: DEBIAN_FRONTEND=noninteractive apt install libssl-dev libyaml-dev libncurses-dev libc-ares-dev libprotobuf-dev protobuf-compiler libjq-dev libyaml-cpp-dev libgrpc++-dev protobuf-compiler-grpc rpm libelf-dev cmake build-essential libcurl4-openssl-dev linux-headers-generic clang llvm git -y
|
command: DEBIAN_FRONTEND=noninteractive apt install libssl-dev libyaml-dev libc-ares-dev libprotobuf-dev protobuf-compiler libjq-dev libyaml-cpp-dev libgrpc++-dev protobuf-compiler-grpc rpm libelf-dev cmake build-essential libcurl4-openssl-dev linux-headers-generic clang llvm git -y
|
||||||
- run:
|
- run:
|
||||||
name: Prepare project
|
name: Prepare project
|
||||||
command: |
|
command: |
|
||||||
@@ -156,7 +156,7 @@ jobs:
|
|||||||
command: apt update -y
|
command: apt update -y
|
||||||
- run:
|
- run:
|
||||||
name: Install dependencies
|
name: Install dependencies
|
||||||
command: DEBIAN_FRONTEND=noninteractive apt install cmake build-essential clang llvm git linux-headers-generic libncurses-dev pkg-config autoconf libtool libelf-dev -y
|
command: DEBIAN_FRONTEND=noninteractive apt install cmake build-essential clang llvm git linux-headers-generic pkg-config autoconf libtool libelf-dev -y
|
||||||
- run:
|
- run:
|
||||||
name: Prepare project
|
name: Prepare project
|
||||||
command: |
|
command: |
|
||||||
@@ -188,7 +188,7 @@ jobs:
|
|||||||
command: dnf update -y
|
command: dnf update -y
|
||||||
- run:
|
- run:
|
||||||
name: Install dependencies
|
name: Install dependencies
|
||||||
command: dnf install gcc gcc-c++ git make cmake autoconf automake pkg-config patch ncurses-devel libtool elfutils-libelf-devel diffutils kernel-devel kernel-headers kernel-core clang llvm which -y
|
command: dnf install gcc gcc-c++ git make cmake autoconf automake pkg-config patch libtool elfutils-libelf-devel diffutils kernel-devel kernel-headers kernel-core clang llvm which -y
|
||||||
- run:
|
- run:
|
||||||
name: Prepare project
|
name: Prepare project
|
||||||
command: |
|
command: |
|
||||||
|
|||||||
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,6 +1,6 @@
|
|||||||
<!-- Thanks for sending a pull request! Here are some tips for you:
|
<!-- Thanks for sending a pull request! Here are some tips for you:
|
||||||
|
|
||||||
1. If this is your first time, please read our contributor guidelines in the [CONTRIBUTING.md](CONTRIBUTING.md) file and learn how to compile Falco from source [here](https://falco.org/docs/source).
|
1. If this is your first time, please read our contributor guidelines in the [CONTRIBUTING.md](https://github.com/falcosecurity/.github/blob/master/CONTRIBUTING.md) file and learn how to compile Falco from source [here](https://falco.org/docs/source).
|
||||||
2. Please label this pull request according to what type of issue you are addressing.
|
2. Please label this pull request according to what type of issue you are addressing.
|
||||||
3. . Please add a release note!
|
3. . Please add a release note!
|
||||||
4. If the PR is unfinished while opening it specify a wip in the title before the actual title, for example, "wip: my awesome feature"
|
4. If the PR is unfinished while opening it specify a wip in the title before the actual title, for example, "wip: my awesome feature"
|
||||||
|
|||||||
49
CHANGELOG.md
49
CHANGELOG.md
@@ -1,5 +1,54 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## v0.29.1
|
||||||
|
|
||||||
|
Released on 2021-06-29
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
* update: bump the Falco engine version to version 9 [[#1675](https://github.com/falcosecurity/falco/pull/1675)] - [@leodido](https://github.com/leodido)
|
||||||
|
|
||||||
|
### Rule Changes
|
||||||
|
|
||||||
|
* rule(list user_known_userfaultfd_processes): list to exclude processes known to use userfaultfd syscall [[#1675](https://github.com/falcosecurity/falco/pull/1675)] - [@leodido](https://github.com/leodido)
|
||||||
|
* rule(macro consider_userfaultfd_activities): macro to gate the "Unprivileged Delegation of Page Faults Handling to a Userspace Process" rule [[#1675](https://github.com/falcosecurity/falco/pull/1675)] - [@leodido](https://github.com/leodido)
|
||||||
|
* rule(Unprivileged Delegation of Page Faults Handling to a Userspace Process): new rule to detect successful unprivileged userfaultfd syscalls [[#1675](https://github.com/falcosecurity/falco/pull/1675)] - [@leodido](https://github.com/leodido)
|
||||||
|
* rule(Linux Kernel Module Injection Detected): adding container info to the output of the rule [[#1675](https://github.com/falcosecurity/falco/pull/1675)] - [@leodido](https://github.com/leodido)
|
||||||
|
|
||||||
|
### Non user-facing changes
|
||||||
|
|
||||||
|
* docs(release.md): update steps [[#1684](https://github.com/falcosecurity/falco/pull/1684)] - [@maxgio92](https://github.com/maxgio92)
|
||||||
|
|
||||||
|
|
||||||
|
## v0.29.0
|
||||||
|
|
||||||
|
Released on 2021-06-21
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
* update: driver version is 17f5df52a7d9ed6bb12d3b1768460def8439936d now [[#1669](https://github.com/falcosecurity/falco/pull/1669)] - [@leogr](https://github.com/leogr)
|
||||||
|
|
||||||
|
### Rule Changes
|
||||||
|
|
||||||
|
* rule(list miner_domains): add rx.unmineable.com for anti-miner detection [[#1676](https://github.com/falcosecurity/falco/pull/1676)] - [@fntlnz](https://github.com/fntlnz)
|
||||||
|
* rule(Change thread namespace and Set Setuid or Setgid bit): disable by default [[#1632](https://github.com/falcosecurity/falco/pull/1632)] - [@Kaizhe](https://github.com/Kaizhe)
|
||||||
|
* rule(list known_sa_list): add namespace-controller, statefulset-controller, disruption-controller, job-controller, horizontal-pod-autoscaler and persistent-volume-binder as allowed service accounts in the kube-system namespace [[#1659](https://github.com/falcosecurity/falco/pull/1659)] - [@sboschman](https://github.com/sboschman)
|
||||||
|
* rule(Non sudo setuid): check user id as well in case user name info is not available [[#1665](https://github.com/falcosecurity/falco/pull/1665)] - [@Kaizhe](https://github.com/Kaizhe)
|
||||||
|
* rule(Debugfs Launched in Privileged Container): fix typo in description [[#1657](https://github.com/falcosecurity/falco/pull/1657)] - [@Kaizhe](https://github.com/Kaizhe)
|
||||||
|
|
||||||
|
### Non user-facing changes
|
||||||
|
|
||||||
|
* Fix link to CONTRIBUTING.md in the Pull Request Template [[#1679](https://github.com/falcosecurity/falco/pull/1679)] - [@tspearconquest](https://github.com/tspearconquest)
|
||||||
|
* fetch libs and drivers from the new repo [[#1552](https://github.com/falcosecurity/falco/pull/1552)] - [@leogr](https://github.com/leogr)
|
||||||
|
* build(test): upgrade urllib3 to 1.26.5 [[#1666](https://github.com/falcosecurity/falco/pull/1666)] - [@leogr](https://github.com/leogr)
|
||||||
|
* revert: add notes for 0.28.2 release [[#1663](https://github.com/falcosecurity/falco/pull/1663)] - [@maxgio92](https://github.com/maxgio92)
|
||||||
|
* changelog: add notes for 0.28.2 release [[#1661](https://github.com/falcosecurity/falco/pull/1661)] - [@maxgio92](https://github.com/maxgio92)
|
||||||
|
* docs(release.md): add blog announcement to post-release tasks [[#1652](https://github.com/falcosecurity/falco/pull/1652)] - [@maxgio92](https://github.com/maxgio92)
|
||||||
|
* add Yahoo!Japan as an adopter [[#1651](https://github.com/falcosecurity/falco/pull/1651)] - [@ukitazume](https://github.com/ukitazume)
|
||||||
|
* Add Replicated to adopters [[#1649](https://github.com/falcosecurity/falco/pull/1649)] - [@diamonwiggins](https://github.com/diamonwiggins)
|
||||||
|
* docs(proposals): fix libs contribution name [[#1641](https://github.com/falcosecurity/falco/pull/1641)] - [@leodido](https://github.com/leodido)
|
||||||
|
|
||||||
|
|
||||||
## v0.28.1
|
## v0.28.1
|
||||||
|
|
||||||
Released on 2021-05-07
|
Released on 2021-05-07
|
||||||
|
|||||||
@@ -77,6 +77,10 @@ Now assume `x.y.z` is the new version.
|
|||||||
| `docker pull docker.io/falcosecurity/falco-driver-loader:x.y.z` |
|
| `docker pull docker.io/falcosecurity/falco-driver-loader:x.y.z` |
|
||||||
| `docker pull docker.io/falcosecurity/falco-no-driver:x.y.z` |
|
| `docker pull docker.io/falcosecurity/falco-no-driver:x.y.z` |
|
||||||
|
|
||||||
|
<changelog>
|
||||||
|
|
||||||
|
<!-- Substitute <changelog> with the one generated by [rn2md](https://github.com/leodido/rn2md) -->
|
||||||
|
|
||||||
### Statistics
|
### Statistics
|
||||||
|
|
||||||
| Merged PRs | Number |
|
| Merged PRs | Number |
|
||||||
@@ -111,3 +115,4 @@ Announce the new release to the world!
|
|||||||
- Publish a blog on [Falco website](https://github.com/falcosecurity/falco-website) ([example](https://github.com/falcosecurity/falco-website/blob/master/content/en/blog/falco-0-28-1.md))
|
- Publish a blog on [Falco website](https://github.com/falcosecurity/falco-website) ([example](https://github.com/falcosecurity/falco-website/blob/master/content/en/blog/falco-0-28-1.md))
|
||||||
- Send an announcement to cncf-falco-dev@lists.cncf.io (plain text, please)
|
- Send an announcement to cncf-falco-dev@lists.cncf.io (plain text, please)
|
||||||
- Let folks in the slack #falco channel know about a new release came out
|
- Let folks in the slack #falco channel know about a new release came out
|
||||||
|
- IFF the on going release introduces a **new minor version**, [archive a snapshot of the Falco website](https://github.com/falcosecurity/falco-website/blob/master/release.md#documentation-versioning)
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ file(MAKE_DIRECTORY ${FALCOSECURITY_LIBS_CMAKE_WORKING_DIR})
|
|||||||
# default below In case you want to test against another falcosecurity/libs version just pass the variable - ie., `cmake
|
# default below In case you want to test against another falcosecurity/libs version just pass the variable - ie., `cmake
|
||||||
# -DFALCOSECURITY_LIBS_VERSION=dev ..`
|
# -DFALCOSECURITY_LIBS_VERSION=dev ..`
|
||||||
if(NOT FALCOSECURITY_LIBS_VERSION)
|
if(NOT FALCOSECURITY_LIBS_VERSION)
|
||||||
set(FALCOSECURITY_LIBS_VERSION "13ec67ebd23417273275296813066e07cb85bc91")
|
set(FALCOSECURITY_LIBS_VERSION "new/plugin-system-api-additions")
|
||||||
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=c2cc1c17af98cef1fa958841da3cfc480774190b5cebc503faf4184cf2b2abfa")
|
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=ba0ea2e22121b8543cb1ebe616090097c4dc3f093db8f0bb5cf2ce5a7e0425a0")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# cd /path/to/build && cmake /path/to/source
|
# cd /path/to/build && cmake /path/to/source
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ ENV FALCO_VERSION=${FALCO_VERSION}
|
|||||||
|
|
||||||
# build toolchain
|
# build toolchain
|
||||||
RUN yum -y install centos-release-scl && \
|
RUN yum -y install centos-release-scl && \
|
||||||
INSTALL_PKGS="devtoolset-7-gcc devtoolset-7-gcc-c++ devtoolset-7-toolchain devtoolset-7-libstdc++-devel devtoolset-7-elfutils-libelf-devel llvm-toolset-7 glibc-static autoconf automake libtool createrepo expect git which libcurl-devel zlib-devel ncurses-devel rpm-build libyaml-devel" && \
|
INSTALL_PKGS="devtoolset-7-gcc devtoolset-7-gcc-c++ devtoolset-7-toolchain devtoolset-7-libstdc++-devel devtoolset-7-elfutils-libelf-devel llvm-toolset-7 glibc-static autoconf automake libtool createrepo expect git which libcurl-devel zlib-devel rpm-build libyaml-devel" && \
|
||||||
yum -y install --setopt=tsflags=nodocs $INSTALL_PKGS && \
|
yum -y install --setopt=tsflags=nodocs $INSTALL_PKGS && \
|
||||||
rpm -V $INSTALL_PKGS
|
rpm -V $INSTALL_PKGS
|
||||||
|
|
||||||
|
|||||||
@@ -15,10 +15,10 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
# The latest Falco Engine version is 8 if you want to
|
# The latest Falco Engine version is 9.
|
||||||
# use exceptions. However the default rules file does not
|
# Starting with version 8, the Falco engine supports exceptions.
|
||||||
# use them so we stick with 7 for compatibility.
|
# However the Falco rules file does not use them by default.
|
||||||
- required_engine_version: 7
|
- required_engine_version: 9
|
||||||
|
|
||||||
# Currently disabled as read/write are ignored syscalls. The nearly
|
# Currently disabled as read/write are ignored syscalls. The nearly
|
||||||
# similar open_write/open_read check for files being opened for
|
# similar open_write/open_read check for files being opened for
|
||||||
@@ -1565,6 +1565,7 @@
|
|||||||
and not calico_node
|
and not calico_node
|
||||||
and not weaveworks_scope
|
and not weaveworks_scope
|
||||||
and not user_known_change_thread_namespace_activities
|
and not user_known_change_thread_namespace_activities
|
||||||
|
enabled: false
|
||||||
output: >
|
output: >
|
||||||
Namespace change (setns) by unexpected program (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline
|
Namespace change (setns) by unexpected program (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline
|
||||||
parent=%proc.pname %container.info container_id=%container.id image=%container.image.repository:%container.image.tag)
|
parent=%proc.pname %container.info container_id=%container.id image=%container.image.repository:%container.image.tag)
|
||||||
@@ -1752,13 +1753,13 @@
|
|||||||
- macro: allowed_aws_ecr_registry_root_for_eks
|
- macro: allowed_aws_ecr_registry_root_for_eks
|
||||||
condition: >
|
condition: >
|
||||||
(container.image.repository startswith "602401143452.dkr.ecr" or
|
(container.image.repository startswith "602401143452.dkr.ecr" or
|
||||||
container.image.repository startswith "877085696533.dkr.ecr" or
|
container.image.repository startswith "877085696533.dkr.ecr" or
|
||||||
container.image.repository startswith "800184023465.dkr.ecr" or
|
container.image.repository startswith "800184023465.dkr.ecr" or
|
||||||
container.image.repository startswith "602401143452.dkr.ecr" or
|
container.image.repository startswith "602401143452.dkr.ecr" or
|
||||||
container.image.repository startswith "918309763551.dkr.ecr" or
|
container.image.repository startswith "918309763551.dkr.ecr" or
|
||||||
container.image.repository startswith "961992271922.dkr.ecr" or
|
container.image.repository startswith "961992271922.dkr.ecr" or
|
||||||
container.image.repository startswith "590381155156.dkr.ecr" or
|
container.image.repository startswith "590381155156.dkr.ecr" or
|
||||||
container.image.repository startswith "558608220178.dkr.ecr" or
|
container.image.repository startswith "558608220178.dkr.ecr" or
|
||||||
container.image.repository startswith "151742754352.dkr.ecr" or
|
container.image.repository startswith "151742754352.dkr.ecr" or
|
||||||
container.image.repository startswith "013241004608.dkr.ecr")
|
container.image.repository startswith "013241004608.dkr.ecr")
|
||||||
|
|
||||||
@@ -2234,7 +2235,7 @@
|
|||||||
condition: >
|
condition: >
|
||||||
evt.type=setuid and evt.dir=>
|
evt.type=setuid and evt.dir=>
|
||||||
and (known_user_in_container or not container)
|
and (known_user_in_container or not container)
|
||||||
and not user.name=root
|
and not (user.name=root or user.uid=0)
|
||||||
and not somebody_becoming_themself
|
and not somebody_becoming_themself
|
||||||
and not proc.name in (known_setuid_binaries, userexec_binaries, mail_binaries, docker_binaries,
|
and not proc.name in (known_setuid_binaries, userexec_binaries, mail_binaries, docker_binaries,
|
||||||
nomachine_binaries)
|
nomachine_binaries)
|
||||||
@@ -2641,6 +2642,7 @@
|
|||||||
and not proc.name in (user_known_chmod_applications)
|
and not proc.name in (user_known_chmod_applications)
|
||||||
and not exe_running_docker_save
|
and not exe_running_docker_save
|
||||||
and not user_known_set_setuid_or_setgid_bit_conditions
|
and not user_known_set_setuid_or_setgid_bit_conditions
|
||||||
|
enabled: false
|
||||||
output: >
|
output: >
|
||||||
Setuid or setgid bit is set via chmod (fd=%evt.arg.fd filename=%evt.arg.filename mode=%evt.arg.mode user=%user.name user_loginuid=%user.loginuid process=%proc.name
|
Setuid or setgid bit is set via chmod (fd=%evt.arg.fd filename=%evt.arg.filename mode=%evt.arg.mode user=%user.name user_loginuid=%user.loginuid process=%proc.name
|
||||||
command=%proc.cmdline container_id=%container.id container_name=%container.name image=%container.image.repository:%container.image.tag)
|
command=%proc.cmdline container_id=%container.id container_name=%container.name image=%container.image.repository:%container.image.tag)
|
||||||
@@ -2745,7 +2747,7 @@
|
|||||||
"xmr-eu1.nanopool.org","xmr-eu2.nanopool.org",
|
"xmr-eu1.nanopool.org","xmr-eu2.nanopool.org",
|
||||||
"xmr-jp1.nanopool.org","xmr-us-east1.nanopool.org",
|
"xmr-jp1.nanopool.org","xmr-us-east1.nanopool.org",
|
||||||
"xmr-us-west1.nanopool.org","xmr.crypto-pool.fr",
|
"xmr-us-west1.nanopool.org","xmr.crypto-pool.fr",
|
||||||
"xmr.pool.minergate.com"
|
"xmr.pool.minergate.com", "rx.unmineable.com"
|
||||||
]
|
]
|
||||||
|
|
||||||
- list: https_miner_domains
|
- list: https_miner_domains
|
||||||
@@ -3001,7 +3003,7 @@
|
|||||||
- rule: Linux Kernel Module Injection Detected
|
- rule: Linux Kernel Module Injection Detected
|
||||||
desc: Detect kernel module was injected (from container).
|
desc: Detect kernel module was injected (from container).
|
||||||
condition: spawned_process and container and proc.name=insmod and not proc.args in (white_listed_modules)
|
condition: spawned_process and container and proc.name=insmod and not proc.args in (white_listed_modules)
|
||||||
output: Linux Kernel Module injection using insmod detected (user=%user.name user_loginuid=%user.loginuid parent_process=%proc.pname module=%proc.args)
|
output: Linux Kernel Module injection using insmod detected (user=%user.name user_loginuid=%user.loginuid parent_process=%proc.pname module=%proc.args %container.info image=%container.image.repository:%container.image.tag)
|
||||||
priority: WARNING
|
priority: WARNING
|
||||||
tags: [process]
|
tags: [process]
|
||||||
|
|
||||||
@@ -3025,13 +3027,13 @@
|
|||||||
# A privilege escalation to root through heap-based buffer overflow
|
# A privilege escalation to root through heap-based buffer overflow
|
||||||
- rule: Sudo Potential Privilege Escalation
|
- rule: Sudo Potential Privilege Escalation
|
||||||
desc: Privilege escalation vulnerability affecting sudo (<= 1.9.5p2). Executing sudo using sudoedit -s or sudoedit -i command with command-line argument that ends with a single backslash character from an unprivileged user it's possible to elevate the user privileges to root.
|
desc: Privilege escalation vulnerability affecting sudo (<= 1.9.5p2). Executing sudo using sudoedit -s or sudoedit -i command with command-line argument that ends with a single backslash character from an unprivileged user it's possible to elevate the user privileges to root.
|
||||||
condition: spawned_process and user.uid!= 0 and proc.name=sudoedit and (proc.args contains -s or proc.args contains -i) and (proc.args contains "\ " or proc.args endswith \)
|
condition: spawned_process and user.uid != 0 and proc.name=sudoedit and (proc.args contains -s or proc.args contains -i) and (proc.args contains "\ " or proc.args endswith \)
|
||||||
output: "Detect Sudo Privilege Escalation Exploit (CVE-2021-3156) (user=%user.name parent=%proc.pname cmdline=%proc.cmdline %container.info)"
|
output: "Detect Sudo Privilege Escalation Exploit (CVE-2021-3156) (user=%user.name parent=%proc.pname cmdline=%proc.cmdline %container.info)"
|
||||||
priority: CRITICAL
|
priority: CRITICAL
|
||||||
tags: [filesystem, mitre_privilege_escalation]
|
tags: [filesystem, mitre_privilege_escalation]
|
||||||
|
|
||||||
- rule: Debugfs Launched in Privileged Container
|
- rule: Debugfs Launched in Privileged Container
|
||||||
desc: Detect file system debugger debugfs launched inside a privilegd container which might lead to container escape.
|
desc: Detect file system debugger debugfs launched inside a privileged container which might lead to container escape.
|
||||||
condition: >
|
condition: >
|
||||||
spawned_process and container
|
spawned_process and container
|
||||||
and container.privileged=true
|
and container.privileged=true
|
||||||
@@ -3054,6 +3056,24 @@
|
|||||||
priority: WARNING
|
priority: WARNING
|
||||||
tags: [container, cis, mitre_lateral_movement]
|
tags: [container, cis, mitre_lateral_movement]
|
||||||
|
|
||||||
|
- macro: consider_userfaultfd_activities
|
||||||
|
condition: (always_true)
|
||||||
|
|
||||||
|
- list: user_known_userfaultfd_processes
|
||||||
|
items: []
|
||||||
|
|
||||||
|
- rule: Unprivileged Delegation of Page Faults Handling to a Userspace Process
|
||||||
|
desc: Detect a successful unprivileged userfaultfd syscall which might act as an attack primitive to exploit other bugs
|
||||||
|
condition: >
|
||||||
|
consider_userfaultfd_activities and
|
||||||
|
evt.type = userfaultfd and
|
||||||
|
user.uid != 0 and
|
||||||
|
(evt.rawres >= 0 or evt.res != -1) and
|
||||||
|
not proc.name in (user_known_userfaultfd_processes)
|
||||||
|
output: An userfaultfd syscall was successfully executed by an unprivileged user (user=%user.name user_loginuid=%user.loginuid process=%proc.name command=%proc.cmdline %container.info image=%container.image.repository:%container.image.tag)
|
||||||
|
priority: CRITICAL
|
||||||
|
tags: [syscall, mitre_defense_evasion]
|
||||||
|
|
||||||
# Application rules have moved to application_rules.yaml. Please look
|
# Application rules have moved to application_rules.yaml. Please look
|
||||||
# there if you want to enable them by adding to
|
# there if you want to enable them by adding to
|
||||||
# falco_rules.local.yaml.
|
# falco_rules.local.yaml.
|
||||||
|
|||||||
@@ -304,7 +304,7 @@
|
|||||||
- list: known_sa_list
|
- list: known_sa_list
|
||||||
items: ["pod-garbage-collector","resourcequota-controller","cronjob-controller","generic-garbage-collector",
|
items: ["pod-garbage-collector","resourcequota-controller","cronjob-controller","generic-garbage-collector",
|
||||||
"daemon-set-controller","endpointslice-controller","deployment-controller", "replicaset-controller",
|
"daemon-set-controller","endpointslice-controller","deployment-controller", "replicaset-controller",
|
||||||
"endpoint-controller"]
|
"endpoint-controller", "namespace-controller", "statefulset-controller", "disruption-controller"]
|
||||||
|
|
||||||
- macro: trusted_sa
|
- macro: trusted_sa
|
||||||
condition: (ka.target.name in (known_sa_list, user_known_sa_list))
|
condition: (ka.target.name in (known_sa_list, user_known_sa_list))
|
||||||
|
|||||||
@@ -763,7 +763,7 @@ trace_files: !mux
|
|||||||
- "Non sudo setuid": 1
|
- "Non sudo setuid": 1
|
||||||
- "Create files below dev": 1
|
- "Create files below dev": 1
|
||||||
- "Modify binary dirs": 2
|
- "Modify binary dirs": 2
|
||||||
- "Change thread namespace": 1
|
- "Change thread namespace": 0
|
||||||
|
|
||||||
disabled_tags_a:
|
disabled_tags_a:
|
||||||
detect: True
|
detect: True
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ has_json_output: !mux
|
|||||||
traces: !mux
|
traces: !mux
|
||||||
change-thread-namespace:
|
change-thread-namespace:
|
||||||
trace_file: traces-positive/change-thread-namespace.scap
|
trace_file: traces-positive/change-thread-namespace.scap
|
||||||
detect: True
|
detect: False
|
||||||
detect_level: NOTICE
|
detect_level: NOTICE
|
||||||
detect_counts:
|
detect_counts:
|
||||||
- "Change thread namespace": 1
|
- "Change thread namespace": 0
|
||||||
|
|
||||||
container-privileged:
|
container-privileged:
|
||||||
trace_file: traces-positive/container-privileged.scap
|
trace_file: traces-positive/container-privileged.scap
|
||||||
@@ -73,7 +73,7 @@ traces: !mux
|
|||||||
- "Non sudo setuid": 1
|
- "Non sudo setuid": 1
|
||||||
- "Create files below dev": 1
|
- "Create files below dev": 1
|
||||||
- "Modify binary dirs": 2
|
- "Modify binary dirs": 2
|
||||||
- "Change thread namespace": 1
|
- "Change thread namespace": 0
|
||||||
|
|
||||||
mkdir-binary-dirs:
|
mkdir-binary-dirs:
|
||||||
trace_file: traces-positive/mkdir-binary-dirs.scap
|
trace_file: traces-positive/mkdir-binary-dirs.scap
|
||||||
|
|||||||
@@ -9,5 +9,5 @@ PyYAML==5.4
|
|||||||
requests==2.23.0
|
requests==2.23.0
|
||||||
six==1.14.0
|
six==1.14.0
|
||||||
stevedore==1.32.0
|
stevedore==1.32.0
|
||||||
urllib3==1.25.9
|
urllib3==1.26.5
|
||||||
watchdog==0.10.2
|
watchdog==0.10.2
|
||||||
|
|||||||
@@ -70,3 +70,5 @@ else()
|
|||||||
FILES_MATCHING
|
FILES_MATCHING
|
||||||
PATTERN *.lua)
|
PATTERN *.lua)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(embeddable)
|
||||||
|
|||||||
43
userspace/engine/embeddable/CMakeLists.txt
Normal file
43
userspace/engine/embeddable/CMakeLists.txt
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2021 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. You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
|
||||||
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
# specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
|
set(FALCO_ENGINE_EMBEDDABLE_SOURCE_FILES
|
||||||
|
falco_engine_embeddable.cpp)
|
||||||
|
|
||||||
|
set(
|
||||||
|
FALCO_LIBRARIES
|
||||||
|
falco_engine
|
||||||
|
sinsp
|
||||||
|
"${LIBYAML_LIB}"
|
||||||
|
"${YAMLCPP_LIB}"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(falco_engine_embeddable SHARED ${FALCO_ENGINE_EMBEDDABLE_SOURCE_FILES})
|
||||||
|
add_dependencies(falco_engine_embeddable falco_engine)
|
||||||
|
|
||||||
|
target_include_directories(
|
||||||
|
falco_engine_embeddable
|
||||||
|
PUBLIC
|
||||||
|
"${PROJECT_SOURCE_DIR}/userspace/engine"
|
||||||
|
"${LUAJIT_INCLUDE}"
|
||||||
|
"${NJSON_INCLUDE}"
|
||||||
|
"${TBB_INCLUDE_DIR}"
|
||||||
|
"${STRING_VIEW_LITE_INCLUDE}"
|
||||||
|
"${LIBSCAP_INCLUDE_DIRS}"
|
||||||
|
"${LIBSINSP_INCLUDE_DIRS}"
|
||||||
|
"${PROJECT_BINARY_DIR}/userspace/engine")
|
||||||
|
|
||||||
|
target_link_libraries(falco_engine_embeddable ${FALCO_LIBRARIES})
|
||||||
|
|
||||||
|
#add_custom_target(example ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/example)
|
||||||
|
#add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/example COMMAND go build ${CMAKE_CURRENT_SOURCE_DIR}/example.go -o ${CMAKE_CURRENT_BINARY_DIR}/example)
|
||||||
|
|
||||||
102
userspace/engine/embeddable/example/example.go
Normal file
102
userspace/engine/embeddable/example/example.go
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
//#cgo CFLAGS: -I../
|
||||||
|
//#cgo LDFLAGS: -L/home/mstemm/work/falco-build/userspace/engine/embeddable -lfalco_engine_embeddable -Wl,-rpath=/home/mstemm/work/falco-build/userspace/engine/embeddable
|
||||||
|
/*
|
||||||
|
#include "stdio.h"
|
||||||
|
#include "falco_engine_embeddable.h"
|
||||||
|
|
||||||
|
int open_engine(void **engine, void *rules_content)
|
||||||
|
{
|
||||||
|
int32_t rc;
|
||||||
|
*engine = falco_engine_embed_init(&rc);
|
||||||
|
|
||||||
|
if (rc != 0)
|
||||||
|
{
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *errstr;
|
||||||
|
rc = falco_engine_embed_load_rules_content(*engine, (const char *) rules_content, &errstr);
|
||||||
|
|
||||||
|
if (rc != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s", errstr);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = falco_engine_embed_open(*engine, &errstr);
|
||||||
|
|
||||||
|
if (rc != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s", errstr);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int next_result(void *engine, char **output)
|
||||||
|
{
|
||||||
|
|
||||||
|
int32_t rc;
|
||||||
|
falco_engine_embed_result *res;
|
||||||
|
char *errstr;
|
||||||
|
|
||||||
|
rc = falco_engine_embed_next_result(engine, &res, &errstr);
|
||||||
|
|
||||||
|
if (rc != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "NEXT ERROR %s", errstr);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
*output = res->output_str;
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func doMain(rules_filename string) int {
|
||||||
|
|
||||||
|
rules_content, err := ioutil.ReadFile(rules_filename)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Could not open rules file %s: %v", rules_filename, err)
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
var handle unsafe.Pointer
|
||||||
|
rc := C.open_engine(&handle, C.CBytes(rules_content))
|
||||||
|
|
||||||
|
if rc != 0 {
|
||||||
|
fmt.Printf("Could not open falco engine")
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for true {
|
||||||
|
var output *C.char
|
||||||
|
rc := C.next_result(handle, &output)
|
||||||
|
if rc != 0 {
|
||||||
|
fmt.Printf("Could not get next result")
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
fmt.Printf("GOT RESULT %s\n", C.GoString(output))
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
os.Exit(doMain(os.Args[1]))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
6
userspace/engine/embeddable/example/go.mod
Normal file
6
userspace/engine/embeddable/example/go.mod
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
module github.com/falcosecurity/falco/embedded/example
|
||||||
|
|
||||||
|
go 1.16
|
||||||
|
|
||||||
|
require (
|
||||||
|
)
|
||||||
356
userspace/engine/embeddable/falco_engine_embeddable.cpp
Normal file
356
userspace/engine/embeddable/falco_engine_embeddable.cpp
Normal file
@@ -0,0 +1,356 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2021 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.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
#include <sinsp.h>
|
||||||
|
#include <event.h>
|
||||||
|
|
||||||
|
#include <falco_engine.h>
|
||||||
|
#include "falco_engine_embeddable.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class falco_engine_embed_int {
|
||||||
|
public:
|
||||||
|
falco_engine_embed_int();
|
||||||
|
virtual ~falco_engine_embed_int();
|
||||||
|
|
||||||
|
bool load_rules_content(const char *rules_content, string &err);
|
||||||
|
bool is_open();
|
||||||
|
bool open(string &err);
|
||||||
|
bool close(string &err);
|
||||||
|
falco_engine_embed_rc next_result(falco_engine_embed_result **result, string &err);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
falco_engine_embed_result *rule_result_to_embed_result(sinsp_evt *ev,
|
||||||
|
unique_ptr<falco_engine::rule_result> &res);
|
||||||
|
|
||||||
|
static void add_output_pair(const string &field, const string &val,
|
||||||
|
char **&fields, char **&vals,
|
||||||
|
uint32_t &len);
|
||||||
|
|
||||||
|
unique_ptr<sinsp_evt_formatter_cache> m_formatters;
|
||||||
|
bool m_open;
|
||||||
|
unique_ptr<sinsp> m_inspector;
|
||||||
|
unique_ptr<falco_engine> m_falco_engine;
|
||||||
|
atomic<bool> m_shutdown;
|
||||||
|
};
|
||||||
|
|
||||||
|
falco_engine_embed_int::falco_engine_embed_int()
|
||||||
|
: m_open(false),
|
||||||
|
m_shutdown(false)
|
||||||
|
{
|
||||||
|
m_inspector.reset(new sinsp());
|
||||||
|
m_falco_engine.reset(new falco_engine());
|
||||||
|
m_falco_engine->set_inspector(m_inspector.get());
|
||||||
|
|
||||||
|
m_formatters.reset(new sinsp_evt_formatter_cache(m_inspector.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
falco_engine_embed_int::~falco_engine_embed_int()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool falco_engine_embed_int::load_rules_content(const char *rules_content, string &err)
|
||||||
|
{
|
||||||
|
bool verbose = false;
|
||||||
|
bool all_events = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
m_falco_engine->load_rules(string(rules_content), verbose, all_events);
|
||||||
|
}
|
||||||
|
catch(falco_exception &e)
|
||||||
|
{
|
||||||
|
err = e.what();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool falco_engine_embed_int::is_open()
|
||||||
|
{
|
||||||
|
return m_open;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool falco_engine_embed_int::open(string &err)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
m_inspector->open();
|
||||||
|
}
|
||||||
|
catch(exception &e)
|
||||||
|
{
|
||||||
|
err = e.what();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_open = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool falco_engine_embed_int::close(string &err)
|
||||||
|
{
|
||||||
|
m_shutdown = true;
|
||||||
|
m_open = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
falco_engine_embed_rc falco_engine_embed_int::next_result(falco_engine_embed_result **result, string &err)
|
||||||
|
{
|
||||||
|
*result = NULL;
|
||||||
|
|
||||||
|
while(!m_shutdown)
|
||||||
|
{
|
||||||
|
sinsp_evt* ev;
|
||||||
|
|
||||||
|
int32_t rc = m_inspector->next(&ev);
|
||||||
|
|
||||||
|
if (rc == SCAP_TIMEOUT)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (rc == SCAP_EOF)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (rc != SCAP_SUCCESS)
|
||||||
|
{
|
||||||
|
err = m_inspector->getlasterr();
|
||||||
|
return FE_EMB_RC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!ev->simple_consumer_consider())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_ptr<falco_engine::rule_result> res = m_falco_engine->process_sinsp_event(ev);
|
||||||
|
if(!res)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
*result = rule_result_to_embed_result(ev, res);
|
||||||
|
|
||||||
|
return FE_EMB_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can only get here if shut down/eof.
|
||||||
|
return FE_EMB_RC_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
falco_engine_embed_result * falco_engine_embed_int::rule_result_to_embed_result(sinsp_evt *ev,
|
||||||
|
unique_ptr<falco_engine::rule_result> &res)
|
||||||
|
{
|
||||||
|
falco_engine_embed_result *result;
|
||||||
|
|
||||||
|
result = (falco_engine_embed_result *) malloc(sizeof(falco_engine_embed_result));
|
||||||
|
|
||||||
|
result->rule = strdup(res->rule.c_str());
|
||||||
|
result->event_source = strdup(res->source.c_str());
|
||||||
|
result->priority_num = res->priority_num;
|
||||||
|
|
||||||
|
// Copy output format string without resolving fields.
|
||||||
|
result->output_format_str = strdup(res->format.c_str());
|
||||||
|
|
||||||
|
// Resolve output format string into resolved output
|
||||||
|
string output;
|
||||||
|
m_formatters->tostring(ev, res->format, &output);
|
||||||
|
result->output_str = strdup(output.c_str());
|
||||||
|
|
||||||
|
result->output_fields = NULL;
|
||||||
|
result->output_values = NULL;
|
||||||
|
result->num_output_values = 0;
|
||||||
|
|
||||||
|
map<string, string> rule_output_fields;
|
||||||
|
m_formatters->resolve_tokens(ev, res->format, rule_output_fields);
|
||||||
|
for(auto &pair : rule_output_fields)
|
||||||
|
{
|
||||||
|
add_output_pair(pair.first, pair.second,
|
||||||
|
result->output_fields, result->output_values,
|
||||||
|
result->num_output_values);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preceding * makes the formatting permissive (not ending at first empty value)
|
||||||
|
std::string exformat = "*";
|
||||||
|
for (const auto& exfield : res->exception_fields)
|
||||||
|
{
|
||||||
|
exformat += " %" + exfield;
|
||||||
|
}
|
||||||
|
|
||||||
|
map<string, string> exception_output_fields;
|
||||||
|
m_formatters->resolve_tokens(ev, exformat, exception_output_fields);
|
||||||
|
for(auto &pair : exception_output_fields)
|
||||||
|
{
|
||||||
|
add_output_pair(pair.first, pair.second,
|
||||||
|
result->output_fields, result->output_values,
|
||||||
|
result->num_output_values);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void falco_engine_embed_int::add_output_pair(const string &field, const string &val,
|
||||||
|
char **&fields, char **&vals,
|
||||||
|
uint32_t &len)
|
||||||
|
{
|
||||||
|
len++;
|
||||||
|
fields = (char **) realloc(fields, len*sizeof(char *));
|
||||||
|
vals = (char **) realloc(vals, len*sizeof(char *));
|
||||||
|
fields[len-1] = strdup(field.c_str());
|
||||||
|
vals[len-1] = strdup(val.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *FALCO_ENGINE_EMBED_VERSION = "1.0.0";
|
||||||
|
|
||||||
|
char *falco_engine_embed_get_version()
|
||||||
|
{
|
||||||
|
return strdup(FALCO_ENGINE_EMBED_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
void falco_engine_embed_free_result(falco_engine_embed_result *result)
|
||||||
|
{
|
||||||
|
free(result->rule);
|
||||||
|
free(result->event_source);
|
||||||
|
free(result->output_format_str);
|
||||||
|
free(result->output_str);
|
||||||
|
|
||||||
|
for(int32_t i; i < result->num_output_values; i++)
|
||||||
|
{
|
||||||
|
free(result->output_fields[i]);
|
||||||
|
free(result->output_values[i]);
|
||||||
|
}
|
||||||
|
free(result->output_fields);
|
||||||
|
free(result->output_values);
|
||||||
|
free(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
falco_engine_embed_t* falco_engine_embed_init(int32_t *rc)
|
||||||
|
{
|
||||||
|
falco_engine_embed_int *eengine = new falco_engine_embed_int();
|
||||||
|
|
||||||
|
*rc = FE_EMB_RC_OK;
|
||||||
|
|
||||||
|
return eengine;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t falco_engine_embed_destroy(falco_engine_embed_t *engine, char *errstr)
|
||||||
|
{
|
||||||
|
falco_engine_embed_int *eengine = (falco_engine_embed_int *) engine;
|
||||||
|
|
||||||
|
if(eengine->is_open())
|
||||||
|
{
|
||||||
|
errstr = strdup("Engine is open--must call close() first");
|
||||||
|
return FE_EMB_RC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(eengine);
|
||||||
|
|
||||||
|
return FE_EMB_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t falco_engine_embed_load_plugin(falco_engine_embed_t *engine,
|
||||||
|
const char *path,
|
||||||
|
const char* init_config,
|
||||||
|
const char* open_params,
|
||||||
|
char **errstr)
|
||||||
|
{
|
||||||
|
falco_engine_embed_int *eengine = (falco_engine_embed_int *) engine;
|
||||||
|
|
||||||
|
// XXX/mstemm fill in
|
||||||
|
return FE_EMB_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t falco_engine_embed_load_rules_content(falco_engine_embed_t *engine,
|
||||||
|
const char *rules_content,
|
||||||
|
char **errstr)
|
||||||
|
{
|
||||||
|
falco_engine_embed_int *eengine = (falco_engine_embed_int *) engine;
|
||||||
|
std::string err;
|
||||||
|
|
||||||
|
if (!eengine->load_rules_content(rules_content, err))
|
||||||
|
{
|
||||||
|
*errstr = strdup(err.c_str());
|
||||||
|
return FE_EMB_RC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FE_EMB_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t falco_engine_embed_enable_source(falco_engine_embed_t *engine,
|
||||||
|
int32_t source,
|
||||||
|
bool enabled,
|
||||||
|
char **errstr)
|
||||||
|
{
|
||||||
|
falco_engine_embed_int *eengine = (falco_engine_embed_int *) engine;
|
||||||
|
|
||||||
|
// XXX/mstemm fill in
|
||||||
|
return FE_EMB_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t falco_engine_embed_open(falco_engine_embed_t *engine,
|
||||||
|
char **errstr)
|
||||||
|
{
|
||||||
|
falco_engine_embed_int *eengine = (falco_engine_embed_int *) engine;
|
||||||
|
std::string err;
|
||||||
|
|
||||||
|
if (!eengine->open(err))
|
||||||
|
{
|
||||||
|
*errstr = strdup(err.c_str());
|
||||||
|
return FE_EMB_RC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FE_EMB_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t falco_engine_embed_close(falco_engine_embed_t *engine,
|
||||||
|
char **errstr)
|
||||||
|
{
|
||||||
|
falco_engine_embed_int *eengine = (falco_engine_embed_int *) engine;
|
||||||
|
std::string err;
|
||||||
|
|
||||||
|
if (!eengine->close(err))
|
||||||
|
{
|
||||||
|
*errstr = strdup(err.c_str());
|
||||||
|
return FE_EMB_RC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FE_EMB_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t falco_engine_embed_next_result(falco_engine_embed_t *engine,
|
||||||
|
falco_engine_embed_result **result,
|
||||||
|
char **errstr)
|
||||||
|
{
|
||||||
|
falco_engine_embed_int *eengine = (falco_engine_embed_int *) engine;
|
||||||
|
std::string err;
|
||||||
|
falco_engine_embed_rc rc;
|
||||||
|
|
||||||
|
rc = eengine->next_result(result, err);
|
||||||
|
|
||||||
|
if(rc == FE_EMB_RC_ERROR)
|
||||||
|
{
|
||||||
|
*errstr = strdup(err.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
268
userspace/engine/embeddable/falco_engine_embeddable.h
Normal file
268
userspace/engine/embeddable/falco_engine_embeddable.h
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2021 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.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
This header file provides a C-only interface to the falco engine,
|
||||||
|
suitable for embedding in other programs as a shared library. This
|
||||||
|
interface handles:
|
||||||
|
- Loading Rules Content
|
||||||
|
- Enabling/Disabling syscall/k8s_audit event sources.
|
||||||
|
- Loading and configuring source/extractor plugins
|
||||||
|
- Starting/Stopping the event processing loop.
|
||||||
|
|
||||||
|
After setup, the main interface involves receiving "results" when
|
||||||
|
syscall/k8s_audit/plugin events match rules.
|
||||||
|
|
||||||
|
This interface does not provide as many features as the c++
|
||||||
|
falco_engine interface, such as interfaces to list rules, segregate
|
||||||
|
rules by "ruleset", enabling/disabling specific rules etc.
|
||||||
|
|
||||||
|
Output handling (e.g. routing alerts to files, stdout, webhook,
|
||||||
|
slack, etc) is not covered by this interface. After receiving a
|
||||||
|
result, a program could use a program like falcosidekick for a rich
|
||||||
|
set of output handling methods.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* A handle to an embeddable falco engine */
|
||||||
|
typedef void falco_engine_embed_t;
|
||||||
|
|
||||||
|
/* Defined return values from API functions. */
|
||||||
|
enum falco_engine_embed_rc
|
||||||
|
{
|
||||||
|
/* No Error */
|
||||||
|
FE_EMB_RC_OK = 0,
|
||||||
|
FE_EMB_RC_ERROR = 1,
|
||||||
|
FE_EMB_RC_EOF = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Defined event sources. */
|
||||||
|
enum falco_engine_embed_evt_source
|
||||||
|
{
|
||||||
|
FE_EMB_SRC_NONE = 0,
|
||||||
|
FE_EMB_SRC_SYSCALL = 1,
|
||||||
|
FE_EMB_K8S_AUDIT = 2,
|
||||||
|
FE_EMB_PLUGINS = 3, // This includes any event from any plugin
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Represents a result (e.g. an event matching a falco rule)
|
||||||
|
|
||||||
|
When returned by a call to next_result(), the struct, as well as
|
||||||
|
every allocated char * within the struct, is allocated via a call
|
||||||
|
to malloc() and must be freed via a call to free().
|
||||||
|
*/
|
||||||
|
typedef struct falco_engine_embed_result
|
||||||
|
{
|
||||||
|
// The rule that matched the event
|
||||||
|
char *rule;
|
||||||
|
|
||||||
|
// The event source of the event that matched the rule
|
||||||
|
char *event_source;
|
||||||
|
|
||||||
|
// An int containing a falco_common::priority_type value of
|
||||||
|
// the priority of the matching rule.
|
||||||
|
int32_t priority_num;
|
||||||
|
|
||||||
|
// A copy of the rule's output string, *without* any
|
||||||
|
// fields (e.g. %proc.name, ...) resolved to values.
|
||||||
|
char *output_format_str;
|
||||||
|
|
||||||
|
// An output string, starting with the rule's output string
|
||||||
|
// with all fields resolved to values.
|
||||||
|
char *output_str;
|
||||||
|
|
||||||
|
// An allocated array of allocated field names from the output
|
||||||
|
// string. Additional fields + values may be included in
|
||||||
|
// addition to those in the output string, to aid in
|
||||||
|
// debugging. Item i in this array maps to item i in
|
||||||
|
// output_values.
|
||||||
|
char **output_fields;
|
||||||
|
|
||||||
|
// An allocated array of allocated field values from the
|
||||||
|
// output string. Additional fields + values may be included in
|
||||||
|
// addition to those in the output string, to aid in
|
||||||
|
// debugging. Item i in this array maps to item i in
|
||||||
|
// output_fields.
|
||||||
|
char **output_values;
|
||||||
|
|
||||||
|
// The length of output_fields/output_values
|
||||||
|
uint32_t num_output_values;
|
||||||
|
} falco_engine_embed_result;
|
||||||
|
|
||||||
|
/* A utility function to free a falco_engine_embed_result struct and
|
||||||
|
* its allocated strings returned by a call to next_result() */
|
||||||
|
void falco_engine_embed_free_result(falco_engine_embed_result *result);
|
||||||
|
|
||||||
|
// Interface to interact with an embeddable falco engine.
|
||||||
|
|
||||||
|
// NOTE: For all functions below that return a char *, the memory
|
||||||
|
// pointed to by the char * is allocated using malloc() and should be
|
||||||
|
// freed by the caller using free().
|
||||||
|
|
||||||
|
// Return the embedded engine version.
|
||||||
|
//
|
||||||
|
// Return value: a version string, in the following format:
|
||||||
|
// "<major>.<minor>.<patch>", e.g. "1.2.3".
|
||||||
|
// This interface is compatible following semver conventions:
|
||||||
|
// <major> changes for incompatible api changes, <minor> for
|
||||||
|
// backwards-compatible additions, <patch> for compatible bug
|
||||||
|
// fixes.
|
||||||
|
char* falco_engine_embed_get_version();
|
||||||
|
|
||||||
|
// Initialize a falco engine.
|
||||||
|
//
|
||||||
|
// Arguments:
|
||||||
|
// - rc: pointer to an integer containing a falco_engine_embed_rc value.
|
||||||
|
//
|
||||||
|
// Return value: pointer to the engine state that is passed to
|
||||||
|
// other API functions.
|
||||||
|
falco_engine_embed_t* falco_engine_embed_init(int32_t *rc);
|
||||||
|
|
||||||
|
// Destroy a falco engine. This frees any resources allocated in
|
||||||
|
// init(). If open() has been called, close() should be called before
|
||||||
|
// destroy().
|
||||||
|
//
|
||||||
|
// Arguments:
|
||||||
|
// - engine: returned by a prior succesful call to init().
|
||||||
|
// - errstr: on error, errstr will point to an allocated
|
||||||
|
// string with additional details on the errror. The string
|
||||||
|
// must be freed via a call to free().
|
||||||
|
//
|
||||||
|
// Return value: an integer containing a falco_engine_embed_rc
|
||||||
|
// value.
|
||||||
|
int32_t falco_engine_embed_destroy(falco_engine_embed_t *engine, char *errstr);
|
||||||
|
|
||||||
|
// Load either a falco source or extractor plugin.
|
||||||
|
//
|
||||||
|
// Arguments:
|
||||||
|
// - engine: returned by a prior succesful call to init().
|
||||||
|
// - path: a file path pointing to a dynamic library that
|
||||||
|
// can be dlopen()ed.
|
||||||
|
// - init_config: a string that will be passed to the plugin's
|
||||||
|
// init() function.
|
||||||
|
// - open_params: a string that will be passed to the
|
||||||
|
// plugin's open() function.
|
||||||
|
// - errstr: on error, errstr will point to an allocated
|
||||||
|
// string with additional details on the errror. The string
|
||||||
|
// must be freed via a call to free().
|
||||||
|
//
|
||||||
|
// Return value: an integer containing a falco_engine_embed_rc
|
||||||
|
// value.
|
||||||
|
int32_t falco_engine_embed_load_plugin(falco_engine_embed_t *engine,
|
||||||
|
const char *path,
|
||||||
|
const char* init_config,
|
||||||
|
const char* open_params,
|
||||||
|
char **errstr);
|
||||||
|
|
||||||
|
// Load the provided rules content. These rules are applied on
|
||||||
|
// top of any previously loaded rules content
|
||||||
|
// (e.g. appending/overriding rule/macro/list objects as
|
||||||
|
// specified via "append:" properties)
|
||||||
|
//
|
||||||
|
// NOTE: Plugins should be loaded before any rules are loaded.
|
||||||
|
//
|
||||||
|
// Arguments:
|
||||||
|
// - engine: returned by a prior succesful call to init().
|
||||||
|
// - rules_content: a null-terminated string containing
|
||||||
|
// yaml rules content.
|
||||||
|
// - errstr: on error, errstr will point to an allocated
|
||||||
|
// string with additional details on the errror. The string
|
||||||
|
// must be freed via a call to free().
|
||||||
|
//
|
||||||
|
// Return value: an integer containing a falco_engine_embed_rc
|
||||||
|
// value.
|
||||||
|
int32_t falco_engine_embed_load_rules_content(falco_engine_embed_t *engine,
|
||||||
|
const char *rules_content,
|
||||||
|
char **errstr);
|
||||||
|
|
||||||
|
// Enable/disable an event source.
|
||||||
|
// By default all event sources are enabled. This function
|
||||||
|
// enables/disables specific event sources.
|
||||||
|
//
|
||||||
|
// Arguments:
|
||||||
|
// - engine: returned by a prior succesful call to init().
|
||||||
|
// - source: an int containing a falco_engine_embed_evt_source value.
|
||||||
|
// - enabled: whether to enable or disable the provided source
|
||||||
|
// - errstr: on error, errstr will point to an allocated
|
||||||
|
// string with additional details on the errror. The string
|
||||||
|
// must be freed via a call to free().
|
||||||
|
//
|
||||||
|
// Return value: an integer containing a falco_engine_embed_rc
|
||||||
|
// value.
|
||||||
|
int32_t falco_engine_embed_enable_source(falco_engine_embed_t *engine,
|
||||||
|
int32_t source,
|
||||||
|
bool enabled,
|
||||||
|
char **errstr);
|
||||||
|
|
||||||
|
// Open the engine, which starts event processing and matching
|
||||||
|
// against the loaded set of rules.
|
||||||
|
//
|
||||||
|
// Arguments:
|
||||||
|
// - engine: returned by a prior succesful call to init().
|
||||||
|
// - errstr: on error, errstr will point to an allocated
|
||||||
|
// string with additional details on the errror. The string
|
||||||
|
// must be freed via a call to free().
|
||||||
|
//
|
||||||
|
// Return value: an integer containing a falco_engine_embed_rc
|
||||||
|
// value.
|
||||||
|
int32_t falco_engine_embed_open(falco_engine_embed_t *engine,
|
||||||
|
char **errstr);
|
||||||
|
|
||||||
|
// Close the engine, which stops event processing.
|
||||||
|
//
|
||||||
|
// Arguments:
|
||||||
|
// - engine: returned by a prior succesful call to init().
|
||||||
|
// - errstr: on error, errstr will point to an allocated
|
||||||
|
// string with additional details on the errror. The string
|
||||||
|
// must be freed via a call to free().
|
||||||
|
//
|
||||||
|
// Return value: an integer containing a falco_engine_embed_rc
|
||||||
|
// value.
|
||||||
|
int32_t falco_engine_embed_close(falco_engine_embed_t *engine,
|
||||||
|
char **errstr);
|
||||||
|
|
||||||
|
// Receive the next result (e.g. an event that matched a
|
||||||
|
// rule). This function blocks until the next result is
|
||||||
|
// available. close() is called, or an error occurs.
|
||||||
|
//
|
||||||
|
// Arguments:
|
||||||
|
// - engine: returned by a prior succesful call to init().
|
||||||
|
// - result: a pointer to a falco_engine_embed_result struct
|
||||||
|
// pointer. On success, a struct will be allocated, and filled in
|
||||||
|
// with allocated char* values, and the pointer updated to point to
|
||||||
|
// the allocated struct.
|
||||||
|
// - errstr: on error, errstr will point to an allocated
|
||||||
|
// string with additional details on the errror. The string
|
||||||
|
// must be freed via a call to free().
|
||||||
|
//
|
||||||
|
// Return value: an integer containing a falco_engine_embed_rc
|
||||||
|
// value.
|
||||||
|
int32_t falco_engine_embed_next_result(falco_engine_embed_t *engine,
|
||||||
|
falco_engine_embed_result **result,
|
||||||
|
char **errstr);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -16,9 +16,9 @@ limitations under the License.
|
|||||||
|
|
||||||
// The version of rules/filter fields/etc supported by this falco
|
// The version of rules/filter fields/etc supported by this falco
|
||||||
// engine.
|
// engine.
|
||||||
#define FALCO_ENGINE_VERSION (8)
|
#define FALCO_ENGINE_VERSION (9)
|
||||||
|
|
||||||
// This is the result of running "falco --list -N | sha256sum" and
|
// This is the result of running "falco --list -N | sha256sum" and
|
||||||
// represents the fields supported by this version of falco. It's used
|
// represents the fields supported by this version of falco. It's used
|
||||||
// at build time to detect a changed set of fields.
|
// at build time to detect a changed set of fields.
|
||||||
#define FALCO_FIELDS_CHECKSUM "2f324e2e66d4b423f53600e7e0fcf2f0ff72e4a87755c490f2ae8f310aba9386"
|
#define FALCO_FIELDS_CHECKSUM "8183621f52451d842036eee409e2ed920d9c91bab33e0c4a44e4a871378d103f"
|
||||||
|
|||||||
Reference in New Issue
Block a user