Compare commits

..

68 Commits

Author SHA1 Message Date
Leonardo Di Giovanna be3800132f docs(OWNERS): add `ekoops` as approver
Signed-off-by: Leonardo Di Giovanna <41296180+ekoops@users.noreply.github.com>
2025-07-23 11:14:33 +02:00
dependabot[bot] 120881647a build(deps): Bump sigstore/cosign-installer in the actions group
Bumps the actions group with 1 update: [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer).


Updates `sigstore/cosign-installer` from 3.8.2 to 3.9.0
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/v3.8.2...v3.9.0)

---
updated-dependencies:
- dependency-name: sigstore/cosign-installer
  dependency-version: 3.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-18 15:33:04 +02:00
Leonardo Di Giovanna d0be92e53e ci: add additional Falco releases to be tested
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2025-06-17 14:37:45 +02:00
Federico Di Pierro 488e6f8f0c fix(rules): fixed `container_started` macro adapting to new container plugin.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-06-17 12:44:44 +02:00
Melissa Kilby 4d51b1813f doc(OWNERS): move incertum (Melissa Kilby) to emeritus_approvers
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2025-06-09 11:51:54 +02:00
dependabot[bot] b4437c492f build(deps): Bump astral-sh/setup-uv from 5.4.1 to 6.1.0
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 5.4.1 to 6.1.0.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](0c5e2b8115...f0ec1fc3b3)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-23 19:33:48 +02:00
Dirk Marwinski cb17833316 Allow new sshd-session binary to read sensitive files
Signed-off-by: Dirk Marwinski <dirk.marwinski@sap.com>
2025-05-22 10:29:39 +02:00
dependabot[bot] 4ccf111c36 build(deps): Bump sigstore/cosign-installer
Bumps the actions group with 1 update in the / directory: [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer).


Updates `sigstore/cosign-installer` from 3.8.1 to 3.8.2
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/v3.8.1...v3.8.2)

---
updated-dependencies:
- dependency-name: sigstore/cosign-installer
  dependency-version: 3.8.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-14 11:06:34 +02:00
Federico Di Pierro ae6ed41a7a cleanup(rules): drop parentheses around args in rule outputs.
Use a pipe instead to divide args from rule title.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-05-13 14:54:29 +02:00
Federico Di Pierro 277b28eb98 update(ci): only keep master as FALCO_VERSION.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-05-13 14:36:29 +02:00
Federico Di Pierro 4f6510b909 chore(rules): require latest 0.2.2 container plugin version.
Also, require Falco 0.41.0 rule engine version (0.50.0).
Finally, bumped copyright year.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-05-13 14:36:29 +02:00
Federico Di Pierro 6f8c46deb5 cleanup(rules): drop `%container.info` from default ruleset too.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-05-13 14:36:29 +02:00
Federico Di Pierro f8fb73a3eb update(rules): require container plugin.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-05-13 14:36:29 +02:00
Federico Di Pierro 3e74a466ae fix(rules): add `conmon` to `container_entrypoint` macro.
This fixes detection of "Terminal shell in container" for podman running with crun.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-05-12 14:32:22 +02:00
Mykhailo 15bb0fea8c rules: add uv to python_package_managers list
This commit updates the Falco rules by adding uv to the python_package_managers list. The uv package manager, a tool for managing Python packages, was previously not accounted for in our detection rules. By adding uv to the list, we enable Falco to accurately identify processes spawned by this package manager.

Signed-off-by: Mykhailo <61192136+shellsession@users.noreply.github.com>
2025-05-08 17:29:57 +02:00
dependabot[bot] 75a39c1dee build(deps): Bump astral-sh/setup-uv in the actions group
Bumps the actions group with 1 update: [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv).


Updates `astral-sh/setup-uv` from 5.4.0 to 5.4.1
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](22695119d7...0c5e2b8115)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-15 10:27:39 +02:00
dependabot[bot] ce46d23f61 build(deps): Bump astral-sh/setup-uv in the actions group
Bumps the actions group with 1 update: [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv).


Updates `astral-sh/setup-uv` from 5.3.1 to 5.4.0
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](f94ec6bedd...22695119d7)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-02 11:01:15 +02:00
dependabot[bot] 371e43167e build(deps): Bump astral-sh/setup-uv in the actions group
Bumps the actions group with 1 update: [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv).


Updates `astral-sh/setup-uv` from 5.3.0 to 5.3.1
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](1edb52594c...f94ec6bedd)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-11 11:32:35 +01:00
Kyle Fazzari 8e4ed0c27d rules: add support for k3s to containerd_activities macro
K3s is a stripped down version of Kubernetes that bundles dependencies
within it, including containerd. It puts containerd files (sockets,
tmpmounts, snapshotter overlayfs, etc.) in namespaced, non-standard
locations in an attempt to not interfere with a system-wide containerd
installation. As a result, the "Clear Log Activities" rule triggers
warnings for the bundled containerd. Fix that by including K3s'
non-standard paths in the containerd_activities macro.

Signed-off-by: Kyle Fazzari <kyrofa@ubuntu.com>
2025-03-02 09:27:47 +01:00
dependabot[bot] 1d2c6b1f0b build(deps): Bump the actions group across 1 directory with 2 updates
Bumps the actions group with 2 updates in the / directory: [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) and [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer).


Updates `astral-sh/setup-uv` from 5.2.2 to 5.3.0
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](4db96194c3...1edb52594c)

Updates `sigstore/cosign-installer` from 3.8.0 to 3.8.1
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/v3.8.0...v3.8.1)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: sigstore/cosign-installer
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-24 18:09:17 +01:00
Luca Guerra 47843ac872 fix(ci): update python deps used in github pages
Signed-off-by: Luca Guerra <luca@guerra.sh>
2025-02-19 15:48:44 +01:00
Luca Guerra 740f8783e0 fix(ci): use falcosecurity/falco instead of falcosecurity/falco-no-driver
Signed-off-by: Luca Guerra <luca@guerra.sh>
2025-02-19 12:40:43 +01:00
Yutong Sun 4633f290ad rules: add runc to known_memfd_execution_binaries
Signed-off-by: Yutong Sun <yutongsu@amazon.com>
2025-02-17 16:02:34 +01:00
dependabot[bot] d8415c1bc1 build(deps): Bump sigstore/cosign-installer in the actions group
Bumps the actions group with 1 update: [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer).


Updates `sigstore/cosign-installer` from 3.7.0 to 3.8.0
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/v3.7.0...v3.8.0)

---
updated-dependencies:
- dependency-name: sigstore/cosign-installer
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-05 17:51:23 +01:00
Federico Di Pierro 8eef0097ca chore(ci): added Falco 0.40.0 (plus 0.39.1 and 0.39.2 that were missing) to FALCO_VERSIONS.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-01-29 11:09:38 +01:00
jordyb6 abf6637e0a Update(sandbox): Add Netcat/Socat Remote Code Execution on Host rule
Signed-off-by: jordyb6 <129943902+jordyb6@users.noreply.github.com>
2025-01-15 11:10:49 +01:00
Trần Đức Phú 283a62f464 fix: fix typo safe_etc_dirs
Signed-off-by: Trần Đức Phú <30786617+Phu96@users.noreply.github.com>
2024-10-23 08:44:07 +02:00
dependabot[bot] 407e99721f build(deps): Bump sigstore/cosign-installer in the actions group
Bumps the actions group with 1 update: [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer).


Updates `sigstore/cosign-installer` from 3.6.0 to 3.7.0
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/v3.6.0...v3.7.0)

---
updated-dependencies:
- dependency-name: sigstore/cosign-installer
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-08 17:27:09 +02:00
Aldo Lacuku e38fb3f6a7 update(ci): add 0.39.0 as supported version
Signed-off-by: Aldo Lacuku <aldo@lacuku.eu>
2024-10-02 15:44:41 +02:00
Melissa Kilby b6ad373719 chore: upgrade py deps for rules_overview_generator
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2024-08-20 18:20:45 +02:00
Luca Guerra bd6d337f0e update(ci): add 0.38.1 and 0.38.2 as supported versions
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-08-19 21:30:41 +02:00
dependabot[bot] baecf181ea build(deps): Bump sigstore/cosign-installer in the actions group
Bumps the actions group with 1 update: [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer).


Updates `sigstore/cosign-installer` from 3.5.0 to 3.6.0
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/v3.5.0...v3.6.0)

---
updated-dependencies:
- dependency-name: sigstore/cosign-installer
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-16 05:51:26 +02:00
Luca Guerra 342b20dc7d update(rule): update description
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-08-02 18:00:30 +02:00
Luca Guerra 1d3cd24e81 fix(incubating_rules): revert #508
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-08-02 18:00:30 +02:00
h4l0gen 068f0f2dc9 changing line length limit to 130
Signed-off-by: h4l0gen <ks3913688@gmail.com>
2024-07-18 16:08:27 +02:00
schie 28b98b6f5f fix: fixed output issues within the sandbox ruleset
Signed-off-by: Stefano Chierici <stefano.chierici@sysdig.com>

Signed-off-by: schie <77834235+darryk10@users.noreply.github.com>
2024-06-27 21:22:50 +02:00
Lorenzo Susini c0a9bf17d5 vote: update(OWNERS): add loresuso to approvers
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2024-06-12 15:29:44 +02:00
schie ea8f792589 fix: fixed output issues within the incubating ruleset
Signed-off-by: Stefano Chierici <stefano.chierici@sysdig.com>

Signed-off-by: schie <77834235+darryk10@users.noreply.github.com>
2024-06-11 20:18:40 +02:00
schie ea57e78ea1 Update falco_rules.yaml
Signed-off-by: Stefano Chierici <stefano.chierici@sysdig.com>

Signed-off-by: schie <77834235+darryk10@users.noreply.github.com>
2024-06-06 17:59:24 +02:00
Damien DELPORTE 36f4320a46 fix: Missing % in "Unexpected UDP Traffic" output rule
Signed-off-by: Damien DELPORTE <damien.delporte@doctolib.com>
2024-06-06 17:30:23 +02:00
Andrea Terzolo df963b6bcd cleanup: remove `startswith /etc`
In macro `sensitive_files` the `startswith /etc` is redundant because it
used in combination with the `in` condition

Signed-off-by: Andrea Terzolo <andreaterzolo3@gmail.com>
2024-05-31 11:59:59 +02:00
Andrea Terzolo a81590059c cleanup(falco_rules): we need only dup exit events
In `Redirect STDOUT/STDIN` rule we check for evt.rawres but this is a
parameter that we only have in the exit event

Signed-off-by: Andrea Terzolo <andreaterzolo3@gmail.com>
2024-05-31 11:59:59 +02:00
Luca Guerra ad27109fa2 chore(gha): add 0.38.0 to supported Falco versions
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-05-30 16:35:56 +02:00
schie 679a50aa5c Create OWNERS
Added myself to maintainers for rules

Signed-off-by: Stefano Chierici <stefano.chierici@sysdig.com>
2024-05-29 16:13:50 +02:00
Leonardo Grasso 9e56293b55 fix(.github/workflow): strict naming convention for changed rules files
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2024-05-22 11:42:19 +02:00
Melissa Kilby 59bf03bf74 chore: bump engine version for incubating rules
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2024-05-20 13:39:10 +02:00
Melissa Kilby 70b0d4f389 fix: add missing Mitre to rule 'Backdoored library loaded into SSHD (CVE-2024-3094)'
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2024-05-20 13:39:10 +02:00
Melissa Kilby 95c822c595 cleanup(rules): transition rule 'BPF Program Not Profiled' to maturity incubating
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2024-05-20 13:39:10 +02:00
Edgaras 29c41c4eed fix: change CVE-2024-3094 to match liblzma contain instead of endswith
Signed-off-by: Edgaras <edgaras@apsega.lt>
2024-05-14 11:13:45 +02:00
Andrea Terzolo 4f153f53ae fix: add `""` case for user.name
Signed-off-by: Andrea Terzolo <andreaterzolo3@gmail.com>
2024-04-30 18:14:51 +02:00
Andrea Terzolo 5ad584f200 fix: add `<NA>` check
Signed-off-by: Andrea Terzolo <andreaterzolo3@gmail.com>
2024-04-30 18:14:51 +02:00
Petter Reinholdtsen e65f2518b0 rule(write_etc_common): Ignore writes by etckeeper under /etc/.git/
Every time etckeeper update the git history of the content in /etc/, it update
files in /etc/.git/ (nd /etc/.etckeeper).  This trigger a warning from falco about
writes in /etc/ for every time the cron job or package update.  This change tell
the write_etc_common macro to ignore all writes under /etc/.git/ by a
process whos anchestor is etckeeper and one of the scripts called by etckeeper
to do the /etc/.git updates.

/kind bug
/kind design
/kind feature
/area rules

Signed-off-by: Petter Reinholdtsen <pere@hungry.com>
2024-04-23 11:02:17 +02:00
dependabot[bot] ec255e68f4 build(deps): Bump sigstore/cosign-installer in the actions group
Bumps the actions group with 1 update: [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer).


Updates `sigstore/cosign-installer` from 3.4.0 to 3.5.0
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/v3.4.0...v3.5.0)

---
updated-dependencies:
- dependency-name: sigstore/cosign-installer
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-17 10:37:52 +02:00
Lorenzo Susini 869c9a7f4d update(falco-incubating_tules.yaml): add Backdoored library loaded into SSHD rule
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2024-04-05 15:12:02 +02:00
Sean Doughty 88a40c8d9c update: add macro known_drop_and_execute_activities
Signed-off-by: Sean Doughty <sean@render.com>
2024-03-22 16:52:54 +01:00
Kapil Sharma 172d2c283f Update .github/workflows/yaml-lint.yaml
Co-authored-by: Federico Di Pierro <nierro92@gmail.com>
Signed-off-by: Kapil Sharma <ks3913688@gmail.com>
Signed-off-by: h4l0gen <ks3913688@gmail.com>
2024-03-22 15:37:53 +01:00
Kapil Sharma d7a3895155 Update .github/workflows/yaml-lint.yaml
Co-authored-by: Federico Di Pierro <nierro92@gmail.com>
Signed-off-by: Kapil Sharma <ks3913688@gmail.com>
Signed-off-by: h4l0gen <ks3913688@gmail.com>
2024-03-22 15:37:53 +01:00
Kapil Sharma 354f9ea692 Update yaml-lint.yaml
Signed-off-by: Kapil Sharma <ks3913688@gmail.com>
Signed-off-by: h4l0gen <ks3913688@gmail.com>
2024-03-22 15:37:53 +01:00
Kapil Sharma 9ba166cf44 Add files via upload
Signed-off-by: Kapil Sharma <ks3913688@gmail.com>
Signed-off-by: h4l0gen <ks3913688@gmail.com>
2024-03-22 15:37:53 +01:00
Leonardo Grasso fbf0a4e8ce update(rules): cleanup k8s.gcr.io
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2024-03-14 09:43:24 +01:00
Louis Cailliot 44addef4f7 fix: authors and required engine version
Signed-off-by: Louis Cailliot <louis.cailliot@thalesgroup.com>
2024-03-08 11:12:03 +01:00
Louis Cailliot acd08c4107 Rename falco_mitre_checker into falco_mitre_attack_checker
Signed-off-by: Louis Cailliot <louis.cailliot@thalesgroup.com>
2024-03-08 11:12:03 +01:00
Louis Cailliot f42e702682 falco rules mitre checker module
Signed-off-by: Louis Cailliot <louis.cailliot@thalesgroup.com>
2024-03-08 11:12:03 +01:00
Petter Reinholdtsen dc7970d175 update(sandbox): Added systemd to list of programs ignored when using BPF.
On Fedora 39, events like this is logged:

  Notice BPF Program  Not Profiled (bpf_cmd=5 evt_type=bpf user=root
  user_uid=0 user_loginuid=-1 process=systemd proc_exepath=/usr/lib/systemd/systemd
  parent=<NA> command=systemd --switched-root --system --deserialize=36 rhgb terminal=0
  exe_flags=<NA> container_id=host container_name=host)

This is just normal systemd behaviour, and not really interesting to log.  The provided
patch include systemd in the list of processes allowed to use BPF without any event logged.

Signed-off-by: Petter Reinholdtsen <pere@hungry.com>
2024-03-01 19:24:37 +01:00
Leonardo Grasso f88b991a7f update(.github/FALCO_VERSIONS): unsupporting 0.37
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2024-02-29 17:34:34 +01:00
RohithRaju 2ded9e2613 update(sandbox): update required_engine_version
Signed-off-by: RohithRaju <rohithraju488@gmail.com>
2024-02-29 17:31:34 +01:00
RohithRaju 623ee22a3e update(rules/sandbox_rules): update bpf cmd format
Signed-off-by: RohithRaju <rohithraju488@gmail.com>
2024-02-29 17:31:34 +01:00
dependabot[bot] b499a1d0d0 build(deps): Bump the actions group with 1 update
Bumps the actions group with 1 update: [Ana06/get-changed-files](https://github.com/ana06/get-changed-files).


Updates `Ana06/get-changed-files` from 2.2.0 to 2.3.0
- [Release notes](https://github.com/ana06/get-changed-files/releases)
- [Commits](https://github.com/ana06/get-changed-files/compare/v2.2.0...v2.3.0)

---
updated-dependencies:
- dependency-name: Ana06/get-changed-files
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-23 11:36:08 +01:00
52 changed files with 2444 additions and 225 deletions

View File

@ -1,3 +1,4 @@
master
0.37.0
0.37.1
0.41.2
0.41.1
0.41.0

1
.github/scripts/.python-version vendored Normal file
View File

@ -0,0 +1 @@
3.12

11
.github/scripts/pyproject.toml vendored Normal file
View File

@ -0,0 +1,11 @@
[project]
name = "scripts"
version = "0.1.0"
description = "GHA scripts to publish pages"
readme = ""
requires-python = ">=3.12"
dependencies = [
"pandas>=2.2.3",
"pyyaml>=6.0.2",
"tabulate>=0.9.0",
]

View File

@ -1,3 +0,0 @@
pandas==2.0.3
pyyaml===6.0.1
tabulate==0.9.0

166
.github/scripts/uv.lock vendored Normal file
View File

@ -0,0 +1,166 @@
version = 1
revision = 1
requires-python = ">=3.12"
[[package]]
name = "numpy"
version = "2.2.3"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/fb/90/8956572f5c4ae52201fdec7ba2044b2c882832dcec7d5d0922c9e9acf2de/numpy-2.2.3.tar.gz", hash = "sha256:dbdc15f0c81611925f382dfa97b3bd0bc2c1ce19d4fe50482cb0ddc12ba30020", size = 20262700 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/43/ec/43628dcf98466e087812142eec6d1c1a6c6bdfdad30a0aa07b872dc01f6f/numpy-2.2.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12c045f43b1d2915eca6b880a7f4a256f59d62df4f044788c8ba67709412128d", size = 20929458 },
{ url = "https://files.pythonhosted.org/packages/9b/c0/2f4225073e99a5c12350954949ed19b5d4a738f541d33e6f7439e33e98e4/numpy-2.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:87eed225fd415bbae787f93a457af7f5990b92a334e346f72070bf569b9c9c95", size = 14115299 },
{ url = "https://files.pythonhosted.org/packages/ca/fa/d2c5575d9c734a7376cc1592fae50257ec95d061b27ee3dbdb0b3b551eb2/numpy-2.2.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:712a64103d97c404e87d4d7c47fb0c7ff9acccc625ca2002848e0d53288b90ea", size = 5145723 },
{ url = "https://files.pythonhosted.org/packages/eb/dc/023dad5b268a7895e58e791f28dc1c60eb7b6c06fcbc2af8538ad069d5f3/numpy-2.2.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:a5ae282abe60a2db0fd407072aff4599c279bcd6e9a2475500fc35b00a57c532", size = 6678797 },
{ url = "https://files.pythonhosted.org/packages/3f/19/bcd641ccf19ac25abb6fb1dcd7744840c11f9d62519d7057b6ab2096eb60/numpy-2.2.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5266de33d4c3420973cf9ae3b98b54a2a6d53a559310e3236c4b2b06b9c07d4e", size = 14067362 },
{ url = "https://files.pythonhosted.org/packages/39/04/78d2e7402fb479d893953fb78fa7045f7deb635ec095b6b4f0260223091a/numpy-2.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b787adbf04b0db1967798dba8da1af07e387908ed1553a0d6e74c084d1ceafe", size = 16116679 },
{ url = "https://files.pythonhosted.org/packages/d0/a1/e90f7aa66512be3150cb9d27f3d9995db330ad1b2046474a13b7040dfd92/numpy-2.2.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:34c1b7e83f94f3b564b35f480f5652a47007dd91f7c839f404d03279cc8dd021", size = 15264272 },
{ url = "https://files.pythonhosted.org/packages/dc/b6/50bd027cca494de4fa1fc7bf1662983d0ba5f256fa0ece2c376b5eb9b3f0/numpy-2.2.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4d8335b5f1b6e2bce120d55fb17064b0262ff29b459e8493d1785c18ae2553b8", size = 17880549 },
{ url = "https://files.pythonhosted.org/packages/96/30/f7bf4acb5f8db10a96f73896bdeed7a63373137b131ca18bd3dab889db3b/numpy-2.2.3-cp312-cp312-win32.whl", hash = "sha256:4d9828d25fb246bedd31e04c9e75714a4087211ac348cb39c8c5f99dbb6683fe", size = 6293394 },
{ url = "https://files.pythonhosted.org/packages/42/6e/55580a538116d16ae7c9aa17d4edd56e83f42126cb1dfe7a684da7925d2c/numpy-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:83807d445817326b4bcdaaaf8e8e9f1753da04341eceec705c001ff342002e5d", size = 12626357 },
{ url = "https://files.pythonhosted.org/packages/0e/8b/88b98ed534d6a03ba8cddb316950fe80842885709b58501233c29dfa24a9/numpy-2.2.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7bfdb06b395385ea9b91bf55c1adf1b297c9fdb531552845ff1d3ea6e40d5aba", size = 20916001 },
{ url = "https://files.pythonhosted.org/packages/d9/b4/def6ec32c725cc5fbd8bdf8af80f616acf075fe752d8a23e895da8c67b70/numpy-2.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:23c9f4edbf4c065fddb10a4f6e8b6a244342d95966a48820c614891e5059bb50", size = 14130721 },
{ url = "https://files.pythonhosted.org/packages/20/60/70af0acc86495b25b672d403e12cb25448d79a2b9658f4fc45e845c397a8/numpy-2.2.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:a0c03b6be48aaf92525cccf393265e02773be8fd9551a2f9adbe7db1fa2b60f1", size = 5130999 },
{ url = "https://files.pythonhosted.org/packages/2e/69/d96c006fb73c9a47bcb3611417cf178049aae159afae47c48bd66df9c536/numpy-2.2.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:2376e317111daa0a6739e50f7ee2a6353f768489102308b0d98fcf4a04f7f3b5", size = 6665299 },
{ url = "https://files.pythonhosted.org/packages/5a/3f/d8a877b6e48103733ac224ffa26b30887dc9944ff95dffdfa6c4ce3d7df3/numpy-2.2.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8fb62fe3d206d72fe1cfe31c4a1106ad2b136fcc1606093aeab314f02930fdf2", size = 14064096 },
{ url = "https://files.pythonhosted.org/packages/e4/43/619c2c7a0665aafc80efca465ddb1f260287266bdbdce517396f2f145d49/numpy-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52659ad2534427dffcc36aac76bebdd02b67e3b7a619ac67543bc9bfe6b7cdb1", size = 16114758 },
{ url = "https://files.pythonhosted.org/packages/d9/79/ee4fe4f60967ccd3897aa71ae14cdee9e3c097e3256975cc9575d393cb42/numpy-2.2.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1b416af7d0ed3271cad0f0a0d0bee0911ed7eba23e66f8424d9f3dfcdcae1304", size = 15259880 },
{ url = "https://files.pythonhosted.org/packages/fb/c8/8b55cf05db6d85b7a7d414b3d1bd5a740706df00bfa0824a08bf041e52ee/numpy-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1402da8e0f435991983d0a9708b779f95a8c98c6b18a171b9f1be09005e64d9d", size = 17876721 },
{ url = "https://files.pythonhosted.org/packages/21/d6/b4c2f0564b7dcc413117b0ffbb818d837e4b29996b9234e38b2025ed24e7/numpy-2.2.3-cp313-cp313-win32.whl", hash = "sha256:136553f123ee2951bfcfbc264acd34a2fc2f29d7cdf610ce7daf672b6fbaa693", size = 6290195 },
{ url = "https://files.pythonhosted.org/packages/97/e7/7d55a86719d0de7a6a597949f3febefb1009435b79ba510ff32f05a8c1d7/numpy-2.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:5b732c8beef1d7bc2d9e476dbba20aaff6167bf205ad9aa8d30913859e82884b", size = 12619013 },
{ url = "https://files.pythonhosted.org/packages/a6/1f/0b863d5528b9048fd486a56e0b97c18bf705e88736c8cea7239012119a54/numpy-2.2.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:435e7a933b9fda8126130b046975a968cc2d833b505475e588339e09f7672890", size = 20944621 },
{ url = "https://files.pythonhosted.org/packages/aa/99/b478c384f7a0a2e0736177aafc97dc9152fc036a3fdb13f5a3ab225f1494/numpy-2.2.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7678556eeb0152cbd1522b684dcd215250885993dd00adb93679ec3c0e6e091c", size = 14142502 },
{ url = "https://files.pythonhosted.org/packages/fb/61/2d9a694a0f9cd0a839501d362de2a18de75e3004576a3008e56bdd60fcdb/numpy-2.2.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:2e8da03bd561504d9b20e7a12340870dfc206c64ea59b4cfee9fceb95070ee94", size = 5176293 },
{ url = "https://files.pythonhosted.org/packages/33/35/51e94011b23e753fa33f891f601e5c1c9a3d515448659b06df9d40c0aa6e/numpy-2.2.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:c9aa4496fd0e17e3843399f533d62857cef5900facf93e735ef65aa4bbc90ef0", size = 6691874 },
{ url = "https://files.pythonhosted.org/packages/ff/cf/06e37619aad98a9d03bd8d65b8e3041c3a639be0f5f6b0a0e2da544538d4/numpy-2.2.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4ca91d61a4bf61b0f2228f24bbfa6a9facd5f8af03759fe2a655c50ae2c6610", size = 14036826 },
{ url = "https://files.pythonhosted.org/packages/0c/93/5d7d19955abd4d6099ef4a8ee006f9ce258166c38af259f9e5558a172e3e/numpy-2.2.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:deaa09cd492e24fd9b15296844c0ad1b3c976da7907e1c1ed3a0ad21dded6f76", size = 16096567 },
{ url = "https://files.pythonhosted.org/packages/af/53/d1c599acf7732d81f46a93621dab6aa8daad914b502a7a115b3f17288ab2/numpy-2.2.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:246535e2f7496b7ac85deffe932896a3577be7af8fb7eebe7146444680297e9a", size = 15242514 },
{ url = "https://files.pythonhosted.org/packages/53/43/c0f5411c7b3ea90adf341d05ace762dad8cb9819ef26093e27b15dd121ac/numpy-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:daf43a3d1ea699402c5a850e5313680ac355b4adc9770cd5cfc2940e7861f1bf", size = 17872920 },
{ url = "https://files.pythonhosted.org/packages/5b/57/6dbdd45ab277aff62021cafa1e15f9644a52f5b5fc840bc7591b4079fb58/numpy-2.2.3-cp313-cp313t-win32.whl", hash = "sha256:cf802eef1f0134afb81fef94020351be4fe1d6681aadf9c5e862af6602af64ef", size = 6346584 },
{ url = "https://files.pythonhosted.org/packages/97/9b/484f7d04b537d0a1202a5ba81c6f53f1846ae6c63c2127f8df869ed31342/numpy-2.2.3-cp313-cp313t-win_amd64.whl", hash = "sha256:aee2512827ceb6d7f517c8b85aa5d3923afe8fc7a57d028cffcd522f1c6fd082", size = 12706784 },
]
[[package]]
name = "pandas"
version = "2.2.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "numpy" },
{ name = "python-dateutil" },
{ name = "pytz" },
{ name = "tzdata" },
]
sdist = { url = "https://files.pythonhosted.org/packages/9c/d6/9f8431bacc2e19dca897724cd097b1bb224a6ad5433784a44b587c7c13af/pandas-2.2.3.tar.gz", hash = "sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667", size = 4399213 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/17/a3/fb2734118db0af37ea7433f57f722c0a56687e14b14690edff0cdb4b7e58/pandas-2.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b1d432e8d08679a40e2a6d8b2f9770a5c21793a6f9f47fdd52c5ce1948a5a8a9", size = 12529893 },
{ url = "https://files.pythonhosted.org/packages/e1/0c/ad295fd74bfac85358fd579e271cded3ac969de81f62dd0142c426b9da91/pandas-2.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a5a1595fe639f5988ba6a8e5bc9649af3baf26df3998a0abe56c02609392e0a4", size = 11363475 },
{ url = "https://files.pythonhosted.org/packages/c6/2a/4bba3f03f7d07207481fed47f5b35f556c7441acddc368ec43d6643c5777/pandas-2.2.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5de54125a92bb4d1c051c0659e6fcb75256bf799a732a87184e5ea503965bce3", size = 15188645 },
{ url = "https://files.pythonhosted.org/packages/38/f8/d8fddee9ed0d0c0f4a2132c1dfcf0e3e53265055da8df952a53e7eaf178c/pandas-2.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fffb8ae78d8af97f849404f21411c95062db1496aeb3e56f146f0355c9989319", size = 12739445 },
{ url = "https://files.pythonhosted.org/packages/20/e8/45a05d9c39d2cea61ab175dbe6a2de1d05b679e8de2011da4ee190d7e748/pandas-2.2.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dfcb5ee8d4d50c06a51c2fffa6cff6272098ad6540aed1a76d15fb9318194d8", size = 16359235 },
{ url = "https://files.pythonhosted.org/packages/1d/99/617d07a6a5e429ff90c90da64d428516605a1ec7d7bea494235e1c3882de/pandas-2.2.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a", size = 14056756 },
{ url = "https://files.pythonhosted.org/packages/29/d4/1244ab8edf173a10fd601f7e13b9566c1b525c4f365d6bee918e68381889/pandas-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13", size = 11504248 },
{ url = "https://files.pythonhosted.org/packages/64/22/3b8f4e0ed70644e85cfdcd57454686b9057c6c38d2f74fe4b8bc2527214a/pandas-2.2.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015", size = 12477643 },
{ url = "https://files.pythonhosted.org/packages/e4/93/b3f5d1838500e22c8d793625da672f3eec046b1a99257666c94446969282/pandas-2.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28", size = 11281573 },
{ url = "https://files.pythonhosted.org/packages/f5/94/6c79b07f0e5aab1dcfa35a75f4817f5c4f677931d4234afcd75f0e6a66ca/pandas-2.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0", size = 15196085 },
{ url = "https://files.pythonhosted.org/packages/e8/31/aa8da88ca0eadbabd0a639788a6da13bb2ff6edbbb9f29aa786450a30a91/pandas-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24", size = 12711809 },
{ url = "https://files.pythonhosted.org/packages/ee/7c/c6dbdb0cb2a4344cacfb8de1c5808ca885b2e4dcfde8008266608f9372af/pandas-2.2.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659", size = 16356316 },
{ url = "https://files.pythonhosted.org/packages/57/b7/8b757e7d92023b832869fa8881a992696a0bfe2e26f72c9ae9f255988d42/pandas-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb", size = 14022055 },
{ url = "https://files.pythonhosted.org/packages/3b/bc/4b18e2b8c002572c5a441a64826252ce5da2aa738855747247a971988043/pandas-2.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d", size = 11481175 },
{ url = "https://files.pythonhosted.org/packages/76/a3/a5d88146815e972d40d19247b2c162e88213ef51c7c25993942c39dbf41d/pandas-2.2.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468", size = 12615650 },
{ url = "https://files.pythonhosted.org/packages/9c/8c/f0fd18f6140ddafc0c24122c8a964e48294acc579d47def376fef12bcb4a/pandas-2.2.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18", size = 11290177 },
{ url = "https://files.pythonhosted.org/packages/ed/f9/e995754eab9c0f14c6777401f7eece0943840b7a9fc932221c19d1abee9f/pandas-2.2.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2", size = 14651526 },
{ url = "https://files.pythonhosted.org/packages/25/b0/98d6ae2e1abac4f35230aa756005e8654649d305df9a28b16b9ae4353bff/pandas-2.2.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4", size = 11871013 },
{ url = "https://files.pythonhosted.org/packages/cc/57/0f72a10f9db6a4628744c8e8f0df4e6e21de01212c7c981d31e50ffc8328/pandas-2.2.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d", size = 15711620 },
{ url = "https://files.pythonhosted.org/packages/ab/5f/b38085618b950b79d2d9164a711c52b10aefc0ae6833b96f626b7021b2ed/pandas-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a", size = 13098436 },
]
[[package]]
name = "python-dateutil"
version = "2.9.0.post0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "six" },
]
sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 },
]
[[package]]
name = "pytz"
version = "2025.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/5f/57/df1c9157c8d5a05117e455d66fd7cf6dbc46974f832b1058ed4856785d8a/pytz-2025.1.tar.gz", hash = "sha256:c2db42be2a2518b28e65f9207c4d05e6ff547d1efa4086469ef855e4ab70178e", size = 319617 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/eb/38/ac33370d784287baa1c3d538978b5e2ea064d4c1b93ffbd12826c190dd10/pytz-2025.1-py2.py3-none-any.whl", hash = "sha256:89dd22dca55b46eac6eda23b2d72721bf1bdfef212645d81513ef5d03038de57", size = 507930 },
]
[[package]]
name = "pyyaml"
version = "6.0.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873 },
{ url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302 },
{ url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154 },
{ url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223 },
{ url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542 },
{ url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164 },
{ url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 },
{ url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 },
{ url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 },
{ url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 },
{ url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 },
{ url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 },
{ url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 },
{ url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 },
{ url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 },
{ url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 },
{ url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 },
{ url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 },
]
[[package]]
name = "scripts"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "pandas" },
{ name = "pyyaml" },
{ name = "tabulate" },
]
[package.metadata]
requires-dist = [
{ name = "pandas", specifier = ">=2.2.3" },
{ name = "pyyaml", specifier = ">=6.0.2" },
{ name = "tabulate", specifier = ">=0.9.0" },
]
[[package]]
name = "six"
version = "1.17.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 },
]
[[package]]
name = "tabulate"
version = "0.9.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/ec/fe/802052aecb21e3797b8f7902564ab6ea0d60ff8ca23952079064155d1ae1/tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c", size = 81090 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f", size = 35252 },
]
[[package]]
name = "tzdata"
version = "2025.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/43/0f/fa4723f22942480be4ca9527bbde8d43f6c3f2fe8412f00e7f5f6746bc8b/tzdata-2025.1.tar.gz", hash = "sha256:24894909e88cdb28bd1636c6887801df64cb485bd593f2fd83ef29075a81d694", size = 194950 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/0f/dd/84f10e23edd882c6f968c21c2434fe67bd4a528967067515feca9e611e5e/tzdata-2025.1-py2.py3-none-any.whl", hash = "sha256:7e127113816800496f027041c570f50bcd464a020098a3b6b199517772303639", size = 346762 },
]

6
.github/workflows/.yamllint vendored Normal file
View File

@ -0,0 +1,6 @@
extends: default
rules:
line-length:
max: 130
level: error

View File

@ -19,28 +19,25 @@ jobs:
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- uses: actions/setup-python@v5
with:
python-version: 3.x
- name: Install uv
uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v5
- name: Generate updated inventory
run: |
pip install -r .github/scripts/requirements.txt
python .github/scripts/rules_overview_generator.py --rules_dir=rules > docs/index.md
cd .github/scripts/
uv run rules_overview_generator.py --rules_dir=../../rules > ../../docs/index.md
- name: Disable Table Of Content for overview
run: |
sed -i '1s/^/---\nhide:\n- toc\n---\n\n/' docs/index.md
- run: pip install mkdocs mkdocs-material
- run: uvx --with mkdocs-material mkdocs build
- run: mkdocs build
- uses: actions/upload-pages-artifact@v3
- uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
with:
path: 'site'
- id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4

View File

@ -58,7 +58,7 @@ jobs:
# Create a signature of the rules artifact as OCI artifact
- name: Install Cosign
uses: sigstore/cosign-installer@v3.4.0
uses: sigstore/cosign-installer@v3.9.0
- name: Login with cosign
run: cosign login $OCI_REGISTRY --username ${{ github.repository_owner }} --password ${{ secrets.GITHUB_TOKEN }}

View File

@ -23,7 +23,7 @@ jobs:
- name: Get changed files
id: changed-files
if: github.event_name == 'pull_request'
uses: Ana06/get-changed-files@v2.2.0
uses: Ana06/get-changed-files@v2.3.0
with:
format: space-delimited
token: ${{ secrets.GITHUB_TOKEN }}
@ -31,15 +31,17 @@ jobs:
- name: Find changed rules files
id: set-changed-files
run: |
# if we skip changed-files because we're not in a pull-request,
# then we consider all the rules contained in the repo
# Find any changed file located under the /rules folder that matches the naming convention <ruleset>_rules.yaml.
# See https://github.com/falcosecurity/rules/blob/main/README.md#naming-convention for details.
# Additionally, if we skip changed-files because we're not in a pull request,
# then we consider all the rules contained in the repository.
all_files="${{ steps.changed-files.outputs.all }}"
values=""
if [ -z "$all_files" ]; then
values=$(ls rules/*.yaml)
values=$(ls rules/*_rules.yaml)
else
for changed_file in $all_files; do
if [[ "${changed_file}" =~ ^rules/.* ]]; then
if [[ "${changed_file}" =~ ^rules/[^/]*_rules\.yaml$ ]]; then
values=${values}${changed_file}$'\n'
fi
done
@ -86,7 +88,7 @@ jobs:
run: |
build/checker/rules-check \
validate \
--falco-image="falcosecurity/falco-no-driver:${{ matrix.falco-version }}" \
--falco-image="falcosecurity/falco:${{ matrix.falco-version }}" \
-r ${{ matrix.rules-file }}
check-version:
@ -113,7 +115,7 @@ jobs:
run: git fetch --tags origin
- name: Get changed files
uses: Ana06/get-changed-files@v2.2.0
uses: Ana06/get-changed-files@v2.3.0
id: changed
with:
format: space-delimited
@ -134,7 +136,7 @@ jobs:
"${{ matrix.rules-file }}" \
result.txt \
build/checker/rules-check \
"falcosecurity/falco-no-driver:$FALCO_VERSION"
"falcosecurity/falco:$FALCO_VERSION"
if [ -s result.txt ]; then
echo "comment_file=result.txt" >> $GITHUB_OUTPUT
fi

19
.github/workflows/yaml-lint.yaml vendored Normal file
View File

@ -0,0 +1,19 @@
name: Yamllint Github Actions
on:
pull_request:
branches:
- main
jobs:
lintFalcoRules:
name: Yamllint
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: yaml-lint
uses: ibiqlik/action-yamllint@v3
with:
file_or_dir: rules/*.yaml
env:
YAMLLINT_CONFIG_FILE: .github/workflows/.yamllint

196
.gitignore vendored Normal file
View File

@ -0,0 +1,196 @@
# Specific project files
build/mitre_attack_checker/build
build/mitre_attack_checker/reports
**/falco_rules_mitre_errors.json
**/application_rules_errors.json
# IntelliJ project files
.idea
*.iml
out
gen
### Go template
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
# Go workspace file
go.work
### Python template
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/
.run/

3
OWNERS
View File

@ -5,7 +5,7 @@ approvers:
- fededp
- andreagit97
- lucaguerra
- incertum
- ekoops
reviewers:
- leodido
- kaizhe
@ -13,3 +13,4 @@ reviewers:
- loresuso
emeritus_approvers:
- kaizhe
- incertum

View File

@ -23,7 +23,7 @@ import (
"strings"
)
const defaultFalcoDockerImage = "falcosecurity/falco-no-driver:master"
const defaultFalcoDockerImage = "falcosecurity/falco:master"
const defaultFalcoDockerEntrypoint = "/usr/bin/falco"

View File

@ -0,0 +1 @@
3.10.12

View File

@ -0,0 +1,141 @@
# Mitre ATT&CK Checker Module
The Mitre ATT&CK Checker module aims to check the compliance of the Falco rules against the Mitre ATT&CK
framework. This module provides to Falco experts and Falco users a way to check default and custom
rules for Mitre ATT&CK extra tags.
This module uses STIX from the OASIS standards. Structured Threat Information Expression (STIX™) is a
language and serialization format used to exchange cyber threat intelligence (CTI) :
- [STIX CTI documentation](https://oasis-open.github.io/cti-documentation/stix/intro)
Leveraging STIX, Mitre ATT&CK Checker fetches the ATT&CK® STIX Data from MITRE ATT&CK repositories using
the `python-stix2` library implemented by OASIS:
- [ATT&CK STIX Data repository](https://github.com/mitre-attack/attack-stix-data)
- [Python STIX2 repository](https://github.com/oasis-open/cti-python-stix2)
The choice of a module is motivated by the packaging of a python code to integrate it into wider Falco
implementations. More precisely, the module can be used :
- by the rules_overview_generator.py script
- by Falco users and experts to check their Falco rules files
- by other Falco components that need to check the validity of rules files
## Build
Requirements :
- Python >= `3.10`
- Poetry >= `1.5.1`
```sh
./build.sh
```
## Install
Requirements :
- Python >= `3.10`
```sh
./install.sh
```
Or manualy using `pip` :
```sh
pip install dist/falco_mitre_attack_checker-0.1.0-py3-none-any.whl
```
## Usage
```sh
python -m falco_mitre_attack_checker --help
```
Using the stable falco rules :
```sh
python -m falco_mitre_attack_checker -f ../../rules/falco_rules.yaml -o /tmp/
```
## Development
Requirements :
- Python >= `3.10`
- Poetry >= `1.5.1`
```sh
poetry check
poetry update
poetry install --sync
```
### Testing
With coverage :
```sh
poetry update
poetry run python -m pytest --cov=falco_mitre_attack_checker
```
```
---------- coverage: platform linux, python 3.10.12-final-0 ----------
Name Stmts Miss Cover
----------------------------------------------------------------------------
falco_mitre_checker/__init__.py 0 0 100%
falco_mitre_checker/__main__.py 7 7 0%
falco_mitre_checker/api/__init__.py 0 0 100%
falco_mitre_checker/api/core.py 19 19 0%
falco_mitre_checker/cli/__init__.py 0 0 100%
falco_mitre_checker/cli/core.py 18 18 0%
falco_mitre_checker/engine/__init__.py 0 0 100%
falco_mitre_checker/engine/mitre_checker.py 46 1 98%
falco_mitre_checker/exceptions/__init__.py 0 0 100%
falco_mitre_checker/exceptions/rules_exceptions.py 8 0 100%
falco_mitre_checker/models/__init__.py 0 0 100%
falco_mitre_checker/models/falco_mitre_errors.py 16 0 100%
falco_mitre_checker/models/falco_mitre_relations.py 14 2 86%
falco_mitre_checker/parsers/__init__.py 0 0 100%
falco_mitre_checker/parsers/falco_rules.py 30 1 97%
falco_mitre_checker/parsers/mitre_stix.py 31 4 87%
falco_mitre_checker/tests/__init__.py 0 0 100%
falco_mitre_checker/tests/engine/__init__.py 0 0 100%
falco_mitre_checker/tests/engine/test_mitre_checker.py 41 0 100%
falco_mitre_checker/tests/parsers/__init__.py 0 0 100%
falco_mitre_checker/tests/parsers/test_falco_rules.py 18 0 100%
falco_mitre_checker/tests/parsers/test_mitre_stix.py 34 0 100%
falco_mitre_checker/tests/test_common.py 13 2 85%
falco_mitre_checker/utils/__init__.py 0 0 100%
falco_mitre_checker/utils/file.py 10 0 100%
falco_mitre_checker/utils/logger.py 36 7 81%
----------------------------------------------------------------------------
TOTAL 341 61 82%
```
### Security
You should run a vulnerability scanner every time you add a new dependency in projects :
```sh
poetry update
poetry run python -m safety check
```
```
Using non-commercial database
Found and scanned 33 packages
Timestamp 2023-10-02 13:43:51
0 vulnerabilities found
0 vulnerabilities ignored
+=======================================================================================================+
No known security vulnerabilities found.
+=======================================================================================================+
```

View File

@ -0,0 +1,39 @@
#!/usr/bin/env bash
SCRIPT_PATH="$(realpath "$0")"
MODULE_DIR="$(dirname "${SCRIPT_PATH:?}")"
#
# FUNCTIONS
#
function check_requirement(){
if ! eval "$@" >> /dev/null 2>&1 ; then
echo "! Fatal : missing requirement"
if [ -n "${*: -1}" ]; then echo "${@: -1}"; fi
exit 1
fi
}
#
# MAIN
#
check_requirement poetry --version "Install poetry first"
cd "${MODULE_DIR}" || exit
echo "Build environment :"
poetry env info
echo ""
echo "Update dependencies"
poetry check
poetry update --without dev
poetry install --without dev --sync
echo "Build Falco Mitre Checker module"
rm -rf "${MODULE_DIR}/dist"
poetry build --format wheel --no-cache
echo "Built in dist/:"
ls "${MODULE_DIR}/dist/"

View File

@ -0,0 +1,16 @@
from falco_mitre_attack_checker.cli.core import cli
from falco_mitre_attack_checker.utils.logger import MitreCheckerLogger
def main():
# init logger
MitreCheckerLogger()
# init cli
cli()
if __name__ == '__main__':
"""
for debug purpose
"""
main()

View File

@ -0,0 +1,38 @@
import logging
from pathlib import Path
from typing import List, Dict
from falco_mitre_attack_checker.engine.mitre_checker import FalcoMitreChecker
from falco_mitre_attack_checker.models.falco_mitre_errors import FalcoMitreError
from falco_mitre_attack_checker.utils.logger import MitreCheckerLogger
logger = logging.getLogger(MitreCheckerLogger.name)
def mitre_checker_engine(rules_files: List[Path], mitre_domain: str, mitre_version: str,
output_dir: Path = None) -> "Dict[str, List[FalcoMitreError]]":
"""
CLI core function to validate the rules against the Mitre ATT&CK's data.
:param rules_files: One or more falco rules files to check
:param mitre_domain: The name of the Mitre ATT&CK matrix domain to validate the rules. This name is
used to pull the data from the Mitre CTI's database.
:param mitre_version: The version of the Mitre ATT&CK to validate the rules. This version is used to
pull the data from the Mitre CTI's database.
:param output_dir: A folder path to dump the errors information in json format.
:param fix: If True, automatically generate the corrected falco rules file next to the original one
"""
mitre_checker = FalcoMitreChecker(mitre_domain, mitre_version)
errors_reports: Dict[str, List[FalcoMitreError]] = {}
for file in rules_files:
# validate the falco rules against the data of the mitre ATT&CK framework
errors = mitre_checker.validate(file)
errors_reports[file.stem] = errors
output_name = f"{file.stem}_mitre_errors.json"
output_path = output_dir / output_name if output_dir else file.parent / output_name
FalcoMitreChecker.dump_errors(errors, output_path)
logger.info(f"Dumped errors report in '{output_path}'")
logger.info(f"Found {len(errors)} Mitre errors")
return errors_reports

View File

@ -0,0 +1,38 @@
import logging
from pathlib import Path
from typing import List
import typer
from falco_mitre_attack_checker.api.core import mitre_checker_engine
from falco_mitre_attack_checker.exceptions.rules_exceptions import FalcoRulesFileContentError
from falco_mitre_attack_checker.utils.logger import MitreCheckerLogger
app = typer.Typer(help=f"Mitre Checker",
no_args_is_help=True,
context_settings={"help_option_names": ["-h", "--help"]})
logger = logging.getLogger(MitreCheckerLogger.name)
@app.command()
def core(rules_files: List[Path] = typer.Option(..., "-f", "--file",
help="Path to a Falco rules file. "
"Repeat for multiple files validation."),
mitre_domain: str = typer.Option("enterprise-attack", "-d", "--domain",
help="Mitre ATT&CK domain name."),
mitre_version: str = typer.Option("13.1", "-V", "--Version",
help="Mitre ATT&CK domain version."),
output_dir: Path = typer.Option(None, "-o", "--output-dir",
help="Path to a directory to dump the error report for Mitre "
"ATT&CK.")
):
try:
mitre_checker_engine(rules_files, mitre_domain, mitre_version, output_dir)
except FalcoRulesFileContentError as e:
logger.error(e.message)
typer.Exit(1)
def cli():
app()

View File

@ -0,0 +1,111 @@
import logging
from pathlib import Path
from typing import List
from falco_mitre_attack_checker.models.falco_mitre_errors import \
ErrorReason, FalcoMitreError, FalcoRulesErrors
from falco_mitre_attack_checker.models.falco_mitre_relations import MitreRelations
from falco_mitre_attack_checker.parsers.falco_rules import FalcoRulesParser
from falco_mitre_attack_checker.parsers.mitre_stix import MitreParser
from falco_mitre_attack_checker.utils.file import write_file
from falco_mitre_attack_checker.utils.logger import MitreCheckerLogger
logger = logging.getLogger(MitreCheckerLogger.name)
class FalcoMitreChecker(object):
def __init__(self, mitre_domain: str, mitre_domain_version: str):
logger.info(f"Load Mitre ATT&CK STIX Data for domain '{mitre_domain}' and version "
f"'{mitre_domain_version}'")
self.mitre_parser = MitreParser(mitre_domain, mitre_domain_version)
def validate(self, falco_rules_file: Path) -> "List[FalcoMitreError]":
"""
This function validates the falco rules' extra tags against Mitre ATT&CK STIX Data when they
contain mitre information.
This method gets the mitre techniques or sub-techniques IDs and the mitre tactics (mitre phases)
names in the extra tags of each falco rules.
If the mitre techniques or sub-techniques IDs in the tags are not related to proper the mitre
tactics names by comparing them with the mitre data (STIX data from Mitre CTI), this method
considers that the rule contains an error.
For example, if the extra tags contain :
{"tags": ["T1611", "mitre_initial_access"] }
And the actual mitre domain is 'enterprise-attack' in version '13.1', the tags' rule will be
considered erroneous since the proper mitre phase for 'T1611' is 'privilege-escalation' in this
version.
:param falco_rules_file: A falco rule file to analyse against the Mitre ATT&CK STIX Data
:return: A list of models containing a description of each error in the falco rules for Mitre
ATT&CK
"""
logger.info(f"Audit Falco rules file '{falco_rules_file}' for Mitre ATT&CK")
falco_rules_parser = FalcoRulesParser(falco_rules_file)
falco_mitre_errors: List[FalcoMitreError] = []
# build the model relation between technique (or sub-technique) ID and the mitre phase configured
# in each rule
rules_mitre_relations: MitreRelations = falco_rules_parser.get_mitre_relations()
for rule_name, rule_mitre_relation in rules_mitre_relations.rules.items():
rule_tactics = rule_mitre_relation.tactics
all_mitre_tactics = []
all_mitre_techniques_names = []
all_mitre_techniques_urls = []
# verify each technique tag against mitre data
for rule_technique_or_tactic in rule_mitre_relation.techniques:
mitre_technique_or_tactic = self.mitre_parser.get_tactic_or_technique_by_id(
rule_technique_or_tactic)
mitre_tactics_names = self.mitre_parser.get_tactics_names(mitre_technique_or_tactic)
formatted_mitre_tactics_names = [f"mitre_{tactic.replace('-', '_')}" for tactic in
mitre_tactics_names]
# gather all correct mitre tactics & techniques of this rule
all_mitre_tactics += mitre_tactics_names
mitre_technique_name = self.mitre_parser.get_mitre_name(mitre_technique_or_tactic)
mitre_technique_url = self.mitre_parser.get_technique_external_reference(
mitre_technique_or_tactic)['url']
all_mitre_techniques_names.append(mitre_technique_name)
all_mitre_techniques_urls.append(mitre_technique_url)
if not set(formatted_mitre_tactics_names).issubset(set(rule_tactics)):
# detect errors
# missing tactic tag in rule for this technique
falco_error = FalcoMitreError(rule=rule_name,
techniques_tags=[rule_technique_or_tactic],
tactics_tags=rule_tactics,
mitre_techniques_names=[mitre_technique_name],
mitre_tactics_names=mitre_tactics_names,
mitre_techniques_urls=[mitre_technique_url],
reasons=[ErrorReason.MISSING])
falco_mitre_errors.append(falco_error)
# verify tactics
all_mitre_tactics_set = set(all_mitre_tactics)
if len(rule_tactics) > len(all_mitre_tactics_set):
# detect errors when too many tactic tags are included into the rule extra tags
falco_error = FalcoMitreError(rule=rule_name,
techniques_tags=rule_mitre_relation.techniques,
tactics_tags=rule_tactics,
mitre_techniques_names=list(
set(all_mitre_techniques_names)),
mitre_tactics_names=list(set(all_mitre_tactics_set)),
mitre_techniques_urls=list(set(all_mitre_techniques_urls)),
reasons=[ErrorReason.OVERDO])
falco_mitre_errors.append(falco_error)
return falco_mitre_errors
def autofix(self, falco_rules_file: Path, falco_mitre_errors: List[FalcoMitreError]):
"""
Automatically fix Mitre tags in a falco rules file from a provided falco mitre errors report
:param falco_rules_file: the rules file to fix
:param falco_mitre_errors: the falco mitre error report for this file
"""
pass
@staticmethod
def dump_errors(falco_mitre_errors: List[FalcoMitreError], output: Path) -> None:
"""
Write a list of falco mitre errors model to a file
:param output: output file to dump the errors
:param falco_mitre_errors: List of falco mitre errors models
"""
write_file(FalcoRulesErrors(errors=falco_mitre_errors).json(), output)

View File

@ -0,0 +1,12 @@
from pathlib import Path
class FalcoException(Exception):
pass
class FalcoRulesFileContentError(Exception):
def __init__(self, file: Path, message: str = "Wrong Falco Rules file content or format", *args):
self.file = file
self.message = message
super().__init__(self.message, args)

View File

@ -0,0 +1,42 @@
from enum import Enum
from typing import List
from pydantic import BaseModel
class ErrorReason(str, Enum):
MISSING = "One or more tactics tags are missing"
OVERDO = "Too many tactics tags"
class FalcoMitreError(BaseModel):
"""
This model describe an error located in a falco rule and related to its mitre tag
"""
# FALCO RELATED INFORMATION
# 'rule' is the rule description in the falco rules file
rule: str
# 'tactics_tags' are the tags of Mitre ATT&CK tactics in the current falco rule
tactics_tags: List[str]
# 'technique_tag' is the tag of a Mitre ATT&CK technique in the current falco rule
techniques_tags: List[str]
# MITRE ATT&CK RELATED INFORMATION FROM STIX DATA
# 'mitre_tactics_names' are the Mitre ATT&CK's tactics name related to the technique tag in the
# current falco rule. These names are taken from STIX data.
mitre_tactics_names: List[str]
# 'mitre_technique_name' is the Mitre ATT&CK's technique name related to the technique tag in the
# current falco rule. This name is taken from STIX data.
mitre_techniques_names: List[str]
# 'mitre_technique_url' is the Mitre ATT&CK's technique url related to the technique tag in the
# current falco rule. This url is taken from STIX data.
mitre_techniques_urls: List[str]
# details about the error
reasons: List[ErrorReason]
class FalcoRulesErrors(BaseModel):
"""
This model is just useful to dump errors to disk
"""
errors: List[FalcoMitreError]

View File

@ -0,0 +1,29 @@
from typing import List, Dict
from pydantic import BaseModel
class MitreRelation(BaseModel):
"""
Simple relation between Mitre techniques or sub-techniques and the attached mitre phases
"""
techniques: List[str]
tactics: List[str]
class MitreRelations(BaseModel):
"""
This class builds a relation between a Falco rule and the extra tags it uses for Mitre ATT&CK
"""
rules: Dict[str, MitreRelation] = {}
def __len__(self):
return len(self.rules)
def add_techniques_and_tactics(self, rule_name: str, techniques_ids: List[str],
tactics_names: List[str]):
if rule_name in self.rules.keys():
self.rules[rule_name].techniques += techniques_ids
self.rules[rule_name].tactics += tactics_names
else:
self.rules[rule_name] = MitreRelation(techniques=techniques_ids, tactics=tactics_names)

View File

@ -0,0 +1,52 @@
import re
from pathlib import Path
from typing import Dict
from falco_mitre_attack_checker.exceptions.rules_exceptions import FalcoRulesFileContentError
from falco_mitre_attack_checker.models.falco_mitre_relations import MitreRelations
from falco_mitre_attack_checker.utils.file import read_yaml
class FalcoRulesParser(object):
"""
A Deserialization class for Falco rules file in order to define parsing methods
"""
VALIDATION_KEY = "required_engine_version"
rules: Dict
def __init__(self, rules_file: Path):
self.path = rules_file
self.rules = read_yaml(rules_file)
self.validate()
def validate(self):
"""
Simple function to check if the submitted file contains some requirements that Falco rules files
should have.
"""
error = FalcoRulesFileContentError(self.path,
message=f"Missing 'required_engine_version' conf in "
f"{self.path}, so wrong falco rules file format or "
f"not a rules file.")
try:
if not [items for items in self.rules if self.VALIDATION_KEY in items.keys()]:
raise error
except AttributeError:
raise error
def get_mitre_relations(self) -> "MitreRelations":
"""
Build a relation model between techniques and mitre phases described in the falco rules
:return: the list of the relations
"""
# filter for rules with extra tags
filtered_rules = [rule for rule in self.rules if "tags" in rule.keys()]
relations = MitreRelations()
for rule in filtered_rules:
rule_desc: str = rule['rule']
formatted_tags = [str(tag).upper() for tag in rule['tags']]
tactics = [tag.lower() for tag in formatted_tags if "MITRE_" in tag]
techniques = [tag for tag in formatted_tags if re.search("^TA?(\\d+).(\\d+)", tag)]
relations.add_techniques_and_tactics(rule_desc, techniques, tactics)
return relations

View File

@ -0,0 +1,74 @@
import logging
from typing import Dict, List
import requests
from stix2 import MemoryStore, Filter, AttackPattern
from falco_mitre_attack_checker.utils.logger import MitreCheckerLogger
logger = logging.getLogger(MitreCheckerLogger.name)
class MitreParser(object):
"""
A Deserialization class for Mitre ATT&CK STIX2 data from Mitre CTI in order to define parsing methods
"""
# src is the source data directly fetched from STIX2 CTI bundle
src: MemoryStore
def __init__(self, mitre_domain: str, mitre_domain_version: str):
"""
Init the Mitre parser by loading Mitre's STIX data from source.
https://github.com/mitre/cti/blob/master/USAGE.md
:param mitre_domain: either 'enterprise-attack', 'mobile-attack', or 'ics-attack'
:param mitre_domain_version: version of the mitre domain in format 'XX.XX'
"""
self.mitre_domain = mitre_domain
self.mitre_domain_version = mitre_domain_version
stix_json = requests.get(
f"https://raw.githubusercontent.com/mitre/cti/ATT%26CK-v{mitre_domain_version}/{mitre_domain}/{mitre_domain}.json").json()
self.src = MemoryStore(stix_data=stix_json["objects"])
def get_tactic_or_technique_by_id(self, external_id: str) -> "AttackPattern | None":
"""
Query Mitre CTI's STIX data to search a STIX technique definition by its ID
:param external_id: ID of the MITRE ATT&CK technique
:return: the technique definition in STIX2 data format
"""
# by default, a List is returned for STIX2 refs, but we expect only one technique per ID
try:
technique = self.src.query([
Filter('external_references.external_id', '=', external_id),
Filter('type', 'in', ['x-mitre-tactic', 'attack-pattern']),
])[0]
# Some techniques do not contain the 'x_mitre_deprecated' field
# So it is not exploitable with a filter, but we can do it by ourselves
if 'x_mitre_technique' in technique:
# return None if deprecated
return technique if not technique.x_mitre_deprecated else None
# considering technique is valid if no 'deprecation' field is defined
return technique
except IndexError:
logger.warning(f"Technique {external_id} doesn't exist for '{self.mitre_domain}' "
f"v{self.mitre_domain_version}")
return None
@classmethod
def get_tactics_names(cls, ttp: AttackPattern) -> "List[str]":
"""
Get the mitre phase name (tactic) of a given technique or tactic.
If it is a tactic, only return the tactic name.
:param ttp: The MITRE ATT&CK data of a technique of a tactic
:return: The mitre phase names of the given technique or tactic
"""
return [tactic["phase_name"] for tactic in
ttp["kill_chain_phases"]] if "kill_chain_phases" in ttp else [ttp["x_mitre_shortname"]]
@classmethod
def get_mitre_name(cls, ttp: AttackPattern) -> str:
return ttp['name']
@classmethod
def get_technique_external_reference(cls, ttp: AttackPattern) -> "Dict[str, str]":
return [reference for reference in ttp['external_references']
if reference['source_name'] == "mitre-attack"][0]

View File

@ -0,0 +1,63 @@
from pathlib import Path
from typing import List
from falco_mitre_attack_checker.engine.mitre_checker import FalcoMitreChecker
from falco_mitre_attack_checker.models.falco_mitre_errors import ErrorReason, FalcoRulesErrors, FalcoMitreError
from falco_mitre_attack_checker.tests.test_common import MITRE_DOMAIN, MITRE_VERSION, FALCO_RULES_FILE
# global
mitre_checker = FalcoMitreChecker(MITRE_DOMAIN, MITRE_VERSION)
assert mitre_checker.mitre_parser
errors: List[FalcoMitreError] = mitre_checker.validate(FALCO_RULES_FILE)
assert errors
def get_errors_by_rule(rule_name: str,
myerrors: "List[FalcoMitreError]") -> "List[FalcoMitreError]":
return [e for e in myerrors if e.rule == rule_name]
def get_error_by_technique(technique: str,
myerrors: "List[FalcoMitreError]") -> "FalcoMitreError":
return [e for e in myerrors if e.techniques_tags == [technique]][0]
def test_validate():
# mitre tag not matching the technique phase
errors_1 = get_errors_by_rule('wrong mitre rule', errors)
assert errors_1
assert len(errors_1) == 1
error_1: FalcoMitreError = get_error_by_technique('T1610', errors_1)
assert error_1
assert error_1.tactics_tags == ['mitre_lateral_movement']
assert error_1.mitre_tactics_names == ['defense-evasion', 'execution']
assert error_1.reasons == [ErrorReason.MISSING]
# missing mitre tag for multiple techniques
# desc: one tactic tag is missing to fulfill all the mitre phases from the tagged techniques
errors_2 = get_errors_by_rule("wrong mitre rule multiple techniques and missing one tactic", errors)
assert len(errors_2) == 1
error_1020: FalcoMitreError = get_error_by_technique('T1020', errors_2)
assert error_1020
assert error_1020.tactics_tags == ['mitre_credential_access', 'mitre_discovery']
assert error_1020.mitre_tactics_names == ['exfiltration']
assert error_1020.reasons == [ErrorReason.MISSING]
# too many tactics tags
errors_3 = get_errors_by_rule("too many tactics tags with multiple techniques", errors)
assert len(errors_3) == 1
error_tactics: FalcoMitreError = errors_3[0]
assert error_tactics.tactics_tags.sort() == ["mitre_discovery", "mitre_exfiltration",
"mitre_credential_access", "mitre_execution"].sort()
assert error_tactics.mitre_tactics_names.sort() == ["mitre_discovery", "mitre_exfiltration",
"mitre_credential_access"].sort()
assert error_tactics.reasons == [ErrorReason.OVERDO]
def test_dump():
output = Path('/tmp/test_falco_mitre_checker_dump.json')
mitre_checker.dump_errors(errors, output)
assert output.exists()
from_file = FalcoRulesErrors.parse_file(output)
assert from_file

View File

@ -0,0 +1,26 @@
import pytest
from falco_mitre_attack_checker.exceptions.rules_exceptions import FalcoRulesFileContentError
from falco_mitre_attack_checker.parsers.falco_rules import FalcoRulesParser
from falco_mitre_attack_checker.tests.test_common import NOT_FALCO_RULES_FILE, FALCO_RULES_FILE
# test falco rules file validation
with pytest.raises(FalcoRulesFileContentError):
FalcoRulesParser(NOT_FALCO_RULES_FILE)
falco_rules_parser = FalcoRulesParser(FALCO_RULES_FILE)
assert falco_rules_parser.rules
def test_get_mitre_relations():
relations = falco_rules_parser.get_mitre_relations()
assert relations
assert len(relations) == 6
correct_mitre_rule = relations.rules['correct mitre rule']
assert correct_mitre_rule.tactics == ['mitre_persistence']
assert correct_mitre_rule.techniques == ['T1098']
wrong_mitre_rule = relations.rules['wrong mitre rule']
assert wrong_mitre_rule.tactics == ['mitre_lateral_movement']
assert wrong_mitre_rule.techniques == ['T1610']

View File

@ -0,0 +1,50 @@
from falco_mitre_attack_checker.parsers.mitre_stix import MitreParser
from falco_mitre_attack_checker.tests.test_common import RESOURCES_DIR, MITRE_VERSION, MITRE_DOMAIN
MITRE_STIX_DATAFILE = f"{RESOURCES_DIR}/mitre_cti_stix_13_1.json"
mitre_parser = MitreParser(MITRE_DOMAIN, MITRE_VERSION)
assert mitre_parser.src
def test_get_tactic_or_technique_by_id():
# technique
technique = mitre_parser.get_tactic_or_technique_by_id("T1548.001")
assert technique
assert not bool(technique.x_mitre_deprecated)
assert technique.type == 'attack-pattern'
assert technique.kill_chain_phases
kill_chain_names = [chain.kill_chain_name for chain in technique.kill_chain_phases]
assert 'mitre-attack' in kill_chain_names
# tactic
tactic = mitre_parser.get_tactic_or_technique_by_id("TA0001")
assert tactic
assert tactic['type'] == "x-mitre-tactic"
def test_get_mitre_name():
technique = mitre_parser.get_tactic_or_technique_by_id("T1548.001")
assert mitre_parser.get_mitre_name(technique) == "Setuid and Setgid"
def test_get_technique_external_reference():
technique = mitre_parser.get_tactic_or_technique_by_id("T1548.001")
reference = mitre_parser.get_technique_external_reference(technique)
assert reference
assert reference['source_name'] == 'mitre-attack'
assert reference['url'] == "https://attack.mitre.org/techniques/T1548/001"
def test_get_tactics_names():
# technique with multiple tactics
technique = mitre_parser.get_tactic_or_technique_by_id("T1610")
tactics_names = mitre_parser.get_tactics_names(technique)
assert tactics_names
assert tactics_names == ['defense-evasion', 'execution']
# tactic
tactic = mitre_parser.get_tactic_or_technique_by_id("TA0001")
tactics_names = mitre_parser.get_tactics_names(tactic)
assert tactics_names
assert tactics_names == ['initial-access']

View File

@ -0,0 +1,88 @@
- required_engine_version: 0.31.0
- macro: not a rule
condition: true
- rule: not a mitre rule
desc: an attempt to write to any file below /etc
condition: write_etc_common
output: "File below /etc opened for writing (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline pid=%proc.pid parent=%proc.pname pcmdline=%proc.pcmdline file=%fd.name program=%proc.name gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] container_id=%container.id image=%container.image.repository)"
priority: ERROR
tags: [ host, container, filesystem ]
- rule: correct mitre rule
desc: an attempt to write to any file below /etc
condition: write_etc_common
output: "File below /etc opened for writing (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline pid=%proc.pid parent=%proc.pname pcmdline=%proc.pcmdline file=%fd.name program=%proc.name gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] container_id=%container.id image=%container.image.repository)"
priority: ERROR
tags: [ host, container, network, mitre_persistence, T1098 ]
- rule: wrong mitre rule
desc: >
Detect the initial process started by a container that is not in a list of allowed containers.
condition: container_started and container and not allowed_containers
output: Container started and not in allowed list (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline pid=%proc.pid %container.info image=%container.image.repository:%container.image.tag)
priority: WARNING
tags: [ container, mitre_lateral_movement, T1610 ]
- rule: correct mitre rule tactics tags with multiple techniques
desc: >
Directory traversal monitored file read - Web applications can be vulnerable to directory traversal attacks that allow accessing files outside of the web app's root directory (e.g. Arbitrary File Read bugs).
System directories like /etc are typically accessed via absolute paths. Access patterns outside of this (here path traversal) can be regarded as suspicious.
This rule includes failed file open attempts.
condition: (open_read or open_file_failed) and (etc_dir or user_ssh_directory or fd.name startswith /root/.ssh or fd.name contains "id_rsa") and directory_traversal and not proc.pname in (shell_binaries)
enabled: true
output: >
Read monitored file via directory traversal (username=%user.name useruid=%user.uid user_loginuid=%user.loginuid program=%proc.name exe=%proc.exepath
command=%proc.cmdline pid=%proc.pid parent=%proc.pname file=%fd.name fileraw=%fd.nameraw parent=%proc.pname
gparent=%proc.aname[2] container_id=%container.id image=%container.image.repository returncode=%evt.res cwd=%proc.cwd)
priority: WARNING
tags: [ host, container, filesystem, mitre_discovery, mitre_exfiltration, mitre_credential_access, T1555, T1212, T1020, T1552, T1083 ]
- rule: too many tactics tags with multiple techniques
desc: >
Directory traversal monitored file read - Web applications can be vulnerable to directory traversal attacks that allow accessing files outside of the web app's root directory (e.g. Arbitrary File Read bugs).
System directories like /etc are typically accessed via absolute paths. Access patterns outside of this (here path traversal) can be regarded as suspicious.
This rule includes failed file open attempts.
condition: (open_read or open_file_failed) and (etc_dir or user_ssh_directory or fd.name startswith /root/.ssh or fd.name contains "id_rsa") and directory_traversal and not proc.pname in (shell_binaries)
enabled: true
output: >
Read monitored file via directory traversal (username=%user.name useruid=%user.uid user_loginuid=%user.loginuid program=%proc.name exe=%proc.exepath
command=%proc.cmdline pid=%proc.pid parent=%proc.pname file=%fd.name fileraw=%fd.nameraw parent=%proc.pname
gparent=%proc.aname[2] container_id=%container.id image=%container.image.repository returncode=%evt.res cwd=%proc.cwd)
priority: WARNING
tags: [ host, container, filesystem, mitre_discovery, mitre_exfiltration, mitre_credential_access, mitre_execution, T1555, T1212, T1020, T1552, T1083 ]
- rule: wrong mitre rule multiple techniques and missing one tactic
desc: >
Read sensitive file untrusted - an attempt to read any sensitive file (e.g. files containing user/password/authentication
information). Exceptions are made for known trusted programs.
condition: >
sensitive_files and open_read
and proc_name_exists
and not proc.name in (user_mgmt_binaries, userexec_binaries, package_mgmt_binaries,
cron_binaries, read_sensitive_file_binaries, shell_binaries, hids_binaries,
vpn_binaries, mail_config_binaries, nomachine_binaries, sshkit_script_binaries,
in.proftpd, mandb, salt-call, salt-minion, postgres_mgmt_binaries,
google_oslogin_
)
and not cmp_cp_by_passwd
and not ansible_running_python
and not run_by_qualys
and not run_by_chef
and not run_by_google_accounts_daemon
and not user_read_sensitive_file_conditions
and not mandb_postinst
and not perl_running_plesk
and not perl_running_updmap
and not veritas_driver_script
and not perl_running_centrifydc
and not runuser_reading_pam
and not linux_bench_reading_etc_shadow
and not user_known_read_sensitive_files_activities
and not user_read_sensitive_file_containers
output: >
Sensitive file opened for reading by non-trusted program (user=%user.name user_loginuid=%user.loginuid program=%proc.name
command=%proc.cmdline pid=%proc.pid file=%fd.name parent=%proc.pname gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] container_id=%container.id image=%container.image.repository)
priority: WARNING
tags: [ host, container, filesystem, mitre_credential_access, mitre_discovery, T1555, T1212, T1020, T1552, T1083 ]

View File

@ -0,0 +1,2 @@
test: True
falco-rules: false

View File

@ -0,0 +1,20 @@
import os
from pathlib import Path
from falco_mitre_attack_checker.utils.logger import MitreCheckerLogger
MitreCheckerLogger()
TEST_DIR = os.path.dirname(os.path.abspath(__file__))
RESOURCES_DIR = f"{TEST_DIR}/resources"
MITRE_VERSION = "13.1"
MITRE_DOMAIN = "enterprise-attack"
FALCO_RULES_FILE = Path(f"{RESOURCES_DIR}/falco_rules_test.yaml")
NOT_FALCO_RULES_FILE = Path(f"{RESOURCES_DIR}/not_falco_rules_test.yaml")
def read_file(path: Path) -> "str":
with open(path, 'r') as f:
return str(f.read())

View File

@ -0,0 +1,20 @@
import os
from pathlib import Path
from typing import Dict
import yaml
def read_yaml(path: Path) -> Dict:
"""
Validate format and read yaml file content
:param path: Path to a yaml file
:return: file content as dictionnary
"""
with open(path, "r") as p:
return yaml.safe_load(p.read())
def write_file(content: str, output: Path):
with open(os.path.expandvars(output), 'w') as f:
f.write(content)

View File

@ -0,0 +1,55 @@
import logging
import sys
from pathlib import Path
from typing import Optional
class LoggerFormatter(logging.Formatter):
green = "\x1b[92;21m"
cyan = "\x1b[96;21m"
yellow = "\x1b[93;21m"
red = "\x1b[91;21m"
reset = "\x1b[0m"
tag = "[%(levelname)s]"
message = " %(message)s"
file = " - (%(filename)s:%(lineno)d)"
FORMATS = {
logging.DEBUG: cyan + tag + reset + message,
logging.INFO: green + tag + reset + message,
logging.WARNING: yellow + tag + reset + message + file,
logging.ERROR: red + tag + reset + message + file,
logging.FATAL: red + tag + reset + message + file
}
def format(self, record):
log_fmt = self.FORMATS.get(record.levelno)
formatter = logging.Formatter(log_fmt)
return formatter.format(record)
class MitreCheckerLogger:
name: str = "mitre-checker"
formatter: logging.Formatter = LoggerFormatter()
def __init__(self, debug: bool = False, logfile: Optional[Path] = None):
logger = logging.getLogger(self.name)
# verbosity
level = logging.DEBUG if debug else logging.INFO
logger.setLevel(level)
# add stdout logger to logging
stdout_handler = logging.StreamHandler(sys.stdout)
stdout_handler.setFormatter(self.formatter)
logger.addHandler(stdout_handler)
# logfile output
if logfile is not None:
logfile_path = Path(logfile)
logfile_path.parent.mkdir(parents=True, exist_ok=True)
logfile_path.touch(exist_ok=True)
output_file_handler = logging.FileHandler(logfile)
output_file_handler.setLevel(level)
output_file_handler.setFormatter(self.formatter)
logger.addHandler(output_file_handler)

View File

@ -0,0 +1,31 @@
#!/usr/bin/env bash
SCRIPT_PATH="$(realpath "$0")"
MODULE_DIR="$(dirname "${SCRIPT_PATH:?}")"
#
# FUNCTIONS
#
function check_requirement(){
if ! eval "$@" >> /dev/null 2>&1 ; then
echo "! Fatal : missing requirement"
if [ -n "${*: -1}" ]; then echo "${@: -1}"; fi
exit 1
fi
}
#
# MAIN
#
cd "${MODULE_DIR}" || exit
pyversion=$(python --version)
echo "Install falco mitre checker module for: ${pyversion}"
echo ""
wheel="$(find "./dist/" -type f -name "*.whl")"
python -m pip install "${wheel}" --force-reinstall --no-cache-dir
echo ""
echo "OK"

823
build/mitre_attack_checker/poetry.lock generated Normal file
View File

@ -0,0 +1,823 @@
# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand.
[[package]]
name = "antlr4-python3-runtime"
version = "4.9.3"
description = "ANTLR 4.9.3 runtime for Python 3.7"
optional = false
python-versions = "*"
files = [
{file = "antlr4-python3-runtime-4.9.3.tar.gz", hash = "sha256:f224469b4168294902bb1efa80a8bf7855f24c99aef99cbefc1bcd3cce77881b"},
]
[[package]]
name = "certifi"
version = "2023.11.17"
description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.6"
files = [
{file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"},
{file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"},
]
[[package]]
name = "charset-normalizer"
version = "3.3.2"
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
optional = false
python-versions = ">=3.7.0"
files = [
{file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
{file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"},
{file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"},
{file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"},
{file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"},
{file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"},
{file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"},
{file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"},
{file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"},
{file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"},
{file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"},
{file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"},
{file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"},
{file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"},
{file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"},
{file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"},
{file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"},
{file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"},
{file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"},
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"},
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"},
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"},
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"},
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"},
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"},
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"},
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"},
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"},
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"},
{file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"},
{file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"},
{file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"},
{file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"},
{file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"},
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"},
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"},
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"},
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"},
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"},
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"},
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"},
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"},
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"},
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"},
{file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"},
{file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"},
{file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"},
{file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"},
{file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"},
{file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"},
{file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"},
{file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"},
{file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"},
{file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"},
{file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"},
{file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"},
{file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"},
{file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"},
{file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"},
{file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"},
{file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"},
{file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"},
{file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"},
{file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"},
{file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"},
{file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"},
{file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"},
{file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"},
{file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"},
{file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"},
{file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"},
{file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"},
{file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"},
{file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"},
{file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"},
{file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"},
{file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"},
{file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"},
{file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"},
{file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"},
{file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"},
{file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"},
{file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"},
{file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"},
{file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"},
{file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"},
{file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"},
{file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"},
{file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"},
{file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"},
]
[[package]]
name = "click"
version = "8.1.7"
description = "Composable command line interface toolkit"
optional = false
python-versions = ">=3.7"
files = [
{file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
{file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
]
[package.dependencies]
colorama = {version = "*", markers = "platform_system == \"Windows\""}
[[package]]
name = "colorama"
version = "0.4.6"
description = "Cross-platform colored terminal text."
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
files = [
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
]
[[package]]
name = "coverage"
version = "7.3.2"
description = "Code coverage measurement for Python"
optional = false
python-versions = ">=3.8"
files = [
{file = "coverage-7.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf"},
{file = "coverage-7.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda"},
{file = "coverage-7.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a"},
{file = "coverage-7.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c"},
{file = "coverage-7.3.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f"},
{file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6"},
{file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148"},
{file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9"},
{file = "coverage-7.3.2-cp310-cp310-win32.whl", hash = "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f"},
{file = "coverage-7.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611"},
{file = "coverage-7.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c"},
{file = "coverage-7.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074"},
{file = "coverage-7.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a"},
{file = "coverage-7.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3"},
{file = "coverage-7.3.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a"},
{file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1"},
{file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c"},
{file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312"},
{file = "coverage-7.3.2-cp311-cp311-win32.whl", hash = "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640"},
{file = "coverage-7.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2"},
{file = "coverage-7.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836"},
{file = "coverage-7.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63"},
{file = "coverage-7.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216"},
{file = "coverage-7.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4"},
{file = "coverage-7.3.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf"},
{file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf"},
{file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84"},
{file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a"},
{file = "coverage-7.3.2-cp312-cp312-win32.whl", hash = "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb"},
{file = "coverage-7.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed"},
{file = "coverage-7.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738"},
{file = "coverage-7.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2"},
{file = "coverage-7.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2"},
{file = "coverage-7.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c"},
{file = "coverage-7.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9"},
{file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82"},
{file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901"},
{file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76"},
{file = "coverage-7.3.2-cp38-cp38-win32.whl", hash = "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92"},
{file = "coverage-7.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a"},
{file = "coverage-7.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce"},
{file = "coverage-7.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9"},
{file = "coverage-7.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f"},
{file = "coverage-7.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25"},
{file = "coverage-7.3.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9"},
{file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6"},
{file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc"},
{file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083"},
{file = "coverage-7.3.2-cp39-cp39-win32.whl", hash = "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce"},
{file = "coverage-7.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f"},
{file = "coverage-7.3.2-pp38.pp39.pp310-none-any.whl", hash = "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637"},
{file = "coverage-7.3.2.tar.gz", hash = "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef"},
]
[package.dependencies]
tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""}
[package.extras]
toml = ["tomli"]
[[package]]
name = "dparse"
version = "0.6.3"
description = "A parser for Python dependency files"
optional = false
python-versions = ">=3.6"
files = [
{file = "dparse-0.6.3-py3-none-any.whl", hash = "sha256:0d8fe18714056ca632d98b24fbfc4e9791d4e47065285ab486182288813a5318"},
{file = "dparse-0.6.3.tar.gz", hash = "sha256:27bb8b4bcaefec3997697ba3f6e06b2447200ba273c0b085c3d012a04571b528"},
]
[package.dependencies]
packaging = "*"
tomli = {version = "*", markers = "python_version < \"3.11\""}
[package.extras]
conda = ["pyyaml"]
pipenv = ["pipenv (<=2022.12.19)"]
[[package]]
name = "exceptiongroup"
version = "1.2.0"
description = "Backport of PEP 654 (exception groups)"
optional = false
python-versions = ">=3.7"
files = [
{file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"},
{file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"},
]
[package.extras]
test = ["pytest (>=6)"]
[[package]]
name = "idna"
version = "3.6"
description = "Internationalized Domain Names in Applications (IDNA)"
optional = false
python-versions = ">=3.5"
files = [
{file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"},
{file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"},
]
[[package]]
name = "iniconfig"
version = "2.0.0"
description = "brain-dead simple config-ini parsing"
optional = false
python-versions = ">=3.7"
files = [
{file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
{file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
]
[[package]]
name = "packaging"
version = "21.3"
description = "Core utilities for Python packages"
optional = false
python-versions = ">=3.6"
files = [
{file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
{file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
]
[package.dependencies]
pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
[[package]]
name = "pluggy"
version = "1.3.0"
description = "plugin and hook calling mechanisms for python"
optional = false
python-versions = ">=3.8"
files = [
{file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"},
{file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"},
]
[package.extras]
dev = ["pre-commit", "tox"]
testing = ["pytest", "pytest-benchmark"]
[[package]]
name = "pydantic"
version = "1.10.13"
description = "Data validation and settings management using python type hints"
optional = false
python-versions = ">=3.7"
files = [
{file = "pydantic-1.10.13-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:efff03cc7a4f29d9009d1c96ceb1e7a70a65cfe86e89d34e4a5f2ab1e5693737"},
{file = "pydantic-1.10.13-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ecea2b9d80e5333303eeb77e180b90e95eea8f765d08c3d278cd56b00345d01"},
{file = "pydantic-1.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1740068fd8e2ef6eb27a20e5651df000978edce6da6803c2bef0bc74540f9548"},
{file = "pydantic-1.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84bafe2e60b5e78bc64a2941b4c071a4b7404c5c907f5f5a99b0139781e69ed8"},
{file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bc0898c12f8e9c97f6cd44c0ed70d55749eaf783716896960b4ecce2edfd2d69"},
{file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:654db58ae399fe6434e55325a2c3e959836bd17a6f6a0b6ca8107ea0571d2e17"},
{file = "pydantic-1.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:75ac15385a3534d887a99c713aa3da88a30fbd6204a5cd0dc4dab3d770b9bd2f"},
{file = "pydantic-1.10.13-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c553f6a156deb868ba38a23cf0df886c63492e9257f60a79c0fd8e7173537653"},
{file = "pydantic-1.10.13-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5e08865bc6464df8c7d61439ef4439829e3ab62ab1669cddea8dd00cd74b9ffe"},
{file = "pydantic-1.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e31647d85a2013d926ce60b84f9dd5300d44535a9941fe825dc349ae1f760df9"},
{file = "pydantic-1.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:210ce042e8f6f7c01168b2d84d4c9eb2b009fe7bf572c2266e235edf14bacd80"},
{file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8ae5dd6b721459bfa30805f4c25880e0dd78fc5b5879f9f7a692196ddcb5a580"},
{file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f8e81fc5fb17dae698f52bdd1c4f18b6ca674d7068242b2aff075f588301bbb0"},
{file = "pydantic-1.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:61d9dce220447fb74f45e73d7ff3b530e25db30192ad8d425166d43c5deb6df0"},
{file = "pydantic-1.10.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4b03e42ec20286f052490423682016fd80fda830d8e4119f8ab13ec7464c0132"},
{file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f59ef915cac80275245824e9d771ee939133be38215555e9dc90c6cb148aaeb5"},
{file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a1f9f747851338933942db7af7b6ee8268568ef2ed86c4185c6ef4402e80ba8"},
{file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:97cce3ae7341f7620a0ba5ef6cf043975cd9d2b81f3aa5f4ea37928269bc1b87"},
{file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:854223752ba81e3abf663d685f105c64150873cc6f5d0c01d3e3220bcff7d36f"},
{file = "pydantic-1.10.13-cp37-cp37m-win_amd64.whl", hash = "sha256:b97c1fac8c49be29486df85968682b0afa77e1b809aff74b83081cc115e52f33"},
{file = "pydantic-1.10.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c958d053453a1c4b1c2062b05cd42d9d5c8eb67537b8d5a7e3c3032943ecd261"},
{file = "pydantic-1.10.13-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c5370a7edaac06daee3af1c8b1192e305bc102abcbf2a92374b5bc793818599"},
{file = "pydantic-1.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d6f6e7305244bddb4414ba7094ce910560c907bdfa3501e9db1a7fd7eaea127"},
{file = "pydantic-1.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3a3c792a58e1622667a2837512099eac62490cdfd63bd407993aaf200a4cf1f"},
{file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c636925f38b8db208e09d344c7aa4f29a86bb9947495dd6b6d376ad10334fb78"},
{file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:678bcf5591b63cc917100dc50ab6caebe597ac67e8c9ccb75e698f66038ea953"},
{file = "pydantic-1.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:6cf25c1a65c27923a17b3da28a0bdb99f62ee04230c931d83e888012851f4e7f"},
{file = "pydantic-1.10.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8ef467901d7a41fa0ca6db9ae3ec0021e3f657ce2c208e98cd511f3161c762c6"},
{file = "pydantic-1.10.13-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:968ac42970f57b8344ee08837b62f6ee6f53c33f603547a55571c954a4225691"},
{file = "pydantic-1.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9849f031cf8a2f0a928fe885e5a04b08006d6d41876b8bbd2fc68a18f9f2e3fd"},
{file = "pydantic-1.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:56e3ff861c3b9c6857579de282ce8baabf443f42ffba355bf070770ed63e11e1"},
{file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f00790179497767aae6bcdc36355792c79e7bbb20b145ff449700eb076c5f96"},
{file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:75b297827b59bc229cac1a23a2f7a4ac0031068e5be0ce385be1462e7e17a35d"},
{file = "pydantic-1.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:e70ca129d2053fb8b728ee7d1af8e553a928d7e301a311094b8a0501adc8763d"},
{file = "pydantic-1.10.13-py3-none-any.whl", hash = "sha256:b87326822e71bd5f313e7d3bfdc77ac3247035ac10b0c0618bd99dcf95b1e687"},
{file = "pydantic-1.10.13.tar.gz", hash = "sha256:32c8b48dcd3b2ac4e78b0ba4af3a2c2eb6048cb75202f0ea7b34feb740efc340"},
]
[package.dependencies]
typing-extensions = ">=4.2.0"
[package.extras]
dotenv = ["python-dotenv (>=0.10.4)"]
email = ["email-validator (>=1.0.3)"]
[[package]]
name = "pyparsing"
version = "3.1.1"
description = "pyparsing module - Classes and methods to define and execute parsing grammars"
optional = false
python-versions = ">=3.6.8"
files = [
{file = "pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"},
{file = "pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"},
]
[package.extras]
diagrams = ["jinja2", "railroad-diagrams"]
[[package]]
name = "pytest"
version = "7.4.3"
description = "pytest: simple powerful testing with Python"
optional = false
python-versions = ">=3.7"
files = [
{file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"},
{file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"},
]
[package.dependencies]
colorama = {version = "*", markers = "sys_platform == \"win32\""}
exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
iniconfig = "*"
packaging = "*"
pluggy = ">=0.12,<2.0"
tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
[package.extras]
testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
[[package]]
name = "pytest-cov"
version = "4.1.0"
description = "Pytest plugin for measuring coverage."
optional = false
python-versions = ">=3.7"
files = [
{file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"},
{file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"},
]
[package.dependencies]
coverage = {version = ">=5.2.1", extras = ["toml"]}
pytest = ">=4.6"
[package.extras]
testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"]
[[package]]
name = "pytz"
version = "2023.3.post1"
description = "World timezone definitions, modern and historical"
optional = false
python-versions = "*"
files = [
{file = "pytz-2023.3.post1-py2.py3-none-any.whl", hash = "sha256:ce42d816b81b68506614c11e8937d3aa9e41007ceb50bfdcb0749b921bf646c7"},
{file = "pytz-2023.3.post1.tar.gz", hash = "sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b"},
]
[[package]]
name = "pyyaml"
version = "6.0.1"
description = "YAML parser and emitter for Python"
optional = false
python-versions = ">=3.6"
files = [
{file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"},
{file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"},
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
{file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
{file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
{file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
{file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"},
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
{file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
{file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"},
{file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"},
{file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"},
{file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"},
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"},
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"},
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"},
{file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"},
{file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"},
{file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"},
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
{file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
{file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
{file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
{file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"},
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
{file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
{file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
{file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
]
[[package]]
name = "requests"
version = "2.31.0"
description = "Python HTTP for Humans."
optional = false
python-versions = ">=3.7"
files = [
{file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
{file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
]
[package.dependencies]
certifi = ">=2017.4.17"
charset-normalizer = ">=2,<4"
idna = ">=2.5,<4"
urllib3 = ">=1.21.1,<3"
[package.extras]
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
[[package]]
name = "ruamel-yaml"
version = "0.18.5"
description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order"
optional = false
python-versions = ">=3.7"
files = [
{file = "ruamel.yaml-0.18.5-py3-none-any.whl", hash = "sha256:a013ac02f99a69cdd6277d9664689eb1acba07069f912823177c5eced21a6ada"},
{file = "ruamel.yaml-0.18.5.tar.gz", hash = "sha256:61917e3a35a569c1133a8f772e1226961bf5a1198bea7e23f06a0841dea1ab0e"},
]
[package.dependencies]
"ruamel.yaml.clib" = {version = ">=0.2.7", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.13\""}
[package.extras]
docs = ["mercurial (>5.7)", "ryd"]
jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"]
[[package]]
name = "ruamel-yaml-clib"
version = "0.2.8"
description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml"
optional = false
python-versions = ">=3.6"
files = [
{file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"},
{file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"},
{file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412"},
{file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f"},
{file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334"},
{file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d"},
{file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d"},
{file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31"},
{file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069"},
{file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248"},
{file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b"},
{file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe"},
{file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899"},
{file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9"},
{file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7"},
{file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb"},
{file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1"},
{file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2"},
{file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92"},
{file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_24_aarch64.whl", hash = "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62"},
{file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9"},
{file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d"},
{file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa"},
{file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b"},
{file = "ruamel.yaml.clib-0.2.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed"},
{file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942"},
{file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875"},
{file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:77159f5d5b5c14f7c34073862a6b7d34944075d9f93e681638f6d753606c6ce6"},
{file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3"},
{file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4ecbf9c3e19f9562c7fdd462e8d18dd902a47ca046a2e64dba80699f0b6c09b7"},
{file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:87ea5ff66d8064301a154b3933ae406b0863402a799b16e4a1d24d9fbbcbe0d3"},
{file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win32.whl", hash = "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b"},
{file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675"},
{file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615"},
{file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337"},
{file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:305889baa4043a09e5b76f8e2a51d4ffba44259f6b4c72dec8ca56207d9c6fe1"},
{file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91"},
{file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e2b4c44b60eadec492926a7270abb100ef9f72798e18743939bdbf037aab8c28"},
{file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e79e5db08739731b0ce4850bed599235d601701d5694c36570a99a0c5ca41a9d"},
{file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win32.whl", hash = "sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe"},
{file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312"},
{file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001"},
{file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf"},
{file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:a1a45e0bb052edf6a1d3a93baef85319733a888363938e1fc9924cb00c8df24c"},
{file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5"},
{file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:184565012b60405d93838167f425713180b949e9d8dd0bbc7b49f074407c5a8b"},
{file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a75879bacf2c987c003368cf14bed0ffe99e8e85acfa6c0bfffc21a090f16880"},
{file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win32.whl", hash = "sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5"},
{file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win_amd64.whl", hash = "sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15"},
{file = "ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512"},
]
[[package]]
name = "safety"
version = "2.3.5"
description = "Checks installed dependencies for known vulnerabilities and licenses."
optional = false
python-versions = "*"
files = [
{file = "safety-2.3.5-py3-none-any.whl", hash = "sha256:2227fcac1b22b53c1615af78872b48348661691450aa25d6704a5504dbd1f7e2"},
{file = "safety-2.3.5.tar.gz", hash = "sha256:a60c11f8952f412cbb165d70cb1f673a3b43a2ba9a93ce11f97e6a4de834aa3a"},
]
[package.dependencies]
Click = ">=8.0.2"
dparse = ">=0.6.2"
packaging = ">=21.0,<22.0"
requests = "*"
"ruamel.yaml" = ">=0.17.21"
setuptools = ">=19.3"
[package.extras]
github = ["jinja2 (>=3.1.0)", "pygithub (>=1.43.3)"]
gitlab = ["python-gitlab (>=1.3.0)"]
[[package]]
name = "setuptools"
version = "69.0.2"
description = "Easily download, build, install, upgrade, and uninstall Python packages"
optional = false
python-versions = ">=3.8"
files = [
{file = "setuptools-69.0.2-py3-none-any.whl", hash = "sha256:1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2"},
{file = "setuptools-69.0.2.tar.gz", hash = "sha256:735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6"},
]
[package.extras]
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
[[package]]
name = "simplejson"
version = "3.19.2"
description = "Simple, fast, extensible JSON encoder/decoder for Python"
optional = false
python-versions = ">=2.5, !=3.0.*, !=3.1.*, !=3.2.*"
files = [
{file = "simplejson-3.19.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3471e95110dcaf901db16063b2e40fb394f8a9e99b3fe9ee3acc6f6ef72183a2"},
{file = "simplejson-3.19.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:3194cd0d2c959062b94094c0a9f8780ffd38417a5322450a0db0ca1a23e7fbd2"},
{file = "simplejson-3.19.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:8a390e56a7963e3946ff2049ee1eb218380e87c8a0e7608f7f8790ba19390867"},
{file = "simplejson-3.19.2-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1537b3dd62d8aae644f3518c407aa8469e3fd0f179cdf86c5992792713ed717a"},
{file = "simplejson-3.19.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a8617625369d2d03766413bff9e64310feafc9fc4f0ad2b902136f1a5cd8c6b0"},
{file = "simplejson-3.19.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:2c433a412e96afb9a3ce36fa96c8e61a757af53e9c9192c97392f72871e18e69"},
{file = "simplejson-3.19.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:f1c70249b15e4ce1a7d5340c97670a95f305ca79f376887759b43bb33288c973"},
{file = "simplejson-3.19.2-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:287e39ba24e141b046812c880f4619d0ca9e617235d74abc27267194fc0c7835"},
{file = "simplejson-3.19.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6f0a0b41dd05eefab547576bed0cf066595f3b20b083956b1405a6f17d1be6ad"},
{file = "simplejson-3.19.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2f98d918f7f3aaf4b91f2b08c0c92b1774aea113334f7cde4fe40e777114dbe6"},
{file = "simplejson-3.19.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7d74beca677623481810c7052926365d5f07393c72cbf62d6cce29991b676402"},
{file = "simplejson-3.19.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7f2398361508c560d0bf1773af19e9fe644e218f2a814a02210ac2c97ad70db0"},
{file = "simplejson-3.19.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ad331349b0b9ca6da86064a3599c425c7a21cd41616e175ddba0866da32df48"},
{file = "simplejson-3.19.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:332c848f02d71a649272b3f1feccacb7e4f7e6de4a2e6dc70a32645326f3d428"},
{file = "simplejson-3.19.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25785d038281cd106c0d91a68b9930049b6464288cea59ba95b35ee37c2d23a5"},
{file = "simplejson-3.19.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18955c1da6fc39d957adfa346f75226246b6569e096ac9e40f67d102278c3bcb"},
{file = "simplejson-3.19.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:11cc3afd8160d44582543838b7e4f9aa5e97865322844b75d51bf4e0e413bb3e"},
{file = "simplejson-3.19.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b01fda3e95d07a6148702a641e5e293b6da7863f8bc9b967f62db9461330562c"},
{file = "simplejson-3.19.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:778331444917108fa8441f59af45886270d33ce8a23bfc4f9b192c0b2ecef1b3"},
{file = "simplejson-3.19.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9eb117db8d7ed733a7317c4215c35993b815bf6aeab67523f1f11e108c040672"},
{file = "simplejson-3.19.2-cp310-cp310-win32.whl", hash = "sha256:39b6d79f5cbfa3eb63a869639cfacf7c41d753c64f7801efc72692c1b2637ac7"},
{file = "simplejson-3.19.2-cp310-cp310-win_amd64.whl", hash = "sha256:5675e9d8eeef0aa06093c1ff898413ade042d73dc920a03e8cea2fb68f62445a"},
{file = "simplejson-3.19.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ed628c1431100b0b65387419551e822987396bee3c088a15d68446d92f554e0c"},
{file = "simplejson-3.19.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:adcb3332979cbc941b8fff07181f06d2b608625edc0a4d8bc3ffc0be414ad0c4"},
{file = "simplejson-3.19.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:08889f2f597ae965284d7b52a5c3928653a9406d88c93e3161180f0abc2433ba"},
{file = "simplejson-3.19.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef7938a78447174e2616be223f496ddccdbf7854f7bf2ce716dbccd958cc7d13"},
{file = "simplejson-3.19.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a970a2e6d5281d56cacf3dc82081c95c1f4da5a559e52469287457811db6a79b"},
{file = "simplejson-3.19.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:554313db34d63eac3b3f42986aa9efddd1a481169c12b7be1e7512edebff8eaf"},
{file = "simplejson-3.19.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d36081c0b1c12ea0ed62c202046dca11438bee48dd5240b7c8de8da62c620e9"},
{file = "simplejson-3.19.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a3cd18e03b0ee54ea4319cdcce48357719ea487b53f92a469ba8ca8e39df285e"},
{file = "simplejson-3.19.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:66e5dc13bfb17cd6ee764fc96ccafd6e405daa846a42baab81f4c60e15650414"},
{file = "simplejson-3.19.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:972a7833d4a1fcf7a711c939e315721a88b988553fc770a5b6a5a64bd6ebeba3"},
{file = "simplejson-3.19.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3e74355cb47e0cd399ead3477e29e2f50e1540952c22fb3504dda0184fc9819f"},
{file = "simplejson-3.19.2-cp311-cp311-win32.whl", hash = "sha256:1dd4f692304854352c3e396e9b5f0a9c9e666868dd0bdc784e2ac4c93092d87b"},
{file = "simplejson-3.19.2-cp311-cp311-win_amd64.whl", hash = "sha256:9300aee2a8b5992d0f4293d88deb59c218989833e3396c824b69ba330d04a589"},
{file = "simplejson-3.19.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b8d940fd28eb34a7084877747a60873956893e377f15a32ad445fe66c972c3b8"},
{file = "simplejson-3.19.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4969d974d9db826a2c07671273e6b27bc48e940738d768fa8f33b577f0978378"},
{file = "simplejson-3.19.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c594642d6b13d225e10df5c16ee15b3398e21a35ecd6aee824f107a625690374"},
{file = "simplejson-3.19.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2f5a398b5e77bb01b23d92872255e1bcb3c0c719a3be40b8df146570fe7781a"},
{file = "simplejson-3.19.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:176a1b524a3bd3314ed47029a86d02d5a95cc0bee15bd3063a1e1ec62b947de6"},
{file = "simplejson-3.19.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3c7363a8cb8c5238878ec96c5eb0fc5ca2cb11fc0c7d2379863d342c6ee367a"},
{file = "simplejson-3.19.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:346820ae96aa90c7d52653539a57766f10f33dd4be609206c001432b59ddf89f"},
{file = "simplejson-3.19.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de9a2792612ec6def556d1dc621fd6b2073aff015d64fba9f3e53349ad292734"},
{file = "simplejson-3.19.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1c768e7584c45094dca4b334af361e43b0aaa4844c04945ac7d43379eeda9bc2"},
{file = "simplejson-3.19.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:9652e59c022e62a5b58a6f9948b104e5bb96d3b06940c6482588176f40f4914b"},
{file = "simplejson-3.19.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9c1a4393242e321e344213a90a1e3bf35d2f624aa8b8f6174d43e3c6b0e8f6eb"},
{file = "simplejson-3.19.2-cp312-cp312-win32.whl", hash = "sha256:7cb98be113911cb0ad09e5523d0e2a926c09a465c9abb0784c9269efe4f95917"},
{file = "simplejson-3.19.2-cp312-cp312-win_amd64.whl", hash = "sha256:6779105d2fcb7fcf794a6a2a233787f6bbd4731227333a072d8513b252ed374f"},
{file = "simplejson-3.19.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:061e81ea2d62671fa9dea2c2bfbc1eec2617ae7651e366c7b4a2baf0a8c72cae"},
{file = "simplejson-3.19.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4280e460e51f86ad76dc456acdbfa9513bdf329556ffc8c49e0200878ca57816"},
{file = "simplejson-3.19.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11c39fbc4280d7420684494373b7c5904fa72a2b48ef543a56c2d412999c9e5d"},
{file = "simplejson-3.19.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bccb3e88ec26ffa90f72229f983d3a5d1155e41a1171190fa723d4135523585b"},
{file = "simplejson-3.19.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bb5b50dc6dd671eb46a605a3e2eb98deb4a9af787a08fcdddabe5d824bb9664"},
{file = "simplejson-3.19.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:d94245caa3c61f760c4ce4953cfa76e7739b6f2cbfc94cc46fff6c050c2390c5"},
{file = "simplejson-3.19.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d0e5ffc763678d48ecc8da836f2ae2dd1b6eb2d27a48671066f91694e575173c"},
{file = "simplejson-3.19.2-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:d222a9ed082cd9f38b58923775152003765016342a12f08f8c123bf893461f28"},
{file = "simplejson-3.19.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8434dcdd347459f9fd9c526117c01fe7ca7b016b6008dddc3c13471098f4f0dc"},
{file = "simplejson-3.19.2-cp36-cp36m-win32.whl", hash = "sha256:c9ac1c2678abf9270e7228133e5b77c6c3c930ad33a3c1dfbdd76ff2c33b7b50"},
{file = "simplejson-3.19.2-cp36-cp36m-win_amd64.whl", hash = "sha256:92c4a4a2b1f4846cd4364855cbac83efc48ff5a7d7c06ba014c792dd96483f6f"},
{file = "simplejson-3.19.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0d551dc931638e2102b8549836a1632e6e7cf620af3d093a7456aa642bff601d"},
{file = "simplejson-3.19.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:73a8a4653f2e809049999d63530180d7b5a344b23a793502413ad1ecea9a0290"},
{file = "simplejson-3.19.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:40847f617287a38623507d08cbcb75d51cf9d4f9551dd6321df40215128325a3"},
{file = "simplejson-3.19.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be893258d5b68dd3a8cba8deb35dc6411db844a9d35268a8d3793b9d9a256f80"},
{file = "simplejson-3.19.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9eb3cff1b7d71aa50c89a0536f469cb8d6dcdd585d8f14fb8500d822f3bdee4"},
{file = "simplejson-3.19.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d0f402e787e6e7ee7876c8b05e2fe6464820d9f35ba3f172e95b5f8b699f6c7f"},
{file = "simplejson-3.19.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:fbbcc6b0639aa09b9649f36f1bcb347b19403fe44109948392fbb5ea69e48c3e"},
{file = "simplejson-3.19.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:2fc697be37585eded0c8581c4788fcfac0e3f84ca635b73a5bf360e28c8ea1a2"},
{file = "simplejson-3.19.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b0a3eb6dd39cce23801a50c01a0976971498da49bc8a0590ce311492b82c44b"},
{file = "simplejson-3.19.2-cp37-cp37m-win32.whl", hash = "sha256:49f9da0d6cd17b600a178439d7d2d57c5ef01f816b1e0e875e8e8b3b42db2693"},
{file = "simplejson-3.19.2-cp37-cp37m-win_amd64.whl", hash = "sha256:c87c22bd6a987aca976e3d3e23806d17f65426191db36d40da4ae16a6a494cbc"},
{file = "simplejson-3.19.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9e4c166f743bb42c5fcc60760fb1c3623e8fda94f6619534217b083e08644b46"},
{file = "simplejson-3.19.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0a48679310e1dd5c9f03481799311a65d343748fe86850b7fb41df4e2c00c087"},
{file = "simplejson-3.19.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c0521e0f07cb56415fdb3aae0bbd8701eb31a9dfef47bb57206075a0584ab2a2"},
{file = "simplejson-3.19.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d2d5119b1d7a1ed286b8af37357116072fc96700bce3bec5bb81b2e7057ab41"},
{file = "simplejson-3.19.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2c1467d939932901a97ba4f979e8f2642415fcf02ea12f53a4e3206c9c03bc17"},
{file = "simplejson-3.19.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49aaf4546f6023c44d7e7136be84a03a4237f0b2b5fb2b17c3e3770a758fc1a0"},
{file = "simplejson-3.19.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60848ab779195b72382841fc3fa4f71698a98d9589b0a081a9399904487b5832"},
{file = "simplejson-3.19.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0436a70d8eb42bea4fe1a1c32d371d9bb3b62c637969cb33970ad624d5a3336a"},
{file = "simplejson-3.19.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:49e0e3faf3070abdf71a5c80a97c1afc059b4f45a5aa62de0c2ca0444b51669b"},
{file = "simplejson-3.19.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ff836cd4041e16003549449cc0a5e372f6b6f871eb89007ab0ee18fb2800fded"},
{file = "simplejson-3.19.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3848427b65e31bea2c11f521b6fc7a3145d6e501a1038529da2391aff5970f2f"},
{file = "simplejson-3.19.2-cp38-cp38-win32.whl", hash = "sha256:3f39bb1f6e620f3e158c8b2eaf1b3e3e54408baca96a02fe891794705e788637"},
{file = "simplejson-3.19.2-cp38-cp38-win_amd64.whl", hash = "sha256:0405984f3ec1d3f8777c4adc33eac7ab7a3e629f3b1c05fdded63acc7cf01137"},
{file = "simplejson-3.19.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:445a96543948c011a3a47c8e0f9d61e9785df2544ea5be5ab3bc2be4bd8a2565"},
{file = "simplejson-3.19.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4a8c3cc4f9dfc33220246760358c8265dad6e1104f25f0077bbca692d616d358"},
{file = "simplejson-3.19.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:af9c7e6669c4d0ad7362f79cb2ab6784d71147503e62b57e3d95c4a0f222c01c"},
{file = "simplejson-3.19.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:064300a4ea17d1cd9ea1706aa0590dcb3be81112aac30233823ee494f02cb78a"},
{file = "simplejson-3.19.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9453419ea2ab9b21d925d0fd7e3a132a178a191881fab4169b6f96e118cc25bb"},
{file = "simplejson-3.19.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e038c615b3906df4c3be8db16b3e24821d26c55177638ea47b3f8f73615111c"},
{file = "simplejson-3.19.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16ca9c90da4b1f50f089e14485db8c20cbfff2d55424062791a7392b5a9b3ff9"},
{file = "simplejson-3.19.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1018bd0d70ce85f165185d2227c71e3b1e446186f9fa9f971b69eee223e1e3cd"},
{file = "simplejson-3.19.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e8dd53a8706b15bc0e34f00e6150fbefb35d2fd9235d095b4f83b3c5ed4fa11d"},
{file = "simplejson-3.19.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:2d022b14d7758bfb98405672953fe5c202ea8a9ccf9f6713c5bd0718eba286fd"},
{file = "simplejson-3.19.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:febffa5b1eda6622d44b245b0685aff6fb555ce0ed734e2d7b1c3acd018a2cff"},
{file = "simplejson-3.19.2-cp39-cp39-win32.whl", hash = "sha256:4edcd0bf70087b244ba77038db23cd98a1ace2f91b4a3ecef22036314d77ac23"},
{file = "simplejson-3.19.2-cp39-cp39-win_amd64.whl", hash = "sha256:aad7405c033d32c751d98d3a65801e2797ae77fac284a539f6c3a3e13005edc4"},
{file = "simplejson-3.19.2-py3-none-any.whl", hash = "sha256:bcedf4cae0d47839fee7de344f96b5694ca53c786f28b5f773d4f0b265a159eb"},
{file = "simplejson-3.19.2.tar.gz", hash = "sha256:9eb442a2442ce417801c912df68e1f6ccfcd41577ae7274953ab3ad24ef7d82c"},
]
[[package]]
name = "six"
version = "1.16.0"
description = "Python 2 and 3 compatibility utilities"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
files = [
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
]
[[package]]
name = "stix2"
version = "3.0.1"
description = "Produce and consume STIX 2 JSON content"
optional = false
python-versions = ">=3.6"
files = [
{file = "stix2-3.0.1-py2.py3-none-any.whl", hash = "sha256:827acf0b5b319c1b857c9db0d54907bb438b2b32312d236c891a305ad49b0ba2"},
{file = "stix2-3.0.1.tar.gz", hash = "sha256:2a2718dc3451c84c709990b2ca220cc39c75ed23e0864d7e8d8190a9365b0cbf"},
]
[package.dependencies]
pytz = "*"
requests = "*"
simplejson = "*"
stix2-patterns = ">=1.2.0"
[package.extras]
semantic = ["haversine", "rapidfuzz"]
taxii = ["taxii2-client (>=2.3.0)"]
[[package]]
name = "stix2-patterns"
version = "2.0.0"
description = "Validate STIX 2 Patterns."
optional = false
python-versions = ">=3.6"
files = [
{file = "stix2-patterns-2.0.0.tar.gz", hash = "sha256:07750c5a5af2c758e9d2aa4dde9d8e04bcd162ac2a9b0b4c4de4481d443efa08"},
{file = "stix2_patterns-2.0.0-py2.py3-none-any.whl", hash = "sha256:ca4d68b2db42ed99794a418388769d2676ca828e9cac0b8629e73cd3f68f6458"},
]
[package.dependencies]
antlr4-python3-runtime = ">=4.9.0,<4.10.0"
six = "*"
[package.extras]
dev = ["bumpversion", "check-manifest", "coverage", "pre-commit", "pytest", "pytest-cov", "sphinx", "sphinx-prompt", "tox"]
docs = ["sphinx", "sphinx-prompt"]
test = ["coverage", "pytest", "pytest-cov"]
[[package]]
name = "tomli"
version = "2.0.1"
description = "A lil' TOML parser"
optional = false
python-versions = ">=3.7"
files = [
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
]
[[package]]
name = "typer"
version = "0.9.0"
description = "Typer, build great CLIs. Easy to code. Based on Python type hints."
optional = false
python-versions = ">=3.6"
files = [
{file = "typer-0.9.0-py3-none-any.whl", hash = "sha256:5d96d986a21493606a358cae4461bd8cdf83cbf33a5aa950ae629ca3b51467ee"},
{file = "typer-0.9.0.tar.gz", hash = "sha256:50922fd79aea2f4751a8e0408ff10d2662bd0c8bbfa84755a699f3bada2978b2"},
]
[package.dependencies]
click = ">=7.1.1,<9.0.0"
typing-extensions = ">=3.7.4.3"
[package.extras]
all = ["colorama (>=0.4.3,<0.5.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"]
dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2.17.0,<3.0.0)"]
doc = ["cairosvg (>=2.5.2,<3.0.0)", "mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pillow (>=9.3.0,<10.0.0)"]
test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<8.0.0)", "pytest-cov (>=2.10.0,<5.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<4.0.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"]
[[package]]
name = "typing-extensions"
version = "4.8.0"
description = "Backported and Experimental Type Hints for Python 3.8+"
optional = false
python-versions = ">=3.8"
files = [
{file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"},
{file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"},
]
[[package]]
name = "urllib3"
version = "2.1.0"
description = "HTTP library with thread-safe connection pooling, file post, and more."
optional = false
python-versions = ">=3.8"
files = [
{file = "urllib3-2.1.0-py3-none-any.whl", hash = "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3"},
{file = "urllib3-2.1.0.tar.gz", hash = "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54"},
]
[package.extras]
brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
zstd = ["zstandard (>=0.18.0)"]
[metadata]
lock-version = "2.0"
python-versions = "^3.10"
content-hash = "adbf41d469cd7b6a5e736194fa484063e644a43ffb2426173931336e3ae0bf64"

View File

@ -0,0 +1,27 @@
[tool.poetry]
name = "falco_mitre_attack_checker"
version = "0.1.0"
description = "Audit module to validate Falco rules against the Mitre ATT&CK Framework"
authors = ["The Falco Authors <cncf-falco-dev@lists.cncf.io>"]
license = "Apache-2.0"
readme = "README.md"
packages = [{include = "falco_mitre_attack_checker"}]
[tool.poetry.dependencies]
python = "^3.10"
pydantic = "^1.10.9"
stix2 = "^3.0.1"
typer = "^0.9.0"
pyyaml = "^6.0"
[tool.poetry.group.dev.dependencies]
pytest-cov = "^4.1.0"
pytest = "^7.4.0"
safety = "^2.3.5"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[tool.poetry.scripts]
falco_mitre_attack_checker = "mitre_attack_checker.__main__:main"

3
rules/OWNERS Normal file
View File

@ -0,0 +1,3 @@
approvers:
- darryk10
- loresuso

View File

@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2025 The Falco Authors.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
@ -25,7 +25,11 @@
# Starting with version 8, the Falco engine supports exceptions.
# However the Falco rules file does not use them by default.
- required_engine_version: 0.31.0
- required_engine_version: 0.50.0
- required_plugin_versions:
- name: container
version: 0.2.2
# This macro `never_true` is used as placeholder for tuning negative logical sub-expressions, for example
# - macro: allowed_ssh_hosts
@ -87,7 +91,7 @@
and ssh_port
and not allowed_ssh_hosts
enabled: false
output: Disallowed SSH Connection (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Disallowed SSH Connection | connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: NOTICE
tags: [maturity_deprecated, host, container, network, mitre_lateral_movement, T1021.004]
@ -121,16 +125,11 @@
(fd.snet in (allowed_outbound_destination_networks)) or
(fd.sip.name in (allowed_outbound_destination_domains)))
enabled: false
output: Disallowed outbound connection destination (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Disallowed outbound connection destination | connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: NOTICE
tags: [maturity_deprecated, host, container, network, mitre_command_and_control, TA0011]
# Use this to test whether the event occurred within a container.
# When displaying container information in the output field, use
# %container.info, without any leading term (file=%fd.name
# %container.info user=%user.name user_loginuid=%user.loginuid, and not file=%fd.name
# container=%container.info user=%user.name user_loginuid=%user.loginuid). The output will change
# based on the context and whether or not -pk/-pm/-pc was specified on
# the command line.
- macro: container
condition: (container.id != host)
@ -169,7 +168,7 @@
and not proc.name in (authorized_server_binary)
and not fd.sport in (authorized_server_port)
enabled: false
output: Network connection outside authorized port and binary (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Network connection outside authorized port and binary | connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: WARNING
tags: [maturity_deprecated, container, network, mitre_discovery, TA0011, NIST_800-53_CM-7]
@ -190,7 +189,7 @@
outbound
and ((fd.sip in (c2_server_ip_list)) or
(fd.sip.name in (c2_server_fqdn_list)))
output: Outbound connection to C2 server (c2_domain=%fd.sip.name c2_addr=%fd.sip connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Outbound connection to C2 server | c2_domain=%fd.sip.name c2_addr=%fd.sip connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: WARNING
enabled: false
tags: [maturity_deprecated, host, container, network, mitre_command_and_control, TA0011]

View File

@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2025 The Falco Authors.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
@ -25,7 +25,11 @@
# Starting with version 8, the Falco engine supports exceptions.
# However the Falco rules file does not use them by default.
- required_engine_version: 0.31.0
- required_engine_version: 0.50.0
- required_plugin_versions:
- name: container
version: 0.2.2
- macro: open_write
condition: (evt.type in (open,openat,openat2) and evt.is_open_write=true and fd.typechar='f' and fd.num>=0)
@ -63,7 +67,7 @@
# on the identity of the process performing an action such as opening
# a file, etc., we require that the process name be known.
- macro: proc_name_exists
condition: (proc.name!="<NA>")
condition: (not proc.name in ("<NA>","N/A"))
- macro: rename
condition: (evt.type in (rename, renameat, renameat2))
@ -265,7 +269,7 @@
and not proc.name in (shell_binaries)
and not exe_running_docker_save
and not user_known_shell_config_modifiers
output: A shell configuration file has been modified (file=%fd.name pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: A shell configuration file has been modified | file=%fd.name pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority:
WARNING
tags: [maturity_incubating, host, container, filesystem, mitre_persistence, T1546.004]
@ -281,27 +285,18 @@
((open_write and fd.name startswith /etc/cron) or
(spawned_process and proc.name = "crontab"))
and not user_known_cron_jobs
output: Cron jobs were scheduled to run (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Cron jobs were scheduled to run | file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority:
NOTICE
tags: [maturity_incubating, host, container, filesystem, mitre_execution, T1053.003]
# Use this to test whether the event occurred within a container.
#
# When displaying container information in the output field, use
# %container.info, without any leading term (file=%fd.name
# %container.info user=%user.name user_loginuid=%user.loginuid, and not file=%fd.name
# container=%container.info user=%user.name user_loginuid=%user.loginuid). The output will change
# based on the context and whether or not -pk/-pm/-pc was specified on
# the command line.
- macro: container
condition: (container.id != host)
- macro: container_started
condition: >
((evt.type = container or
(spawned_process and proc.vpid=1)) and
container.image.repository != incomplete)
(spawned_process and proc.vpid=1 and container)
- list: cron_binaries
items: [anacron, cron, crond, crontab]
@ -377,7 +372,7 @@
and (user_ssh_directory or fd.name startswith /root/.ssh)
and not user_known_read_ssh_information_activities
and not proc.name in (ssh_binaries)
output: ssh-related file/directory read by non-ssh program (file=%fd.name pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: ssh-related file/directory read by non-ssh program | file=%fd.name pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: ERROR
tags: [maturity_incubating, host, container, filesystem, mitre_collection, T1005]
@ -401,7 +396,7 @@
and not proc.name in (db_server_binaries)
and not postgres_running_wal_e
and not user_known_db_spawned_processes
output: Database-related program spawned process other than itself (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Database-related program spawned process other than itself | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: NOTICE
tags: [maturity_incubating, host, container, process, database, mitre_execution, T1190]
@ -442,7 +437,7 @@
and not calico_node
and not weaveworks_scope
and not user_known_change_thread_namespace_activities
output: Namespace change (setns) by unexpected program (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Namespace change (setns) by unexpected program | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: NOTICE
tags: [maturity_incubating, host, container, process, mitre_privilege_escalation, T1611]
@ -456,7 +451,7 @@
evt.type=unshare and evt.dir=<
and container
and not thread.cap_permitted contains CAP_SYS_ADMIN
output: Change namespace privileges via unshare (res=%evt.res evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Change namespace privileges via unshare | res=%evt.res evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: NOTICE
tags: [maturity_incubating, container, mitre_privilege_escalation, T1611]
@ -559,7 +554,6 @@
- public.ecr.aws/falcosecurity/falco-no-driver
# These container images are allowed to run with --privileged and full set of capabilities
# TODO: Remove k8s.gcr.io reference after 01/Dec/2023
- list: falco_privileged_images
items: [
falco_containers,
@ -578,16 +572,12 @@
gke.gcr.io/netd-amd64,
gke.gcr.io/watcher-daemonset,
gcr.io/google-containers/prometheus-to-sd,
k8s.gcr.io/ip-masq-agent-amd64,
k8s.gcr.io/kube-proxy,
k8s.gcr.io/prometheus-to-sd,
registry.k8s.io/ip-masq-agent-amd64,
registry.k8s.io/kube-proxy,
registry.k8s.io/prometheus-to-sd,
quay.io/calico/node,
sysdig/sysdig,
sematext_images,
k8s.gcr.io/dns/k8s-dns-node-cache,
registry.k8s.io/dns/k8s-dns-node-cache,
mcr.microsoft.com/oss/kubernetes/kube-proxy
]
@ -618,12 +608,11 @@
seen as more suspicious, prompting a closer inspection.
condition: >
container_started
and container
and container.privileged=true
and not falco_privileged_containers
and not user_privileged_containers
and not redhat_image
output: Privileged container started (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Privileged container started | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: INFO
tags: [maturity_incubating, container, cis, mitre_execution, T1610, PCI_DSS_10.2.5]
@ -648,11 +637,10 @@
raise suspicion, prompting closer scrutiny.
condition: >
container_started
and container
and excessively_capable_container
and not falco_privileged_containers
and not user_privileged_containers
output: Excessively capable container started (cap_permitted=%thread.cap_permitted evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Excessively capable container started | cap_permitted=%thread.cap_permitted evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: INFO
tags: [maturity_incubating, container, cis, mitre_execution, T1610]
@ -673,7 +661,7 @@
and not proc.name in (known_system_procs_network_activity_binaries)
and not login_doing_dns_lookup
and not user_expected_system_procs_network_activity_conditions
output: Known system binary sent/received network traffic (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Known system binary sent/received network traffic | connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=%fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: NOTICE
tags: [maturity_incubating, host, network, process, mitre_execution, T1059]
@ -712,7 +700,7 @@
and http_proxy_procs
and proc.env icontains HTTP_PROXY
and not allowed_ssh_proxy_env
output: Curl or wget run with disallowed HTTP_PROXY environment variable (env=%proc.env evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Curl or wget run with disallowed HTTP_PROXY environment variable | env=%proc.env evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: NOTICE
tags: [maturity_incubating, host, container, users, mitre_execution, T1204]
@ -752,7 +740,7 @@
inbound_outbound
and fd.l4proto=udp
and not expected_udp_traffic
output: Unexpected UDP Traffic Seen (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Unexpected UDP Traffic Seen | connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=%fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: NOTICE
tags: [maturity_incubating, host, container, network, mitre_exfiltration, TA0011]
@ -774,7 +762,7 @@
# https://github.com/draios/sysdig/issues/954). So in that case, allow
# a setuid.
- macro: known_user_in_container
condition: (container and user.name != "N/A")
condition: (container and not user.name in ("<NA>","N/A",""))
# Add conditions to this macro (probably in a separate file,
# overwriting this macro) to allow for specific combinations of
@ -804,7 +792,7 @@
and not java_running_sdjagent
and not nrpe_becoming_nagios
and not user_known_non_sudo_setuid_conditions
output: Unexpected setuid call by non-sudo, non-root program (arg_uid=%evt.arg.uid evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Unexpected setuid call by non-sudo, non-root program | arg_uid=%evt.arg.uid evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: NOTICE
tags: [maturity_incubating, host, container, users, mitre_privilege_escalation, T1548.001]
@ -836,7 +824,7 @@
and not run_by_google_accounts_daemon
and not chage_list
and not user_known_user_management_activities
output: User management binary command run outside of container (gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: User management binary command run outside of container | gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: NOTICE
tags: [maturity_incubating, host, users, software_mgmt, mitre_persistence, T1098]
@ -864,7 +852,7 @@
and not fd.name in (allowed_dev_files)
and not fd.name startswith /dev/tty
and not user_known_create_files_below_dev_activities
output: File created below /dev by untrusted program (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: File created below /dev by untrusted program | file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: ERROR
tags: [maturity_incubating, host, filesystem, mitre_persistence, T1543]
@ -891,7 +879,7 @@
and container
and fd.sip="169.254.169.254"
and not ec2_metadata_containers
output: Outbound connection to EC2 instance metadata service (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Outbound connection to EC2 instance metadata service | connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=%fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: NOTICE
tags: [maturity_incubating, network, aws, container, mitre_credential_access, T1552.005]
@ -912,7 +900,7 @@
and fd.sip="169.254.169.254"
and not user_known_metadata_access
enabled: true
output: Outbound connection to cloud instance metadata service (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Outbound connection to cloud instance metadata service | connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=%fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: NOTICE
tags: [maturity_incubating, network, container, mitre_discovery, T1565]
@ -932,12 +920,10 @@
condition: (never_true)
# Container is supposed to be immutable. Package management should be done in building the image.
# TODO: Remove k8s.gcr.io reference after 01/Dec/2023
- macro: pkg_mgmt_in_kube_proxy
condition: >
(proc.cmdline startswith "update-alternat"
and (container.image.repository = "registry.k8s.io/kube-proxy"
or container.image.repository = "k8s.gcr.io/kube-proxy"))
and container.image.repository = "registry.k8s.io/kube-proxy")
- rule: Launch Package Management Process in Container
desc: >
@ -953,7 +939,7 @@
and not package_mgmt_ancestor_procs
and not user_known_package_manager_in_container
and not pkg_mgmt_in_kube_proxy
output: Package management process launched in container (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Package management process launched in container | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: ERROR
tags: [maturity_incubating, container, process, software_mgmt, mitre_persistence, T1505]
@ -970,7 +956,7 @@
and container
and network_tool_procs
and not user_known_network_tool_activities
output: Network tool launched in container (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Network tool launched in container | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: NOTICE
tags: [maturity_incubating, container, network, process, mitre_execution, T1059]
@ -984,7 +970,7 @@
and not container
and network_tool_procs
and not user_known_network_tool_activities
output: Network tool launched on host (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags)
output: Network tool launched on host | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: NOTICE
tags: [maturity_incubating, host, network, process, mitre_execution, T1059]
@ -1030,7 +1016,7 @@
(modify_shell_history or truncate_shell_history)
and not var_lib_docker_filepath
and not proc.name in (docker_binaries)
output: Shell history deleted or renamed (file=%fd.name name=%evt.arg.name path=%evt.arg.path oldpath=%evt.arg.oldpath evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Shell history deleted or renamed | file=%fd.name name=%evt.arg.name path=%evt.arg.path oldpath=%evt.arg.oldpath evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority:
WARNING
tags: [maturity_incubating, host, container, process, filesystem, mitre_defense_evasion, T1070]
@ -1061,7 +1047,7 @@
and not proc.name in (user_known_chmod_applications)
and not exe_running_docker_save
and not user_known_set_setuid_or_setgid_bit_conditions
output: Setuid or setgid bit is set via chmod (fd=%evt.arg.fd filename=%evt.arg.filename mode=%evt.arg.mode evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Setuid or setgid bit is set via chmod | fd=%evt.arg.fd filename=%evt.arg.filename mode=%evt.arg.mode evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority:
NOTICE
tags: [maturity_incubating, host, container, process, users, mitre_privilege_escalation, T1548.001]
@ -1086,7 +1072,7 @@
and container
and remote_file_copy_procs
and not user_known_remote_file_copy_activities
output: Remote file copy tool launched in container (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Remote file copy tool launched in container | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: NOTICE
tags: [maturity_incubating, container, network, process, mitre_exfiltration, T1020]
@ -1116,7 +1102,7 @@
and container
and k8s.ns.name in (namespace_scope_network_only_subnet)
and not network_local_subnet
output: Network connection outside local subnet (fd_rip_name=%fd.rip.name fd_lip_name=%fd.lip.name fd_cip_name=%fd.cip.name fd_sip_name=%fd.sip.name connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Network connection outside local subnet | fd_rip_name=%fd.rip.name fd_lip_name=%fd.lip.name fd_cip_name=%fd.cip.name fd_sip_name=%fd.sip.name connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=%fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: WARNING
tags: [maturity_incubating, container, network, mitre_discovery, T1046, PCI_DSS_6.4.2]
@ -1150,7 +1136,7 @@
and not known_gke_mount_in_privileged_containers
and not known_aks_mount_in_privileged_containers
and not user_known_mount_in_privileged_containers
output: Mount was executed inside a privileged container (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Mount was executed inside a privileged container | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: WARNING
tags: [maturity_incubating, container, cis, filesystem, mitre_privilege_escalation, T1611]
@ -1182,7 +1168,7 @@
and container
and (ingress_remote_file_copy_procs or curl_download)
and not user_known_ingress_remote_file_copy_activities
output: Ingress remote file copy tool launched in container (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Ingress remote file copy tool launched in container | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: NOTICE
tags: [maturity_incubating, container, network, process, mitre_command_and_control, TA0011]
@ -1203,7 +1189,7 @@
and container
and (fd.name glob /proc/*/environ)
and not proc.name in (known_binaries_to_read_environment_variables_from_proc_files)
output: Environment variables were retrieved from /proc files (file=%fd.name gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Environment variables were retrieved from /proc files | file=%fd.name gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: WARNING
tags: [maturity_incubating, container, filesystem, process, mitre_discovery, T1083]
@ -1218,7 +1204,7 @@
# We also let runc:[1:CHILD] count as the parent process, which can occur
# when we lose events and lose track of state.
- macro: container_entrypoint
condition: (not proc.pname exists or proc.pname in (runc:[0:PARENT], runc:[1:CHILD], runc, docker-runc, exe, docker-runc-cur, containerd-shim, systemd, crio))
condition: (not proc.pname exists or proc.pname in (runc:[0:PARENT], runc:[1:CHILD], runc, docker-runc, exe, docker-runc-cur, containerd-shim, systemd, crio, conmon))
- macro: system_level_side_effect_artifacts_kubectl_cp
condition: (fd.name startswith /etc or
@ -1242,7 +1228,7 @@
and container_entrypoint
and proc.tty=0
and not system_level_side_effect_artifacts_kubectl_cp
output: Exfiltrating Artifacts via Kubernetes Control Plane (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Exfiltrating Artifacts via Kubernetes Control Plane | file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: NOTICE
tags: [maturity_incubating, container, filesystem, mitre_exfiltration, TA0010]
@ -1259,7 +1245,7 @@
and (user_ssh_directory or fd.name startswith /root/.ssh)
and fd.name endswith authorized_keys
and not proc.name in (ssh_binaries)
output: Adding ssh keys to authorized_keys (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty)
output: Adding ssh keys to authorized_keys | file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: WARNING
tags: [maturity_incubating, host, filesystem, mitre_persistence, T1098.004]
@ -1278,6 +1264,37 @@
spawned_process
and glibc_tunables_env
enabled: true
output: Process run with suspect environment variable which could be attempting privilege escalation (env=%proc.env evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Process run with suspect environment variable which could be attempting privilege escalation | env=%proc.env evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: NOTICE
tags: [maturity_incubating, host, container, users, mitre_privilege_escalation, TA0004]
- rule: Backdoored library loaded into SSHD (CVE-2024-3094)
desc: This rule detects possible CVE-2024-3094 exploitation when the SSH daemon process loads a vulnerable version of the liblzma library. An attacker could exploit this to interfere with authentication in sshd via systemd, potentially compromising sensitive data or escalating their privileges.
condition: >
open_read and
proc.name=sshd and
(fd.name contains "liblzma.so.5.6.0" or fd.name contains "liblzma.so.5.6.1")
output: SSHD loaded a backdoored version of liblzma library %fd.name with parent %proc.pname and cmdline %proc.cmdline | process=%proc.name parent=%proc.pname file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid proc_exepath=%proc.exepath command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: WARNING
tags: [maturity_incubating, host, container, mitre_initial_access, T1556]
- list: bpf_profiled_binaries
items: [falco, bpftool, systemd]
- macro: bpf_profiled_procs
condition: (proc.name in (bpf_profiled_binaries))
- rule: BPF Program Not Profiled
desc: >
BPF is a kernel technology that can be misused for malicious purposes, like "Linux Kernel Module Injection". This
rule should be considered an auditing rule to notify you of any unprofiled BPF tools running in your environment.
However, it requires customization after profiling your environment. BPF-powered agents make bpf syscalls all the
time, so this rule only sends logs for BPF_PROG_LOAD calls (bpf cmd=5) in the enter event. If you also want to log
whether the syscall failed or succeeded, remove the direction filter and add the evt.arg.res_or_fd output field.
condition: >
evt.type=bpf and evt.dir=>
and (evt.arg.cmd=5 or evt.arg.cmd=BPF_PROG_LOAD)
and not bpf_profiled_procs
output: BPF Program Not Profiled | bpf_cmd=%evt.arg.cmd evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: NOTICE
tags: [maturity_incubating, host, container, mitre_persistence, TA0003]

View File

@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2025 The Falco Authors.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
@ -25,7 +25,11 @@
# Starting with version 8, the Falco engine supports exceptions.
# However the Falco rules file does not use them by default.
- required_engine_version: 0.31.0
- required_engine_version: 0.50.0
- required_plugin_versions:
- name: container
version: 0.2.2
# Currently disabled as read/write are ignored syscalls. The nearly
# similar open_write/open_read check for files being opened for
@ -68,7 +72,7 @@
# on the identity of the process performing an action such as opening
# a file, etc., we require that the process name be known.
- macro: proc_name_exists
condition: (proc.name!="<NA>")
condition: (not proc.name in ("<NA>","N/A"))
- macro: rename
condition: (evt.type in (rename, renameat, renameat2))
@ -269,7 +273,7 @@
(fd.cnet in (allowed_inbound_source_networks)) or
(fd.cip.name in (allowed_inbound_source_domains)))
enabled: false
output: Disallowed inbound connection source (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Disallowed inbound connection source | connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=%fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: NOTICE
tags: [maturity_sandbox, host, container, network, mitre_command_and_control, TA0011]
@ -312,26 +316,18 @@
fd.directory in (shell_config_directories))
and not proc.name in (shell_binaries)
enabled: false
output: A shell configuration file was read by a non-shell program (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: A shell configuration file was read by a non-shell program | file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority:
WARNING
tags: [maturity_sandbox, host, container, filesystem, mitre_discovery, T1546.004]
# Use this to test whether the event occurred within a container.
# When displaying container information in the output field, use
# %container.info, without any leading term (file=%fd.name
# %container.info user=%user.name user_loginuid=%user.loginuid, and not file=%fd.name
# container=%container.info user=%user.name user_loginuid=%user.loginuid). The output will change
# based on the context and whether or not -pk/-pm/-pc was specified on
# the command line.
- macro: container
condition: (container.id != host)
- macro: container_started
condition: >
((evt.type = container or
(spawned_process and proc.vpid=1)) and
container.image.repository != incomplete)
(spawned_process and proc.vpid=1 and container)
# Possible scripts run by sshkit
- list: sshkit_script_binaries
@ -601,7 +597,7 @@
and not package_mgmt_ancestor_procs
and not exe_running_docker_save
and not user_known_update_package_registry
output: Repository files get updated (newpath=%evt.arg.newpath file=%fd.name pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Repository files get updated | newpath=%evt.arg.newpath file=%fd.name pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority:
NOTICE
tags: [maturity_sandbox, host, container, filesystem, mitre_execution, T1072]
@ -626,7 +622,7 @@
and not python_running_get_pip
and not python_running_ms_oms
and not user_known_write_below_binary_dir_activities
output: File below a known binary directory opened for writing (file=%fd.name pcmdline=%proc.pcmdline gparent=%proc.aname[2] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: File below a known binary directory opened for writing | file=%fd.name pcmdline=%proc.pcmdline gparent=%proc.aname[2] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: ERROR
tags: [maturity_sandbox, host, container, filesystem, mitre_persistence, T1543]
@ -681,12 +677,12 @@
and not google_accounts_daemon_writing_ssh
and not cloud_init_writing_ssh
and not user_known_write_monitored_dir_conditions
output: File below a monitored directory opened for writing (file=%fd.name pcmdline=%proc.pcmdline gparent=%proc.aname[2] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: File below a monitored directory opened for writing | file=%fd.name pcmdline=%proc.pcmdline gparent=%proc.aname[2] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: ERROR
tags: [maturity_sandbox, host, container, filesystem, mitre_persistence, T1543]
- list: safe_etc_dirs
items: [/etc/cassandra, /etc/ssl/certs/java, /etc/logstash, /etc/nginx/conf.d, /etc/container_environment, /etc/hrmconfig, /etc/fluent/configs.d. /etc/alertmanager]
items: [/etc/cassandra, /etc/ssl/certs/java, /etc/logstash, /etc/nginx/conf.d, /etc/container_environment, /etc/hrmconfig, /etc/fluent/configs.d, /etc/alertmanager]
- macro: fluentd_writing_conf_files
condition: (proc.name=start-fluentd and fd.name in (/etc/fluent/fluent.conf, /etc/td-agent/td-agent.conf))
@ -834,6 +830,17 @@
fd.name startswith /etc/ssh/ssh_monitor_config_ or
fd.name startswith /etc/ssh/ssh_config_))
- macro: etckeeper_activities
condition: (never_true)
- macro: etckeeper
condition: >
(proc.aname = etckeeper
or (proc.aname in (50vcs-commit, 30store-metadata, 50uncommitted-c))
and (fd.name startswith /etc/.git/
or fd.name = /etc/.etckeeper)
and etckeeper_activities)
- macro: multipath_writing_conf
condition: (proc.name = multipath and fd.name startswith /etc/multipath/)
@ -961,6 +968,7 @@
and not automount_using_mtab
and not mcafee_writing_cma_d
and not avinetworks_supervisor_writing_ssh
and not etckeeper
and not multipath_writing_conf
and not calico_node)
@ -971,7 +979,7 @@
profiling of your environment can transform this rule into an effective rule for detecting unusual behavior associated with system
changes, including compliance-related cases.
condition: write_etc_common
output: File below /etc opened for writing (file=%fd.name pcmdline=%proc.pcmdline gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: File below /etc opened for writing | file=%fd.name pcmdline=%proc.pcmdline gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: ERROR
tags: [maturity_sandbox, host, container, filesystem, mitre_persistence, T1098]
@ -1074,7 +1082,7 @@
and not known_root_conditions
and not user_known_write_root_conditions
and not user_known_write_below_root_activities
output: File below / or /root opened for writing (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: File below / or /root opened for writing | file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: ERROR
tags: [maturity_sandbox, host, container, filesystem, mitre_persistence, TA0003]
@ -1103,7 +1111,7 @@
and not exe_running_docker_save
and not amazon_linux_running_python_yum
and not user_known_write_rpm_database_activities
output: rpm database opened for writing by a non-rpm program (file=%fd.name pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: rpm database opened for writing by a non-rpm program | file=%fd.name pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: ERROR
tags: [maturity_sandbox, host, container, filesystem, software_mgmt, mitre_persistence, T1072]
@ -1122,7 +1130,7 @@
and not package_mgmt_procs
and not exe_running_docker_save
and not user_known_modify_bin_dir_activities
output: File below known binary directory renamed/removed (file=%fd.name pcmdline=%proc.pcmdline evt_args=%evt.args evt_type=%evt.type evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: File below known binary directory renamed/removed | file=%fd.name pcmdline=%proc.pcmdline evt_args=%evt.args evt_type=%evt.type evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: ERROR
tags: [maturity_sandbox, host, container, filesystem, mitre_defense_evasion, T1222.002]
@ -1141,7 +1149,7 @@
and not package_mgmt_procs
and not user_known_mkdir_bin_dir_activities
and not exe_running_docker_save
output: Directory below known binary directory created (directory=%evt.arg.path evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Directory below known binary directory created | directory=%evt.arg.path evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: ERROR
tags: [maturity_sandbox, host, container, filesystem, mitre_persistence, T1222.002]
@ -1235,18 +1243,18 @@
# below /etc as well, but the globbing mechanism
# doesn't allow exclusions of a full pattern, only single characters.
- macro: sensitive_mount
condition: (container.mount.dest[/proc*] != "N/A" or
container.mount.dest[/var/run/docker.sock] != "N/A" or
container.mount.dest[/var/run/crio/crio.sock] != "N/A" or
container.mount.dest[/run/containerd/containerd.sock] != "N/A" or
container.mount.dest[/var/lib/kubelet] != "N/A" or
container.mount.dest[/var/lib/kubelet/pki] != "N/A" or
container.mount.dest[/] != "N/A" or
container.mount.dest[/home/admin] != "N/A" or
container.mount.dest[/etc] != "N/A" or
container.mount.dest[/etc/kubernetes] != "N/A" or
container.mount.dest[/etc/kubernetes/manifests] != "N/A" or
container.mount.dest[/root*] != "N/A")
condition: (not container.mount.dest[/proc*] in ("<NA>","N/A") or
not container.mount.dest[/var/run/docker.sock] in ("<NA>","N/A") or
not container.mount.dest[/var/run/crio/crio.sock] in ("<NA>","N/A") or
not container.mount.dest[/run/containerd/containerd.sock] in ("<NA>","N/A") or
not container.mount.dest[/var/lib/kubelet] in ("<NA>","N/A") or
not container.mount.dest[/var/lib/kubelet/pki] in ("<NA>","N/A") or
not container.mount.dest[/] in ("<NA>","N/A") or
not container.mount.dest[/home/admin] in ("<NA>","N/A") or
not container.mount.dest[/etc] in ("<NA>","N/A") or
not container.mount.dest[/etc/kubernetes] in ("<NA>","N/A") or
not container.mount.dest[/etc/kubernetes/manifests] in ("<NA>","N/A") or
not container.mount.dest[/root*] in ("<NA>","N/A"))
- rule: Launch Sensitive Mount Container
desc: >
@ -1255,11 +1263,10 @@
varies based on your environment.
condition: >
container_started
and container
and sensitive_mount
and not falco_sensitive_mount_containers
and not user_sensitive_mount_containers
output: Container with sensitive mount started (mounts=%container.mounts evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Container with sensitive mount started | mounts=%container.mounts evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: INFO
tags: [maturity_sandbox, container, cis, mitre_execution, T1610]
@ -1282,9 +1289,8 @@
this can be challenging to manage.
condition: >
container_started
and container
and not allowed_containers
output: Container started and not in allowed list (evt_type=%evt.type user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Container started and not in allowed list | evt_type=%evt.type user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: WARNING
tags: [maturity_sandbox, container, mitre_lateral_movement, T1610]
@ -1301,7 +1307,7 @@
inbound
and interpreted_procs
enabled: false
output: Interpreted program received/listened for network traffic (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Interpreted program received/listened for network traffic | connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=%fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: NOTICE
tags: [maturity_sandbox, host, container, network, mitre_exfiltration, TA0011]
@ -1314,7 +1320,7 @@
outbound
and interpreted_procs
enabled: false
output: Interpreted program performed outgoing network connection (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Interpreted program performed outgoing network connection | connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=%fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: NOTICE
tags: [maturity_sandbox, host, container, network, mitre_exfiltration, TA0011]
@ -1340,7 +1346,7 @@
and fd.sport <= 32767
and not nodeport_containers
enabled: false
output: Unexpected K8s NodePort Connection (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Unexpected K8s NodePort Connection | connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=%fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: NOTICE
tags: [maturity_sandbox, network, k8s, container, mitre_persistence, T1205.001, NIST_800-53_AC-6]
@ -1364,7 +1370,7 @@
and not user_known_create_hidden_file_activities
and not exe_running_docker_save
enabled: false
output: Hidden file or directory created (file=%fd.name newpath=%evt.arg.newpath evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Hidden file or directory created | file=%fd.name newpath=%evt.arg.newpath evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority:
NOTICE
tags: [maturity_sandbox, host, container, filesystem, mitre_defense_evasion, T1564.001]
@ -1475,7 +1481,7 @@
net_miner_pool
and not trusted_images_query_miner_domain_dns
enabled: false
output: Outbound connection to IP/Port flagged by https://cryptoioc.ch (ip=%fd.rip connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Outbound connection to IP/Port flagged by https://cryptoioc.ch | ip=%fd.rip connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=%fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: CRITICAL
tags: [maturity_sandbox, host, container, network, mitre_impact, T1496]
@ -1489,18 +1495,15 @@
proc.cmdline contains "stratum2+tcp" or
proc.cmdline contains "stratum+ssl" or
proc.cmdline contains "stratum2+ssl")
output: Possible miner running (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Possible miner running | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: CRITICAL
tags: [maturity_sandbox, host, container, process, mitre_impact, T1496]
- list: k8s_client_binaries
items: [docker, kubectl, crictl]
# TODO: Remove k8s.gcr.io reference after 01/Dec/2023
- list: user_known_k8s_ns_kube_system_images
items: [
k8s.gcr.io/fluentd-gcp-scaler,
k8s.gcr.io/node-problem-detector/node-problem-detector,
registry.k8s.io/fluentd-gcp-scaler,
registry.k8s.io/node-problem-detector/node-problem-detector
]
@ -1511,8 +1514,7 @@
]
# Whitelist for known docker client binaries run inside container
# - k8s.gcr.io/fluentd-gcp-scaler / registry.k8s.io/fluentd-gcp-scaler in GCP/GKE
# TODO: Remove k8s.gcr.io reference after 01/Dec/2023
# - registry.k8s.io/fluentd-gcp-scaler in GCP/GKE
- macro: user_known_k8s_client_container
condition: >
(k8s.ns.name="kube-system" and container.image.repository in (user_known_k8s_ns_kube_system_images)) or container.image.repository in (user_known_k8s_images)
@ -1530,7 +1532,7 @@
and container
and not user_known_k8s_client_container_parens
and proc.name in (k8s_client_binaries)
output: Kubernetes Client Tool Launched in Container (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Kubernetes Client Tool Launched in Container | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: WARNING
tags: [maturity_sandbox, container, mitre_execution, T1610]
@ -1563,7 +1565,7 @@
and not runc_writing_var_lib_docker
and not user_known_container_drift_activities
enabled: false
output: Drift detected (chmod), new executable created in a container (filename=%evt.arg.filename name=%evt.arg.name mode=%evt.arg.mode evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Drift detected (chmod), new executable created in a container | filename=%evt.arg.filename name=%evt.arg.name mode=%evt.arg.mode evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: ERROR
tags: [maturity_sandbox, container, process, filesystem, mitre_execution, T1059]
@ -1583,7 +1585,7 @@
and not runc_writing_var_lib_docker
and not user_known_container_drift_activities
enabled: false
output: Drift detected (open+create), new executable created in a container (filename=%evt.arg.filename name=%evt.arg.name mode=%evt.arg.mode evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Drift detected (open+create), new executable created in a container | filename=%evt.arg.filename name=%evt.arg.name mode=%evt.arg.mode evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: ERROR
tags: [maturity_sandbox, container, process, filesystem, mitre_execution, T1059]
@ -1607,7 +1609,7 @@
and user.uid=0
and not user_known_run_as_root_container
enabled: false
output: Container launched with root user privilege (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Container launched with root user privilege | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: INFO
tags: [maturity_sandbox, container, process, users, mitre_execution, T1610]
@ -1624,7 +1626,7 @@
and (proc.name=sudoedit or proc.name = sudo)
and (proc.args contains -s or proc.args contains -i or proc.args contains --login)
and (proc.args contains "\ " or proc.args endswith \)
output: Detect Sudo Privilege Escalation Exploit (CVE-2021-3156) (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Detect Sudo Privilege Escalation Exploit (CVE-2021-3156) | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: CRITICAL
tags: [maturity_sandbox, host, container, filesystem, users, mitre_privilege_escalation, T1548.003]
@ -1640,7 +1642,7 @@
and user.uid != 0
and (evt.rawres >= 0 or evt.res != -1)
and not proc.name in (user_known_userfaultfd_processes)
output: An userfaultfd syscall was successfully executed by an unprivileged user (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: An userfaultfd syscall was successfully executed by an unprivileged user | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: CRITICAL
tags: [maturity_sandbox, host, container, process, mitre_defense_evasion, TA0005]
@ -1656,7 +1658,7 @@
and user.uid != 0
and proc.name=pkexec
and proc.args = ''
output: Detect Polkit pkexec Local Privilege Escalation Exploit (CVE-2021-4034) (args=%proc.args evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Detect Polkit pkexec Local Privilege Escalation Exploit (CVE-2021-4034) | args=%proc.args evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: CRITICAL
tags: [maturity_sandbox, host, container, process, users, mitre_privilege_escalation, TA0004]
@ -1672,7 +1674,7 @@
condition: >
java_network_read
and evt.buffer bcontains cafebabe
output: Java process class file download (server_ip=%fd.sip server_port=%fd.sport connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Java process class file download | server_ip=%fd.sip server_port=%fd.sport connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=%fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: CRITICAL
enabled: false
tags: [maturity_sandbox, host, container, process, mitre_initial_access, T1190]
@ -1694,31 +1696,10 @@
and not docker_procs
and not proc.cmdline = "runc:[1:CHILD] init"
enabled: false
output: Detect Potential Container Breakout Exploit (CVE-2019-5736) (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Detect Potential Container Breakout Exploit (CVE-2019-5736) | file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: WARNING
tags: [maturity_sandbox, container, filesystem, mitre_initial_access, T1611]
- list: bpf_profiled_binaries
items: [falco, bpftool]
- macro: bpf_profiled_procs
condition: (proc.name in (bpf_profiled_binaries))
- rule: BPF Program Not Profiled
desc: >
BPF is a kernel technology that can be misused for malicious purposes, like "Linux Kernel Module Injection". This
rule should be considered an auditing rule to notify you of any unprofiled BPF tools running in your environment.
However, it requires customization after profiling your environment. BPF-powered agents make bpf syscalls all the
time, so this rule only sends logs for BPF_PROG_LOAD calls (bpf cmd=5) in the enter event. If you also want to log
whether the syscall failed or succeeded, remove the direction filter and add the evt.arg.res_or_fd output field.
condition: >
evt.type=bpf and evt.dir=>
and evt.arg.cmd=5
and not bpf_profiled_procs
output: BPF Program Not Profiled (bpf_cmd=%evt.arg.cmd evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
priority: NOTICE
tags: [maturity_sandbox, host, container, mitre_persistence, TA0003]
- list: known_decode_payload_containers
items: []
@ -1738,7 +1719,7 @@
and container
and base64_decoding
and not container.image.repository in (known_decode_payload_containers)
output: Decoding Payload in Container (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Decoding Payload in Container | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: INFO
tags: [maturity_sandbox, container, process, mitre_command_and_control, T1132]
- list: recon_binaries
@ -1761,6 +1742,25 @@
and recon_binaries_procs
and proc.tty != 0
and proc.is_vpgid_leader=true
output: Basic Interactive Reconnaissance (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Basic Interactive Reconnaissance | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: NOTICE
tags: [maturity_sandbox, host, container, process, mitre_reconnaissance, TA0043]
- rule: Netcat/Socat Remote Code Execution on Host
desc: >
Netcat/Socat Program runs on host that allows remote code execution and may be utilized
as a part of a variety of reverse shell payload https://github.com/swisskyrepo/PayloadsAllTheThings/.
These programs are of higher relevance as they are commonly installed on UNIX-like operating systems.
condition: >
spawned_process
and not container
and ((proc.name = "nc" and (proc.cmdline contains "-e" or
proc.cmdline contains "-c")) or
(proc.name = "ncat" and (proc.args contains "--sh-exec" or
proc.args contains "--exec" or proc.args contains "-e " or
proc.args contains "-c " or proc.args contains "--lua-exec")) or
(proc.name = 'socat' and (proc.args contains "EXEC" or
proc.args contains "SYSTEM")))
output: Netcat/Socat runs on host that allows remote code execution | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: WARNING
tags: [maturity_sandbox, host, network, process, mitre_execution, T1059]

View File

@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2025 The Falco Authors.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
@ -25,7 +25,11 @@
# Starting with version 8, the Falco engine supports exceptions.
# However the Falco rules file does not use them by default.
- required_engine_version: 0.31.0
- required_engine_version: 0.50.0
- required_plugin_versions:
- name: container
version: 0.2.2
# Currently disabled as read/write are ignored syscalls. The nearly
# similar open_write/open_read check for files being opened for
@ -74,8 +78,9 @@
# the process name may be missing. For some rules that really depend
# on the identity of the process performing an action such as opening
# a file, etc., we require that the process name be known.
# TODO: At the moment we keep the `N/A` variant for compatibility with old scap-files
- macro: proc_name_exists
condition: (proc.name!="<NA>")
condition: (not proc.name in ("<NA>","N/A"))
- macro: spawned_process
condition: (evt.type in (execve, execveat) and evt.dir=<)
@ -90,7 +95,7 @@
condition: (evt.type in (init_module, finit_module) and evt.dir=<)
- macro: dup
condition: (evt.type in (dup, dup2, dup3))
condition: (evt.type in (dup, dup2, dup3) and evt.dir=<)
# File categories
- macro: etc_dir
@ -158,7 +163,7 @@
apt-listchanges, unattended-upgr, apt-add-reposit, apt-cache, apt.systemd.dai
]
- list: python_package_managers
items: [pip, pip3, conda]
items: [pip, pip3, conda, uv]
# The truncated dpkg-preconfigu is intentional, process names are
# truncated at the falcosecurity-libs level.
@ -207,7 +212,7 @@
- macro: sensitive_files
condition: >
((fd.name startswith /etc and fd.name in (sensitive_file_names)) or
(fd.name in (sensitive_file_names) or
fd.directory in (/etc/sudoers.d, /etc/pam.d))
# Indicates that the process is new. Currently detected using time
@ -216,12 +221,6 @@
condition: (proc.duration <= 5000000000)
# Use this to test whether the event occurred within a container.
# When displaying container information in the output field, use
# %container.info, without any leading term (file=%fd.name
# %container.info user=%user.name user_loginuid=%user.loginuid, and not file=%fd.name
# container=%container.info user=%user.name user_loginuid=%user.loginuid). The output will change
# based on the context and whether or not -pk/-pm/-pc was specified on
# the command line.
- macro: container
condition: (container.id != host)
@ -329,7 +328,7 @@
and directory_traversal
and not proc.pname in (shell_binaries)
enabled: true
output: Read monitored file via directory traversal (file=%fd.name fileraw=%fd.nameraw gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Read monitored file via directory traversal | file=%fd.name fileraw=%fd.nameraw gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: WARNING
tags: [maturity_stable, host, container, filesystem, mitre_credential_access, T1555]
@ -355,7 +354,7 @@
and not proc_is_new
and proc.name!="sshd"
and not user_known_read_sensitive_files_activities
output: Sensitive file opened for reading by trusted program after startup (file=%fd.name pcmdline=%proc.pcmdline gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Sensitive file opened for reading by trusted program after startup | file=%fd.name pcmdline=%proc.pcmdline gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: WARNING
tags: [maturity_stable, host, container, filesystem, mitre_credential_access, T1555]
@ -364,7 +363,8 @@
iptables, ps, lsb_release, check-new-relea, dumpe2fs, accounts-daemon, sshd,
vsftpd, systemd, mysql_install_d, psql, screen, debconf-show, sa-update,
pam-auth-update, pam-config, /usr/sbin/spamd, polkit-agent-he, lsattr, file, sosreport,
scxcimservera, adclient, rtvscand, cockpit-session, userhelper, ossec-syscheckd
scxcimservera, adclient, rtvscand, cockpit-session, userhelper, ossec-syscheckd,
sshd-session
]
# Add conditions to this macro (probably in a separate file,
@ -427,7 +427,7 @@
and not linux_bench_reading_etc_shadow
and not user_known_read_sensitive_files_activities
and not user_read_sensitive_file_containers
output: Sensitive file opened for reading by non-trusted program (file=%fd.name gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Sensitive file opened for reading by non-trusted program | file=%fd.name gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: WARNING
tags: [maturity_stable, host, container, filesystem, mitre_credential_access, T1555]
@ -599,7 +599,7 @@
and not rabbitmqctl_running_scripts
and not run_by_appdynamics
and not user_shell_container_exclusions
output: Shell spawned by untrusted binary (parent_exe=%proc.pexe parent_exepath=%proc.pexepath pcmdline=%proc.pcmdline gparent=%proc.aname[2] ggparent=%proc.aname[3] aname[4]=%proc.aname[4] aname[5]=%proc.aname[5] aname[6]=%proc.aname[6] aname[7]=%proc.aname[7] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Shell spawned by untrusted binary | parent_exe=%proc.pexe parent_exepath=%proc.pexepath pcmdline=%proc.pcmdline gparent=%proc.aname[2] ggparent=%proc.aname[3] aname[4]=%proc.aname[4] aname[5]=%proc.aname[5] aname[6]=%proc.aname[6] aname[7]=%proc.aname[7] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: NOTICE
tags: [maturity_stable, host, container, process, shell, mitre_execution, T1059.004]
@ -634,7 +634,6 @@
- public.ecr.aws/falcosecurity/falco-no-driver
# These container images are allowed to run with --privileged and full set of capabilities
# TODO: Remove k8s.gcr.io reference after 01/Dec/2023
- list: falco_privileged_images
items: [
falco_containers,
@ -653,16 +652,12 @@
gke.gcr.io/netd-amd64,
gke.gcr.io/watcher-daemonset,
gcr.io/google-containers/prometheus-to-sd,
k8s.gcr.io/ip-masq-agent-amd64,
k8s.gcr.io/kube-proxy,
k8s.gcr.io/prometheus-to-sd,
registry.k8s.io/ip-masq-agent-amd64,
registry.k8s.io/kube-proxy,
registry.k8s.io/prometheus-to-sd,
quay.io/calico/node,
sysdig/sysdig,
sematext_images,
k8s.gcr.io/dns/k8s-dns-node-cache,
registry.k8s.io/dns/k8s-dns-node-cache,
mcr.microsoft.com/oss/kubernetes/kube-proxy
]
@ -678,14 +673,14 @@
# We also let runc:[1:CHILD] count as the parent process, which can occur
# when we lose events and lose track of state.
- macro: container_entrypoint
condition: (not proc.pname exists or proc.pname in (runc:[0:PARENT], runc:[1:CHILD], runc, docker-runc, exe, docker-runc-cur, containerd-shim, systemd, crio))
condition: (not proc.pname exists or proc.pname in (runc:[0:PARENT], runc:[1:CHILD], runc, docker-runc, exe, docker-runc-cur, containerd-shim, systemd, crio, conmon))
- macro: user_known_system_user_login
condition: (never_true)
# Anything run interactively by root
# - condition: evt.type != switch and user.name = root and proc.name != sshd and interactive
# output: "Interactive root (%user.name %proc.name %evt.dir %evt.type %evt.args %fd.name)"
# output: "Interactive root | %user.name %proc.name %evt.dir %evt.type %evt.args %fd.name"
# priority: WARNING
- rule: System user interactive
desc: >
@ -702,7 +697,7 @@
and system_users
and interactive
and not user_known_system_user_login
output: System user ran an interactive command (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: System user ran an interactive command | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: INFO
tags: [maturity_stable, host, container, users, mitre_execution, T1059, NIST_800-53_AC-2]
@ -725,7 +720,7 @@
and proc.tty != 0
and container_entrypoint
and not user_expected_terminal_shell_in_container_conditions
output: A shell was spawned in a container with an attached terminal (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: A shell was spawned in a container with an attached terminal | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: NOTICE
tags: [maturity_stable, container, shell, mitre_execution, T1059]
@ -796,7 +791,6 @@
# allowed to contact the K8s API Server from within a container. This
# might cover cases where the K8s infrastructure itself is running
# within a container.
# TODO: Remove k8s.gcr.io reference after 01/Dec/2023
- macro: k8s_containers
condition: >
(container.image.repository in (gcr.io/google_containers/hyperkube-amd64,
@ -808,7 +802,7 @@
ibm_cloud_containers,
velero/velero,
quay.io/jetstack/cert-manager-cainjector, weaveworks/kured,
quay.io/prometheus-operator/prometheus-operator, k8s.gcr.io/ingress-nginx/kube-webhook-certgen,
quay.io/prometheus-operator/prometheus-operator,
registry.k8s.io/ingress-nginx/kube-webhook-certgen, quay.io/spotahome/redis-operator,
registry.opensource.zalan.do/acid/postgres-operator, registry.opensource.zalan.do/acid/postgres-operator-ui,
rabbitmqoperator/cluster-operator, quay.io/kubecost1/kubecost-cost-model,
@ -836,7 +830,7 @@
and k8s_api_server
and not k8s_containers
and not user_known_contact_k8s_api_server_activities
output: Unexpected connection to K8s API Server from container (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Unexpected connection to K8s API Server from container | connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=%fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: NOTICE
tags: [maturity_stable, container, network, k8s, mitre_discovery, T1565]
@ -856,7 +850,7 @@
proc.args contains "--exec" or proc.args contains "-e " or
proc.args contains "-c " or proc.args contains "--lua-exec"))
)
output: Netcat runs inside container that allows remote code execution (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Netcat runs inside container that allows remote code execution | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: WARNING
tags: [maturity_stable, container, network, process, mitre_execution, T1059]
@ -898,7 +892,7 @@
proc.args contains "id_ecdsa"
)
))
output: Grep private keys or passwords activities found (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Grep private keys or passwords activities found | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority:
WARNING
tags: [maturity_stable, host, container, process, filesystem, mitre_credential_access, T1552.001]
@ -924,7 +918,9 @@
- macro: containerd_activities
condition: (proc.name=containerd and (fd.name startswith "/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/" or
fd.name startswith "/var/lib/containerd/tmpmounts/"))
fd.name startswith "/var/lib/rancher/k3s/agent/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots" or
fd.name startswith "/var/lib/containerd/tmpmounts/" or
fd.name startswith "/var/lib/rancher/k3s/agent/containerd/tmpmounts/"))
- rule: Clear Log Activities
desc: >
@ -938,7 +934,7 @@
and not containerd_activities
and not trusted_logging_images
and not allowed_clear_log_files
output: Log files were tampered (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Log files were tampered | file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority:
WARNING
tags: [maturity_stable, host, container, filesystem, mitre_defense_evasion, T1070, NIST_800-53_AU-10]
@ -960,7 +956,7 @@
spawned_process
and clear_data_procs
and not user_known_remove_data_activities
output: Bulk data has been removed from disk (file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Bulk data has been removed from disk | file=%fd.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority:
WARNING
tags: [maturity_stable, host, container, process, filesystem, mitre_impact, T1485]
@ -973,7 +969,7 @@
condition: >
create_symlink
and (evt.arg.target in (sensitive_file_names) or evt.arg.target in (sensitive_directory_names))
output: Symlinks created over sensitive files (target=%evt.arg.target linkpath=%evt.arg.linkpath evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Symlinks created over sensitive files | target=%evt.arg.target linkpath=%evt.arg.linkpath evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: WARNING
tags: [maturity_stable, host, container, filesystem, mitre_credential_access, T1555]
@ -985,7 +981,7 @@
condition: >
create_hardlink
and (evt.arg.oldpath in (sensitive_file_names))
output: Hardlinks created over sensitive files (target=%evt.arg.oldpath linkpath=%evt.arg.newpath evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Hardlinks created over sensitive files | target=%evt.arg.oldpath linkpath=%evt.arg.newpath evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: WARNING
tags: [maturity_stable, host, container, filesystem, mitre_credential_access, T1555]
@ -1002,7 +998,7 @@
and container
and evt.arg.domain contains AF_PACKET
and not proc.name in (user_known_packet_socket_binaries)
output: Packet socket was created in a container (socket_info=%evt.args connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Packet socket was created in a container | socket_info=%evt.args connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=%fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: NOTICE
tags: [maturity_stable, container, network, mitre_credential_access, T1557.002]
@ -1035,7 +1031,7 @@
and evt.rawres in (0, 1, 2)
and fd.type in ("ipv4", "ipv6")
and not user_known_stand_streams_redirect_activities
output: Redirect stdout/stdin to network connection (gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] fd.sip=%fd.sip connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Redirect stdout/stdin to network connection | gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] fd.sip=%fd.sip connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=%fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: NOTICE
tags: [maturity_stable, container, network, process, mitre_execution, T1059]
@ -1052,7 +1048,7 @@
and container
and thread.cap_effective icontains sys_module
and not container.image.repository in (allowed_container_images_loading_kernel_module)
output: Linux Kernel Module injection from container (parent_exepath=%proc.pexepath gparent=%proc.aname[2] gexepath=%proc.aexepath[2] module=%proc.args res=%evt.res evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Linux Kernel Module injection from container | parent_exepath=%proc.pexepath gparent=%proc.aname[2] gexepath=%proc.aexepath[2] module=%proc.args res=%evt.res evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: WARNING
tags: [maturity_stable, host, container, process, mitre_persistence, TA0003]
@ -1065,7 +1061,7 @@
and container
and container.privileged=true
and proc.name=debugfs
output: Debugfs launched started in a privileged container (evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Debugfs launched started in a privileged container | evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: WARNING
tags: [maturity_stable, container, cis, process, mitre_privilege_escalation, T1611]
@ -1080,7 +1076,7 @@
and fd.name endswith release_agent
and (user.uid=0 or thread.cap_effective contains CAP_DAC_OVERRIDE)
and thread.cap_effective contains CAP_SYS_ADMIN
output: Detect an attempt to exploit a container escape using release_agent file (file=%fd.name cap_effective=%thread.cap_effective evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Detect an attempt to exploit a container escape using release_agent file | file=%fd.name cap_effective=%thread.cap_effective evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: CRITICAL
tags: [maturity_stable, container, process, mitre_privilege_escalation, T1611]
@ -1112,7 +1108,7 @@
ptrace_attach_or_injection
and proc_name_exists
and not known_ptrace_procs
output: Detected ptrace PTRACE_ATTACH attempt (proc_pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Detected ptrace PTRACE_ATTACH attempt | proc_pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: WARNING
tags: [maturity_stable, host, container, process, mitre_privilege_escalation, T1055.008]
@ -1125,7 +1121,7 @@
evt.type=ptrace and evt.dir=>
and evt.arg.request contains PTRACE_TRACEME
and proc_name_exists
output: Detected potential PTRACE_TRACEME anti-debug attempt (proc_pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Detected potential PTRACE_TRACEME anti-debug attempt | proc_pcmdline=%proc.pcmdline evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: NOTICE
tags: [maturity_stable, host, container, process, mitre_defense_evasion, T1622]
@ -1147,7 +1143,7 @@
spawned_process
and ((grep_commands and private_aws_credentials) or
(proc.name = "find" and proc.args endswith ".aws/credentials"))
output: Detected AWS credentials search activity (proc_pcmdline=%proc.pcmdline proc_cwd=%proc.cwd group_gid=%group.gid group_name=%group.name user_loginname=%user.loginname evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Detected AWS credentials search activity | proc_pcmdline=%proc.pcmdline proc_cwd=%proc.cwd group_gid=%group.gid group_name=%group.name user_loginname=%user.loginname evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: WARNING
tags: [maturity_stable, host, container, process, aws, mitre_credential_access, T1552]
@ -1166,7 +1162,7 @@
(shell_procs and proc.args startswith "/dev/shm") or
(proc.cwd startswith "/dev/shm/" and proc.args startswith "./" ))
and not container.image.repository in (falco_privileged_images, trusted_images)
output: File execution detected from /dev/shm (evt_res=%evt.res file=%fd.name proc_cwd=%proc.cwd proc_pcmdline=%proc.pcmdline user_loginname=%user.loginname group_gid=%group.gid group_name=%group.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: File execution detected from /dev/shm | evt_res=%evt.res file=%fd.name proc_cwd=%proc.cwd proc_pcmdline=%proc.pcmdline user_loginname=%user.loginname group_gid=%group.gid group_name=%group.name evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: WARNING
tags: [maturity_stable, host, container, mitre_execution, T1059.004]
@ -1174,6 +1170,9 @@
- list: known_drop_and_execute_containers
items: []
- macro: known_drop_and_execute_activities
condition: (never_true)
- rule: Drop and execute new binary in container
desc: >
Detect if an executable not belonging to the base image of a container is being executed.
@ -1189,7 +1188,8 @@
and container
and proc.is_exe_upper_layer=true
and not container.image.repository in (known_drop_and_execute_containers)
output: Executing binary not part of base image (proc_exe=%proc.exe proc_sname=%proc.sname gparent=%proc.aname[2] proc_exe_ino_ctime=%proc.exe_ino.ctime proc_exe_ino_mtime=%proc.exe_ino.mtime proc_exe_ino_ctime_duration_proc_start=%proc.exe_ino.ctime_duration_proc_start proc_cwd=%proc.cwd container_start_ts=%container.start_ts evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
and not known_drop_and_execute_activities
output: Executing binary not part of base image | proc_exe=%proc.exe proc_sname=%proc.sname gparent=%proc.aname[2] proc_exe_ino_ctime=%proc.exe_ino.ctime proc_exe_ino_mtime=%proc.exe_ino.mtime proc_exe_ino_ctime_duration_proc_start=%proc.exe_ino.ctime_duration_proc_start proc_cwd=%proc.cwd container_start_ts=%container.start_ts evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: CRITICAL
tags: [maturity_stable, container, process, mitre_persistence, TA0003, PCI_DSS_11.5.1]
@ -1226,15 +1226,20 @@
and proc.exe endswith ssh
and fd.l4proto=tcp
and ssh_non_standard_ports_network
output: Disallowed SSH Connection (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty %container.info)
output: Disallowed SSH Connection | connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=%fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty
priority: NOTICE
tags: [maturity_stable, host, container, network, process, mitre_execution, T1059]
- list: known_memfd_execution_binaries
items: []
items: [runc]
- macro: known_memfd_execution_processes
condition: (proc.name in (known_memfd_execution_binaries))
condition: >
(proc.name in (known_memfd_execution_binaries))
or (proc.pname in (known_memfd_execution_binaries))
or (proc.exepath = "memfd:runc_cloned:/proc/self/exe")
or (proc.exe = "memfd:runc_cloned:/proc/self/exe")
- rule: Fileless execution via memfd_create
desc: >
@ -1246,6 +1251,6 @@
spawned_process
and proc.is_exe_from_memfd=true
and not known_memfd_execution_processes
output: Fileless execution via memfd_create (container_start_ts=%container.start_ts proc_cwd=%proc.cwd evt_res=%evt.res proc_sname=%proc.sname gparent=%proc.aname[2] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
output: Fileless execution via memfd_create | container_start_ts=%container.start_ts proc_cwd=%proc.cwd evt_res=%evt.res proc_sname=%proc.sname gparent=%proc.aname[2] evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: CRITICAL
tags: [maturity_stable, host, container, process, mitre_defense_evasion, T1620]