From cd042d2bcd32053440c7686e44e736775470f44a Mon Sep 17 00:00:00 2001 From: Evan Gibler Date: Tue, 7 May 2024 08:43:48 -0500 Subject: [PATCH 01/35] Replace panther_analysis_tool import with updated import (#1230) --- global_helpers/global_helpers_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global_helpers/global_helpers_test.py b/global_helpers/global_helpers_test.py index 8988c67d5..dba629cb5 100755 --- a/global_helpers/global_helpers_test.py +++ b/global_helpers/global_helpers_test.py @@ -10,7 +10,7 @@ import sys import unittest -from panther_analysis_tool.immutable import ImmutableCaseInsensitiveDict, ImmutableList +from panther_core.immutable import ImmutableCaseInsensitiveDict, ImmutableList # pipenv run does the right thing, but IDE based debuggers may fail to import # so noting, we append this directory to sys.path From 5e5f196e78d9b6d7411771392adf72640003cdd9 Mon Sep 17 00:00:00 2001 From: Evan Gibler Date: Tue, 7 May 2024 11:48:25 -0500 Subject: [PATCH 02/35] Update Action versions; use SHAs (#1231) * Update Action versions; use SHAs * Add dependabot.yml to keep Actions updated * Update PAT to 0.49.0 --- .github/workflows/check-packs.yml | 4 +- .github/workflows/docker.yml | 6 +- .github/workflows/lint.yml | 4 +- .github/workflows/release.yml | 4 +- .github/workflows/sync-from-upstream.yml | 10 +- .github/workflows/test.yml | 4 +- .github/workflows/upload.yml | 4 +- Pipfile | 2 +- Pipfile.lock | 372 +++++++++++------------ dependabot.yml | 6 + 10 files changed, 207 insertions(+), 209 deletions(-) create mode 100644 dependabot.yml diff --git a/.github/workflows/check-packs.yml b/.github/workflows/check-packs.yml index 9621a0d12..31a0495ac 100644 --- a/.github/workflows/check-packs.yml +++ b/.github/workflows/check-packs.yml @@ -8,10 +8,10 @@ jobs: steps: - name: Checkout panther-analysis - uses: actions/checkout@v4 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 - name: Set python version - uses: actions/setup-python@v4 + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d #v5.1.0 with: python-version: "3.11" diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index ab349936e..d9f205a58 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -9,11 +9,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout panther-analysis - uses: actions/checkout@v4 - - uses: docker/setup-qemu-action@v3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 + - uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 #v3.0.0 - name: Set up Docker Buildx id: buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb #v3.3.0 - name: Build Image run: docker buildx build --load -f Dockerfile -t panther-analysis:latest . - name: Test Image diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 8d00b2a1f..0d2f267bf 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -8,12 +8,12 @@ jobs: steps: - name: Checkout panther-analysis - uses: actions/checkout@v4 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 with: ref: ${{ github.event.pull_request.head.sha }} - name: Set python version - uses: actions/setup-python@v4 + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d #v5.1.0 with: python-version: "3.11" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e5847838a..3e3af00f1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.PANTHER_BOT_AUTOMATION_TOKEN }} steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 with: fetch-depth: 0 token: ${{ env.GITHUB_TOKEN }} @@ -23,7 +23,7 @@ jobs: aws-region: ${{ secrets.AWS_REGION }} role-session-name: panther-analysis-release - name: Install Python - uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1 + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d #v5.1.0 with: python-version: "3.11" - name: Create new panther-analysis release diff --git a/.github/workflows/sync-from-upstream.yml b/.github/workflows/sync-from-upstream.yml index c93a8b788..ffbd3faac 100644 --- a/.github/workflows/sync-from-upstream.yml +++ b/.github/workflows/sync-from-upstream.yml @@ -15,7 +15,7 @@ jobs: github.repository != 'panther-labs/panther-analysis' runs-on: ubuntu-latest steps: - - uses: actions/github-script@v7 + - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea #v7.0.1 id: set_upstream name: Check Upstream with: @@ -29,7 +29,7 @@ jobs: process.env['GITHUB_OUTPUT'], 'latest-release=' + upstreamLatest.data.tag_name + '\n'); ## CREATE A BRANCH - - uses: peterjgrainger/action-create-branch@v3.0.0 + - uses: peterjgrainger/action-create-branch@10c7d268152480ae859347db45dc69086cef1d9c #v3.0.0 id: create_a_branch env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -37,14 +37,14 @@ jobs: branch: "sync_upstream_${{steps.set_upstream.outputs.latest-release}}" # Checkout this repo into the branch - name: Checkout your local repo in PR branch - uses: actions/checkout@v4 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 with: ref: "sync_upstream_${{steps.set_upstream.outputs.latest-release}}" token: ${{ secrets.GITHUB_TOKEN }} # Sync this branch with upstream - name: Sync upstream changes into PR branch id: sync - uses: aormsby/Fork-Sync-With-Upstream-action@v3.4 + uses: aormsby/Fork-Sync-With-Upstream-action@1090e365224fc834e7e1de521c417ded2d6fcb53 #v3.4.1 with: # target_sync_branch == the branch in your fork that you want to sync to upstream target_sync_branch: "sync_upstream_${{steps.set_upstream.outputs.latest-release}}" @@ -58,7 +58,7 @@ jobs: #test_mode: true upstream_pull_args: "--allow-unrelated-histories" # Create a PR from this branch back to this fork's primary branch - - uses: actions/github-script@v7 + - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea #v7.0.1 id: create_pr name: Create a PR to bring upstream changes into the local repo primary branch if: steps.sync.outputs.has_new_commits == 'true' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 556d4389a..e4d4c6acc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,10 +8,10 @@ jobs: steps: - name: Checkout panther-analysis - uses: actions/checkout@v4 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 - name: Set python version - uses: actions/setup-python@v5 + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d #v5.1.0 with: python-version: "3.11" diff --git a/.github/workflows/upload.yml b/.github/workflows/upload.yml index 8dab51d7c..4c313e8a3 100644 --- a/.github/workflows/upload.yml +++ b/.github/workflows/upload.yml @@ -18,10 +18,10 @@ jobs: exit 0 - name: Checkout panther-analysis - uses: actions/checkout@v4 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 - name: Set python version - uses: actions/setup-python@v4 + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d #v5.1.0 with: python-version: "3.11" diff --git a/Pipfile b/Pipfile index 4b911258c..300548ead 100644 --- a/Pipfile +++ b/Pipfile @@ -19,7 +19,7 @@ wrapt = "~=1.15" [packages] policyuniverse = "==1.5.1.20230817" requests = "==2.31.0" -panther-analysis-tool = "~=0.48" +panther-analysis-tool = "~=0.49" panther-detection-helpers = "==0.4.0" [requires] diff --git a/Pipfile.lock b/Pipfile.lock index b2a660cdf..89994b31a 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "0d2bae7d56a67c3955954c5c15351a876208d46d458051d6a1789b5241c541e4" + "sha256": "17b8e970a9987cbf1b1990b9bd6832b6012de2263f46f946b3d22bd42e42d2d8" }, "pipfile-spec": 6, "requires": { @@ -139,19 +139,19 @@ }, "boto3": { "hashes": [ - "sha256:decf52f8d5d8a1b10c9ff2a0e96ee207ed79e33d2e53fdf0880a5cbef70785e0", - "sha256:e836b71d79671270fccac0a4d4c8ec239a6b82ea47c399b64675aa597d0ee63b" + "sha256:6f600b3fe0bda53476395c902d9af5a47294c93ec52a9cdc2b926a9dc705ce79", + "sha256:b54084d000483b578757df03ce39a819fbba47071c9aa98611beb8806bcecd45" ], "markers": "python_version >= '3.8'", - "version": "==1.34.95" + "version": "==1.34.99" }, "botocore": { "hashes": [ - "sha256:6bd76a2eadb42b91fa3528392e981ad5b4dfdee3968fa5b904278acf6cbf15ff", - "sha256:ead5823e0dd6751ece5498cb979fd9abf190e691c8833bcac6876fd6ca261fa7" + "sha256:18c68bdeb0ffb73290912b0c96204fc36d3128f00a00b5cdc35ac34d66225f1c", + "sha256:cafe569e2136cb33cb0e5dd32fb1c0e1503ddc1413d3be215df8ddf05e69137a" ], "markers": "python_version >= '3.8'", - "version": "==1.34.95" + "version": "==1.34.99" }, "certifi": { "hashes": [ @@ -281,14 +281,6 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", "version": "==0.4.6" }, - "contextlib2": { - "hashes": [ - "sha256:3fbdb64466afd23abaf6c977627b75b6139a5a3e8ce38405c5b413aed7a0471f", - "sha256:ab1e2bfe1d01d968e1b7e8d9023bc51ef3509bba217bb730cee3827e1ee82869" - ], - "markers": "python_version >= '3.6'", - "version": "==21.6.0" - }, "datadog": { "hashes": [ "sha256:4a56d57490ea699a0dfd9253547485a57b4120e93489defadcf95c66272374d6", @@ -429,11 +421,11 @@ }, "jinja2": { "hashes": [ - "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa", - "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90" + "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", + "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d" ], "markers": "python_version >= '3.7'", - "version": "==3.1.3" + "version": "==3.1.4" }, "jmespath": { "hashes": [ @@ -652,10 +644,10 @@ }, "panther-analysis-tool": { "hashes": [ - "sha256:220b9f8dfb7780854f756b4886e62d26ac28f7afb21e745786bdedef7cf6cd2b" + "sha256:b2c80ad4e1ad7a506a581c78fd01df2769970d92c6f70f0cb723cbc70947db6c" ], "index": "pypi", - "version": "==0.48.0" + "version": "==0.49.0" }, "panther-core": { "hashes": [ @@ -704,11 +696,11 @@ }, "pygments": { "hashes": [ - "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c", - "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367" + "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", + "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a" ], - "markers": "python_version >= '3.7'", - "version": "==2.17.2" + "markers": "python_version >= '3.8'", + "version": "==2.18.0" }, "pytest": { "hashes": [ @@ -723,7 +715,7 @@ "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.9.0.post0" }, "pyyaml": { @@ -785,11 +777,11 @@ }, "referencing": { "hashes": [ - "sha256:191e936b0c696d0af17ad7430a3dc68e88bc11be6514f4757dc890f04ab05889", - "sha256:8080727b30e364e5783152903672df9b6b091c926a146a759080b62ca3126cd6" + "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c", + "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de" ], "markers": "python_version >= '3.8'", - "version": "==0.35.0" + "version": "==0.35.1" }, "regex": { "hashes": [ @@ -887,108 +879,108 @@ }, "rpds-py": { "hashes": [ - "sha256:01e36a39af54a30f28b73096dd39b6802eddd04c90dbe161c1b8dbe22353189f", - "sha256:044a3e61a7c2dafacae99d1e722cc2d4c05280790ec5a05031b3876809d89a5c", - "sha256:08231ac30a842bd04daabc4d71fddd7e6d26189406d5a69535638e4dcb88fe76", - "sha256:08f9ad53c3f31dfb4baa00da22f1e862900f45908383c062c27628754af2e88e", - "sha256:0ab39c1ba9023914297dd88ec3b3b3c3f33671baeb6acf82ad7ce883f6e8e157", - "sha256:0af039631b6de0397ab2ba16eaf2872e9f8fca391b44d3d8cac317860a700a3f", - "sha256:0b8612cd233543a3781bc659c731b9d607de65890085098986dfd573fc2befe5", - "sha256:11a8c85ef4a07a7638180bf04fe189d12757c696eb41f310d2426895356dcf05", - "sha256:1374f4129f9bcca53a1bba0bb86bf78325a0374577cf7e9e4cd046b1e6f20e24", - "sha256:1d4acf42190d449d5e89654d5c1ed3a4f17925eec71f05e2a41414689cda02d1", - "sha256:1d9a5be316c15ffb2b3c405c4ff14448c36b4435be062a7f578ccd8b01f0c4d8", - "sha256:1df3659d26f539ac74fb3b0c481cdf9d725386e3552c6fa2974f4d33d78e544b", - "sha256:22806714311a69fd0af9b35b7be97c18a0fc2826e6827dbb3a8c94eac6cf7eeb", - "sha256:2644e47de560eb7bd55c20fc59f6daa04682655c58d08185a9b95c1970fa1e07", - "sha256:2e6d75ab12b0bbab7215e5d40f1e5b738aa539598db27ef83b2ec46747df90e1", - "sha256:30f43887bbae0d49113cbaab729a112251a940e9b274536613097ab8b4899cf6", - "sha256:34b18ba135c687f4dac449aa5157d36e2cbb7c03cbea4ddbd88604e076aa836e", - "sha256:36b3ee798c58ace201289024b52788161e1ea133e4ac93fba7d49da5fec0ef9e", - "sha256:39514da80f971362f9267c600b6d459bfbbc549cffc2cef8e47474fddc9b45b1", - "sha256:39f5441553f1c2aed4de4377178ad8ff8f9d733723d6c66d983d75341de265ab", - "sha256:3a96e0c6a41dcdba3a0a581bbf6c44bb863f27c541547fb4b9711fd8cf0ffad4", - "sha256:3f26b5bd1079acdb0c7a5645e350fe54d16b17bfc5e71f371c449383d3342e17", - "sha256:41ef53e7c58aa4ef281da975f62c258950f54b76ec8e45941e93a3d1d8580594", - "sha256:42821446ee7a76f5d9f71f9e33a4fb2ffd724bb3e7f93386150b61a43115788d", - "sha256:43fbac5f22e25bee1d482c97474f930a353542855f05c1161fd804c9dc74a09d", - "sha256:4457a94da0d5c53dc4b3e4de1158bdab077db23c53232f37a3cb7afdb053a4e3", - "sha256:465a3eb5659338cf2a9243e50ad9b2296fa15061736d6e26240e713522b6235c", - "sha256:482103aed1dfe2f3b71a58eff35ba105289b8d862551ea576bd15479aba01f66", - "sha256:4832d7d380477521a8c1644bbab6588dfedea5e30a7d967b5fb75977c45fd77f", - "sha256:4901165d170a5fde6f589acb90a6b33629ad1ec976d4529e769c6f3d885e3e80", - "sha256:5307def11a35f5ae4581a0b658b0af8178c65c530e94893345bebf41cc139d33", - "sha256:5417558f6887e9b6b65b4527232553c139b57ec42c64570569b155262ac0754f", - "sha256:56a737287efecafc16f6d067c2ea0117abadcd078d58721f967952db329a3e5c", - "sha256:586f8204935b9ec884500498ccc91aa869fc652c40c093bd9e1471fbcc25c022", - "sha256:5b4e7d8d6c9b2e8ee2d55c90b59c707ca59bc30058269b3db7b1f8df5763557e", - "sha256:5ddcba87675b6d509139d1b521e0c8250e967e63b5909a7e8f8944d0f90ff36f", - "sha256:618a3d6cae6ef8ec88bb76dd80b83cfe415ad4f1d942ca2a903bf6b6ff97a2da", - "sha256:635dc434ff724b178cb192c70016cc0ad25a275228f749ee0daf0eddbc8183b1", - "sha256:661d25cbffaf8cc42e971dd570d87cb29a665f49f4abe1f9e76be9a5182c4688", - "sha256:66e6a3af5a75363d2c9a48b07cb27c4ea542938b1a2e93b15a503cdfa8490795", - "sha256:67071a6171e92b6da534b8ae326505f7c18022c6f19072a81dcf40db2638767c", - "sha256:685537e07897f173abcf67258bee3c05c374fa6fff89d4c7e42fb391b0605e98", - "sha256:69e64831e22a6b377772e7fb337533c365085b31619005802a79242fee620bc1", - "sha256:6b0817e34942b2ca527b0e9298373e7cc75f429e8da2055607f4931fded23e20", - "sha256:6c81e5f372cd0dc5dc4809553d34f832f60a46034a5f187756d9b90586c2c307", - "sha256:6d7faa6f14017c0b1e69f5e2c357b998731ea75a442ab3841c0dbbbfe902d2c4", - "sha256:6ef0befbb5d79cf32d0266f5cff01545602344eda89480e1dd88aca964260b18", - "sha256:6ef687afab047554a2d366e112dd187b62d261d49eb79b77e386f94644363294", - "sha256:7223a2a5fe0d217e60a60cdae28d6949140dde9c3bcc714063c5b463065e3d66", - "sha256:77f195baa60a54ef9d2de16fbbfd3ff8b04edc0c0140a761b56c267ac11aa467", - "sha256:793968759cd0d96cac1e367afd70c235867831983f876a53389ad869b043c948", - "sha256:7bd339195d84439cbe5771546fe8a4e8a7a045417d8f9de9a368c434e42a721e", - "sha256:7cd863afe7336c62ec78d7d1349a2f34c007a3cc6c2369d667c65aeec412a5b1", - "sha256:7f2facbd386dd60cbbf1a794181e6aa0bd429bd78bfdf775436020172e2a23f0", - "sha256:84ffab12db93b5f6bad84c712c92060a2d321b35c3c9960b43d08d0f639d60d7", - "sha256:8c8370641f1a7f0e0669ddccca22f1da893cef7628396431eb445d46d893e5cd", - "sha256:8db715ebe3bb7d86d77ac1826f7d67ec11a70dbd2376b7cc214199360517b641", - "sha256:8e8916ae4c720529e18afa0b879473049e95949bf97042e938530e072fde061d", - "sha256:8f03bccbd8586e9dd37219bce4d4e0d3ab492e6b3b533e973fa08a112cb2ffc9", - "sha256:8f2fc11e8fe034ee3c34d316d0ad8808f45bc3b9ce5857ff29d513f3ff2923a1", - "sha256:923d39efa3cfb7279a0327e337a7958bff00cc447fd07a25cddb0a1cc9a6d2da", - "sha256:93df1de2f7f7239dc9cc5a4a12408ee1598725036bd2dedadc14d94525192fc3", - "sha256:998e33ad22dc7ec7e030b3df701c43630b5bc0d8fbc2267653577e3fec279afa", - "sha256:99f70b740dc04d09e6b2699b675874367885217a2e9f782bdf5395632ac663b7", - "sha256:9a00312dea9310d4cb7dbd7787e722d2e86a95c2db92fbd7d0155f97127bcb40", - "sha256:9d54553c1136b50fd12cc17e5b11ad07374c316df307e4cfd6441bea5fb68496", - "sha256:9dbbeb27f4e70bfd9eec1be5477517365afe05a9b2c441a0b21929ee61048124", - "sha256:a1ce3ba137ed54f83e56fb983a5859a27d43a40188ba798993812fed73c70836", - "sha256:a34d557a42aa28bd5c48a023c570219ba2593bcbbb8dc1b98d8cf5d529ab1434", - "sha256:a5f446dd5055667aabaee78487f2b5ab72e244f9bc0b2ffebfeec79051679984", - "sha256:ad36cfb355e24f1bd37cac88c112cd7730873f20fb0bdaf8ba59eedf8216079f", - "sha256:aec493917dd45e3c69d00a8874e7cbed844efd935595ef78a0f25f14312e33c6", - "sha256:b316144e85316da2723f9d8dc75bada12fa58489a527091fa1d5a612643d1a0e", - "sha256:b34ae4636dfc4e76a438ab826a0d1eed2589ca7d9a1b2d5bb546978ac6485461", - "sha256:b34b7aa8b261c1dbf7720b5d6f01f38243e9b9daf7e6b8bc1fd4657000062f2c", - "sha256:bc362ee4e314870a70f4ae88772d72d877246537d9f8cb8f7eacf10884862432", - "sha256:bed88b9a458e354014d662d47e7a5baafd7ff81c780fd91584a10d6ec842cb73", - "sha256:c0013fe6b46aa496a6749c77e00a3eb07952832ad6166bd481c74bda0dcb6d58", - "sha256:c0b5dcf9193625afd8ecc92312d6ed78781c46ecbf39af9ad4681fc9f464af88", - "sha256:c4325ff0442a12113a6379af66978c3fe562f846763287ef66bdc1d57925d337", - "sha256:c463ed05f9dfb9baebef68048aed8dcdc94411e4bf3d33a39ba97e271624f8f7", - "sha256:c8362467a0fdeccd47935f22c256bec5e6abe543bf0d66e3d3d57a8fb5731863", - "sha256:cd5bf1af8efe569654bbef5a3e0a56eca45f87cfcffab31dd8dde70da5982475", - "sha256:cf1ea2e34868f6fbf070e1af291c8180480310173de0b0c43fc38a02929fc0e3", - "sha256:d62dec4976954a23d7f91f2f4530852b0c7608116c257833922a896101336c51", - "sha256:d68c93e381010662ab873fea609bf6c0f428b6d0bb00f2c6939782e0818d37bf", - "sha256:d7c36232a90d4755b720fbd76739d8891732b18cf240a9c645d75f00639a9024", - "sha256:dd18772815d5f008fa03d2b9a681ae38d5ae9f0e599f7dda233c439fcaa00d40", - "sha256:ddc2f4dfd396c7bfa18e6ce371cba60e4cf9d2e5cdb71376aa2da264605b60b9", - "sha256:e003b002ec72c8d5a3e3da2989c7d6065b47d9eaa70cd8808b5384fbb970f4ec", - "sha256:e32a92116d4f2a80b629778280103d2a510a5b3f6314ceccd6e38006b5e92dcb", - "sha256:e4461d0f003a0aa9be2bdd1b798a041f177189c1a0f7619fe8c95ad08d9a45d7", - "sha256:e541ec6f2ec456934fd279a3120f856cd0aedd209fc3852eca563f81738f6861", - "sha256:e546e768d08ad55b20b11dbb78a745151acbd938f8f00d0cfbabe8b0199b9880", - "sha256:ea7d4a99f3b38c37eac212dbd6ec42b7a5ec51e2c74b5d3223e43c811609e65f", - "sha256:ed4eb745efbff0a8e9587d22a84be94a5eb7d2d99c02dacf7bd0911713ed14dd", - "sha256:f8a2f084546cc59ea99fda8e070be2fd140c3092dc11524a71aa8f0f3d5a55ca", - "sha256:fcb25daa9219b4cf3a0ab24b0eb9a5cc8949ed4dc72acb8fa16b7e1681aa3c58", - "sha256:fdea4952db2793c4ad0bdccd27c1d8fdd1423a92f04598bc39425bcc2b8ee46e" + "sha256:05f3d615099bd9b13ecf2fc9cf2d839ad3f20239c678f461c753e93755d629ee", + "sha256:06d218939e1bf2ca50e6b0ec700ffe755e5216a8230ab3e87c059ebb4ea06afc", + "sha256:07f2139741e5deb2c5154a7b9629bc5aa48c766b643c1a6750d16f865a82c5fc", + "sha256:08d74b184f9ab6289b87b19fe6a6d1a97fbfea84b8a3e745e87a5de3029bf944", + "sha256:0abeee75434e2ee2d142d650d1e54ac1f8b01e6e6abdde8ffd6eeac6e9c38e20", + "sha256:154bf5c93d79558b44e5b50cc354aa0459e518e83677791e6adb0b039b7aa6a7", + "sha256:17c6d2155e2423f7e79e3bb18151c686d40db42d8645e7977442170c360194d4", + "sha256:1805d5901779662d599d0e2e4159d8a82c0b05faa86ef9222bf974572286b2b6", + "sha256:19ba472b9606c36716062c023afa2484d1e4220548751bda14f725a7de17b4f6", + "sha256:19e515b78c3fc1039dd7da0a33c28c3154458f947f4dc198d3c72db2b6b5dc93", + "sha256:1d54f74f40b1f7aaa595a02ff42ef38ca654b1469bef7d52867da474243cc633", + "sha256:207c82978115baa1fd8d706d720b4a4d2b0913df1c78c85ba73fe6c5804505f0", + "sha256:2625f03b105328729f9450c8badda34d5243231eef6535f80064d57035738360", + "sha256:27bba383e8c5231cd559affe169ca0b96ec78d39909ffd817f28b166d7ddd4d8", + "sha256:2c3caec4ec5cd1d18e5dd6ae5194d24ed12785212a90b37f5f7f06b8bedd7139", + "sha256:2cc7c1a47f3a63282ab0f422d90ddac4aa3034e39fc66a559ab93041e6505da7", + "sha256:2fc24a329a717f9e2448f8cd1f960f9dac4e45b6224d60734edeb67499bab03a", + "sha256:312fe69b4fe1ffbe76520a7676b1e5ac06ddf7826d764cc10265c3b53f96dbe9", + "sha256:32b7daaa3e9389db3695964ce8e566e3413b0c43e3394c05e4b243a4cd7bef26", + "sha256:338dee44b0cef8b70fd2ef54b4e09bb1b97fc6c3a58fea5db6cc083fd9fc2724", + "sha256:352a88dc7892f1da66b6027af06a2e7e5d53fe05924cc2cfc56495b586a10b72", + "sha256:35b2b771b13eee8729a5049c976197ff58a27a3829c018a04341bcf1ae409b2b", + "sha256:38e14fb4e370885c4ecd734f093a2225ee52dc384b86fa55fe3f74638b2cfb09", + "sha256:3c20f05e8e3d4fc76875fc9cb8cf24b90a63f5a1b4c5b9273f0e8225e169b100", + "sha256:3dd3cd86e1db5aadd334e011eba4e29d37a104b403e8ca24dcd6703c68ca55b3", + "sha256:489bdfe1abd0406eba6b3bb4fdc87c7fa40f1031de073d0cfb744634cc8fa261", + "sha256:48c2faaa8adfacefcbfdb5f2e2e7bdad081e5ace8d182e5f4ade971f128e6bb3", + "sha256:4a98a1f0552b5f227a3d6422dbd61bc6f30db170939bd87ed14f3c339aa6c7c9", + "sha256:4adec039b8e2928983f885c53b7cc4cda8965b62b6596501a0308d2703f8af1b", + "sha256:4e0ee01ad8260184db21468a6e1c37afa0529acc12c3a697ee498d3c2c4dcaf3", + "sha256:51584acc5916212e1bf45edd17f3a6b05fe0cbb40482d25e619f824dccb679de", + "sha256:531796fb842b53f2695e94dc338929e9f9dbf473b64710c28af5a160b2a8927d", + "sha256:5463c47c08630007dc0fe99fb480ea4f34a89712410592380425a9b4e1611d8e", + "sha256:5c45a639e93a0c5d4b788b2613bd637468edd62f8f95ebc6fcc303d58ab3f0a8", + "sha256:6031b25fb1b06327b43d841f33842b383beba399884f8228a6bb3df3088485ff", + "sha256:607345bd5912aacc0c5a63d45a1f73fef29e697884f7e861094e443187c02be5", + "sha256:618916f5535784960f3ecf8111581f4ad31d347c3de66d02e728de460a46303c", + "sha256:636a15acc588f70fda1661234761f9ed9ad79ebed3f2125d44be0862708b666e", + "sha256:673fdbbf668dd958eff750e500495ef3f611e2ecc209464f661bc82e9838991e", + "sha256:6afd80f6c79893cfc0574956f78a0add8c76e3696f2d6a15bca2c66c415cf2d4", + "sha256:6b5ff7e1d63a8281654b5e2896d7f08799378e594f09cf3674e832ecaf396ce8", + "sha256:6c4c4c3f878df21faf5fac86eda32671c27889e13570645a9eea0a1abdd50922", + "sha256:6cd8098517c64a85e790657e7b1e509b9fe07487fd358e19431cb120f7d96338", + "sha256:6d1e42d2735d437e7e80bab4d78eb2e459af48c0a46e686ea35f690b93db792d", + "sha256:6e30ac5e329098903262dc5bdd7e2086e0256aa762cc8b744f9e7bf2a427d3f8", + "sha256:70a838f7754483bcdc830444952fd89645569e7452e3226de4a613a4c1793fb2", + "sha256:720edcb916df872d80f80a1cc5ea9058300b97721efda8651efcd938a9c70a72", + "sha256:732672fbc449bab754e0b15356c077cc31566df874964d4801ab14f71951ea80", + "sha256:740884bc62a5e2bbb31e584f5d23b32320fd75d79f916f15a788d527a5e83644", + "sha256:7700936ef9d006b7ef605dc53aa364da2de5a3aa65516a1f3ce73bf82ecfc7ae", + "sha256:7732770412bab81c5a9f6d20aeb60ae943a9b36dcd990d876a773526468e7163", + "sha256:7750569d9526199c5b97e5a9f8d96a13300950d910cf04a861d96f4273d5b104", + "sha256:7f1944ce16401aad1e3f7d312247b3d5de7981f634dc9dfe90da72b87d37887d", + "sha256:81c5196a790032e0fc2464c0b4ab95f8610f96f1f2fa3d4deacce6a79852da60", + "sha256:8352f48d511de5f973e4f2f9412736d7dea76c69faa6d36bcf885b50c758ab9a", + "sha256:8927638a4d4137a289e41d0fd631551e89fa346d6dbcfc31ad627557d03ceb6d", + "sha256:8c7672e9fba7425f79019db9945b16e308ed8bc89348c23d955c8c0540da0a07", + "sha256:8d2e182c9ee01135e11e9676e9a62dfad791a7a467738f06726872374a83db49", + "sha256:910e71711d1055b2768181efa0a17537b2622afeb0424116619817007f8a2b10", + "sha256:942695a206a58d2575033ff1e42b12b2aece98d6003c6bc739fbf33d1773b12f", + "sha256:9437ca26784120a279f3137ee080b0e717012c42921eb07861b412340f85bae2", + "sha256:967342e045564cef76dfcf1edb700b1e20838d83b1aa02ab313e6a497cf923b8", + "sha256:998125738de0158f088aef3cb264a34251908dd2e5d9966774fdab7402edfab7", + "sha256:9e6934d70dc50f9f8ea47081ceafdec09245fd9f6032669c3b45705dea096b88", + "sha256:a3d456ff2a6a4d2adcdf3c1c960a36f4fd2fec6e3b4902a42a384d17cf4e7a65", + "sha256:a7b28c5b066bca9a4eb4e2f2663012debe680f097979d880657f00e1c30875a0", + "sha256:a888e8bdb45916234b99da2d859566f1e8a1d2275a801bb8e4a9644e3c7e7909", + "sha256:aa3679e751408d75a0b4d8d26d6647b6d9326f5e35c00a7ccd82b78ef64f65f8", + "sha256:aaa71ee43a703c321906813bb252f69524f02aa05bf4eec85f0c41d5d62d0f4c", + "sha256:b646bf655b135ccf4522ed43d6902af37d3f5dbcf0da66c769a2b3938b9d8184", + "sha256:b906b5f58892813e5ba5c6056d6a5ad08f358ba49f046d910ad992196ea61397", + "sha256:b9bb1f182a97880f6078283b3505a707057c42bf55d8fca604f70dedfdc0772a", + "sha256:bd1105b50ede37461c1d51b9698c4f4be6e13e69a908ab7751e3807985fc0346", + "sha256:bf18932d0003c8c4d51a39f244231986ab23ee057d235a12b2684ea26a353590", + "sha256:c273e795e7a0f1fddd46e1e3cb8be15634c29ae8ff31c196debb620e1edb9333", + "sha256:c69882964516dc143083d3795cb508e806b09fc3800fd0d4cddc1df6c36e76bb", + "sha256:c827576e2fa017a081346dce87d532a5310241648eb3700af9a571a6e9fc7e74", + "sha256:cbfbea39ba64f5e53ae2915de36f130588bba71245b418060ec3330ebf85678e", + "sha256:ce0bb20e3a11bd04461324a6a798af34d503f8d6f1aa3d2aa8901ceaf039176d", + "sha256:d0cee71bc618cd93716f3c1bf56653740d2d13ddbd47673efa8bf41435a60daa", + "sha256:d21be4770ff4e08698e1e8e0bce06edb6ea0626e7c8f560bc08222880aca6a6f", + "sha256:d31dea506d718693b6b2cffc0648a8929bdc51c70a311b2770f09611caa10d53", + "sha256:d44607f98caa2961bab4fa3c4309724b185b464cdc3ba6f3d7340bac3ec97cc1", + "sha256:d58ad6317d188c43750cb76e9deacf6051d0f884d87dc6518e0280438648a9ac", + "sha256:d70129cef4a8d979caa37e7fe957202e7eee8ea02c5e16455bc9808a59c6b2f0", + "sha256:d85164315bd68c0806768dc6bb0429c6f95c354f87485ee3593c4f6b14def2bd", + "sha256:d960de62227635d2e61068f42a6cb6aae91a7fe00fca0e3aeed17667c8a34611", + "sha256:dc48b479d540770c811fbd1eb9ba2bb66951863e448efec2e2c102625328e92f", + "sha256:e1735502458621921cee039c47318cb90b51d532c2766593be6207eec53e5c4c", + "sha256:e2be6e9dd4111d5b31ba3b74d17da54a8319d8168890fbaea4b9e5c3de630ae5", + "sha256:e4c39ad2f512b4041343ea3c7894339e4ca7839ac38ca83d68a832fc8b3748ab", + "sha256:ed402d6153c5d519a0faf1bb69898e97fb31613b49da27a84a13935ea9164dfc", + "sha256:ee17cd26b97d537af8f33635ef38be873073d516fd425e80559f4585a7b90c43", + "sha256:f3027be483868c99b4985fda802a57a67fdf30c5d9a50338d9db646d590198da", + "sha256:f5bab211605d91db0e2995a17b5c6ee5edec1270e46223e513eaa20da20076ac", + "sha256:f6f8e3fecca256fefc91bb6765a693d96692459d7d4c644660a9fff32e517843", + "sha256:f7afbfee1157e0f9376c00bb232e80a60e59ed716e3211a80cb8506550671e6e", + "sha256:fa242ac1ff583e4ec7771141606aafc92b361cd90a05c30d93e343a0c2d82a89", + "sha256:fab6ce90574645a0d6c58890e9bcaac8d94dff54fb51c69e5522a7358b80ab64" ], "markers": "python_version >= '3.8'", - "version": "==0.18.0" + "version": "==0.18.1" }, "ruamel.yaml": { "hashes": [ @@ -1051,7 +1043,7 @@ "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875", "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412" ], - "markers": "platform_python_implementation == 'CPython' and python_version < '3.13'", + "markers": "python_version < '3.13' and platform_python_implementation == 'CPython'", "version": "==0.2.8" }, "s3transfer": { @@ -1064,10 +1056,10 @@ }, "schema": { "hashes": [ - "sha256:f06717112c61895cabc4707752b88716e8420a8819d71404501e114f91043197", - "sha256:f3ffdeeada09ec34bf40d7d79996d9f7175db93b7a5065de0faa7f41083c1e6c" + "sha256:5d976a5b50f36e74e2157b47097b60002bd4d42e65425fcc9c9befadb4255dde", + "sha256:7da553abd2958a19dc2547c388cde53398b39196175a9be59ea1caf5ab0a1807" ], - "version": "==0.7.5" + "version": "==0.7.7" }, "semver": { "hashes": [ @@ -1082,7 +1074,7 @@ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.16.0" }, "sniffio": { @@ -1095,11 +1087,11 @@ }, "sqlfluff": { "hashes": [ - "sha256:5a4a08e4e4dedcadf4f544de83a7edab66e1decf7d946ec5fdbe59db49d6c2fe", - "sha256:b7818ea9954d9efc5b2f913df6e3d2270c42532cbad815f73ab582a410d9a39e" + "sha256:43805e5b1bfa6425d66f2eac3f34007a5bd259cf3bf4cff1bcfa4e2706055656", + "sha256:fa60e2a16e2500368d4ab98b5246ac85d4542c134413a5e650ed4d356adf7ddd" ], "markers": "python_version >= '3.8'", - "version": "==3.0.5" + "version": "==3.0.6" }, "tblib": { "hashes": [ @@ -1111,11 +1103,11 @@ }, "tqdm": { "hashes": [ - "sha256:1ee4f8a893eb9bef51c6e35730cebf234d5d0b6bd112b0271e10ed7c24a02bd9", - "sha256:6cd52cdf0fef0e0f543299cfc96fec90d7b8a7e88745f411ec33eb44d5ed3531" + "sha256:b75ca56b413b030bc3f00af51fd2c1a1a5eac6a0c1cca83cbb37a5c52abce644", + "sha256:e4d936c9de8727928f3be6079590e97d9abfe8d39a590be678eb5919ffc186bb" ], "markers": "python_version >= '3.7'", - "version": "==4.66.2" + "version": "==4.66.4" }, "typing-extensions": { "hashes": [ @@ -1279,19 +1271,19 @@ }, "boto3": { "hashes": [ - "sha256:decf52f8d5d8a1b10c9ff2a0e96ee207ed79e33d2e53fdf0880a5cbef70785e0", - "sha256:e836b71d79671270fccac0a4d4c8ec239a6b82ea47c399b64675aa597d0ee63b" + "sha256:6f600b3fe0bda53476395c902d9af5a47294c93ec52a9cdc2b926a9dc705ce79", + "sha256:b54084d000483b578757df03ce39a819fbba47071c9aa98611beb8806bcecd45" ], "markers": "python_version >= '3.8'", - "version": "==1.34.95" + "version": "==1.34.99" }, "botocore": { "hashes": [ - "sha256:6bd76a2eadb42b91fa3528392e981ad5b4dfdee3968fa5b904278acf6cbf15ff", - "sha256:ead5823e0dd6751ece5498cb979fd9abf190e691c8833bcac6876fd6ca261fa7" + "sha256:18c68bdeb0ffb73290912b0c96204fc36d3128f00a00b5cdc35ac34d66225f1c", + "sha256:cafe569e2136cb33cb0e5dd32fb1c0e1503ddc1413d3be215df8ddf05e69137a" ], "markers": "python_version >= '3.8'", - "version": "==1.34.95" + "version": "==1.34.99" }, "certifi": { "hashes": [ @@ -1465,41 +1457,41 @@ }, "cryptography": { "hashes": [ - "sha256:0270572b8bd2c833c3981724b8ee9747b3ec96f699a9665470018594301439ee", - "sha256:111a0d8553afcf8eb02a4fea6ca4f59d48ddb34497aa8706a6cf536f1a5ec576", - "sha256:16a48c23a62a2f4a285699dba2e4ff2d1cff3115b9df052cdd976a18856d8e3d", - "sha256:1b95b98b0d2af784078fa69f637135e3c317091b615cd0905f8b8a087e86fa30", - "sha256:1f71c10d1e88467126f0efd484bd44bca5e14c664ec2ede64c32f20875c0d413", - "sha256:2424ff4c4ac7f6b8177b53c17ed5d8fa74ae5955656867f5a8affaca36a27abb", - "sha256:2bce03af1ce5a5567ab89bd90d11e7bbdff56b8af3acbbec1faded8f44cb06da", - "sha256:329906dcc7b20ff3cad13c069a78124ed8247adcac44b10bea1130e36caae0b4", - "sha256:37dd623507659e08be98eec89323469e8c7b4c1407c85112634ae3dbdb926fdd", - "sha256:3eaafe47ec0d0ffcc9349e1708be2aaea4c6dd4978d76bf6eb0cb2c13636c6fc", - "sha256:5e6275c09d2badf57aea3afa80d975444f4be8d3bc58f7f80d2a484c6f9485c8", - "sha256:6fe07eec95dfd477eb9530aef5bead34fec819b3aaf6c5bd6d20565da607bfe1", - "sha256:7367d7b2eca6513681127ebad53b2582911d1736dc2ffc19f2c3ae49997496bc", - "sha256:7cde5f38e614f55e28d831754e8a3bacf9ace5d1566235e39d91b35502d6936e", - "sha256:9481ffe3cf013b71b2428b905c4f7a9a4f76ec03065b05ff499bb5682a8d9ad8", - "sha256:98d8dc6d012b82287f2c3d26ce1d2dd130ec200c8679b6213b3c73c08b2b7940", - "sha256:a011a644f6d7d03736214d38832e030d8268bcff4a41f728e6030325fea3e400", - "sha256:a2913c5375154b6ef2e91c10b5720ea6e21007412f6437504ffea2109b5a33d7", - "sha256:a30596bae9403a342c978fb47d9b0ee277699fa53bbafad14706af51fe543d16", - "sha256:b03c2ae5d2f0fc05f9a2c0c997e1bc18c8229f392234e8a0194f202169ccd278", - "sha256:b6cd2203306b63e41acdf39aa93b86fb566049aeb6dc489b70e34bcd07adca74", - "sha256:b7ffe927ee6531c78f81aa17e684e2ff617daeba7f189f911065b2ea2d526dec", - "sha256:b8cac287fafc4ad485b8a9b67d0ee80c66bf3574f655d3b97ef2e1082360faf1", - "sha256:ba334e6e4b1d92442b75ddacc615c5476d4ad55cc29b15d590cc6b86efa487e2", - "sha256:ba3e4a42397c25b7ff88cdec6e2a16c2be18720f317506ee25210f6d31925f9c", - "sha256:c41fb5e6a5fe9ebcd58ca3abfeb51dffb5d83d6775405305bfa8715b76521922", - "sha256:cd2030f6650c089aeb304cf093f3244d34745ce0cfcc39f20c6fbfe030102e2a", - "sha256:cd65d75953847815962c84a4654a84850b2bb4aed3f26fadcc1c13892e1e29f6", - "sha256:e4985a790f921508f36f81831817cbc03b102d643b5fcb81cd33df3fa291a1a1", - "sha256:e807b3188f9eb0eaa7bbb579b462c5ace579f1cedb28107ce8b48a9f7ad3679e", - "sha256:f12764b8fffc7a123f641d7d049d382b73f96a34117e0b637b80643169cec8ac", - "sha256:f8837fe1d6ac4a8052a9a8ddab256bc006242696f03368a4009be7ee3075cdb7" + "sha256:02c0eee2d7133bdbbc5e24441258d5d2244beb31da5ed19fbb80315f4bbbff55", + "sha256:0d563795db98b4cd57742a78a288cdbdc9daedac29f2239793071fe114f13785", + "sha256:16268d46086bb8ad5bf0a2b5544d8a9ed87a0e33f5e77dd3c3301e63d941a83b", + "sha256:1a58839984d9cb34c855197043eaae2c187d930ca6d644612843b4fe8513c886", + "sha256:2954fccea107026512b15afb4aa664a5640cd0af630e2ee3962f2602693f0c82", + "sha256:2e47577f9b18723fa294b0ea9a17d5e53a227867a0a4904a1a076d1646d45ca1", + "sha256:31adb7d06fe4383226c3e963471f6837742889b3c4caa55aac20ad951bc8ffda", + "sha256:3577d029bc3f4827dd5bf8bf7710cac13527b470bbf1820a3f394adb38ed7d5f", + "sha256:36017400817987670037fbb0324d71489b6ead6231c9604f8fc1f7d008087c68", + "sha256:362e7197754c231797ec45ee081f3088a27a47c6c01eff2ac83f60f85a50fe60", + "sha256:3de9a45d3b2b7d8088c3fbf1ed4395dfeff79d07842217b38df14ef09ce1d8d7", + "sha256:4f698edacf9c9e0371112792558d2f705b5645076cc0aaae02f816a0171770fd", + "sha256:5482e789294854c28237bba77c4c83be698be740e31a3ae5e879ee5444166582", + "sha256:5e44507bf8d14b36b8389b226665d597bc0f18ea035d75b4e53c7b1ea84583cc", + "sha256:779245e13b9a6638df14641d029add5dc17edbef6ec915688f3acb9e720a5858", + "sha256:789caea816c6704f63f6241a519bfa347f72fbd67ba28d04636b7c6b7da94b0b", + "sha256:7f8b25fa616d8b846aef64b15c606bb0828dbc35faf90566eb139aa9cff67af2", + "sha256:8cb8ce7c3347fcf9446f201dc30e2d5a3c898d009126010cbd1f443f28b52678", + "sha256:93a3209f6bb2b33e725ed08ee0991b92976dfdcf4e8b38646540674fc7508e13", + "sha256:a3a5ac8b56fe37f3125e5b72b61dcde43283e5370827f5233893d461b7360cd4", + "sha256:a47787a5e3649008a1102d3df55424e86606c9bae6fb77ac59afe06d234605f8", + "sha256:a79165431551042cc9d1d90e6145d5d0d3ab0f2d66326c201d9b0e7f5bf43604", + "sha256:a987f840718078212fdf4504d0fd4c6effe34a7e4740378e59d47696e8dfb477", + "sha256:a9bc127cdc4ecf87a5ea22a2556cab6c7eda2923f84e4f3cc588e8470ce4e42e", + "sha256:bd13b5e9b543532453de08bcdc3cc7cebec6f9883e886fd20a92f26940fd3e7a", + "sha256:c65f96dad14f8528a447414125e1fc8feb2ad5a272b8f68477abbcc1ea7d94b9", + "sha256:d8e3098721b84392ee45af2dd554c947c32cc52f862b6a3ae982dbb90f577f14", + "sha256:e6b79d0adb01aae87e8a44c2b64bc3f3fe59515280e00fb6d57a7267a2583cda", + "sha256:e6b8f1881dac458c34778d0a424ae5769de30544fc678eac51c1c8bb2183e9da", + "sha256:e9b2a6309f14c0497f348d08a065d52f3020656f675819fc405fb63bbcd26562", + "sha256:ecbfbc00bf55888edda9868a4cf927205de8499e7fabe6c050322298382953f2", + "sha256:efd0bf5205240182e0f13bcaea41be4fdf5c22c5129fc7ced4a0282ac86998c9" ], "markers": "python_version >= '3.7'", - "version": "==42.0.5" + "version": "==42.0.7" }, "decorator": { "hashes": [ @@ -1538,11 +1530,11 @@ }, "jinja2": { "hashes": [ - "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa", - "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90" + "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", + "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d" ], "markers": "python_version >= '3.7'", - "version": "==3.1.3" + "version": "==3.1.4" }, "jmespath": { "hashes": [ @@ -1778,11 +1770,11 @@ }, "pygments": { "hashes": [ - "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c", - "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367" + "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", + "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a" ], - "markers": "python_version >= '3.7'", - "version": "==2.17.2" + "markers": "python_version >= '3.8'", + "version": "==2.18.0" }, "pylint": { "hashes": [ @@ -1807,7 +1799,7 @@ "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.9.0.post0" }, "pyyaml": { @@ -1905,7 +1897,7 @@ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.16.0" }, "stevedore": { @@ -1942,11 +1934,11 @@ }, "werkzeug": { "hashes": [ - "sha256:3aac3f5da756f93030740bc235d3e09449efcf65f2f55e3602e1d851b8f48795", - "sha256:e39b645a6ac92822588e7b39a692e7828724ceae0b0d702ef96701f90e70128d" + "sha256:097e5bfda9f0aba8da6b8545146def481d06aa7d3266e7448e2cccf67dd8bd18", + "sha256:fc9645dc43e03e4d630d23143a04a7f947a9a3b5727cd535fdfe155a17cc48c8" ], "markers": "python_version >= '3.8'", - "version": "==3.0.2" + "version": "==3.0.3" }, "wrapt": { "hashes": [ diff --git a/dependabot.yml b/dependabot.yml new file mode 100644 index 000000000..63ef6509d --- /dev/null +++ b/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: daily From 0f2828589aab4bd1cb3ba94a3f00d98adbbf649a Mon Sep 17 00:00:00 2001 From: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> Date: Wed, 8 May 2024 08:53:37 -0600 Subject: [PATCH 03/35] migrates the gcp_storage_hmac_keys_create rule to (#1233) python from sdyaml --- rules/gcp_audit_rules/gcp_storage_hmac_keys_create.py | 8 ++++++++ rules/gcp_audit_rules/gcp_storage_hmac_keys_create.yml | 9 +-------- 2 files changed, 9 insertions(+), 8 deletions(-) create mode 100644 rules/gcp_audit_rules/gcp_storage_hmac_keys_create.py diff --git a/rules/gcp_audit_rules/gcp_storage_hmac_keys_create.py b/rules/gcp_audit_rules/gcp_storage_hmac_keys_create.py new file mode 100644 index 000000000..02455acbf --- /dev/null +++ b/rules/gcp_audit_rules/gcp_storage_hmac_keys_create.py @@ -0,0 +1,8 @@ +def rule(event): + auth_info = event.deep_walk("protoPayload", "authorizationInfo", default=[]) + auth_info = auth_info if isinstance(auth_info, list) else [auth_info] + + for auth in auth_info: + if auth.get("granted", False) and auth.get("permission", "") == "storage.hmacKeys.create": + return True + return False diff --git a/rules/gcp_audit_rules/gcp_storage_hmac_keys_create.yml b/rules/gcp_audit_rules/gcp_storage_hmac_keys_create.yml index 8a1137ad6..20d09f006 100644 --- a/rules/gcp_audit_rules/gcp_storage_hmac_keys_create.yml +++ b/rules/gcp_audit_rules/gcp_storage_hmac_keys_create.yml @@ -12,14 +12,7 @@ Reference: https://rhinosecuritylabs.com/cloud-security/privilege-escalation-goo Reports: MITRE ATT&CK: - TA0004:T1548 -Detection: - - All: - - KeyPath: protoPayload.authorizationInfo[*].granted - Condition: Contains - Value: true - - KeyPath: protoPayload.authorizationInfo[*].permission - Condition: Contains - Value: storage.hmacKeys.create +Filename: gcp_storage_hmac_keys_create.py Tests: - Name: privilege-escalation ExpectedResult: true From 83e6d745ef0c935dbe6e3a09c4161369f3de378b Mon Sep 17 00:00:00 2001 From: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> Date: Wed, 8 May 2024 09:18:06 -0600 Subject: [PATCH 04/35] move scheduled rules to the queries directory (#1234) --- .../abnormally_high_event_volume.py | 0 .../abnormally_high_event_volume.yml | 0 ...tion_from_CrowdStrike_Unmanaged_Device.yml | 63 ++++-- ...rom_CrowdStrike_Unmanaged_Device_Query.yml | 19 ++ ...ogin_From_CrowdStrike_Unmanaged_Device.yml | 183 ++++++++++++++++-- ...rom_CrowdStrike_Unmanaged_Device_Query.yml | 21 ++ ...ation_from_crowdstrike_unmanaged_device.py | 0 ...login_from_crowdstrike_unmanaged_device.py | 0 ...om_crowdstrike_unmanaged_device_query.yml} | 0 ...login_from_crowdstrike_unmanaged_device.py | 0 ...ogin_from_crowdstrike_unmanaged_device.yml | 0 .../dropbox_queries/Dropbox_Many_Deletes.yml | 41 ++-- .../Dropbox_Many_Deletes_Query.yml | 19 ++ .../Dropbox_Many_Downloads.yml | 41 ++-- .../Dropbox_Many_Downloads_Query.yml | 19 ++ .../dropbox_queries}/dropbox_many_deletes.py | 0 .../dropbox_many_downloads.py | 0 .../gsuite_drive_many_docs_deleted.py | 0 .../gsuite_drive_many_docs_deleted.yml | 0 .../gsuite_drive_many_docs_downloaded.py | 0 .../gsuite_drive_many_docs_downloaded.yml | 0 ...tion_from_crowdstrike_unmanaged_device.yml | 46 ----- ...ogin_from_crowdstrike_unmanaged_device.yml | 164 ---------------- rules/dropbox_rules/dropbox_many_deletes.yml | 24 --- .../dropbox_rules/dropbox_many_downloads.yml | 24 --- 25 files changed, 332 insertions(+), 332 deletions(-) rename {rules/aws_cloudtrail_rules => queries/aws_queries}/abnormally_high_event_volume.py (100%) rename {rules/aws_cloudtrail_rules => queries/aws_queries}/abnormally_high_event_volume.yml (100%) create mode 100644 queries/crowdstrike_queries/AWS_Authentication_from_CrowdStrike_Unmanaged_Device_Query.yml create mode 100644 queries/crowdstrike_queries/Okta_Login_From_CrowdStrike_Unmanaged_Device_Query.yml rename {rules/crowdstrike_rules => queries/crowdstrike_queries}/aws_authentication_from_crowdstrike_unmanaged_device.py (100%) rename {rules/crowdstrike_rules => queries/crowdstrike_queries}/okta_login_from_crowdstrike_unmanaged_device.py (100%) rename queries/crowdstrike_queries/{onepass_login_from_crowdstrike_unmanaged_device.yml => onepass_login_from_crowdstrike_unmanaged_device_query.yml} (100%) rename {rules/crowdstrike_rules => queries/crowdstrike_queries}/onepassword_login_from_crowdstrike_unmanaged_device.py (100%) rename {rules/crowdstrike_rules => queries/crowdstrike_queries}/onepassword_login_from_crowdstrike_unmanaged_device.yml (100%) create mode 100644 queries/dropbox_queries/Dropbox_Many_Deletes_Query.yml create mode 100644 queries/dropbox_queries/Dropbox_Many_Downloads_Query.yml rename {rules/dropbox_rules => queries/dropbox_queries}/dropbox_many_deletes.py (100%) rename {rules/dropbox_rules => queries/dropbox_queries}/dropbox_many_downloads.py (100%) rename {rules/gsuite_activityevent_rules => queries/gsuite_queries}/gsuite_drive_many_docs_deleted.py (100%) rename {rules/gsuite_activityevent_rules => queries/gsuite_queries}/gsuite_drive_many_docs_deleted.yml (100%) rename {rules/gsuite_activityevent_rules => queries/gsuite_queries}/gsuite_drive_many_docs_downloaded.py (100%) rename {rules/gsuite_activityevent_rules => queries/gsuite_queries}/gsuite_drive_many_docs_downloaded.yml (100%) delete mode 100644 rules/crowdstrike_rules/aws_authentication_from_crowdstrike_unmanaged_device.yml delete mode 100644 rules/crowdstrike_rules/okta_login_from_crowdstrike_unmanaged_device.yml delete mode 100644 rules/dropbox_rules/dropbox_many_deletes.yml delete mode 100644 rules/dropbox_rules/dropbox_many_downloads.yml diff --git a/rules/aws_cloudtrail_rules/abnormally_high_event_volume.py b/queries/aws_queries/abnormally_high_event_volume.py similarity index 100% rename from rules/aws_cloudtrail_rules/abnormally_high_event_volume.py rename to queries/aws_queries/abnormally_high_event_volume.py diff --git a/rules/aws_cloudtrail_rules/abnormally_high_event_volume.yml b/queries/aws_queries/abnormally_high_event_volume.yml similarity index 100% rename from rules/aws_cloudtrail_rules/abnormally_high_event_volume.yml rename to queries/aws_queries/abnormally_high_event_volume.yml diff --git a/queries/crowdstrike_queries/AWS_Authentication_from_CrowdStrike_Unmanaged_Device.yml b/queries/crowdstrike_queries/AWS_Authentication_from_CrowdStrike_Unmanaged_Device.yml index b7a4b767e..d09d83efc 100644 --- a/queries/crowdstrike_queries/AWS_Authentication_from_CrowdStrike_Unmanaged_Device.yml +++ b/queries/crowdstrike_queries/AWS_Authentication_from_CrowdStrike_Unmanaged_Device.yml @@ -1,19 +1,46 @@ -AnalysisType: scheduled_query -Description: Detects AWS Authentication events with IP Addresses not found in CrowdStrike's AIP List +AnalysisType: scheduled_rule +Description: Detects AWS Logins from IP addresses not found in CrowdStrike's AIP list. May indicate unmanaged device being used, or faulty CrowdStrike Sensor. +DisplayName: "AWS Authentication From CrowdStrike Unmanaged Device" Enabled: false -Query: | - SELECT * - FROM panther_logs.public.aws_cloudtrail - WHERE p_occurs_since('1 hour') - AND eventName IN ('ConsoleLogin', 'SignIn', 'GetSessionToken') - AND eventSource IN ('sts.amazonaws.com', 'signin.amazonaws.com') - AND sourceIPAddress NOT IN - ( - SELECT DISTINCT aip - FROM panther_logs.public.crowdstrike_aidmaster - WHERE p_occurs_since('3 days') - ) -QueryName: "AWS Authentication from CrowdStrike Unmanaged Device" -Schedule: - RateMinutes: 60 - TimeoutMinutes: 3 +Filename: aws_authentication_from_crowdstrike_unmanaged_device.py +Reference: https://www.crowdstrike.com/wp-content/uploads/2023/05/crowdstrike-falcon-device-control-data-sheet.pdf +Severity: Medium +Tests: + - ExpectedResult: true + Log: + additionalEventData: + LoginTo: https://console.aws.amazon.com/console/home + MFAIdentifier: arn:aws:iam::12345:mfa/homer_simpson + MFAUsed: "Yes" + MobileVersion: "No" + awsRegion: us-east-2 + eventCategory: Management + eventID: "12345" + eventName: ConsoleLogin + eventSource: signin.amazonaws.com + eventTime: "2023-01-10 20:10:41" + eventType: AwsConsoleSignIn + eventVersion: "1.08" + managementEvent: true + readOnly: false + recipientAccountId: "12345" + responseElements: + ConsoleLogin: Success + sourceIPAddress: 1.2.3.4 + tlsDetails: + cipherSuite: ECDHE-RSA-AES128-GCM-SHA256 + clientProvidedHostHeader: us-east-2.signin.aws.amazon.com + tlsVersion: TLSv1.2 + userAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 + userIdentity: + accountId: "12345" + arn: arn:aws:iam::12345:user/homer_simpson + principalId: ABCDEF + type: IAMUser + userName: homer_simpson + Name: Test-d8301d +DedupPeriodMinutes: 60 +RuleID: "AWS.Authentication.From.CrowdStrike.Unmanaged.Device" +Threshold: 1 +ScheduledQueries: + - AWS Authentication from CrowdStrike Unmanaged Device diff --git a/queries/crowdstrike_queries/AWS_Authentication_from_CrowdStrike_Unmanaged_Device_Query.yml b/queries/crowdstrike_queries/AWS_Authentication_from_CrowdStrike_Unmanaged_Device_Query.yml new file mode 100644 index 000000000..b7a4b767e --- /dev/null +++ b/queries/crowdstrike_queries/AWS_Authentication_from_CrowdStrike_Unmanaged_Device_Query.yml @@ -0,0 +1,19 @@ +AnalysisType: scheduled_query +Description: Detects AWS Authentication events with IP Addresses not found in CrowdStrike's AIP List +Enabled: false +Query: | + SELECT * + FROM panther_logs.public.aws_cloudtrail + WHERE p_occurs_since('1 hour') + AND eventName IN ('ConsoleLogin', 'SignIn', 'GetSessionToken') + AND eventSource IN ('sts.amazonaws.com', 'signin.amazonaws.com') + AND sourceIPAddress NOT IN + ( + SELECT DISTINCT aip + FROM panther_logs.public.crowdstrike_aidmaster + WHERE p_occurs_since('3 days') + ) +QueryName: "AWS Authentication from CrowdStrike Unmanaged Device" +Schedule: + RateMinutes: 60 + TimeoutMinutes: 3 diff --git a/queries/crowdstrike_queries/Okta_Login_From_CrowdStrike_Unmanaged_Device.yml b/queries/crowdstrike_queries/Okta_Login_From_CrowdStrike_Unmanaged_Device.yml index ab3f40ee2..ed4d0a4e4 100644 --- a/queries/crowdstrike_queries/Okta_Login_From_CrowdStrike_Unmanaged_Device.yml +++ b/queries/crowdstrike_queries/Okta_Login_From_CrowdStrike_Unmanaged_Device.yml @@ -1,21 +1,164 @@ -AnalysisType: scheduled_query -Description: Okta Logins from an IP Address not found in CrowdStrike's AIP List +AnalysisType: scheduled_rule +Description: Detects Okta Logins from IP addresses not found in CrowdStrike''s AIP list. May indicate unmanaged device being used, or faulty CrowdStrike Sensor. +DisplayName: "Okta Login From CrowdStrike Unmanaged Device" Enabled: false -Query: | - SELECT * - FROM panther_logs.public.okta_systemlog - WHERE p_occurs_since('1 hour') - AND eventtype = 'user.session.start' - AND outcome:result = 'SUCCESS' - AND client:device = 'Computer' - AND client:ipAddress LIKE '%.%.%.%' - AND client:ipAddress NOT IN - ( - SELECT DISTINCT aip - FROM panther_logs.public.crowdstrike_aidmaster - WHERE p_occurs_since('3 days') - ) -QueryName: "Okta Login From CrowdStrike Unmanaged Device" -Schedule: - RateMinutes: 60 - TimeoutMinutes: 1 +Filename: okta_login_from_crowdstrike_unmanaged_device.py +Reference: https://www.crowdstrike.com/wp-content/uploads/2023/05/crowdstrike-falcon-device-control-data-sheet.pdf +Severity: Medium +Tests: + - ExpectedResult: true + Log: + actor: + alternateId: homer.simpson@springfield.com + displayName: Homer Simpson + id: AbcdEfghIjklmno + type: User + authenticationcontext: + authenticationStep: 0 + externalSessionId: AbcDefgiH + client: + device: Computer + geographicalContext: + city: San Francisco + country: United States + geolocation: + lat: 30 + lon: -100 + postalCode: "9000" + state: California + ipAddress: 1.2.3.4 + userAgent: + browser: CHROME + os: Mac OS X + rawUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 + zone: "null" + debugcontext: + debugData: + authnRequestId: abcdefg + deviceFingerprint: abcdefg + dtHash: abcdefgc + logOnlySecurityData: '{"risk":{"level":"LOW"},"behaviors":{"New Geo-Location":"NEGATIVE","New Device":"NEGATIVE","New IP":"NEGATIVE","New State":"NEGATIVE","New Country":"NEGATIVE","Velocity":"NEGATIVE","New City":"NEGATIVE"}}' + origin: https://springfield.okta.com + requestId: abcdefg + requestUri: /idp/idx/identify + threatSuspected: "false" + url: /idp/idx/identify? + displaymessage: User login to Okta + eventtype: user.session.start + legacyeventtype: core.user_auth.login_success + outcome: + result: SUCCESS + published: "2023-01-10 17:39:40.526" + request: + ipChain: + - geographicalContext: + city: San Francisco + country: United States + geolocation: + lat: 30 + lon: -100 + postalCode: "90000" + state: California + ip: 1.2.3.4 + version: V4 + securitycontext: + asNumber: 1337 + asOrg: springfield + domain: . + isProxy: false + isp: duff inc + severity: INFO + target: + - alternateId: unknown + displayName: Password + id: abcdefg + type: AuthenticatorEnrollment + - alternateId: Okta Dashboard + displayName: Okta Dashboard + id: abcdefg + type: AppInstance + transaction: + detail: {} + id: abcdefg + type: WEB + uuid: abcdefg + version: "0" + Name: Event + - ExpectedResult: true + Log: + authenticationcontext: + authenticationStep: 0 + externalSessionId: AbcDefgiH + client: + device: Computer + geographicalContext: + city: San Francisco + country: United States + geolocation: + lat: 30 + lon: -100 + postalCode: "9000" + state: California + ipAddress: 1.2.3.4 + userAgent: + browser: CHROME + os: Mac OS X + rawUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 + zone: "null" + debugcontext: + debugData: + authnRequestId: abcdefg + deviceFingerprint: abcdefg + dtHash: abcdefgc + logOnlySecurityData: '{"risk":{"level":"LOW"},"behaviors":{"New Geo-Location":"NEGATIVE","New Device":"NEGATIVE","New IP":"NEGATIVE","New State":"NEGATIVE","New Country":"NEGATIVE","Velocity":"NEGATIVE","New City":"NEGATIVE"}}' + origin: https://springfield.okta.com + requestId: abcdefg + requestUri: /idp/idx/identify + threatSuspected: "false" + url: /idp/idx/identify? + displaymessage: User login to Okta + eventtype: user.session.start + legacyeventtype: core.user_auth.login_success + outcome: + result: SUCCESS + published: "2023-01-10 17:39:40.526" + request: + ipChain: + - geographicalContext: + city: San Francisco + country: United States + geolocation: + lat: 30 + lon: -100 + postalCode: "90000" + state: California + ip: 1.2.3.4 + version: V4 + securitycontext: + asNumber: 1337 + asOrg: springfield + domain: . + isProxy: false + isp: duff inc + severity: INFO + target: + - alternateId: unknown + displayName: Password + id: abcdefg + type: AuthenticatorEnrollment + - alternateId: Okta Dashboard + displayName: Okta Dashboard + id: abcdefg + type: AppInstance + transaction: + detail: {} + id: abcdefg + type: WEB + uuid: abcdefg + version: "0" + Name: No Email +DedupPeriodMinutes: 60 +RuleID: "Okta.Login.From.CrowdStrike.Unmanaged.Device" +Threshold: 1 +ScheduledQueries: + - Okta Login From CrowdStrike Unmanaged Device diff --git a/queries/crowdstrike_queries/Okta_Login_From_CrowdStrike_Unmanaged_Device_Query.yml b/queries/crowdstrike_queries/Okta_Login_From_CrowdStrike_Unmanaged_Device_Query.yml new file mode 100644 index 000000000..ab3f40ee2 --- /dev/null +++ b/queries/crowdstrike_queries/Okta_Login_From_CrowdStrike_Unmanaged_Device_Query.yml @@ -0,0 +1,21 @@ +AnalysisType: scheduled_query +Description: Okta Logins from an IP Address not found in CrowdStrike's AIP List +Enabled: false +Query: | + SELECT * + FROM panther_logs.public.okta_systemlog + WHERE p_occurs_since('1 hour') + AND eventtype = 'user.session.start' + AND outcome:result = 'SUCCESS' + AND client:device = 'Computer' + AND client:ipAddress LIKE '%.%.%.%' + AND client:ipAddress NOT IN + ( + SELECT DISTINCT aip + FROM panther_logs.public.crowdstrike_aidmaster + WHERE p_occurs_since('3 days') + ) +QueryName: "Okta Login From CrowdStrike Unmanaged Device" +Schedule: + RateMinutes: 60 + TimeoutMinutes: 1 diff --git a/rules/crowdstrike_rules/aws_authentication_from_crowdstrike_unmanaged_device.py b/queries/crowdstrike_queries/aws_authentication_from_crowdstrike_unmanaged_device.py similarity index 100% rename from rules/crowdstrike_rules/aws_authentication_from_crowdstrike_unmanaged_device.py rename to queries/crowdstrike_queries/aws_authentication_from_crowdstrike_unmanaged_device.py diff --git a/rules/crowdstrike_rules/okta_login_from_crowdstrike_unmanaged_device.py b/queries/crowdstrike_queries/okta_login_from_crowdstrike_unmanaged_device.py similarity index 100% rename from rules/crowdstrike_rules/okta_login_from_crowdstrike_unmanaged_device.py rename to queries/crowdstrike_queries/okta_login_from_crowdstrike_unmanaged_device.py diff --git a/queries/crowdstrike_queries/onepass_login_from_crowdstrike_unmanaged_device.yml b/queries/crowdstrike_queries/onepass_login_from_crowdstrike_unmanaged_device_query.yml similarity index 100% rename from queries/crowdstrike_queries/onepass_login_from_crowdstrike_unmanaged_device.yml rename to queries/crowdstrike_queries/onepass_login_from_crowdstrike_unmanaged_device_query.yml diff --git a/rules/crowdstrike_rules/onepassword_login_from_crowdstrike_unmanaged_device.py b/queries/crowdstrike_queries/onepassword_login_from_crowdstrike_unmanaged_device.py similarity index 100% rename from rules/crowdstrike_rules/onepassword_login_from_crowdstrike_unmanaged_device.py rename to queries/crowdstrike_queries/onepassword_login_from_crowdstrike_unmanaged_device.py diff --git a/rules/crowdstrike_rules/onepassword_login_from_crowdstrike_unmanaged_device.yml b/queries/crowdstrike_queries/onepassword_login_from_crowdstrike_unmanaged_device.yml similarity index 100% rename from rules/crowdstrike_rules/onepassword_login_from_crowdstrike_unmanaged_device.yml rename to queries/crowdstrike_queries/onepassword_login_from_crowdstrike_unmanaged_device.yml diff --git a/queries/dropbox_queries/Dropbox_Many_Deletes.yml b/queries/dropbox_queries/Dropbox_Many_Deletes.yml index 523e1381a..502aba3b6 100644 --- a/queries/dropbox_queries/Dropbox_Many_Deletes.yml +++ b/queries/dropbox_queries/Dropbox_Many_Deletes.yml @@ -1,19 +1,24 @@ -AnalysisType: scheduled_query -Description: Dropbox Many Deletes +AnalysisType: scheduled_rule +Description: Detects when a dropbox user deletes many documents. +DisplayName: "Dropbox Many Deletes" Enabled: false -Query: |- - SELECT - actor:user:email AS user, - ARRAY_AGG( DISTINCT assets[0]:path:contextual) AS deleted_files, - ARRAY_SIZE(deleted_files) as delete_count, - TIME_SLICE(p_event_time, 60, 'minute') as t_s - FROM panther_logs.public.dropbox_teamevent - WHERE p_occurs_since('1 day') - AND event_type:_tag = 'file_delete' - GROUP BY actor:user:email, t_s - HAVING delete_count > 2 - ORDER BY delete_count DESC -QueryName: "Dropbox Many Deletes" -Schedule: - RateMinutes: 1440 - TimeoutMinutes: 3 +Filename: dropbox_many_deletes.py +Reference: https://help.dropbox.com/delete-restore/delete-files +Severity: Medium +Tests: + - ExpectedResult: true + Log: + deleted_files: + - /test/test2.txt + - /test/test3.txt + - /test/test5.txt + - /test/test4.txt + delete_count: 4 + t_s: "2023-04-19 19:00:00" + user: alice.bob@company.com + Name: Test-8f5ece +DedupPeriodMinutes: 60 +RuleID: "Dropbox.Many.Deletes" +Threshold: 1 +ScheduledQueries: + - Dropbox Many Deletes diff --git a/queries/dropbox_queries/Dropbox_Many_Deletes_Query.yml b/queries/dropbox_queries/Dropbox_Many_Deletes_Query.yml new file mode 100644 index 000000000..523e1381a --- /dev/null +++ b/queries/dropbox_queries/Dropbox_Many_Deletes_Query.yml @@ -0,0 +1,19 @@ +AnalysisType: scheduled_query +Description: Dropbox Many Deletes +Enabled: false +Query: |- + SELECT + actor:user:email AS user, + ARRAY_AGG( DISTINCT assets[0]:path:contextual) AS deleted_files, + ARRAY_SIZE(deleted_files) as delete_count, + TIME_SLICE(p_event_time, 60, 'minute') as t_s + FROM panther_logs.public.dropbox_teamevent + WHERE p_occurs_since('1 day') + AND event_type:_tag = 'file_delete' + GROUP BY actor:user:email, t_s + HAVING delete_count > 2 + ORDER BY delete_count DESC +QueryName: "Dropbox Many Deletes" +Schedule: + RateMinutes: 1440 + TimeoutMinutes: 3 diff --git a/queries/dropbox_queries/Dropbox_Many_Downloads.yml b/queries/dropbox_queries/Dropbox_Many_Downloads.yml index dcce47b4f..92d85e326 100644 --- a/queries/dropbox_queries/Dropbox_Many_Downloads.yml +++ b/queries/dropbox_queries/Dropbox_Many_Downloads.yml @@ -1,19 +1,24 @@ -AnalysisType: scheduled_query -Description: Dropbox Many Downloads +AnalysisType: scheduled_rule +Description: Detects when a dropbox user downloads many documents. +DisplayName: "Dropbox Many Downloads" Enabled: false -Query: |- - SELECT - actor:user:email AS user, - ARRAY_AGG( DISTINCT assets[0]:path:contextual) AS downloaded_files, - ARRAY_SIZE(downloaded_files) as download_count, - TIME_SLICE(p_event_time, 60, 'minute') as t_s - FROM panther_logs.public.dropbox_teamevent - WHERE p_occurs_since('1 day') - AND event_type:_tag = 'file_download' - GROUP BY actor:user:email, t_s - HAVING download_count > 10 - ORDER BY download_count DESC -QueryName: "Dropbox Many Downloads" -Schedule: - RateMinutes: 1440 - TimeoutMinutes: 3 +Filename: dropbox_many_downloads.py +Reference: https://learn.dropbox.com/video-library/upload-and-download-files +Severity: Medium +Tests: + - ExpectedResult: true + Log: + downloaded_files: + - /test/test2.txt + - /test/test3.txt + - /test/test5.txt + - /test/test4.txt + download_count: 4 + t_s: "2023-04-19 19:00:00" + user: alice.bob@company.com + Name: Test-8f5ece +DedupPeriodMinutes: 60 +RuleID: "Dropbox.Many.Downloads" +Threshold: 1 +ScheduledQueries: + - Dropbox Many Downloads diff --git a/queries/dropbox_queries/Dropbox_Many_Downloads_Query.yml b/queries/dropbox_queries/Dropbox_Many_Downloads_Query.yml new file mode 100644 index 000000000..dcce47b4f --- /dev/null +++ b/queries/dropbox_queries/Dropbox_Many_Downloads_Query.yml @@ -0,0 +1,19 @@ +AnalysisType: scheduled_query +Description: Dropbox Many Downloads +Enabled: false +Query: |- + SELECT + actor:user:email AS user, + ARRAY_AGG( DISTINCT assets[0]:path:contextual) AS downloaded_files, + ARRAY_SIZE(downloaded_files) as download_count, + TIME_SLICE(p_event_time, 60, 'minute') as t_s + FROM panther_logs.public.dropbox_teamevent + WHERE p_occurs_since('1 day') + AND event_type:_tag = 'file_download' + GROUP BY actor:user:email, t_s + HAVING download_count > 10 + ORDER BY download_count DESC +QueryName: "Dropbox Many Downloads" +Schedule: + RateMinutes: 1440 + TimeoutMinutes: 3 diff --git a/rules/dropbox_rules/dropbox_many_deletes.py b/queries/dropbox_queries/dropbox_many_deletes.py similarity index 100% rename from rules/dropbox_rules/dropbox_many_deletes.py rename to queries/dropbox_queries/dropbox_many_deletes.py diff --git a/rules/dropbox_rules/dropbox_many_downloads.py b/queries/dropbox_queries/dropbox_many_downloads.py similarity index 100% rename from rules/dropbox_rules/dropbox_many_downloads.py rename to queries/dropbox_queries/dropbox_many_downloads.py diff --git a/rules/gsuite_activityevent_rules/gsuite_drive_many_docs_deleted.py b/queries/gsuite_queries/gsuite_drive_many_docs_deleted.py similarity index 100% rename from rules/gsuite_activityevent_rules/gsuite_drive_many_docs_deleted.py rename to queries/gsuite_queries/gsuite_drive_many_docs_deleted.py diff --git a/rules/gsuite_activityevent_rules/gsuite_drive_many_docs_deleted.yml b/queries/gsuite_queries/gsuite_drive_many_docs_deleted.yml similarity index 100% rename from rules/gsuite_activityevent_rules/gsuite_drive_many_docs_deleted.yml rename to queries/gsuite_queries/gsuite_drive_many_docs_deleted.yml diff --git a/rules/gsuite_activityevent_rules/gsuite_drive_many_docs_downloaded.py b/queries/gsuite_queries/gsuite_drive_many_docs_downloaded.py similarity index 100% rename from rules/gsuite_activityevent_rules/gsuite_drive_many_docs_downloaded.py rename to queries/gsuite_queries/gsuite_drive_many_docs_downloaded.py diff --git a/rules/gsuite_activityevent_rules/gsuite_drive_many_docs_downloaded.yml b/queries/gsuite_queries/gsuite_drive_many_docs_downloaded.yml similarity index 100% rename from rules/gsuite_activityevent_rules/gsuite_drive_many_docs_downloaded.yml rename to queries/gsuite_queries/gsuite_drive_many_docs_downloaded.yml diff --git a/rules/crowdstrike_rules/aws_authentication_from_crowdstrike_unmanaged_device.yml b/rules/crowdstrike_rules/aws_authentication_from_crowdstrike_unmanaged_device.yml deleted file mode 100644 index d09d83efc..000000000 --- a/rules/crowdstrike_rules/aws_authentication_from_crowdstrike_unmanaged_device.yml +++ /dev/null @@ -1,46 +0,0 @@ -AnalysisType: scheduled_rule -Description: Detects AWS Logins from IP addresses not found in CrowdStrike's AIP list. May indicate unmanaged device being used, or faulty CrowdStrike Sensor. -DisplayName: "AWS Authentication From CrowdStrike Unmanaged Device" -Enabled: false -Filename: aws_authentication_from_crowdstrike_unmanaged_device.py -Reference: https://www.crowdstrike.com/wp-content/uploads/2023/05/crowdstrike-falcon-device-control-data-sheet.pdf -Severity: Medium -Tests: - - ExpectedResult: true - Log: - additionalEventData: - LoginTo: https://console.aws.amazon.com/console/home - MFAIdentifier: arn:aws:iam::12345:mfa/homer_simpson - MFAUsed: "Yes" - MobileVersion: "No" - awsRegion: us-east-2 - eventCategory: Management - eventID: "12345" - eventName: ConsoleLogin - eventSource: signin.amazonaws.com - eventTime: "2023-01-10 20:10:41" - eventType: AwsConsoleSignIn - eventVersion: "1.08" - managementEvent: true - readOnly: false - recipientAccountId: "12345" - responseElements: - ConsoleLogin: Success - sourceIPAddress: 1.2.3.4 - tlsDetails: - cipherSuite: ECDHE-RSA-AES128-GCM-SHA256 - clientProvidedHostHeader: us-east-2.signin.aws.amazon.com - tlsVersion: TLSv1.2 - userAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - userIdentity: - accountId: "12345" - arn: arn:aws:iam::12345:user/homer_simpson - principalId: ABCDEF - type: IAMUser - userName: homer_simpson - Name: Test-d8301d -DedupPeriodMinutes: 60 -RuleID: "AWS.Authentication.From.CrowdStrike.Unmanaged.Device" -Threshold: 1 -ScheduledQueries: - - AWS Authentication from CrowdStrike Unmanaged Device diff --git a/rules/crowdstrike_rules/okta_login_from_crowdstrike_unmanaged_device.yml b/rules/crowdstrike_rules/okta_login_from_crowdstrike_unmanaged_device.yml deleted file mode 100644 index ed4d0a4e4..000000000 --- a/rules/crowdstrike_rules/okta_login_from_crowdstrike_unmanaged_device.yml +++ /dev/null @@ -1,164 +0,0 @@ -AnalysisType: scheduled_rule -Description: Detects Okta Logins from IP addresses not found in CrowdStrike''s AIP list. May indicate unmanaged device being used, or faulty CrowdStrike Sensor. -DisplayName: "Okta Login From CrowdStrike Unmanaged Device" -Enabled: false -Filename: okta_login_from_crowdstrike_unmanaged_device.py -Reference: https://www.crowdstrike.com/wp-content/uploads/2023/05/crowdstrike-falcon-device-control-data-sheet.pdf -Severity: Medium -Tests: - - ExpectedResult: true - Log: - actor: - alternateId: homer.simpson@springfield.com - displayName: Homer Simpson - id: AbcdEfghIjklmno - type: User - authenticationcontext: - authenticationStep: 0 - externalSessionId: AbcDefgiH - client: - device: Computer - geographicalContext: - city: San Francisco - country: United States - geolocation: - lat: 30 - lon: -100 - postalCode: "9000" - state: California - ipAddress: 1.2.3.4 - userAgent: - browser: CHROME - os: Mac OS X - rawUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - zone: "null" - debugcontext: - debugData: - authnRequestId: abcdefg - deviceFingerprint: abcdefg - dtHash: abcdefgc - logOnlySecurityData: '{"risk":{"level":"LOW"},"behaviors":{"New Geo-Location":"NEGATIVE","New Device":"NEGATIVE","New IP":"NEGATIVE","New State":"NEGATIVE","New Country":"NEGATIVE","Velocity":"NEGATIVE","New City":"NEGATIVE"}}' - origin: https://springfield.okta.com - requestId: abcdefg - requestUri: /idp/idx/identify - threatSuspected: "false" - url: /idp/idx/identify? - displaymessage: User login to Okta - eventtype: user.session.start - legacyeventtype: core.user_auth.login_success - outcome: - result: SUCCESS - published: "2023-01-10 17:39:40.526" - request: - ipChain: - - geographicalContext: - city: San Francisco - country: United States - geolocation: - lat: 30 - lon: -100 - postalCode: "90000" - state: California - ip: 1.2.3.4 - version: V4 - securitycontext: - asNumber: 1337 - asOrg: springfield - domain: . - isProxy: false - isp: duff inc - severity: INFO - target: - - alternateId: unknown - displayName: Password - id: abcdefg - type: AuthenticatorEnrollment - - alternateId: Okta Dashboard - displayName: Okta Dashboard - id: abcdefg - type: AppInstance - transaction: - detail: {} - id: abcdefg - type: WEB - uuid: abcdefg - version: "0" - Name: Event - - ExpectedResult: true - Log: - authenticationcontext: - authenticationStep: 0 - externalSessionId: AbcDefgiH - client: - device: Computer - geographicalContext: - city: San Francisco - country: United States - geolocation: - lat: 30 - lon: -100 - postalCode: "9000" - state: California - ipAddress: 1.2.3.4 - userAgent: - browser: CHROME - os: Mac OS X - rawUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 - zone: "null" - debugcontext: - debugData: - authnRequestId: abcdefg - deviceFingerprint: abcdefg - dtHash: abcdefgc - logOnlySecurityData: '{"risk":{"level":"LOW"},"behaviors":{"New Geo-Location":"NEGATIVE","New Device":"NEGATIVE","New IP":"NEGATIVE","New State":"NEGATIVE","New Country":"NEGATIVE","Velocity":"NEGATIVE","New City":"NEGATIVE"}}' - origin: https://springfield.okta.com - requestId: abcdefg - requestUri: /idp/idx/identify - threatSuspected: "false" - url: /idp/idx/identify? - displaymessage: User login to Okta - eventtype: user.session.start - legacyeventtype: core.user_auth.login_success - outcome: - result: SUCCESS - published: "2023-01-10 17:39:40.526" - request: - ipChain: - - geographicalContext: - city: San Francisco - country: United States - geolocation: - lat: 30 - lon: -100 - postalCode: "90000" - state: California - ip: 1.2.3.4 - version: V4 - securitycontext: - asNumber: 1337 - asOrg: springfield - domain: . - isProxy: false - isp: duff inc - severity: INFO - target: - - alternateId: unknown - displayName: Password - id: abcdefg - type: AuthenticatorEnrollment - - alternateId: Okta Dashboard - displayName: Okta Dashboard - id: abcdefg - type: AppInstance - transaction: - detail: {} - id: abcdefg - type: WEB - uuid: abcdefg - version: "0" - Name: No Email -DedupPeriodMinutes: 60 -RuleID: "Okta.Login.From.CrowdStrike.Unmanaged.Device" -Threshold: 1 -ScheduledQueries: - - Okta Login From CrowdStrike Unmanaged Device diff --git a/rules/dropbox_rules/dropbox_many_deletes.yml b/rules/dropbox_rules/dropbox_many_deletes.yml deleted file mode 100644 index 502aba3b6..000000000 --- a/rules/dropbox_rules/dropbox_many_deletes.yml +++ /dev/null @@ -1,24 +0,0 @@ -AnalysisType: scheduled_rule -Description: Detects when a dropbox user deletes many documents. -DisplayName: "Dropbox Many Deletes" -Enabled: false -Filename: dropbox_many_deletes.py -Reference: https://help.dropbox.com/delete-restore/delete-files -Severity: Medium -Tests: - - ExpectedResult: true - Log: - deleted_files: - - /test/test2.txt - - /test/test3.txt - - /test/test5.txt - - /test/test4.txt - delete_count: 4 - t_s: "2023-04-19 19:00:00" - user: alice.bob@company.com - Name: Test-8f5ece -DedupPeriodMinutes: 60 -RuleID: "Dropbox.Many.Deletes" -Threshold: 1 -ScheduledQueries: - - Dropbox Many Deletes diff --git a/rules/dropbox_rules/dropbox_many_downloads.yml b/rules/dropbox_rules/dropbox_many_downloads.yml deleted file mode 100644 index 92d85e326..000000000 --- a/rules/dropbox_rules/dropbox_many_downloads.yml +++ /dev/null @@ -1,24 +0,0 @@ -AnalysisType: scheduled_rule -Description: Detects when a dropbox user downloads many documents. -DisplayName: "Dropbox Many Downloads" -Enabled: false -Filename: dropbox_many_downloads.py -Reference: https://learn.dropbox.com/video-library/upload-and-download-files -Severity: Medium -Tests: - - ExpectedResult: true - Log: - downloaded_files: - - /test/test2.txt - - /test/test3.txt - - /test/test5.txt - - /test/test4.txt - download_count: 4 - t_s: "2023-04-19 19:00:00" - user: alice.bob@company.com - Name: Test-8f5ece -DedupPeriodMinutes: 60 -RuleID: "Dropbox.Many.Downloads" -Threshold: 1 -ScheduledQueries: - - Dropbox Many Downloads From 575cf47aa052f75129aaeaecec9a224d5e94378e Mon Sep 17 00:00:00 2001 From: kjihso <133820431+kjihso@users.noreply.github.com> Date: Mon, 13 May 2024 08:11:59 -0700 Subject: [PATCH 05/35] consistency nit fixes (#1235) * consistency nit fixes * - somethings -> some things --- .github/workflows/check-packs.yml | 8 ++++---- Dockerfile | 2 +- Makefile | 2 +- global_helpers/global_filter_auth0.yml | 4 ++-- global_helpers/global_filter_azuresignin.yml | 4 ++-- global_helpers/global_filter_cloudflare.yml | 4 ++-- global_helpers/global_filter_github.yml | 4 ++-- global_helpers/global_filter_notion.yml | 4 ++-- global_helpers/global_filter_snyk.yml | 4 ++-- global_helpers/global_filter_tailscale.yml | 4 ++-- global_helpers/global_filter_tines.yml | 4 ++-- .../cloudtrail_password_spraying_query.yml | 4 ++-- .../ec2_crud_activity_by_role_query.yml | 14 +++++++------- .../ec2_crud_activity_by_useragent_query.yml | 14 +++++++------- .../aws_queries/vpc_dns_tunneling_query.yml | 2 +- .../CrowdStrike_Large_Zip_Creation.yml | 16 ++++++++-------- ...CrowdStrike_Large_Zip_Creation_FDREvent.yml | 14 +++++++------- .../MacOS_Browser_Credential_Access.yml | 6 +++--- ...acOS_Browser_Credential_Access_FDREvent.yml | 4 ++-- ...from_crowdstrike_unmanaged_device_query.yml | 4 ++-- ...etes_cron_job_created_or_modified_query.yml | 2 +- .../kubernetes_ioc_activity.yml | 2 +- .../kubernetes_ioc_activity_query.yml | 4 ++-- ...ate_or_modify_host_path_vol_mount_query.yml | 2 +- ...s_service_type_node_port_deployed_query.yml | 8 ++++---- .../okta_queries/okta_admin_access_granted.yml | 18 +++++++++--------- .../okta_mfa_password_reset_audit.yml | 4 ++-- queries/okta_queries/okta_session_id_audit.yml | 4 ++-- queries/okta_queries/okta_support_access.yml | 16 ++++++++-------- ...m_crowdstrike_unmanaged_device_FDREvent.yml | 4 ++-- .../snowflake_account_admin_assigned_query.yml | 2 +- ...failed_logins_followed_by_success_query.yml | 4 ++-- .../aws_cloudtrail_rules/aws_macie_evasion.yml | 2 +- ...aws_modify_cloud_compute_infrastructure.yml | 2 +- .../aws_rds_manual_snapshot_created.yml | 2 +- .../aws_snapshot_backup_exfiltration.yml | 2 +- .../system_namespace_public_ip.yml | 4 ++-- .../azure_failed_signins.yml | 2 +- .../azure_risklevel_passthrough.yml | 6 +++--- .../gcp_iam_org_folder_changes.yml | 6 +++--- rules/gcp_k8s_rules/gcp_k8s_ioc_activity.yml | 2 +- ...od_create_or_modify_host_path_vol_mount.yml | 6 +++--- .../gcp_k8s_privileged_pod_created.yml | 8 ++++---- ...gcp_k8s_service_type_node_port_deployed.yml | 8 ++++---- rules/github_rules/github_action_failed.yml | 2 +- .../okta_app_refresh_access_token_reuse.yml | 2 +- rules/okta_rules/okta_idp_create_modify.yml | 8 ++++---- rules/okta_rules/okta_idp_signin.yml | 12 ++++++------ .../okta_org2org_creation_modification.yml | 2 +- rules/snyk_rules/snyk_ou_change.yml | 2 +- rules/snyk_rules/snyk_svcacct_change.yml | 2 +- rules/snyk_rules/snyk_system_sso.yml | 2 +- .../standard_rules/impossible_travel_login.yml | 2 +- ...operation_user_granted_admin_deprecated.yml | 2 +- 54 files changed, 139 insertions(+), 139 deletions(-) diff --git a/.github/workflows/check-packs.yml b/.github/workflows/check-packs.yml index 31a0495ac..c2374d928 100644 --- a/.github/workflows/check-packs.yml +++ b/.github/workflows/check-packs.yml @@ -33,8 +33,8 @@ jobs: with: mode: upsert message: | - :scream: - looks like somethings could be wrong with the packs + :scream: + looks like some things could be wrong with the packs ```diff ${{ steps.check-packs.outputs.errors }} comment_tag: check-packs @@ -44,8 +44,8 @@ jobs: with: mode: delete message: | - :scream: - looks like somethings could be wrong with the packs + :scream: + looks like some things could be wrong with the packs ```diff ${{ steps.check-packs.outputs.errors }} comment_tag: check-packs diff --git a/Dockerfile b/Dockerfile index 06441ce26..08073e15d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -56,5 +56,5 @@ RUN npm install ENV PATH="/home/panther-analysis/node_modules/.bin:$PATH" # Remove pipfile so it doesn't interfere with local files after install -RUN rm Pipfile +RUN rm Pipfile RUN rm Pipfile.lock diff --git a/Makefile b/Makefile index 5e557d304..a4bbcb8e5 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ vscode-config: install-pipenv install @echo "Creating new vscode config files" cp .vscode/example_launch.json .vscode/launch.json sed -e 's#XXX_pipenv_py_output_XXX#$(shell pipenv --py)#' .vscode/example_settings.json > .vscode/settings.json - which code && code . + which code && code . ci: pipenv run $(MAKE) lint test diff --git a/global_helpers/global_filter_auth0.yml b/global_helpers/global_filter_auth0.yml index 9528ce7b6..4be72f748 100644 --- a/global_helpers/global_filter_auth0.yml +++ b/global_helpers/global_filter_auth0.yml @@ -6,6 +6,6 @@ Description: > This filter defines if events should be included or excluded. - You can change the definition of this filter to work in your own environment. - Panther will not change the filter definition, and should not create + You can change the definition of this filter to work in your own environment. + Panther will not change the filter definition, and should not create merge conflicts. diff --git a/global_helpers/global_filter_azuresignin.yml b/global_helpers/global_filter_azuresignin.yml index b1a92e5c8..352d40d16 100644 --- a/global_helpers/global_filter_azuresignin.yml +++ b/global_helpers/global_filter_azuresignin.yml @@ -6,6 +6,6 @@ Description: > This filter defines if events should be included or excluded. - You can change the definition of this filter to work in your own environment. - Panther will not change the filter definition, and should not create + You can change the definition of this filter to work in your own environment. + Panther will not change the filter definition, and should not create merge conflicts. diff --git a/global_helpers/global_filter_cloudflare.yml b/global_helpers/global_filter_cloudflare.yml index 464100e30..a0d8d855d 100644 --- a/global_helpers/global_filter_cloudflare.yml +++ b/global_helpers/global_filter_cloudflare.yml @@ -6,6 +6,6 @@ Description: > This filter defines if events should be included or excluded. - You can change the definition of this filter to work in your own environment. - Panther will not change the filter definition, and should not create + You can change the definition of this filter to work in your own environment. + Panther will not change the filter definition, and should not create merge conflicts. diff --git a/global_helpers/global_filter_github.yml b/global_helpers/global_filter_github.yml index 5d548f3b5..b60b6f65c 100644 --- a/global_helpers/global_filter_github.yml +++ b/global_helpers/global_filter_github.yml @@ -6,6 +6,6 @@ Description: > This filter defines if events should be included or excluded. - You can change the definition of this filter to work in your own environment. - Panther will not change the filter definition, and should not create + You can change the definition of this filter to work in your own environment. + Panther will not change the filter definition, and should not create merge conflicts. diff --git a/global_helpers/global_filter_notion.yml b/global_helpers/global_filter_notion.yml index 0771c07a0..9acbe8a5a 100644 --- a/global_helpers/global_filter_notion.yml +++ b/global_helpers/global_filter_notion.yml @@ -6,6 +6,6 @@ Description: > This filter defines if events should be included or excluded. - You can change the definition of this filter to work in your own environment. - Panther will not change the filter definition, and should not create + You can change the definition of this filter to work in your own environment. + Panther will not change the filter definition, and should not create merge conflicts. diff --git a/global_helpers/global_filter_snyk.yml b/global_helpers/global_filter_snyk.yml index 523cb4e63..3ec9216a2 100644 --- a/global_helpers/global_filter_snyk.yml +++ b/global_helpers/global_filter_snyk.yml @@ -6,6 +6,6 @@ Description: > This filter defines if events should be included or excluded. - You can change the definition of this filter to work in your own environment. - Panther will not change the filter definition, and should not create + You can change the definition of this filter to work in your own environment. + Panther will not change the filter definition, and should not create merge conflicts. diff --git a/global_helpers/global_filter_tailscale.yml b/global_helpers/global_filter_tailscale.yml index 64cf3f8ba..f0d5f1788 100644 --- a/global_helpers/global_filter_tailscale.yml +++ b/global_helpers/global_filter_tailscale.yml @@ -6,6 +6,6 @@ Description: > This filter defines if events should be included or excluded. - You can change the definition of this filter to work in your own environment. - Panther will not change the filter definition, and should not create + You can change the definition of this filter to work in your own environment. + Panther will not change the filter definition, and should not create merge conflicts. diff --git a/global_helpers/global_filter_tines.yml b/global_helpers/global_filter_tines.yml index 8d313b15d..8b3d16e4c 100644 --- a/global_helpers/global_filter_tines.yml +++ b/global_helpers/global_filter_tines.yml @@ -6,6 +6,6 @@ Description: > This filter defines if events should be included or excluded. - You can change the definition of this filter to work in your own environment. - Panther will not change the filter definition, and should not create + You can change the definition of this filter to work in your own environment. + Panther will not change the filter definition, and should not create merge conflicts. diff --git a/queries/aws_queries/cloudtrail_password_spraying_query.yml b/queries/aws_queries/cloudtrail_password_spraying_query.yml index 4a27f6ab0..6f3aa68e3 100644 --- a/queries/aws_queries/cloudtrail_password_spraying_query.yml +++ b/queries/aws_queries/cloudtrail_password_spraying_query.yml @@ -4,7 +4,7 @@ Enabled: false Description: > Detect password spraying in cloudtrail logs AthenaQuery: > - /* athena query not supported */ + /* athena query not supported */ SELECT count(1) SnowflakeQuery: > SELECT @@ -18,7 +18,7 @@ SnowflakeQuery: > FROM panther_logs.public.aws_cloudtrail WHERE - p_occurs_since(3600) + p_occurs_since(3600) AND eventtype = 'AwsConsoleSignIn' AND diff --git a/queries/aws_queries/ec2_crud_activity_by_role_query.yml b/queries/aws_queries/ec2_crud_activity_by_role_query.yml index 9d25ce457..2483fe0f0 100644 --- a/queries/aws_queries/ec2_crud_activity_by_role_query.yml +++ b/queries/aws_queries/ec2_crud_activity_by_role_query.yml @@ -4,18 +4,18 @@ Enabled: false Description: > This query searches for CRUD activity in EC2 by role arn. Activities from a role outside typical deployment processes may warrant investigation. AthenaQuery: > - /* athena query not supported */ + /* athena query not supported */ SELECT count(1) SnowflakeQuery: > - SELECT + SELECT count(*) as num_logs, - recipientAccountId, - userIdentity:arn as arn, - eventName, + recipientAccountId, + userIdentity:arn as arn, + eventName, eventSource FROM panther_logs.public.aws_cloudtrail - WHERE - eventSource = 'ec2.amazonaws.com' + WHERE + eventSource = 'ec2.amazonaws.com' AND eventName LIKE '%Image%' AND eventName NOT LIKE '%Describe%' AND p_occurs_since('3 day') diff --git a/queries/aws_queries/ec2_crud_activity_by_useragent_query.yml b/queries/aws_queries/ec2_crud_activity_by_useragent_query.yml index dc5f2b5a8..27e01669e 100644 --- a/queries/aws_queries/ec2_crud_activity_by_useragent_query.yml +++ b/queries/aws_queries/ec2_crud_activity_by_useragent_query.yml @@ -4,18 +4,18 @@ Enabled: false Description: > This query searches for CRUD activity in EC2 by userAgent. A low count or previously unseen useragent may indicate that the action was not performed by an automated process. AthenaQuery: > - /* athena query not supported */ + /* athena query not supported */ SELECT count(1) SnowflakeQuery: > - SELECT + SELECT count(*) as num_logs, - recipientAccountId, - userAgent, - eventName, + recipientAccountId, + userAgent, + eventName, eventSource FROM panther_logs.public.aws_cloudtrail - WHERE - eventSource = 'ec2.amazonaws.com' + WHERE + eventSource = 'ec2.amazonaws.com' AND eventName LIKE '%Image%' AND eventName NOT LIKE '%Describe%' AND p_occurs_since('3 day') diff --git a/queries/aws_queries/vpc_dns_tunneling_query.yml b/queries/aws_queries/vpc_dns_tunneling_query.yml index ccbb7b44b..a709f179c 100644 --- a/queries/aws_queries/vpc_dns_tunneling_query.yml +++ b/queries/aws_queries/vpc_dns_tunneling_query.yml @@ -4,7 +4,7 @@ Enabled: false Description: > Detect activity similar to DNS tunneling traffic in AWS VPC Logs AthenaQuery: > - /* athena query not supported */ + /* athena query not supported */ SELECT count(1) SnowflakeQuery: > SELECT diff --git a/queries/crowdstrike_queries/CrowdStrike_Large_Zip_Creation.yml b/queries/crowdstrike_queries/CrowdStrike_Large_Zip_Creation.yml index b0ca7bca4..95b6d4e97 100644 --- a/queries/crowdstrike_queries/CrowdStrike_Large_Zip_Creation.yml +++ b/queries/crowdstrike_queries/CrowdStrike_Large_Zip_Creation.yml @@ -5,9 +5,9 @@ Query: | select ppr.commandline as parent_commandline, zip_proc.* - from + from ( - select + select zips.*, pr2.targetprocessid as process_targetpid, pr2.parentprocessid as process_parentpid, @@ -18,7 +18,7 @@ Query: | * from panther_logs.public.crowdstrike_unknown - where + where event_simpleName IN ( 'GzipFileWritten', 'SevenZipFileWritten', @@ -30,12 +30,12 @@ Query: | ) zips left join panther_logs.public.crowdstrike_processrollup2 pr2 on zips.ContextProcessId = pr2.targetprocessid - - where + + where pr2.commandline like any( '%zip%' ) - + and not ( pr2.commandline like any ( '%curl%', @@ -47,9 +47,9 @@ Query: | ) zip_proc LEFT JOIN panther_logs.public.crowdstrike_processrollup2 ppr on zip_proc.process_parentpid = ppr.targetprocessid - where + where ( - (parent_commandline is null) or + (parent_commandline is null) or not (parent_commandline like any ( '%homebrew%', '%Homebrew%', diff --git a/queries/crowdstrike_queries/CrowdStrike_Large_Zip_Creation_FDREvent.yml b/queries/crowdstrike_queries/CrowdStrike_Large_Zip_Creation_FDREvent.yml index c900e952b..7a75e104c 100644 --- a/queries/crowdstrike_queries/CrowdStrike_Large_Zip_Creation_FDREvent.yml +++ b/queries/crowdstrike_queries/CrowdStrike_Large_Zip_Creation_FDREvent.yml @@ -8,9 +8,9 @@ Query: | select ppr.event:CommandLine as parent_commandline, zip_proc.* - from + from ( - select + select zips.*, pr2.event:TargetProcessId as process_targetpid, pr2.event:ParentProcessId as process_parentpid, @@ -21,7 +21,7 @@ Query: | * from panther_logs.public.crowdstrike_fdrevent - where + where event_simpleName IN ( 'GzipFileWritten', 'SevenZipFileWritten', @@ -33,12 +33,12 @@ Query: | ) zips left join panther_logs.public.crowdstrike_fdrevent pr2 on zips.ContextProcessId = pr2.TargetProcessId_decimal and pr2.fdr_event_type = 'ProcessRollup2' - - where + + where pr2.event:CommandLine like any( '%zip%' ) - + and not ( pr2.event:CommandLine like any ( '%curl%', @@ -50,7 +50,7 @@ Query: | ) zip_proc LEFT JOIN panther_logs.public.crowdstrike_fdrevent ppr on zip_proc.process_parentpid = ppr.TargetProcessId_decimal and ppr.fdr_event_type = 'ProcessRollup2' - where + where ( (parent_commandline is null) or not (parent_commandline like any ( diff --git a/queries/crowdstrike_queries/MacOS_Browser_Credential_Access.yml b/queries/crowdstrike_queries/MacOS_Browser_Credential_Access.yml index b478c1f94..844a61f31 100644 --- a/queries/crowdstrike_queries/MacOS_Browser_Credential_Access.yml +++ b/queries/crowdstrike_queries/MacOS_Browser_Credential_Access.yml @@ -2,11 +2,11 @@ AnalysisType: scheduled_query Description: Detects processes that contain known browser credential files in arguments. Enabled: false Query: | - SELECT + SELECT * - FROM + FROM panther_logs.public.crowdstrike_processrollup2 - WHERE + WHERE commandline LIKE ANY ( '%/Users/%/Library/Application Support/Google/Chrome/Default/Login Data%', '%/Users/%/Library/Application Support/Google/Chrome/Default/Cookies%', diff --git a/queries/crowdstrike_queries/MacOS_Browser_Credential_Access_FDREvent.yml b/queries/crowdstrike_queries/MacOS_Browser_Credential_Access_FDREvent.yml index ed8fb3a76..3f05365d5 100644 --- a/queries/crowdstrike_queries/MacOS_Browser_Credential_Access_FDREvent.yml +++ b/queries/crowdstrike_queries/MacOS_Browser_Credential_Access_FDREvent.yml @@ -5,10 +5,10 @@ AnalysisType: scheduled_query Description: Detects processes that contain known browser credential files in arguments. (crowdstrike_fdrevent table) Enabled: false Query: | - SELECT + SELECT * FROM panther_logs.public.crowdstrike_fdrevent - WHERE + WHERE fdr_event_type = 'ProcessRollup2' AND event:CommandLine LIKE ANY ( '%/Users/%/Library/Application Support/Google/Chrome/Default/Login Data%', diff --git a/queries/crowdstrike_queries/onepass_login_from_crowdstrike_unmanaged_device_query.yml b/queries/crowdstrike_queries/onepass_login_from_crowdstrike_unmanaged_device_query.yml index 1abe592d8..fd1bc3085 100644 --- a/queries/crowdstrike_queries/onepass_login_from_crowdstrike_unmanaged_device_query.yml +++ b/queries/crowdstrike_queries/onepass_login_from_crowdstrike_unmanaged_device_query.yml @@ -2,7 +2,7 @@ AnalysisType: scheduled_query Description: Looks for OnePassword Logins from IP Addresses that aren''t seen in CrowdStrike''s AIP List. Enabled: false Query: | - SELECT * + SELECT * FROM panther_logs.public.onepassword_signinattempt WHERE category = 'success' AND client:ip_address LIKE '%.%.%.%' @@ -10,7 +10,7 @@ Query: | AND client:platform_name NOT LIKE '%iPhone' AND type = 'credentials_ok' AND client:app_name != '1Password SCIM Bridge' - AND client:ip_address NOT IN + AND client:ip_address NOT IN ( SELECT distinct aip FROM panther_logs.public.crowdstrike_aidmaster diff --git a/queries/kubernetes_queries/kubernetes_cron_job_created_or_modified_query.yml b/queries/kubernetes_queries/kubernetes_cron_job_created_or_modified_query.yml index 0ecb49619..01eac35fc 100644 --- a/queries/kubernetes_queries/kubernetes_cron_job_created_or_modified_query.yml +++ b/queries/kubernetes_queries/kubernetes_cron_job_created_or_modified_query.yml @@ -15,7 +15,7 @@ Query: > verb IN ('create', 'update', 'patch') AND objectRef:resource = 'cronjobs' AND p_occurs_since('30 minutes') - --insert allow-list for expected cronjobs in a cluster, for example a sync service + --insert allow-list for expected cronjobs in a cluster, for example a sync service LIMIT 100 Schedule: RateMinutes: 30 diff --git a/queries/kubernetes_queries/kubernetes_ioc_activity.yml b/queries/kubernetes_queries/kubernetes_ioc_activity.yml index f0d6ab488..02ef5576e 100644 --- a/queries/kubernetes_queries/kubernetes_ioc_activity.yml +++ b/queries/kubernetes_queries/kubernetes_ioc_activity.yml @@ -3,7 +3,7 @@ Filename: scheduled_rule_default_k8s.py RuleID: "Kubernetes.IOCActivity" DisplayName: "IOC Activity in K8 Control Plane" Description: > - This detection monitors for any kuberentes API Request originating from an Indicator of Compromise. + This detection monitors for any kubernetes API Request originating from an Indicator of Compromise. Enabled: false Runbook: > . diff --git a/queries/kubernetes_queries/kubernetes_ioc_activity_query.yml b/queries/kubernetes_queries/kubernetes_ioc_activity_query.yml index 25f9d695e..52855d246 100644 --- a/queries/kubernetes_queries/kubernetes_ioc_activity_query.yml +++ b/queries/kubernetes_queries/kubernetes_ioc_activity_query.yml @@ -4,7 +4,7 @@ Enabled: false Tags: - Optional Description: > - This detection monitors for any kuberentes API Request originating from an Indicator of Compromise. + This detection monitors for any kubernetes API Request originating from an Indicator of Compromise. Query: > SELECT *, VALUE as SRC_IP, @@ -17,7 +17,7 @@ Query: > FROM panther_logs.public.amazon_eks_audit, lateral flatten(source_ips) WHERE p_occurs_since('30 minutes') -- as an example, could be replaced with any IOC data store in a lookup table - INNER JOIN panther_lookups.public.tor_exit_nodes + INNER JOIN panther_lookups.public.tor_exit_nodes ON value = ip LIMIT 10 Schedule: diff --git a/queries/kubernetes_queries/kubernetes_pod_create_or_modify_host_path_vol_mount_query.yml b/queries/kubernetes_queries/kubernetes_pod_create_or_modify_host_path_vol_mount_query.yml index 71ee7aef1..bfa8d12e8 100644 --- a/queries/kubernetes_queries/kubernetes_pod_create_or_modify_host_path_vol_mount_query.yml +++ b/queries/kubernetes_queries/kubernetes_pod_create_or_modify_host_path_vol_mount_query.yml @@ -14,7 +14,7 @@ Query: > WHERE verb IN ('create', 'update', 'patch') AND objectRef:resource = 'pods' - AND requestObject:spec:volumes[0]:hostPath:path ilike ANY ('/var/run/docker.sock','/var/run/crio/crio.sock','/var/lib/kubelet','/var/lib/kubelet/pki','/var/lib/docker/overlay2','/etc/kubernetes','/etc/kubernetes/manifests','/etc/kubernetes/pki','/home/admin') + AND requestObject:spec:volumes[0]:hostPath:path ilike ANY ('/var/run/docker.sock','/var/run/crio/crio.sock','/var/lib/kubelet','/var/lib/kubelet/pki','/var/lib/docker/overlay2','/etc/kubernetes','/etc/kubernetes/manifests','/etc/kubernetes/pki','/home/admin') AND p_occurs_since('30 minutes') --insert allow-list for expected workloads that require a sensitive mount LIMIT 10 diff --git a/queries/kubernetes_queries/kubernetes_service_type_node_port_deployed_query.yml b/queries/kubernetes_queries/kubernetes_service_type_node_port_deployed_query.yml index 2400b4c1e..3ee6e34e2 100644 --- a/queries/kubernetes_queries/kubernetes_service_type_node_port_deployed_query.yml +++ b/queries/kubernetes_queries/kubernetes_service_type_node_port_deployed_query.yml @@ -9,17 +9,17 @@ Query: > SELECT *, objectRef:name as service, objectRef:namespace as namespace, - objectRef:resource as resource_type, + objectRef:resource as resource_type, COALESCE(impersonated_user, USER:username) as src_user, userAgent, responseObject:spec:externalTrafficPolicy as external_traffic_policy, responseObject:spec:internalTrafficPolicy as internal_traffic_policy, responseObject:spec:clusterIP as cluster_ip_address, - VALUE:port as port, --port where traffic gets forwarded to in the pod + VALUE:port as port, --port where traffic gets forwarded to in the pod VALUE:protocol as protocol, --protocol the service uses - VALUE:nodePort as node_port, --which port acts as the nodeport on all the nodes + VALUE:nodePort as node_port, --which port acts as the nodeport on all the nodes requestObject:spec:type as type, - IFF(requestObject:spec:status:loadBalancer is null, 'No LB Present', + IFF(requestObject:spec:status:loadBalancer is null, 'No LB Present', requestObject:spec:status:loadBalancer) as load_balancer, responseStatus:code as response_status FROM panther_logs.public.kubernetes_control_plane, lateral flatten(response_object:spec:ports) diff --git a/queries/okta_queries/okta_admin_access_granted.yml b/queries/okta_queries/okta_admin_access_granted.yml index af44f8595..42e5920c2 100644 --- a/queries/okta_queries/okta_admin_access_granted.yml +++ b/queries/okta_queries/okta_admin_access_granted.yml @@ -4,7 +4,7 @@ Enabled: false Description: > Audit instances of admin access granted in your okta tenant AthenaQuery: > - SELECT + SELECT p_event_time as event_time, actor.alternateid as actor_email, actor.displayName as actor_name, @@ -17,9 +17,9 @@ AthenaQuery: > client.geographicalContext.country as country, client.useragent.rawUserAgent as user_agent FROM panther_logs.okta_systemlog - WHERE + WHERE ( - eventType = 'user.account.privilege.grant' OR + eventType = 'user.account.privilege.grant' OR eventType = 'group.privilege.grant' AND cast(json_extract(debugcontext.debugdata, '$.privilegeGranted') as varchar) LIKE '%Admin%' ) AND @@ -27,7 +27,7 @@ AthenaQuery: > ORDER BY event_time desc SnowflakeQuery: > - SELECT + SELECT p_event_time as event_time, actor:alternateId as actor_email, actor:displayName as actor_name, @@ -39,16 +39,16 @@ SnowflakeQuery: > client:geographicalContext:city as city, client:geographicalContext:country as country, client:userAgent:rawUserAgent as user_agent - FROM + FROM panther_logs.public.okta_systemlog - WHERE - ( eventType = 'user.account.privilege.grant' - OR + WHERE + ( eventType = 'user.account.privilege.grant' + OR eventType = 'group.privilege.grant' AND debugContext:debugData:privilegeGranted like '%Admin%' ) - AND + AND p_occurs_between('2022-01-14','2022-03-22') ORDER BY event_time desc diff --git a/queries/okta_queries/okta_mfa_password_reset_audit.yml b/queries/okta_queries/okta_mfa_password_reset_audit.yml index 6b5709239..1a8d71915 100644 --- a/queries/okta_queries/okta_mfa_password_reset_audit.yml +++ b/queries/okta_queries/okta_mfa_password_reset_audit.yml @@ -8,7 +8,7 @@ AthenaQuery: > FROM panther_logs.okta_systemlog WHERE eventType IN ('user.mfa.factor.reset_all', 'user.mfa.factor.deactivate', 'user.mfa.factor.suspend', 'user.account.reset_password', 'user.account.update_password') and p_occurs_since('7 days') - -- If you wish to investigate an individual user , uncomment this line and add their email here + -- If you wish to investigate an individual user , uncomment this line and add their email here -- and actor:alternateId = '' ORDER by p_event_time DESC SnowflakeQuery: > @@ -16,7 +16,7 @@ SnowflakeQuery: > FROM panther_logs.public.okta_systemlog WHERE eventType IN ('user.mfa.factor.reset_all', 'user.mfa.factor.deactivate', 'user.mfa.factor.suspend', 'user.account.reset_password', 'user.account.update_password','user.mfa.factor.update') and p_occurs_since('7 days') - -- If you wish to investigate an individual user , uncomment this line and add their email here + -- If you wish to investigate an individual user , uncomment this line and add their email here -- and actor:alternateId = '' ORDER by p_event_time DESC Schedule: diff --git a/queries/okta_queries/okta_session_id_audit.yml b/queries/okta_queries/okta_session_id_audit.yml index 64bc28b45..c4f72d1cc 100644 --- a/queries/okta_queries/okta_session_id_audit.yml +++ b/queries/okta_queries/okta_session_id_audit.yml @@ -4,7 +4,7 @@ Enabled: false Description: > Search for activity related to a specific SessionID in Okta panther_logs.okta_systemlog AthenaQuery: > - SELECT + SELECT p_event_time as event_time, actor.alternateId as actor_email, actor.displayName as actor_name, @@ -21,7 +21,7 @@ AthenaQuery: > -- and authenticationContext:externalSessionId = '' ORDER BY event_time DESC SnowflakeQuery: > - SELECT + SELECT p_event_time as event_time, actor:alternateId as actor_email, actor:displayName as actor_name, diff --git a/queries/okta_queries/okta_support_access.yml b/queries/okta_queries/okta_support_access.yml index 10d53688a..bb0d6b4cf 100644 --- a/queries/okta_queries/okta_support_access.yml +++ b/queries/okta_queries/okta_support_access.yml @@ -4,7 +4,7 @@ Enabled: false Description: > Show instances that Okta support was granted to your account AthenaQuery: > - SELECT + SELECT p_event_time as event_time, actor.alternateid as actor_email, actor.displayName as actor_name, @@ -15,16 +15,16 @@ AthenaQuery: > client.geographicalContext.country as country, client.useragent.rawUserAgent as user_agent FROM panther_logs.okta_systemlog - WHERE + WHERE ( - eventType = 'user.session.impersonation.grant' OR + eventType = 'user.session.impersonation.grant' OR eventType = 'user.session.impersonation.initiate' ) and p_occurs_between('2022-01-14','2022-03-22') ORDER BY event_time desc SnowflakeQuery: > - SELECT + SELECT p_event_time as event_time, actor:alternateId as actor_email, actor:displayName as actor_name, @@ -36,11 +36,11 @@ SnowflakeQuery: > eventType FROM panther_logs.public.okta_systemlog - WHERE - eventType = 'user.session.impersonation.grant' - OR + WHERE + eventType = 'user.session.impersonation.grant' + OR eventType = 'user.session.impersonation.initiate' - AND + AND p_occurs_between('2022-01-14','2022-03-22') ORDER BY event_time desc diff --git a/queries/onepassword_queries/onepass_login_from_crowdstrike_unmanaged_device_FDREvent.yml b/queries/onepassword_queries/onepass_login_from_crowdstrike_unmanaged_device_FDREvent.yml index b22452281..ee620b734 100644 --- a/queries/onepassword_queries/onepass_login_from_crowdstrike_unmanaged_device_FDREvent.yml +++ b/queries/onepassword_queries/onepass_login_from_crowdstrike_unmanaged_device_FDREvent.yml @@ -5,7 +5,7 @@ AnalysisType: scheduled_query Description: Looks for OnePassword Logins from IP Addresses that aren''t seen in CrowdStrike''s AIP List. (crowdstrike_fdrevent table) Enabled: false Query: | - SELECT * + SELECT * FROM panther_logs.public.onepassword_signinattempt WHERE category = 'success' AND client:ip_address LIKE '%.%.%.%' @@ -13,7 +13,7 @@ Query: | AND client:platform_name NOT LIKE '%iPhone' AND type = 'credentials_ok' AND client:app_name != '1Password SCIM Bridge' - AND client:ip_address NOT IN + AND client:ip_address NOT IN ( SELECT distinct aip FROM panther_logs.public.crowdstrike_fdrevent diff --git a/queries/snowflake_queries/snowflake_account_admin_assigned_query.yml b/queries/snowflake_queries/snowflake_account_admin_assigned_query.yml index b4a16b622..5ab609bf2 100644 --- a/queries/snowflake_queries/snowflake_account_admin_assigned_query.yml +++ b/queries/snowflake_queries/snowflake_account_admin_assigned_query.yml @@ -7,7 +7,7 @@ AthenaQuery: > /* athena query not supported */ SELECT count(1) SnowflakeQuery: > - --return instances where active (not deleted) roles are granted within the last 24 hours + --return instances where active (not deleted) roles are granted within the last 24 hours --this was adapted from a Security Feature Checklist query diff --git a/queries/snowflake_queries/snowflake_multiple_failed_logins_followed_by_success_query.yml b/queries/snowflake_queries/snowflake_multiple_failed_logins_followed_by_success_query.yml index 79ff59bab..e8e6c01aa 100644 --- a/queries/snowflake_queries/snowflake_multiple_failed_logins_followed_by_success_query.yml +++ b/queries/snowflake_queries/snowflake_multiple_failed_logins_followed_by_success_query.yml @@ -24,8 +24,8 @@ SnowflakeQuery: > AND event_type = 'LOGIN' AND client_ip != '0.0.0.0' -- filtering out unnecessary 'elided' snowflake entries ) - SELECT - * + SELECT + * FROM login_attempts MATCH_RECOGNIZE( PARTITION BY client_ip, user_name diff --git a/rules/aws_cloudtrail_rules/aws_macie_evasion.yml b/rules/aws_cloudtrail_rules/aws_macie_evasion.yml index e0f62976a..4dc2c7e3b 100644 --- a/rules/aws_cloudtrail_rules/aws_macie_evasion.yml +++ b/rules/aws_cloudtrail_rules/aws_macie_evasion.yml @@ -11,7 +11,7 @@ Reports: Severity: Medium Description: > Amazon Macie is a data security and data privacy service to discover and protect sensitive data. - Security teams use Macie to detect open S3 Buckets that could have potentially sensitive data in it along with + Security teams use Macie to detect open S3 Buckets that could have potentially sensitive data in it along with policy violations, such as missing Encryption. If an attacker disables Macie, it could potentially hide data exfiltration. Reference: https://aws.amazon.com/macie/ Runbook: > diff --git a/rules/aws_cloudtrail_rules/aws_modify_cloud_compute_infrastructure.yml b/rules/aws_cloudtrail_rules/aws_modify_cloud_compute_infrastructure.yml index cfd75aba6..7d40014c6 100644 --- a/rules/aws_cloudtrail_rules/aws_modify_cloud_compute_infrastructure.yml +++ b/rules/aws_cloudtrail_rules/aws_modify_cloud_compute_infrastructure.yml @@ -14,7 +14,7 @@ Tags: - Configuration Required Runbook: > This detection reports on eventSource ec2 Change events. This detection excludes Cross-Service - change events. As such, this detection will perform well in environments where changes are + change events. As such, this detection will perform well in environments where changes are expected to originate only from AWS service entities. This detection will emit alerts frequently in environments where users are diff --git a/rules/aws_cloudtrail_rules/aws_rds_manual_snapshot_created.yml b/rules/aws_cloudtrail_rules/aws_rds_manual_snapshot_created.yml index 0134e917d..0927c2627 100644 --- a/rules/aws_cloudtrail_rules/aws_rds_manual_snapshot_created.yml +++ b/rules/aws_cloudtrail_rules/aws_rds_manual_snapshot_created.yml @@ -14,7 +14,7 @@ Reports: - TA0010:T1537 Severity: Low Description: > - A manual snapshot of an RDS database was created. + A manual snapshot of an RDS database was created. An attacker may use this to exfiltrate the DB contents to another account; use this as a correlation rule. Runbook: > Ensure the snapshot was shared with an allowed AWS account. If not, delete the snapshot and quarantine the compromised IAM user. diff --git a/rules/aws_cloudtrail_rules/aws_snapshot_backup_exfiltration.yml b/rules/aws_cloudtrail_rules/aws_snapshot_backup_exfiltration.yml index 950cd4348..4c40e8893 100644 --- a/rules/aws_cloudtrail_rules/aws_snapshot_backup_exfiltration.yml +++ b/rules/aws_cloudtrail_rules/aws_snapshot_backup_exfiltration.yml @@ -1,7 +1,7 @@ AnalysisType: rule Description: Detects the modification of an EC2 snapshot's permissions to enable access from another account. DisplayName: "--DEPRECATED-- Snapshot Backup Exfiltration" -Enabled: False +Enabled: false Filename: aws_snapshot_backup_exfiltration.py Reports: MITRE ATT&CK: diff --git a/rules/aws_eks_rules/system_namespace_public_ip.yml b/rules/aws_eks_rules/system_namespace_public_ip.yml index 1bec2cdf8..75c0b9335 100644 --- a/rules/aws_eks_rules/system_namespace_public_ip.yml +++ b/rules/aws_eks_rules/system_namespace_public_ip.yml @@ -13,8 +13,8 @@ Reports: Reference: https://docs.aws.amazon.com/eks/latest/userguide/network_reqs.html Severity: Info Description: > - This detection identifies if an activity is recorded in the Kubernetes audit log where - the user:username attribute begins with "system:" or "eks:" and the requests originating + This detection identifies if an activity is recorded in the Kubernetes audit log where + the user:username attribute begins with "system:" or "eks:" and the requests originating IP Address is a Public IP Address DedupPeriodMinutes: 1440 # 24 hours Threshold: 1 diff --git a/rules/azure_signin_rules/azure_failed_signins.yml b/rules/azure_signin_rules/azure_failed_signins.yml index d496c783c..a5e965b9b 100644 --- a/rules/azure_signin_rules/azure_failed_signins.yml +++ b/rules/azure_signin_rules/azure_failed_signins.yml @@ -18,7 +18,7 @@ Reports: - TA0001:T1078 Runbook: > Querying Sign-In logs for the ServicePrincipalName or UserPrincipalName may indicate - that the principal is under attack, or that a sign-in credential rolled and some + that the principal is under attack, or that a sign-in credential rolled and some user of the credential didn't get updated. Reference: https://learn.microsoft.com/en-us/entra/identity/authentication/overview-authentication SummaryAttributes: diff --git a/rules/azure_signin_rules/azure_risklevel_passthrough.yml b/rules/azure_signin_rules/azure_risklevel_passthrough.yml index 53a49b48b..cf938ec36 100644 --- a/rules/azure_signin_rules/azure_risklevel_passthrough.yml +++ b/rules/azure_signin_rules/azure_risklevel_passthrough.yml @@ -9,10 +9,10 @@ LogTypes: - Azure.Audit Severity: Medium Description: > - This detection surfaces an alert based on + This detection surfaces an alert based on riskLevelAggregated, riskLevelDuringSignIn, and riskState. - riskLevelAggregated and riskLevelDuringSignIn are only + riskLevelAggregated and riskLevelDuringSignIn are only expected for Azure AD Premium P2 customers. Reference: https://learn.microsoft.com/en-us/azure/active-directory/identity-protection/howto-identity-protection-risk-feedback Reports: @@ -20,7 +20,7 @@ Reports: - TA0006:T1110 - TA0001:T1078 Runbook: > - There are a variety of potential responses to these sign-in risks. + There are a variety of potential responses to these sign-in risks. MSFT has provided an in-depth reference material at https://learn.microsoft.com/en-us/azure/active-directory/identity-protection/howto-identity-protection-risk-feedback SummaryAttributes: diff --git a/rules/gcp_audit_rules/gcp_iam_org_folder_changes.yml b/rules/gcp_audit_rules/gcp_iam_org_folder_changes.yml index a8906aab1..634fa7df1 100644 --- a/rules/gcp_audit_rules/gcp_iam_org_folder_changes.yml +++ b/rules/gcp_audit_rules/gcp_iam_org_folder_changes.yml @@ -19,10 +19,10 @@ Description: > Alert if a GCP Org or Folder Policy Was Changed Manually. Runbook: > Contact the party that made the change. - If it was intended to be temporary, ask for a window for rollback (< 24 hours). - If it must be permanent, ask for change-management doc explaining why it was needed. + If it was intended to be temporary, ask for a window for rollback (< 24 hours). + If it must be permanent, ask for change-management doc explaining why it was needed. Direct them to make the change in Terraform to avoid automated rollback. - Grep for google_org and google_folder in terraform repos for places to + Grep for google_org and google_folder in terraform repos for places to put your new policy bindings. Reference: https://cloud.google.com/iam/docs/granting-changing-revoking-access SummaryAttributes: diff --git a/rules/gcp_k8s_rules/gcp_k8s_ioc_activity.yml b/rules/gcp_k8s_rules/gcp_k8s_ioc_activity.yml index e735b9a2c..5e8b6663b 100644 --- a/rules/gcp_k8s_rules/gcp_k8s_ioc_activity.yml +++ b/rules/gcp_k8s_rules/gcp_k8s_ioc_activity.yml @@ -9,7 +9,7 @@ Tags: - GCP - Optional Severity: Medium -Description: This detection monitors for any kuberentes API Request originating from an Indicator of Compromise. +Description: This detection monitors for any kubernetes API Request originating from an Indicator of Compromise. Reports: MITRE ATT&CK: - T1573.002 # Encrypted Channel: Asymmetric Cryptography diff --git a/rules/gcp_k8s_rules/gcp_k8s_pod_create_or_modify_host_path_vol_mount.yml b/rules/gcp_k8s_rules/gcp_k8s_pod_create_or_modify_host_path_vol_mount.yml index 88baacdaf..49c1c37cd 100644 --- a/rules/gcp_k8s_rules/gcp_k8s_pod_create_or_modify_host_path_vol_mount.yml +++ b/rules/gcp_k8s_rules/gcp_k8s_pod_create_or_modify_host_path_vol_mount.yml @@ -6,11 +6,11 @@ LogTypes: - GCP.AuditLog Severity: High Description: > - This detection monitors for pod creation with a hostPath volume mount. The attachment to a node's volume can allow - for privilege escalation through underlying vulnerabilities or it can open up possibilities for data exfiltration + This detection monitors for pod creation with a hostPath volume mount. The attachment to a node's volume can allow + for privilege escalation through underlying vulnerabilities or it can open up possibilities for data exfiltration or unauthorized file access. It is very rare to see this being a pod requirement. Runbook: > - Investigate the reason of adding hostPath volume mount. Advise that it is discouraged practice. + Investigate the reason of adding hostPath volume mount. Advise that it is discouraged practice. Create ticket if appropriate. Reference: https://linuxhint.com/kubernetes-hostpath-volumes/ Reports: diff --git a/rules/gcp_k8s_rules/gcp_k8s_privileged_pod_created.yml b/rules/gcp_k8s_rules/gcp_k8s_privileged_pod_created.yml index 944534a65..52b8ab878 100644 --- a/rules/gcp_k8s_rules/gcp_k8s_privileged_pod_created.yml +++ b/rules/gcp_k8s_rules/gcp_k8s_privileged_pod_created.yml @@ -7,12 +7,12 @@ LogTypes: Severity: High Filename: gcp_k8s_privileged_pod_created.py Description: > - Alerts when a user creates privileged pod. These particular pods have full access to the host’s namespace and - devices, have the ability to exploit the kernel, have dangerous linux capabilities, and can be a powerful launching - point for further attacks. In the event of a successful container escape where a user is operating with root + Alerts when a user creates privileged pod. These particular pods have full access to the host’s namespace and + devices, have the ability to exploit the kernel, have dangerous linux capabilities, and can be a powerful launching + point for further attacks. In the event of a successful container escape where a user is operating with root privileges, the attacker retains this role on the node. Runbook: > - Investigate the reason of creating privileged pod. Advise that it is discouraged practice. + Investigate the reason of creating privileged pod. Advise that it is discouraged practice. Create ticket if appropriate. Reference: https://www.golinuxcloud.com/kubernetes-privileged-pod-examples/ Reports: diff --git a/rules/gcp_k8s_rules/gcp_k8s_service_type_node_port_deployed.yml b/rules/gcp_k8s_rules/gcp_k8s_service_type_node_port_deployed.yml index 8c9c8232b..8f3c54afb 100644 --- a/rules/gcp_k8s_rules/gcp_k8s_service_type_node_port_deployed.yml +++ b/rules/gcp_k8s_rules/gcp_k8s_service_type_node_port_deployed.yml @@ -7,12 +7,12 @@ LogTypes: - GCP.AuditLog Severity: High Description: > - This detection monitors for any kubernetes service deployed with type node port. A Node Port service allows - an attacker to expose a set of pods hosting the service to the internet by opening their port and redirecting - traffic here. This can be used to bypass network controls and intercept traffic, creating a direct line to + This detection monitors for any kubernetes service deployed with type node port. A Node Port service allows + an attacker to expose a set of pods hosting the service to the internet by opening their port and redirecting + traffic here. This can be used to bypass network controls and intercept traffic, creating a direct line to the outside network. Runbook: > - Investigate the reason of creating NodePort service. Advise that it is discouraged practice. + Investigate the reason of creating NodePort service. Advise that it is discouraged practice. Create ticket if appropriate. Reference: https://kubernetes.io/docs/tutorials/kubernetes-basics/expose/expose-intro/ Reports: diff --git a/rules/github_rules/github_action_failed.yml b/rules/github_rules/github_action_failed.yml index 208ddd4f8..c5c9bbdb4 100644 --- a/rules/github_rules/github_action_failed.yml +++ b/rules/github_rules/github_action_failed.yml @@ -2,7 +2,7 @@ AnalysisType: rule Filename: github_action_failed.py RuleID: "GitHub.Action.Failed" DisplayName: "GitHub Action Failed" -Enabled: False +Enabled: false LogTypes: - GitHub.Audit Tags: diff --git a/rules/okta_rules/okta_app_refresh_access_token_reuse.yml b/rules/okta_rules/okta_app_refresh_access_token_reuse.yml index 8431bf95f..cc2e5daab 100644 --- a/rules/okta_rules/okta_app_refresh_access_token_reuse.yml +++ b/rules/okta_rules/okta_app_refresh_access_token_reuse.yml @@ -1,6 +1,6 @@ AnalysisType: rule Description: |- - When a client wants to renew an access token, it sends the refresh token with the access token request to the /token Okta endpoint. + When a client wants to renew an access token, it sends the refresh token with the access token request to the /token Okta endpoint. Okta validates the incoming refresh token, issues a new set of tokens and invalidates the refresh token that was passed with the initial request. This detection alerts when a previously used refresh token is used again with the token request Reference: https://developer.okta.com/docs/guides/refresh-tokens/main/#refresh-token-reuse-detection diff --git a/rules/okta_rules/okta_idp_create_modify.yml b/rules/okta_rules/okta_idp_create_modify.yml index 88a8c313b..ae8518375 100644 --- a/rules/okta_rules/okta_idp_create_modify.yml +++ b/rules/okta_rules/okta_idp_create_modify.yml @@ -12,10 +12,10 @@ Reports: - TA0003:T1098 # Account Manipulation Severity: High Description: > - A new 3rd party Identity Provider has been created or modified. - Attackers have been observed configuring a second Identity Provider to act as an "impersonation app" - to access applications within the compromised Org on behalf of other users. This second Identity Provider, - also controlled by the attacker, would act as a “source” IdP in an inbound federation relationship + A new 3rd party Identity Provider has been created or modified. + Attackers have been observed configuring a second Identity Provider to act as an "impersonation app" + to access applications within the compromised Org on behalf of other users. This second Identity Provider, + also controlled by the attacker, would act as a “source” IdP in an inbound federation relationship (sometimes called “Org2Org”) with the target. Runbook: > Delegate access to this feature to a Custom Admin Role with the minimum required permissions. diff --git a/rules/okta_rules/okta_idp_signin.yml b/rules/okta_rules/okta_idp_signin.yml index 266a57128..4cf20b812 100644 --- a/rules/okta_rules/okta_idp_signin.yml +++ b/rules/okta_rules/okta_idp_signin.yml @@ -13,13 +13,13 @@ Reports: - TA0003:T1098 # Account Manipulation Severity: High Description: > - A user has signed in using a 3rd party Identity Provider. - Attackers have been observed configuring a second Identity Provider to act as an "impersonation app" - to access applications within the compromised Org on behalf of other users. This second Identity Provider, - also controlled by the attacker, would act as a “source” IdP in an inbound federation relationship + A user has signed in using a 3rd party Identity Provider. + Attackers have been observed configuring a second Identity Provider to act as an "impersonation app" + to access applications within the compromised Org on behalf of other users. This second Identity Provider, + also controlled by the attacker, would act as a “source” IdP in an inbound federation relationship (sometimes called “Org2Org”) with the target. - From this “source” IdP, the threat actor manipulated the username parameter for targeted users in the second - “source” Identity Provider to match a real user in the compromised “target” Identity Provider. + From this “source” IdP, the threat actor manipulated the username parameter for targeted users in the second + “source” Identity Provider to match a real user in the compromised “target” Identity Provider. This provided the ability to Single sign-on (SSO) into applications in the target IdP as the targeted user. Do not use this rule if your organization uses legitimate 3rd-party Identity Providers. Reference: > diff --git a/rules/okta_rules/okta_org2org_creation_modification.yml b/rules/okta_rules/okta_org2org_creation_modification.yml index 370a059de..c23e0c3e6 100644 --- a/rules/okta_rules/okta_org2org_creation_modification.yml +++ b/rules/okta_rules/okta_org2org_creation_modification.yml @@ -13,7 +13,7 @@ Severity: High Description: > An Okta Org2Org application has been created or modified. Okta's Org2Org applications instances are used to push and match users from one Okta organization to another. - A malicious actor can add an Org2Org application instance and create a user in the source organization (controlled by the attacker) + A malicious actor can add an Org2Org application instance and create a user in the source organization (controlled by the attacker) with the same identifier as a Super Administrator in the target organization. Reference: > https://www.authomize.com/blog/authomize-discovers-password-stealing-and-impersonation-risks-to-in-okta/ diff --git a/rules/snyk_rules/snyk_ou_change.yml b/rules/snyk_rules/snyk_ou_change.yml index 2ebf839cb..2e5e4aaa4 100644 --- a/rules/snyk_rules/snyk_ou_change.yml +++ b/rules/snyk_rules/snyk_ou_change.yml @@ -12,7 +12,7 @@ Severity: High Description: > Detects when Snyk Group or Organization Settings are changed. Runbook: > - These actions in the Snyk Audit logs indicate that a Organization or + These actions in the Snyk Audit logs indicate that a Organization or Group setting has changed, including Group and Org creation/deletion. Deletion events are marked with HIGH severity Creation events are marked with INFO severity diff --git a/rules/snyk_rules/snyk_svcacct_change.yml b/rules/snyk_rules/snyk_svcacct_change.yml index df63eea6c..2df189abf 100644 --- a/rules/snyk_rules/snyk_svcacct_change.yml +++ b/rules/snyk_rules/snyk_svcacct_change.yml @@ -15,7 +15,7 @@ Runbook: > These actions in the Snyk Audit logs indicate that a ServiceAccount has been created/deleted/modified. - Service Accounts are system user accounts with an API token + Service Accounts are system user accounts with an API token associated to it in place of standard user credentials. All events where the Service Account's role is ADMIN have CRITICAL severity Deletion events are marked with HIGH severity diff --git a/rules/snyk_rules/snyk_system_sso.yml b/rules/snyk_rules/snyk_system_sso.yml index b61a0d528..ab8838574 100644 --- a/rules/snyk_rules/snyk_system_sso.yml +++ b/rules/snyk_rules/snyk_system_sso.yml @@ -10,7 +10,7 @@ Tags: Severity: High Description: > Detects Snyk SSO Settings have been changed. - The reference URL from Snyk indicates that these events are likely to + The reference URL from Snyk indicates that these events are likely to originate exclusively from Snyk Support. Reference: https://docs.snyk.io/user-and-group-management/setting-up-sso-for-authentication/set-up-snyk-single-sign-on-sso DedupPeriodMinutes: 60 diff --git a/rules/standard_rules/impossible_travel_login.yml b/rules/standard_rules/impossible_travel_login.yml index 83c142692..60ba68227 100644 --- a/rules/standard_rules/impossible_travel_login.yml +++ b/rules/standard_rules/impossible_travel_login.yml @@ -17,7 +17,7 @@ Reports: Severity: High Description: A user has subsequent logins from two geographic locations that are very far apart Runbook: > - Reach out to the user if needed to validate the activity, then lock the account. + Reach out to the user if needed to validate the activity, then lock the account. If the user responds that the geolocation on the new location is incorrect, you can directly report the inaccuracy via https://ipinfo.io/corrections diff --git a/rules/zoom_operation_rules/zoom_operation_user_granted_admin_deprecated.yml b/rules/zoom_operation_rules/zoom_operation_user_granted_admin_deprecated.yml index efc46721e..dc0905ec5 100644 --- a/rules/zoom_operation_rules/zoom_operation_user_granted_admin_deprecated.yml +++ b/rules/zoom_operation_rules/zoom_operation_user_granted_admin_deprecated.yml @@ -2,7 +2,7 @@ AnalysisType: rule Filename: zoom_operation_user_granted_admin_deprecated.py RuleID: "Zoom.UserGrantedAdmin" DisplayName: "--DEPRECATED -- Zoom User Granted Admin Rights" -Enabled: False +Enabled: false LogTypes: - Zoom.Operation Tags: From c8b6ad924885bc8103e1e910aaa2504020179d44 Mon Sep 17 00:00:00 2001 From: jzandona <79932094+jzandona@users.noreply.github.com> Date: Tue, 14 May 2024 07:56:02 -0700 Subject: [PATCH 06/35] AppOmni Alert passthrough (#1211) * alert passthrough * Deprecate GreyNoise detections (#1205) * Deprecate GreyNoise detections * Update rules/aws_cloudtrail_rules/aws_s3_activity_greynoise.yml * Update rules/cloudflare_rules/cloudflare_firewall_suspicious_event_greynoise.yml * Update cloudflare_httpreq_bot_high_volume_greynoise.yml --------- Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> * fix - Notion Login From New Location - NoneType error (#1206) * fix - Notion Login From New Location - NoneType error * fix - Notion Login From New Location - NoneType error - linter fix * remove codeowners (#1208) * linting * fix - GCP rules - AttributeError (#1210) * fix - GCP rules - AttributeError * fix - GCP rules - AttributeError - linter fix * MITRE ATT&CK Mappings for MS Rules (#1209) * added MITRE mappings for microsoft rules * fixed formatting on some helper files --------- Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> * traildiscover enrichment with managed schema (#1177) * traildiscover enrichment with managed schema * Add npm install in dockerfile (#1172) * add npm install in dockerfile * Remove Python optimizations; add prettier to PATH --------- Co-authored-by: egibs * schema name: TrailDiscover.CloudTrail * Fix Dockerfile; add Workflow to test image * updated data set * Add MongoDB.2FA.Disabled rule (#1190) Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> * lint and fmt * fmt * add OCSF selector * additional OCSF mappings * Fix Pipfile * Rebase changes --------- Co-authored-by: Panos Sakkos Co-authored-by: egibs Co-authored-by: Oleh Melenevskyi <767472+melenevskyi@users.noreply.github.com> * Update PAT to 0.46.0 (#1216) * add file/host state to msft graph alert context (#1220) * fix timestamps (#1219) * Update PAT to 0.46.1 (#1222) * pack for traildiscover LUT (#1221) * use event.deep_get and remove InlineFilters * add pack --------- Co-authored-by: Oleh Melenevskyi <767472+melenevskyi@users.noreply.github.com> Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> Co-authored-by: akozlovets098 <95437895+akozlovets098@users.noreply.github.com> Co-authored-by: Panos Sakkos Co-authored-by: ben-githubs <38414634+ben-githubs@users.noreply.github.com> Co-authored-by: egibs Co-authored-by: Evan Gibler Co-authored-by: Nick Hakmiller <49166439+nhakmiller@users.noreply.github.com> Co-authored-by: Ariel Ropek --- packs/appomni.yml | 7 + .../appomni_alert_passthrough.py | 35 +++ .../appomni_alert_passthrough.yml | 232 ++++++++++++++++++ 3 files changed, 274 insertions(+) create mode 100644 packs/appomni.yml create mode 100644 rules/appomni_rules/appomni_alert_passthrough.py create mode 100644 rules/appomni_rules/appomni_alert_passthrough.yml diff --git a/packs/appomni.yml b/packs/appomni.yml new file mode 100644 index 000000000..eaf6b9da7 --- /dev/null +++ b/packs/appomni.yml @@ -0,0 +1,7 @@ +AnalysisType: pack +PackID: PantherManaged.AppOmni +Description: Group of all AppOmni detections +PackDefinition: + IDs: + - AppOmni.Alert.Passthrough +DisplayName: "Panther AppOmni Pack" diff --git a/rules/appomni_rules/appomni_alert_passthrough.py b/rules/appomni_rules/appomni_alert_passthrough.py new file mode 100644 index 000000000..9cbc07a6b --- /dev/null +++ b/rules/appomni_rules/appomni_alert_passthrough.py @@ -0,0 +1,35 @@ +def rule(event): + # Only alert where event.kind == "alert" + if event.deep_get("event", "kind") == "alert": + return True + return False + + +def title(event): + # Create title that includes severity and message + sev_dict = {0: "Critical", 1: "High", 2: "Medium", 3: "Low", 4: "Informational"} + sev = sev_dict[event.deep_get("event", "severity")] + + # Use type service in title if only one field, label as 'Multiple Services' if more than one. + if len(event.deep_get("related", "services", "type")) == 1: + service = event.deep_get("related", "services", "type")[0] + else: + service = "Multiple Services" + + return f'[{sev}] - {service} - {event.get("message")}' + + +def severity(event): + # Update Panther alert severity based on severity from AppOmni Alert + sev = {0: "Critical", 1: "High", 2: "Medium", 3: "Low", 4: "Informational"} + return sev[event.deep_get("event", "severity")] + + +def dedup(event): + # Dedup by the events alert id, make sure we alert each time a new AppOmni alert is logged + return f'Event ID: {event.deep_get("appomni", "event", "id")}' + + +def alert_context(event): + # 'Threat' and 'related' data to be included in the alert sent to the alert destination + return {"threat": event.deep_get("rule", "threat"), "related": event.deep_get("related")} diff --git a/rules/appomni_rules/appomni_alert_passthrough.yml b/rules/appomni_rules/appomni_alert_passthrough.yml new file mode 100644 index 000000000..4a46eee49 --- /dev/null +++ b/rules/appomni_rules/appomni_alert_passthrough.yml @@ -0,0 +1,232 @@ +AnalysisType: rule +Filename: appomni_alert_passthrough.py +RuleID: "AppOmni.Alert.Passthrough" +DisplayName: "AppOmni Alert Passthrough" +Enabled: true +LogTypes: + - AppOmni.Alerts +Severity: Medium +Reports: + MITRE ATT&CK: + - TA0001:T1566 + - TA0001:T1528 + - TA0001:T1190 + - TA0001:T1078 + - TA0001:T1199 + - TA0004:T1548 + - TA0005:T1562 + - TA0005:T1090 + - TA0005:T1564 + - TA0005:T1556 + - TA0005:T1550 + - TA0005:T1078 + - TA0006:T1110 + - TA0006:T1111 + - TA0006:T1550 + - TA0006:T1528 + - TA0006:T1552 + - TA0006:T1539 + - TA0040:T1486 + - TA0040:T1565 + - TA0040:T1485 + - TA0040:T1531 + - TA0002:T1204 + - TA0003:T1114 + - TA0003:T1098 + - TA0003:T1556 + - TA0003:T1078 + - TA0003:T1136 + - TA0004:T1484 + - TA0007:T1518 + - TA0007:T1087 + - TA0008:T1550 + - TA0042:T1608 + - TA0009:T1530 + - TA0009:T1213 + - TA0009:T1114 + - TA0004:T1078 + - TA0010:T1537 + - TA0010:T1567 +DedupPeriodMinutes: 60 +Threshold: 1 +Tests: + - Name: Alert Type Severity 2 + ExpectedResult: true + Log: + appomni: + alert: + channel: prod + event: + dataset: appomni_alert + id: 2ae1e281-4df1-5d26-81e2-7b75589e5dd4 + sortable_event_id: 01HQ6JKJ5VE68CAT71JM27Z1D2 + sortable_ingest_id: 01HQ6KGT23SN874A9ATHZCM1JH + organization: + id: 285 + event: + created: "2024-02-21T19:50:42.499Z" + kind: alert + severity: 2 + message: Security issue detected in GitHub repository 'appomni/ao_factory_interfaces' + related: + event: + - cf8e782f-1657-5a4e-bdc2-cff1d147c912 + services: + id: + - 12477 + type: + - github + rule: + name: Repository Security Issue Detected + ruleset: 1423ff39-3250-4d53-aafb-142e740668bd + threat: + framework: MITRE ATT&CK + tactic: + id: + - TA0001 + name: + - Initial Access + technique: + id: + - T1195 + name: + - Supply Chain Compromise + uuid: 6d873f19-4847-4412-9b70-6dca598ee64c + version: "1" + timestamp: "2024-02-21T19:34:44.155Z" + version: 2.0.0 + - Name: Event Type + ExpectedResult: false + Log: + appomni: + event: + collected_time: "2024-02-28T19:53:34.266Z" + dataset: ao_auditlogs + id: e4431a54-e57d-5cab-8b24-af194d49ebec + ingestion_time: "2024-02-28T19:53:34.298Z" + organization: + id: 6 + service: + account_id: "6" + id: 0 + name: AppOmni + type: appomni + event: + action: update_token + category: + - authentication + code: access_token_refreshed_refreshtoken + created: "2024-02-28T19:53:34.266Z" + dataset: ao_auditlogs + id: b90b4447-ae6a-4257-95fe-a3f9c5577158 + ingested: "2024-02-28T19:53:34.298Z" + kind: event + module: appomni + original: '{"action_at":"2024-02-28T19:53:34.256900+00:00","action_data":{"md_kind":"core.aoaudit.auditdata","md_version":1},"action_type":"access_token_refreshed_refreshtoken","log_id":"b90b4447-ae6a-4257-95fe-a3f9c5577158","org_id":6,"perspective_id":1487,"service_id":34,"service_type":"workday"}' + type: + - change + timestamp: "2024-02-28T19:53:34.256Z" + version: 2.0.0 + - Name: External App Install - Severity 3 + ExpectedResult: true + Log: + "@timestamp": "2024-02-26T18:02:09.044Z" + appomni: + alert: + channel: prod + event: + dataset: appomni_alert + id: e927e832-bfb1-55d7-9159-0e5cd84dcc65 + sortable_event_id: 01HQK99M8MZKWGZG24B5WV4JDK + sortable_ingest_id: 01HQK9DFC5DS5MYM0YEFFW7PF8 + organization: + id: 6 + event: + created: "2024-02-26T18:04:15.109Z" + kind: alert + severity: 3 + message: An external application has been installed by appomni_int_justinz in Workday + related: + event: + - cb786453-a105-5438-97a6-903d15e0cb7e + ip: + - 71.218.228.62 + services: + id: + - 34 + type: + - workday + user: + - appomni_int_justinz + rule: + name: External Application Installed + ruleset: 1423ff39-3250-4d53-aafb-142e740668bd + threat: + framework: MITRE ATT&CK + tactic: + id: + - TA0005 + - TA0008 + - TA0010 + name: + - Defense Evasion + - Lateral Movement + - Exfiltration + technique: + id: + - T1550 + - T1550 + - T1567 + name: + - Use Alternate Authentication Material + - Use Alternate Authentication Material + - Exfiltration Over Web Service + uuid: 2aadaafd-4ec5-4a09-be6e-c2d70b555d19 + version: "1" + version: 2.0.0 + - Name: Multiple Services + ExpectedResult: true + Log: + appomni: + alert: + channel: prod + event: + dataset: appomni_alert + id: 2ae1e281-4df1-5d26-81e2-7b75589e5dd4 + sortable_event_id: 01HQ6JKJ5VE68CAT71JM27Z1D2 + sortable_ingest_id: 01HQ6KGT23SN874A9ATHZCM1JH + organization: + id: 285 + event: + created: "2024-02-21T19:50:42.499Z" + kind: alert + severity: 2 + message: Security issue detected in GitHub repository 'appomni/ao_factory_interfaces' + related: + event: + - cf8e782f-1657-5a4e-bdc2-cff1d147c912 + services: + id: + - 12477 + type: + - github + - workday + rule: + name: Repository Security Issue Detected + ruleset: 1423ff39-3250-4d53-aafb-142e740668bd + threat: + framework: MITRE ATT&CK + tactic: + id: + - TA0001 + name: + - Initial Access + technique: + id: + - T1195 + name: + - Supply Chain Compromise + uuid: 6d873f19-4847-4412-9b70-6dca598ee64c + version: "1" + timestamp: "2024-02-21T19:34:44.155Z" + version: 2.0.0 From 8012f1148954cbcee086995d9e3a4c6dbf4f3697 Mon Sep 17 00:00:00 2001 From: Joe Stanulis <126097374+jstanulis-push@users.noreply.github.com> Date: Tue, 21 May 2024 10:16:53 -0400 Subject: [PATCH 07/35] Push Security rules (#1207) * Deprecate GreyNoise detections (#1205) * Deprecate GreyNoise detections * Update rules/aws_cloudtrail_rules/aws_s3_activity_greynoise.yml * Update rules/cloudflare_rules/cloudflare_firewall_suspicious_event_greynoise.yml * Update cloudflare_httpreq_bot_high_volume_greynoise.yml --------- Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> * fix - Notion Login From New Location - NoneType error (#1206) * fix - Notion Login From New Location - NoneType error * fix - Notion Login From New Location - NoneType error - linter fix * Push Security rules * remove codeowners (#1208) * fix - GCP rules - AttributeError (#1210) * fix - GCP rules - AttributeError * fix - GCP rules - AttributeError - linter fix * MITRE ATT&CK Mappings for MS Rules (#1209) * added MITRE mappings for microsoft rules * fixed formatting on some helper files --------- Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> * traildiscover enrichment with managed schema (#1177) * traildiscover enrichment with managed schema * Add npm install in dockerfile (#1172) * add npm install in dockerfile * Remove Python optimizations; add prettier to PATH --------- Co-authored-by: egibs * schema name: TrailDiscover.CloudTrail * Fix Dockerfile; add Workflow to test image * updated data set * Add MongoDB.2FA.Disabled rule (#1190) Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> * lint and fmt * fmt * add OCSF selector * additional OCSF mappings * Fix Pipfile * Rebase changes --------- Co-authored-by: Panos Sakkos Co-authored-by: egibs Co-authored-by: Oleh Melenevskyi <767472+melenevskyi@users.noreply.github.com> * Update PAT to 0.46.0 (#1216) * add file/host state to msft graph alert context (#1220) * fix timestamps (#1219) * Update PAT to 0.46.1 (#1222) * pack for traildiscover LUT (#1221) * pack, fmt lint, event.deep_get * pack update --------- Co-authored-by: Oleh Melenevskyi <767472+melenevskyi@users.noreply.github.com> Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> Co-authored-by: akozlovets098 <95437895+akozlovets098@users.noreply.github.com> Co-authored-by: Panos Sakkos Co-authored-by: ben-githubs <38414634+ben-githubs@users.noreply.github.com> Co-authored-by: egibs Co-authored-by: Evan Gibler Co-authored-by: Nick Hakmiller <49166439+nhakmiller@users.noreply.github.com> Co-authored-by: Ariel Ropek --- .../push_security_app_banner_acknowledged.py | 26 +++ .../push_security_app_banner_acknowledged.yml | 98 ++++++++++ .../push_security_mfa_method_changed.py | 33 ++++ .../push_security_mfa_method_changed.yml | 167 ++++++++++++++++++ .../push_security_new_app_detected.py | 16 ++ .../push_security_new_app_detected.yml | 54 ++++++ .../push_security_new_saas_account_created.py | 17 ++ ...push_security_new_saas_account_created.yml | 115 ++++++++++++ .../push_security_open_security_finding.py | 22 +++ .../push_security_open_security_finding.yml | 86 +++++++++ .../push_security_phishable_mfa_method.py | 33 ++++ .../push_security_phishable_mfa_method.yml | 99 +++++++++++ .../push_security_phishing_attack.py | 22 +++ .../push_security_phishing_attack.yml | 63 +++++++ .../push_security_unauthorized_idp_login.py | 31 ++++ .../push_security_unauthorized_idp_login.yml | 88 +++++++++ 16 files changed, 970 insertions(+) create mode 100644 rules/push_security_rules/push_security_app_banner_acknowledged.py create mode 100644 rules/push_security_rules/push_security_app_banner_acknowledged.yml create mode 100644 rules/push_security_rules/push_security_mfa_method_changed.py create mode 100644 rules/push_security_rules/push_security_mfa_method_changed.yml create mode 100644 rules/push_security_rules/push_security_new_app_detected.py create mode 100644 rules/push_security_rules/push_security_new_app_detected.yml create mode 100644 rules/push_security_rules/push_security_new_saas_account_created.py create mode 100644 rules/push_security_rules/push_security_new_saas_account_created.yml create mode 100644 rules/push_security_rules/push_security_open_security_finding.py create mode 100644 rules/push_security_rules/push_security_open_security_finding.yml create mode 100644 rules/push_security_rules/push_security_phishable_mfa_method.py create mode 100644 rules/push_security_rules/push_security_phishable_mfa_method.yml create mode 100644 rules/push_security_rules/push_security_phishing_attack.py create mode 100644 rules/push_security_rules/push_security_phishing_attack.yml create mode 100644 rules/push_security_rules/push_security_unauthorized_idp_login.py create mode 100644 rules/push_security_rules/push_security_unauthorized_idp_login.yml diff --git a/rules/push_security_rules/push_security_app_banner_acknowledged.py b/rules/push_security_rules/push_security_app_banner_acknowledged.py new file mode 100644 index 000000000..baa13bb69 --- /dev/null +++ b/rules/push_security_rules/push_security_app_banner_acknowledged.py @@ -0,0 +1,26 @@ +from panther_base_helpers import deep_get + + +def rule(event): + if event.get("object") != "APP_BANNER": + return False + + if deep_get(event, "new", "action") == "ACKNOWLEDGED": + return True + + return False + + +def title(event): + app_type = deep_get(event, "new", "appType") + employee_email = deep_get(event, "new", "employee", "email") + return f"{app_type} accessed by {employee_email}" + + +def alert_context(event): + return { + "Push Security app banner": deep_get(event, "new", "appBanner", "mode"), + "Title": deep_get(event, "new", "appBanner", "title"), + "Subtext": deep_get(event, "new", "appBanner", "subtext"), + "Button": deep_get(event, "new", "appBanner", "buttonText"), + } diff --git a/rules/push_security_rules/push_security_app_banner_acknowledged.yml b/rules/push_security_rules/push_security_app_banner_acknowledged.yml new file mode 100644 index 000000000..7a141a067 --- /dev/null +++ b/rules/push_security_rules/push_security_app_banner_acknowledged.yml @@ -0,0 +1,98 @@ +AnalysisType: rule +Filename: push_security_app_banner_acknowledged.py +RuleID: "Push.Security.App.Banner.Acknowledged" +DisplayName: "Push Security App Banner Acknowledged" +Enabled: true +LogTypes: + - Custom.PushSecurity.Activity +Severity: Low +DedupPeriodMinutes: 60 +Threshold: 1 +Tests: + - Name: App Banner Acknowledged + ExpectedResult: true + Log: + id: c478966c-f927-411c-b919-179832d3d50c + new: + action: ACKNOWLEDGED + appBanner: + buttonText: Proceed anyway + mode: ACKNOWLEDGE + subtext: This app is not approved, please use Google Drive instead. + title: This app is not approved for use + appType: DROPBOX + browser: CHROME + employee: + chatopsEnabled: true + creationTimestamp: 1.698669223e+09 + department: Security Engineering + email: john.hill@example.com + firstName: John + id: 2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0 + lastName: Hill + licensed: true + location: New York + os: WINDOWS + sourceIpAddress: 8.158.25.38 + userAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299 + object: APP_BANNER + timestamp: 1.698604061e+09 + version: "1" + - Name: App Banner Displayed + ExpectedResult: false + Log: + id: c478966c-f927-411c-b919-179832d3d50c + new: + action: DISPLAYED + appBanner: + buttonText: Proceed anyway + mode: ACKNOWLEDGE + subtext: This app is not approved, please use Google Drive instead. + title: This app is not approved for use + appType: DROPBOX + browser: CHROME + employee: + chatopsEnabled: true + creationTimestamp: 1.698669223e+09 + department: Security Engineering + email: john.hill@example.com + firstName: John + id: 2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0 + lastName: Hill + licensed: true + location: New York + os: WINDOWS + sourceIpAddress: 8.158.25.38 + userAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299 + object: APP_BANNER + timestamp: 1.698604061e+09 + version: "1" + - Name: App Banner Inform Mode + ExpectedResult: false + Log: + id: c478966c-f927-411c-b919-179832d3d50c + new: + action: DISPLAYED + appBanner: + buttonText: null + mode: INFORM + subtext: This app is not approved, please use Google Drive instead. + title: This app is not approved for use + appType: DROPBOX + browser: CHROME + employee: + chatopsEnabled: true + creationTimestamp: 1.698669223e+09 + department: Security Engineering + email: john.hill@example.com + firstName: John + id: 2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0 + lastName: Hill + licensed: true + location: New York + os: WINDOWS + sourceIpAddress: 8.158.25.38 + userAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299 + object: APP_BANNER + timestamp: 1.698604061e+09 + version: "1" diff --git a/rules/push_security_rules/push_security_mfa_method_changed.py b/rules/push_security_rules/push_security_mfa_method_changed.py new file mode 100644 index 000000000..7bae8a4be --- /dev/null +++ b/rules/push_security_rules/push_security_mfa_method_changed.py @@ -0,0 +1,33 @@ +from panther_base_helpers import deep_get + + +def rule(event): + if event.get("object") != "ACCOUNT": + return False + + if event.get("old") is None: + return False + + new_mfa_methods = set(deep_get(event, "new", "mfaMethods")) + old_mfa_methods = set(deep_get(event, "old", "mfaMethods", default=[])) + + if new_mfa_methods != old_mfa_methods: + return True + + return False + + +def severity(event): + if deep_get(event, "new", "mfaMethods") == []: + return "HIGH" + return "LOW" + + +def title(event): + mfa_methods = ", ".join(deep_get(event, "new", "mfaMethods", default="No MFA")) + new_email = deep_get(event, "new", "email") + new_apptype = deep_get(event, "new", "appType") + + if mfa_methods == "": + return f"{new_email} removed all MFA methods on {new_apptype}" + return f"{new_email} changed MFA method to {mfa_methods} on {new_apptype}" diff --git a/rules/push_security_rules/push_security_mfa_method_changed.yml b/rules/push_security_rules/push_security_mfa_method_changed.yml new file mode 100644 index 000000000..892e54d9f --- /dev/null +++ b/rules/push_security_rules/push_security_mfa_method_changed.yml @@ -0,0 +1,167 @@ +AnalysisType: rule +Filename: push_security_mfa_method_changed.py +RuleID: "Push.Security.MFA.Method.Changed" +DisplayName: "Push Security SaaS App MFA Method Changed" +Enabled: true +LogTypes: + - Custom.PushSecurity.Entities +Severity: Info +Description: MFA method on SaaS app changed +DedupPeriodMinutes: 60 +Threshold: 1 +Tests: + - Name: All MFA methods removed + ExpectedResult: true + Log: + id: d1e5794f-666d-4cba-abae-c6d889ca1903 + new: + appId: 67ef5c13-b5e6-4945-af7b-c11ac98f630f + appType: CONTENTFUL + creationTimestamp: 1.707775048e+09 + email: jet.black@issp.com + employeeId: ca6cf7ce-90e6-4eb5-a262-7899bc48c39c + id: 5e15ce4c-6b93-4fbf-aed9-1890775efa90 + lastUsedTimestamp: null + loginMethods: + oidcLogin: null + oktaSwaLogin: false + passwordLogin: false + samlLogin: null + mfaMethods: [] + mfaRegistered: false + passwordId: null + object: ACCOUNT + old: + appId: 67ef5c13-b5e6-4945-af7b-c11ac98f630f + appType: CONTENTFUL + creationTimestamp: 1.707775048e+09 + email: jet.black@issp.com + employeeId: ca6cf7ce-90e6-4eb5-a262-7899bc48c39c + id: 5e15ce4c-6b93-4fbf-aed9-1890775efa90 + lastUsedTimestamp: null + loginMethods: + oidcLogin: null + oktaSwaLogin: false + passwordLogin: false + samlLogin: null + mfaMethods: + - SMS + mfaRegistered: false + passwordId: null + timestamp: 1.707775049e+09 + type: CREATE + version: "1" + - Name: First seen + ExpectedResult: false + Log: + id: d1e5794f-666d-4cba-abae-c6d889ca1903 + new: + appId: 67ef5c13-b5e6-4945-af7b-c11ac98f630f + appType: CONTENTFUL + creationTimestamp: 1.707775048e+09 + email: jet.black@issp.com + employeeId: ca6cf7ce-90e6-4eb5-a262-7899bc48c39c + id: 5e15ce4c-6b93-4fbf-aed9-1890775efa90 + lastUsedTimestamp: null + loginMethods: + oidcLogin: null + oktaSwaLogin: false + passwordLogin: false + samlLogin: null + mfaMethods: + - SMS + - APP_OTP + mfaRegistered: false + passwordId: null + object: ACCOUNT + old: null + timestamp: 1.707775049e+09 + type: CREATE + version: "1" + - Name: MFA method added + ExpectedResult: true + Log: + id: d1e5794f-666d-4cba-abae-c6d889ca1903 + new: + appId: 67ef5c13-b5e6-4945-af7b-c11ac98f630f + appType: CONTENTFUL + creationTimestamp: 1.707775048e+09 + email: jet.black@issp.com + employeeId: ca6cf7ce-90e6-4eb5-a262-7899bc48c39c + id: 5e15ce4c-6b93-4fbf-aed9-1890775efa90 + lastUsedTimestamp: null + loginMethods: + oidcLogin: null + oktaSwaLogin: false + passwordLogin: false + samlLogin: null + mfaMethods: + - SMS + - APP_OTP + mfaRegistered: false + passwordId: null + object: ACCOUNT + old: + appId: 67ef5c13-b5e6-4945-af7b-c11ac98f630f + appType: CONTENTFUL + creationTimestamp: 1.707775048e+09 + email: jet.black@issp.com + employeeId: ca6cf7ce-90e6-4eb5-a262-7899bc48c39c + id: 5e15ce4c-6b93-4fbf-aed9-1890775efa90 + lastUsedTimestamp: null + loginMethods: + oidcLogin: null + oktaSwaLogin: false + passwordLogin: false + samlLogin: null + mfaMethods: + - SMS + mfaRegistered: false + passwordId: null + timestamp: 1.707775049e+09 + type: CREATE + version: "1" + - Name: No MFA method change + ExpectedResult: false + Log: + id: d1e5794f-666d-4cba-abae-c6d889ca1903 + new: + appId: 67ef5c13-b5e6-4945-af7b-c11ac98f630f + appType: CONTENTFUL + creationTimestamp: 1.707775048e+09 + email: jet.black@issp.com + employeeId: ca6cf7ce-90e6-4eb5-a262-7899bc48c39c + id: 5e15ce4c-6b93-4fbf-aed9-1890775efa90 + lastUsedTimestamp: null + loginMethods: + oidcLogin: null + oktaSwaLogin: false + passwordLogin: false + samlLogin: null + mfaMethods: + - SMS + - APP_OTP + mfaRegistered: false + passwordId: null + object: ACCOUNT + old: + appId: 67ef5c13-b5e6-4945-af7b-c11ac98f630f + appType: CONTENTFUL + creationTimestamp: 1.707775048e+09 + email: jet.black@issp.com + employeeId: ca6cf7ce-90e6-4eb5-a262-7899bc48c39c + id: 5e15ce4c-6b93-4fbf-aed9-1890775efa90 + lastUsedTimestamp: null + loginMethods: + oidcLogin: null + oktaSwaLogin: false + passwordLogin: false + samlLogin: null + mfaMethods: + - SMS + - APP_OTP + mfaRegistered: false + passwordId: null + timestamp: 1.707775049e+09 + type: CREATE + version: "1" diff --git a/rules/push_security_rules/push_security_new_app_detected.py b/rules/push_security_rules/push_security_new_app_detected.py new file mode 100644 index 000000000..0388dd77e --- /dev/null +++ b/rules/push_security_rules/push_security_new_app_detected.py @@ -0,0 +1,16 @@ +from panther_base_helpers import deep_get + + +def rule(event): + if event.get("object") != "APP": + return False + + if event.get("type") == "CREATE": + return True + + return False + + +def title(event): + new_type = deep_get(event, "new", "type") + return f"New app in use: {new_type}" diff --git a/rules/push_security_rules/push_security_new_app_detected.yml b/rules/push_security_rules/push_security_new_app_detected.yml new file mode 100644 index 000000000..c06391513 --- /dev/null +++ b/rules/push_security_rules/push_security_new_app_detected.yml @@ -0,0 +1,54 @@ +AnalysisType: rule +Filename: push_security_new_app_detected.py +RuleID: "Push.Security.New.App.Detected" +DisplayName: "Push Security New App Detected" +Enabled: true +LogTypes: + - Custom.PushSecurity.Entities +Severity: Info +DedupPeriodMinutes: 60 +Threshold: 1 +Tests: + - Name: New App + ExpectedResult: true + Log: + id: c478966c-f927-411c-b919-179832d3d50c + new: + approvalStatus: null + creationTimestamp: 1.698064423e+09 + id: 2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0 + notes: "" + ownerId: null + sensitivityLevel: null + type: ZAPIER + object: APP + old: null + timestamp: 1.698604061e+09 + type: CREATE + version: "1" + - Name: App Updated + ExpectedResult: false + Log: + id: c478966c-f927-411c-b919-179832d3d50c + new: + approvalStatus: APPROVED + creationTimestamp: 1.698064423e+09 + id: 2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0 + notes: | + Last security audit: 16 January 2023. + ownerId: 87569da6-fb7a-4df7-8ce2-246c14044911 + sensitivityLevel: HIGH + type: ZAPIER + object: APP + old: + approvalStatus: UNDER_REVIEW + creationTimestamp: 1.698064423e+09 + id: 2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0 + notes: | + Initial submission for review. + ownerId: 87569da6-fb7a-4df7-8ce2-246c14044911 + sensitivityLevel: MEDIUM + type: ZAPIER + timestamp: 1.698604061e+09 + type: UPDATE + version: "1" diff --git a/rules/push_security_rules/push_security_new_saas_account_created.py b/rules/push_security_rules/push_security_new_saas_account_created.py new file mode 100644 index 000000000..942ab2581 --- /dev/null +++ b/rules/push_security_rules/push_security_new_saas_account_created.py @@ -0,0 +1,17 @@ +from panther_base_helpers import deep_get + + +def rule(event): + if event.get("object") != "ACCOUNT": + return False + + if event.get("type") == "CREATE": + return True + + return False + + +def title(event): + app_type = deep_get(event, "new", "appType") + new_email = deep_get(event, "new", "email") + return f"New account on {app_type} created by {new_email}" diff --git a/rules/push_security_rules/push_security_new_saas_account_created.yml b/rules/push_security_rules/push_security_new_saas_account_created.yml new file mode 100644 index 000000000..cf20f2705 --- /dev/null +++ b/rules/push_security_rules/push_security_new_saas_account_created.yml @@ -0,0 +1,115 @@ +AnalysisType: rule +Filename: push_security_new_saas_account_created.py +RuleID: "Push.Security.New.SaaS.Account.Created" +DisplayName: "Push Security New SaaS Account Created" +Enabled: true +LogTypes: + - Custom.PushSecurity.Entities +Severity: Info +DedupPeriodMinutes: 60 +Threshold: 1 +Tests: + - Name: Account Update + ExpectedResult: false + Log: + id: c478966c-f927-411c-b919-179832d3d50c + new: + appId: 2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0 + appType: ATLASSIAN + creationTimestamp: 1.698064423e+09 + email: john.hill@example.com + employeeId: 72d0347a-2663-4ef5-b1c5-df39163f1603 + id: d6a32ba5-0532-4a66-8137-48cdf409c972 + lastUsedTimestamp: 1.698669168e+09 + loginMethods: + oidcLogin: GOOGLE_WORKSPACE + oktaSwaLogin: true + passwordLogin: true + samlLogin: OKTA + vendorSsoLogin: GOOGLE_WORKSPACE + mfaMethods: + - APP_TOTP + - PUSH_NOTIFICATION + - EMAIL_OTP + - U2F + - HARDWARE_TOTP + - PHONE_CALL + - SMS_OTP + - APP_PASSWORD + - GRID_CARD + - EXTERNAL_PROVIDER + - BACKUP_CODES + - WEBAUTHN + mfaRegistered: true + passwordId: 4c13674f-e88a-4411-bfa2-53a70468a898 + object: ACCOUNT + old: + appId: 2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0 + appType: ATLASSIAN + creationTimestamp: 1.698064423e+09 + email: john.hill@example.com + employeeId: 72d0347a-2663-4ef5-b1c5-df39163f1603 + id: d6a32ba5-0532-4a66-8137-48cdf409c972 + lastUsedTimestamp: 1.698669168e+09 + loginMethods: + oidcLogin: GOOGLE_WORKSPACE + oktaSwaLogin: true + passwordLogin: true + samlLogin: OKTA + vendorSsoLogin: GOOGLE_WORKSPACE + mfaMethods: + - APP_TOTP + - PUSH_NOTIFICATION + - EMAIL_OTP + - U2F + - HARDWARE_TOTP + - PHONE_CALL + - SMS_OTP + - APP_PASSWORD + - GRID_CARD + - EXTERNAL_PROVIDER + - BACKUP_CODES + - WEBAUTHN + mfaRegistered: true + passwordId: 4c13674f-e88a-4411-bfa2-53a70468a898 + timestamp: 1.698604061e+09 + type: UPDATE + version: "1" + - Name: New Account + ExpectedResult: true + Log: + id: c478966c-f927-411c-b919-179832d3d50c + new: + appId: 2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0 + appType: ATLASSIAN + creationTimestamp: 1.698064423e+09 + email: john.hill@example.com + employeeId: 72d0347a-2663-4ef5-b1c5-df39163f1603 + id: d6a32ba5-0532-4a66-8137-48cdf409c972 + lastUsedTimestamp: 1.698669168e+09 + loginMethods: + oidcLogin: GOOGLE_WORKSPACE + oktaSwaLogin: true + passwordLogin: true + samlLogin: OKTA + vendorSsoLogin: GOOGLE_WORKSPACE + mfaMethods: + - APP_TOTP + - PUSH_NOTIFICATION + - EMAIL_OTP + - U2F + - HARDWARE_TOTP + - PHONE_CALL + - SMS_OTP + - APP_PASSWORD + - GRID_CARD + - EXTERNAL_PROVIDER + - BACKUP_CODES + - WEBAUTHN + mfaRegistered: true + passwordId: 4c13674f-e88a-4411-bfa2-53a70468a898 + object: ACCOUNT + old: null + timestamp: 1.698604061e+09 + type: CREATE + version: "1" diff --git a/rules/push_security_rules/push_security_open_security_finding.py b/rules/push_security_rules/push_security_open_security_finding.py new file mode 100644 index 000000000..6b6d7f82d --- /dev/null +++ b/rules/push_security_rules/push_security_open_security_finding.py @@ -0,0 +1,22 @@ +from panther_base_helpers import deep_get + + +def rule(event): + if event.get("object") != "FINDING": + return False + + event_type = event.get("type") + + if event_type == "CREATE": + return True + + if event_type == "UPDATE" and deep_get(event, "new", "state") == "OPEN": + return True + + return False + + +def title(event): + new_type = deep_get(event, "new", "type") + app_type = deep_get(event, "new", "appType") + return f"Open finding {new_type} for app {app_type}" diff --git a/rules/push_security_rules/push_security_open_security_finding.yml b/rules/push_security_rules/push_security_open_security_finding.yml new file mode 100644 index 000000000..8d46a7f23 --- /dev/null +++ b/rules/push_security_rules/push_security_open_security_finding.yml @@ -0,0 +1,86 @@ +AnalysisType: rule +Filename: push_security_open_security_finding.py +RuleID: "Push.Security.Open.Security.Finding" +DisplayName: "Push Security Open Security Finding" +Enabled: true +LogTypes: + - Custom.PushSecurity.Entities +Severity: Info +DedupPeriodMinutes: 60 +Threshold: 1 +Tests: + - Name: Resolved Finding + ExpectedResult: false + Log: + id: c478966c-f927-411c-b919-179832d3d50c + new: + accountId: null + appId: 2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0 + appType: PUSH_SECURITY + creationTimestamp: 1.698064423e+09 + employeeId: 379ac7ea-ff2a-42ef-af37-06d2020dc46a + id: d6a32ba5-0532-4a66-8137-48cdf409c972 + passwordId: c4a045a1-5331-4714-af83-6a361e98960d + state: RESOLVED + type: WEAK_PASSWORD + object: FINDING + old: + accountId: null + appId: 2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0 + appType: PUSH_SECURITY + creationTimestamp: 1.698064423e+09 + employeeId: 379ac7ea-ff2a-42ef-af37-06d2020dc46a + id: d6a32ba5-0532-4a66-8137-48cdf409c972 + passwordId: c4a045a1-5331-4714-af83-6a361e98960d + state: OPEN + type: WEAK_PASSWORD + timestamp: 1.698604061e+09 + type: UPDATE + version: "1" + - Name: New Finding + ExpectedResult: true + Log: + id: c478966c-f927-411c-b919-179832d3d50c + new: + accountId: null + appId: 2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0 + appType: PUSH_SECURITY + creationTimestamp: 1.698064423e+09 + employeeId: 379ac7ea-ff2a-42ef-af37-06d2020dc46a + id: d6a32ba5-0532-4a66-8137-48cdf409c972 + passwordId: c4a045a1-5331-4714-af83-6a361e98960d + state: OPEN + type: WEAK_PASSWORD + object: FINDING + old: null + timestamp: 1.698604061e+09 + type: CREATE + version: "1" + - Name: Reopened Finding + ExpectedResult: true + Log: + id: c478966c-f927-411c-b919-179832d3d50c + new: + accountId: null + appId: 2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0 + appType: PUSH_SECURITY + creationTimestamp: 1.698064423e+09 + employeeId: 379ac7ea-ff2a-42ef-af37-06d2020dc46a + id: d6a32ba5-0532-4a66-8137-48cdf409c972 + passwordId: c4a045a1-5331-4714-af83-6a361e98960d + state: OPEN + type: WEAK_PASSWORD + object: FINDING + old: + accountId: null + appId: 2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0 + appType: PUSH_SECURITY + creationTimestamp: 1.698064423e+09 + employeeId: 379ac7ea-ff2a-42ef-af37-06d2020dc46a + id: d6a32ba5-0532-4a66-8137-48cdf409c972 + passwordId: c4a045a1-5331-4714-af83-6a361e98960d + state: RESOLVED + type: WEAK_PASSWORD + timestamp: 1.698604061e+09 + type: UPDATE + version: "1" diff --git a/rules/push_security_rules/push_security_phishable_mfa_method.py b/rules/push_security_rules/push_security_phishable_mfa_method.py new file mode 100644 index 000000000..dac56cccd --- /dev/null +++ b/rules/push_security_rules/push_security_phishable_mfa_method.py @@ -0,0 +1,33 @@ +from panther_base_helpers import deep_get + +identity_providers = ("MICROSOFT_365", "GOOGLE_WORKSPACE", "OKTA", "JUMPCLOUD", "PING") + +phishable_mfa = ("EMAIL_OTP", "PHONE_CALL", "SMS", "APP_PASSWORD") + + +def rule(event): + if event.get("object") != "ACCOUNT": + return False + + mfa_methods = deep_get(event, "new", "mfaMethods") + + for method in mfa_methods: + if method in phishable_mfa: + return True + + return False + + +def severity(event): + if deep_get(event, "new", "appType") in identity_providers: + return "HIGH" + return "INFO" + + +def title(event): + mfa_methods = ", ".join(deep_get(event, "new", "mfaMethods", default="No MFA")) + new_email = deep_get(event, "new", "email") + app_type = deep_get(event, "new", "appType", default=[]) + + return f"{new_email} using phisbable MFA method with {app_type}. \ + MFA methods enabled: {mfa_methods}" diff --git a/rules/push_security_rules/push_security_phishable_mfa_method.yml b/rules/push_security_rules/push_security_phishable_mfa_method.yml new file mode 100644 index 000000000..be2f81530 --- /dev/null +++ b/rules/push_security_rules/push_security_phishable_mfa_method.yml @@ -0,0 +1,99 @@ +AnalysisType: rule +Filename: push_security_phishable_mfa_method.py +RuleID: "Push.Security.Phishable.MFA.Method" +DisplayName: "Push Security Phishable MFA Method" +Enabled: true +LogTypes: + - Custom.PushSecurity.Entities +Severity: Info +DedupPeriodMinutes: 60 +Threshold: 1 +Tests: + - Name: Dropbox Phishable MFA + ExpectedResult: true + Log: + id: d1e5794f-666d-4cba-abae-c6d889ca1903 + new: + appId: 67ef5c13-b5e6-4945-af7b-c11ac98f630f + appType: DROPBOX + creationTimestamp: 1.707775048e+09 + email: jet.black@issp.com + employeeId: ca6cf7ce-90e6-4eb5-a262-7899bc48c39c + id: 5e15ce4c-6b93-4fbf-aed9-1890775efa90 + lastUsedTimestamp: null + loginMethods: + oidcLogin: null + oktaSwaLogin: false + passwordLogin: false + samlLogin: null + mfaMethods: + - SMS + - EMAIL_OTP + mfaRegistered: false + passwordId: null + object: ACCOUNT + old: null + - Name: Google Workspace Phishable MFA + ExpectedResult: true + Log: + id: d1e5794f-666d-4cba-abae-c6d889ca1903 + new: + appId: 67ef5c13-b5e6-4945-af7b-c11ac98f630f + appType: GOOGLE_WORKSPACE + creationTimestamp: 1.707775048e+09 + email: jet.black@issp.com + employeeId: ca6cf7ce-90e6-4eb5-a262-7899bc48c39c + id: 5e15ce4c-6b93-4fbf-aed9-1890775efa90 + lastUsedTimestamp: null + loginMethods: + oidcLogin: null + oktaSwaLogin: false + passwordLogin: false + samlLogin: null + mfaMethods: + - SMS + - EMAIL_OTP + mfaRegistered: false + passwordId: null + object: ACCOUNT + old: null + - Name: No MFA Enabled + ExpectedResult: false + Log: + id: d1e5794f-666d-4cba-abae-c6d889ca1903 + new: + appId: 67ef5c13-b5e6-4945-af7b-c11ac98f630f + appType: CONTENTFUL + creationTimestamp: 1.707775048e+09 + email: jet.black@issp.com + employeeId: ca6cf7ce-90e6-4eb5-a262-7899bc48c39c + id: 5e15ce4c-6b93-4fbf-aed9-1890775efa90 + lastUsedTimestamp: null + loginMethods: + oidcLogin: null + oktaSwaLogin: false + passwordLogin: false + samlLogin: null + mfaMethods: [] + mfaRegistered: false + passwordId: null + object: ACCOUNT + old: + appId: 67ef5c13-b5e6-4945-af7b-c11ac98f630f + appType: CONTENTFUL + creationTimestamp: 1.707775048e+09 + email: jet.black@issp.com + employeeId: ca6cf7ce-90e6-4eb5-a262-7899bc48c39c + id: 5e15ce4c-6b93-4fbf-aed9-1890775efa90 + lastUsedTimestamp: null + loginMethods: + oidcLogin: null + oktaSwaLogin: false + passwordLogin: false + samlLogin: null + mfaMethods: [] + mfaRegistered: false + passwordId: null + timestamp: 1.707775049e+09 + type: CREATE + version: "1" diff --git a/rules/push_security_rules/push_security_phishing_attack.py b/rules/push_security_rules/push_security_phishing_attack.py new file mode 100644 index 000000000..814fb6083 --- /dev/null +++ b/rules/push_security_rules/push_security_phishing_attack.py @@ -0,0 +1,22 @@ +from panther_base_helpers import deep_get + + +def rule(event): + if event.get("object") == "PASSWORD_PHISHING": + return True + + return False + + +def severity(event): + if deep_get(event, "new", "mode") != "BLOCK": + return "HIGH" + return "LOW" + + +def title(event): + app_type = deep_get(event, "new", "appType") + employee_email = deep_get(event, "new", "employee", "email") + new_mode = deep_get(event, "new", "mode") + return f"Phishing attack on app {app_type} user {employee_email}. \ + Attack detected in mode {new_mode}." diff --git a/rules/push_security_rules/push_security_phishing_attack.yml b/rules/push_security_rules/push_security_phishing_attack.yml new file mode 100644 index 000000000..974542099 --- /dev/null +++ b/rules/push_security_rules/push_security_phishing_attack.yml @@ -0,0 +1,63 @@ +AnalysisType: rule +Filename: push_security_phishing_attack.py +RuleID: "Push.Security.Phishing.Attack" +DisplayName: "Push Security Phishing Attack" +Enabled: true +LogTypes: + - Custom.PushSecurity.AttackDetection +Severity: High +DedupPeriodMinutes: 60 +Threshold: 1 +Tests: + - Name: Phishing Detected - Block Mode + ExpectedResult: true + Log: + id: c478966c-f927-411c-b919-179832d3d50c + new: + appType: OKTA + browser: CHROME + employee: + chatopsEnabled: true + creationTimestamp: 1.698669223e+09 + department: Security Engineering + email: john.hill@example.com + firstName: John + id: 2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0 + lastName: Hill + licensed: true + location: New York + mode: BLOCK + os: WINDOWS + referrerUrl: https://statics.teams.cdn.office.net/ + sourceIpAddress: 8.158.25.38 + url: https://evil.com/okta.php + userAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299 + object: PASSWORD_PHISHING + timestamp: 1.698604061e+09 + version: "1" + - Name: Phishing Detected - Monitor Mode + ExpectedResult: true + Log: + id: c478966c-f927-411c-b919-179832d3d50c + new: + appType: OKTA + browser: CHROME + employee: + chatopsEnabled: true + creationTimestamp: 1.698669223e+09 + department: Security Engineering + email: john.hill@example.com + firstName: John + id: 2a2197de-ad2c-47e4-8dcb-fb0f04cf83e0 + lastName: Hill + licensed: true + location: New York + mode: MONITOR + os: WINDOWS + referrerUrl: https://statics.teams.cdn.office.net/ + sourceIpAddress: 8.158.25.38 + url: https://evil.com/okta.php + userAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299 + object: PASSWORD_PHISHING + timestamp: 1.698604061e+09 + version: "1" diff --git a/rules/push_security_rules/push_security_unauthorized_idp_login.py b/rules/push_security_rules/push_security_unauthorized_idp_login.py new file mode 100644 index 000000000..72af762cf --- /dev/null +++ b/rules/push_security_rules/push_security_unauthorized_idp_login.py @@ -0,0 +1,31 @@ +from panther_base_helpers import deep_get + +# Configure allowed identity provider logins to SaaS apps +allowed_idps = { + "GOOGLE_WORKSPACE": {"OIDC_LOGIN", "SAML_LOGIN"}, + "OKTA": {"PASSWORD_LOGIN"}, + None: {"PASSWORD_LOGIN"}, +} + + +def rule(event): + if event.get("object") != "LOGIN": + return False + + identity_provider = deep_get(event, "new", "identityProvider") + login_type = deep_get(event, "new", "loginType") + + if identity_provider in allowed_idps and login_type in allowed_idps[identity_provider]: + return False + + return True + + +def title(event): + identity_provider = deep_get(event, "new", "identityProvider", default="Null identityProvider") + login_type = deep_get(event, "new", "loginType", default="Null loginType") + app_type = deep_get(event, "new", "appType", default="Null appType") + new_email = deep_get(event, "new", "email") + + return f"Unauthorized identity provider in use. User: {new_email} \ + used {identity_provider} {login_type} on {app_type}" diff --git a/rules/push_security_rules/push_security_unauthorized_idp_login.yml b/rules/push_security_rules/push_security_unauthorized_idp_login.yml new file mode 100644 index 000000000..69188c856 --- /dev/null +++ b/rules/push_security_rules/push_security_unauthorized_idp_login.yml @@ -0,0 +1,88 @@ +AnalysisType: rule +Filename: push_security_unauthorized_idp_login.py +RuleID: "Push.Security.Unauthorized.IdP.Login" +DisplayName: "Push Security Unauthorized IdP Login" +Enabled: true +LogTypes: + - Custom.PushSecurity.Activity +Severity: High +Description: Login to application with unauthorized identity provider which could indicate a SAMLjacking attack. +Reference: https://github.com/pushsecurity/saas-attacks/blob/main/techniques/samljacking/description.md +DedupPeriodMinutes: 60 +Threshold: 1 +Tests: + - Name: Google Workspace Password Login + ExpectedResult: true + Log: + id: d240e3f2-3cd6-425f-a835-dad0ff237d09 + new: + accountId: a93b45a7-fdce-489e-b76d-2bd6862a62ba + appId: 8348ca36-d254-4e1b-8f31-6837d82fc5cb + appType: GOOGLE_WORKSPACE + browser: EDGE + email: jet.black@issp.com + employeeId: ca6cf7ce-90e6-4eb5-a262-7899bc48c39c + identityProvider: GOOGLE_WORKSPACE + leakedPassword: false + loginTimestamp: 1.707773386e+09 + loginType: PASSWORD_LOGIN + os: WINDOWS + passwordId: 6ae9f0b2-9300-43f0-b210-c0d3c16640f8 + passwordManuallyTyped: false + sourceIpAddress: 35.90.103.134 + userAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.2420.81 + weakPassword: false + weakPasswordReasons: null + object: LOGIN + timestamp: 1.707774319e+09 + version: "1" + - Name: Microsoft 365 OIDC Login + ExpectedResult: true + Log: + id: d240e3f2-3cd6-425f-a835-dad0ff237d09 + new: + accountId: a93b45a7-fdce-489e-b76d-2bd6862a62ba + appId: 8348ca36-d254-4e1b-8f31-6837d82fc5cb + appType: DROPBOX + browser: EDGE + email: jet.black@issp.com + employeeId: ca6cf7ce-90e6-4eb5-a262-7899bc48c39c + identityProvider: MICROSOFT_365 + leakedPassword: false + loginTimestamp: 1.707773386e+09 + loginType: OIDC_LOGIN + os: WINDOWS + passwordId: 6ae9f0b2-9300-43f0-b210-c0d3c16640f8 + passwordManuallyTyped: false + sourceIpAddress: 35.90.103.134 + userAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.2420.81 + weakPassword: false + weakPasswordReasons: null + object: LOGIN + timestamp: 1.707774319e+09 + version: "1" + - Name: Password Login + ExpectedResult: false + Log: + id: d240e3f2-3cd6-425f-a835-dad0ff237d09 + new: + accountId: a93b45a7-fdce-489e-b76d-2bd6862a62ba + appId: 8348ca36-d254-4e1b-8f31-6837d82fc5cb + appType: DROPBOX + browser: EDGE + email: jet.black@issp.com + employeeId: ca6cf7ce-90e6-4eb5-a262-7899bc48c39c + identityProvider: null + leakedPassword: false + loginTimestamp: 1.707773386e+09 + loginType: PASSWORD_LOGIN + os: WINDOWS + passwordId: 6ae9f0b2-9300-43f0-b210-c0d3c16640f8 + passwordManuallyTyped: false + sourceIpAddress: 35.90.103.134 + userAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.2420.81 + weakPassword: false + weakPasswordReasons: null + object: LOGIN + timestamp: 1.707774319e+09 + version: "1" From 1252a700ab802a310d60e88f1ac83de9d328aa31 Mon Sep 17 00:00:00 2001 From: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> Date: Tue, 21 May 2024 09:34:59 -0600 Subject: [PATCH 08/35] created pack and updated event.deep_get (#1239) --- packs/push_security.yml | 13 +++++++++++++ .../push_security_app_banner_acknowledged.py | 17 +++++++---------- .../push_security_mfa_method_changed.py | 15 ++++++--------- .../push_security_new_app_detected.py | 5 +---- .../push_security_new_saas_account_created.py | 7 ++----- .../push_security_open_security_finding.py | 9 +++------ .../push_security_phishable_mfa_method.py | 12 +++++------- .../push_security_phishing_attack.py | 11 ++++------- .../push_security_unauthorized_idp_login.py | 14 ++++++-------- .../push_security_unauthorized_idp_login.yml | 4 +++- 10 files changed, 50 insertions(+), 57 deletions(-) create mode 100644 packs/push_security.yml diff --git a/packs/push_security.yml b/packs/push_security.yml new file mode 100644 index 000000000..358494f68 --- /dev/null +++ b/packs/push_security.yml @@ -0,0 +1,13 @@ +AnalysisType: pack +PackID: PantherManaged.PushSecurity +Description: Group of all Push Security detections +PackDefinition: + IDs: + - Push.Security.App.Banner.Acknowledged + - Push.Security.MFA.Method.Changed + - Push.Security.New.App.Detected + - Push.Security.New.SaaS.Account.Created + - Push.Security.Open.Security.Finding + - Push.Security.Phishable.MFA.Method + - Push.Security.Phishing.Attack +DisplayName: "Panther Push Security Pack" diff --git a/rules/push_security_rules/push_security_app_banner_acknowledged.py b/rules/push_security_rules/push_security_app_banner_acknowledged.py index baa13bb69..558633a4c 100644 --- a/rules/push_security_rules/push_security_app_banner_acknowledged.py +++ b/rules/push_security_rules/push_security_app_banner_acknowledged.py @@ -1,26 +1,23 @@ -from panther_base_helpers import deep_get - - def rule(event): if event.get("object") != "APP_BANNER": return False - if deep_get(event, "new", "action") == "ACKNOWLEDGED": + if event.deep_get("new", "action") == "ACKNOWLEDGED": return True return False def title(event): - app_type = deep_get(event, "new", "appType") - employee_email = deep_get(event, "new", "employee", "email") + app_type = event.deep_get("new", "appType") + employee_email = event.deep_get("new", "employee", "email") return f"{app_type} accessed by {employee_email}" def alert_context(event): return { - "Push Security app banner": deep_get(event, "new", "appBanner", "mode"), - "Title": deep_get(event, "new", "appBanner", "title"), - "Subtext": deep_get(event, "new", "appBanner", "subtext"), - "Button": deep_get(event, "new", "appBanner", "buttonText"), + "Push Security app banner": event.deep_get("new", "appBanner", "mode"), + "Title": event.deep_get("new", "appBanner", "title"), + "Subtext": event.deep_get("new", "appBanner", "subtext"), + "Button": event.deep_get("new", "appBanner", "buttonText"), } diff --git a/rules/push_security_rules/push_security_mfa_method_changed.py b/rules/push_security_rules/push_security_mfa_method_changed.py index 7bae8a4be..d8f74471c 100644 --- a/rules/push_security_rules/push_security_mfa_method_changed.py +++ b/rules/push_security_rules/push_security_mfa_method_changed.py @@ -1,6 +1,3 @@ -from panther_base_helpers import deep_get - - def rule(event): if event.get("object") != "ACCOUNT": return False @@ -8,8 +5,8 @@ def rule(event): if event.get("old") is None: return False - new_mfa_methods = set(deep_get(event, "new", "mfaMethods")) - old_mfa_methods = set(deep_get(event, "old", "mfaMethods", default=[])) + new_mfa_methods = set(event.deep_get("new", "mfaMethods")) + old_mfa_methods = set(event.deep_get("old", "mfaMethods", default=[])) if new_mfa_methods != old_mfa_methods: return True @@ -18,15 +15,15 @@ def rule(event): def severity(event): - if deep_get(event, "new", "mfaMethods") == []: + if event.deep_get("new", "mfaMethods") == []: return "HIGH" return "LOW" def title(event): - mfa_methods = ", ".join(deep_get(event, "new", "mfaMethods", default="No MFA")) - new_email = deep_get(event, "new", "email") - new_apptype = deep_get(event, "new", "appType") + mfa_methods = ", ".join(event.deep_get("new", "mfaMethods", default="No MFA")) + new_email = event.deep_get("new", "email") + new_apptype = event.deep_get("new", "appType") if mfa_methods == "": return f"{new_email} removed all MFA methods on {new_apptype}" diff --git a/rules/push_security_rules/push_security_new_app_detected.py b/rules/push_security_rules/push_security_new_app_detected.py index 0388dd77e..aa59ccd9b 100644 --- a/rules/push_security_rules/push_security_new_app_detected.py +++ b/rules/push_security_rules/push_security_new_app_detected.py @@ -1,6 +1,3 @@ -from panther_base_helpers import deep_get - - def rule(event): if event.get("object") != "APP": return False @@ -12,5 +9,5 @@ def rule(event): def title(event): - new_type = deep_get(event, "new", "type") + new_type = event.deep_get("new", "type") return f"New app in use: {new_type}" diff --git a/rules/push_security_rules/push_security_new_saas_account_created.py b/rules/push_security_rules/push_security_new_saas_account_created.py index 942ab2581..2be527213 100644 --- a/rules/push_security_rules/push_security_new_saas_account_created.py +++ b/rules/push_security_rules/push_security_new_saas_account_created.py @@ -1,6 +1,3 @@ -from panther_base_helpers import deep_get - - def rule(event): if event.get("object") != "ACCOUNT": return False @@ -12,6 +9,6 @@ def rule(event): def title(event): - app_type = deep_get(event, "new", "appType") - new_email = deep_get(event, "new", "email") + app_type = event.deep_get("new", "appType") + new_email = event.deep_get("new", "email") return f"New account on {app_type} created by {new_email}" diff --git a/rules/push_security_rules/push_security_open_security_finding.py b/rules/push_security_rules/push_security_open_security_finding.py index 6b6d7f82d..6bb780ca0 100644 --- a/rules/push_security_rules/push_security_open_security_finding.py +++ b/rules/push_security_rules/push_security_open_security_finding.py @@ -1,6 +1,3 @@ -from panther_base_helpers import deep_get - - def rule(event): if event.get("object") != "FINDING": return False @@ -10,13 +7,13 @@ def rule(event): if event_type == "CREATE": return True - if event_type == "UPDATE" and deep_get(event, "new", "state") == "OPEN": + if event_type == "UPDATE" and event.deep_get("new", "state") == "OPEN": return True return False def title(event): - new_type = deep_get(event, "new", "type") - app_type = deep_get(event, "new", "appType") + new_type = event.deep_get("new", "type") + app_type = event.deep_get("new", "appType") return f"Open finding {new_type} for app {app_type}" diff --git a/rules/push_security_rules/push_security_phishable_mfa_method.py b/rules/push_security_rules/push_security_phishable_mfa_method.py index dac56cccd..7a8b0ec1d 100644 --- a/rules/push_security_rules/push_security_phishable_mfa_method.py +++ b/rules/push_security_rules/push_security_phishable_mfa_method.py @@ -1,5 +1,3 @@ -from panther_base_helpers import deep_get - identity_providers = ("MICROSOFT_365", "GOOGLE_WORKSPACE", "OKTA", "JUMPCLOUD", "PING") phishable_mfa = ("EMAIL_OTP", "PHONE_CALL", "SMS", "APP_PASSWORD") @@ -9,7 +7,7 @@ def rule(event): if event.get("object") != "ACCOUNT": return False - mfa_methods = deep_get(event, "new", "mfaMethods") + mfa_methods = event.deep_get("new", "mfaMethods") for method in mfa_methods: if method in phishable_mfa: @@ -19,15 +17,15 @@ def rule(event): def severity(event): - if deep_get(event, "new", "appType") in identity_providers: + if event.deep_get("new", "appType") in identity_providers: return "HIGH" return "INFO" def title(event): - mfa_methods = ", ".join(deep_get(event, "new", "mfaMethods", default="No MFA")) - new_email = deep_get(event, "new", "email") - app_type = deep_get(event, "new", "appType", default=[]) + mfa_methods = ", ".join(event.deep_get("new", "mfaMethods", default="No MFA")) + new_email = event.deep_get("new", "email") + app_type = event.deep_get("new", "appType", default=[]) return f"{new_email} using phisbable MFA method with {app_type}. \ MFA methods enabled: {mfa_methods}" diff --git a/rules/push_security_rules/push_security_phishing_attack.py b/rules/push_security_rules/push_security_phishing_attack.py index 814fb6083..20a25830e 100644 --- a/rules/push_security_rules/push_security_phishing_attack.py +++ b/rules/push_security_rules/push_security_phishing_attack.py @@ -1,6 +1,3 @@ -from panther_base_helpers import deep_get - - def rule(event): if event.get("object") == "PASSWORD_PHISHING": return True @@ -9,14 +6,14 @@ def rule(event): def severity(event): - if deep_get(event, "new", "mode") != "BLOCK": + if event.deep_get("new", "mode") != "BLOCK": return "HIGH" return "LOW" def title(event): - app_type = deep_get(event, "new", "appType") - employee_email = deep_get(event, "new", "employee", "email") - new_mode = deep_get(event, "new", "mode") + app_type = event.deep_get("new", "appType") + employee_email = event.deep_get("new", "employee", "email") + new_mode = event.deep_get("new", "mode") return f"Phishing attack on app {app_type} user {employee_email}. \ Attack detected in mode {new_mode}." diff --git a/rules/push_security_rules/push_security_unauthorized_idp_login.py b/rules/push_security_rules/push_security_unauthorized_idp_login.py index 72af762cf..346a33d71 100644 --- a/rules/push_security_rules/push_security_unauthorized_idp_login.py +++ b/rules/push_security_rules/push_security_unauthorized_idp_login.py @@ -1,5 +1,3 @@ -from panther_base_helpers import deep_get - # Configure allowed identity provider logins to SaaS apps allowed_idps = { "GOOGLE_WORKSPACE": {"OIDC_LOGIN", "SAML_LOGIN"}, @@ -12,8 +10,8 @@ def rule(event): if event.get("object") != "LOGIN": return False - identity_provider = deep_get(event, "new", "identityProvider") - login_type = deep_get(event, "new", "loginType") + identity_provider = event.deep_get("new", "identityProvider") + login_type = event.deep_get("new", "loginType") if identity_provider in allowed_idps and login_type in allowed_idps[identity_provider]: return False @@ -22,10 +20,10 @@ def rule(event): def title(event): - identity_provider = deep_get(event, "new", "identityProvider", default="Null identityProvider") - login_type = deep_get(event, "new", "loginType", default="Null loginType") - app_type = deep_get(event, "new", "appType", default="Null appType") - new_email = deep_get(event, "new", "email") + identity_provider = event.deep_get("new", "identityProvider", default="Null identityProvider") + login_type = event.deep_get("new", "loginType", default="Null loginType") + app_type = event.deep_get("new", "appType", default="Null appType") + new_email = event.deep_get("new", "email") return f"Unauthorized identity provider in use. User: {new_email} \ used {identity_provider} {login_type} on {app_type}" diff --git a/rules/push_security_rules/push_security_unauthorized_idp_login.yml b/rules/push_security_rules/push_security_unauthorized_idp_login.yml index 69188c856..70e80e147 100644 --- a/rules/push_security_rules/push_security_unauthorized_idp_login.yml +++ b/rules/push_security_rules/push_security_unauthorized_idp_login.yml @@ -2,7 +2,9 @@ AnalysisType: rule Filename: push_security_unauthorized_idp_login.py RuleID: "Push.Security.Unauthorized.IdP.Login" DisplayName: "Push Security Unauthorized IdP Login" -Enabled: true +Enabled: false +Tags: + - Configuration Required LogTypes: - Custom.PushSecurity.Activity Severity: High From 63db6ceb27d165e7366990e488e52b6ef6d82429 Mon Sep 17 00:00:00 2001 From: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> Date: Tue, 21 May 2024 15:22:06 -0600 Subject: [PATCH 09/35] Push logtype update (#1240) * created pack and updated event.deep_get * update logtype --- .../push_security_app_banner_acknowledged.yml | 2 +- rules/push_security_rules/push_security_mfa_method_changed.yml | 2 +- rules/push_security_rules/push_security_new_app_detected.yml | 2 +- .../push_security_new_saas_account_created.yml | 2 +- .../push_security_rules/push_security_open_security_finding.yml | 2 +- .../push_security_rules/push_security_phishable_mfa_method.yml | 2 +- rules/push_security_rules/push_security_phishing_attack.yml | 2 +- .../push_security_unauthorized_idp_login.yml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/rules/push_security_rules/push_security_app_banner_acknowledged.yml b/rules/push_security_rules/push_security_app_banner_acknowledged.yml index 7a141a067..b6172e695 100644 --- a/rules/push_security_rules/push_security_app_banner_acknowledged.yml +++ b/rules/push_security_rules/push_security_app_banner_acknowledged.yml @@ -4,7 +4,7 @@ RuleID: "Push.Security.App.Banner.Acknowledged" DisplayName: "Push Security App Banner Acknowledged" Enabled: true LogTypes: - - Custom.PushSecurity.Activity + - PushSecurity.Activity Severity: Low DedupPeriodMinutes: 60 Threshold: 1 diff --git a/rules/push_security_rules/push_security_mfa_method_changed.yml b/rules/push_security_rules/push_security_mfa_method_changed.yml index 892e54d9f..d564d94a6 100644 --- a/rules/push_security_rules/push_security_mfa_method_changed.yml +++ b/rules/push_security_rules/push_security_mfa_method_changed.yml @@ -4,7 +4,7 @@ RuleID: "Push.Security.MFA.Method.Changed" DisplayName: "Push Security SaaS App MFA Method Changed" Enabled: true LogTypes: - - Custom.PushSecurity.Entities + - PushSecurity.Entities Severity: Info Description: MFA method on SaaS app changed DedupPeriodMinutes: 60 diff --git a/rules/push_security_rules/push_security_new_app_detected.yml b/rules/push_security_rules/push_security_new_app_detected.yml index c06391513..ba18a596f 100644 --- a/rules/push_security_rules/push_security_new_app_detected.yml +++ b/rules/push_security_rules/push_security_new_app_detected.yml @@ -4,7 +4,7 @@ RuleID: "Push.Security.New.App.Detected" DisplayName: "Push Security New App Detected" Enabled: true LogTypes: - - Custom.PushSecurity.Entities + - PushSecurity.Entities Severity: Info DedupPeriodMinutes: 60 Threshold: 1 diff --git a/rules/push_security_rules/push_security_new_saas_account_created.yml b/rules/push_security_rules/push_security_new_saas_account_created.yml index cf20f2705..1260a0ce2 100644 --- a/rules/push_security_rules/push_security_new_saas_account_created.yml +++ b/rules/push_security_rules/push_security_new_saas_account_created.yml @@ -4,7 +4,7 @@ RuleID: "Push.Security.New.SaaS.Account.Created" DisplayName: "Push Security New SaaS Account Created" Enabled: true LogTypes: - - Custom.PushSecurity.Entities + - PushSecurity.Entities Severity: Info DedupPeriodMinutes: 60 Threshold: 1 diff --git a/rules/push_security_rules/push_security_open_security_finding.yml b/rules/push_security_rules/push_security_open_security_finding.yml index 8d46a7f23..1b3c6a2b6 100644 --- a/rules/push_security_rules/push_security_open_security_finding.yml +++ b/rules/push_security_rules/push_security_open_security_finding.yml @@ -4,7 +4,7 @@ RuleID: "Push.Security.Open.Security.Finding" DisplayName: "Push Security Open Security Finding" Enabled: true LogTypes: - - Custom.PushSecurity.Entities + - PushSecurity.Entities Severity: Info DedupPeriodMinutes: 60 Threshold: 1 diff --git a/rules/push_security_rules/push_security_phishable_mfa_method.yml b/rules/push_security_rules/push_security_phishable_mfa_method.yml index be2f81530..cefd8350b 100644 --- a/rules/push_security_rules/push_security_phishable_mfa_method.yml +++ b/rules/push_security_rules/push_security_phishable_mfa_method.yml @@ -4,7 +4,7 @@ RuleID: "Push.Security.Phishable.MFA.Method" DisplayName: "Push Security Phishable MFA Method" Enabled: true LogTypes: - - Custom.PushSecurity.Entities + - PushSecurity.Entities Severity: Info DedupPeriodMinutes: 60 Threshold: 1 diff --git a/rules/push_security_rules/push_security_phishing_attack.yml b/rules/push_security_rules/push_security_phishing_attack.yml index 974542099..7aa4c4070 100644 --- a/rules/push_security_rules/push_security_phishing_attack.yml +++ b/rules/push_security_rules/push_security_phishing_attack.yml @@ -4,7 +4,7 @@ RuleID: "Push.Security.Phishing.Attack" DisplayName: "Push Security Phishing Attack" Enabled: true LogTypes: - - Custom.PushSecurity.AttackDetection + - PushSecurity.AttackDetection Severity: High DedupPeriodMinutes: 60 Threshold: 1 diff --git a/rules/push_security_rules/push_security_unauthorized_idp_login.yml b/rules/push_security_rules/push_security_unauthorized_idp_login.yml index 70e80e147..32eb90f02 100644 --- a/rules/push_security_rules/push_security_unauthorized_idp_login.yml +++ b/rules/push_security_rules/push_security_unauthorized_idp_login.yml @@ -6,7 +6,7 @@ Enabled: false Tags: - Configuration Required LogTypes: - - Custom.PushSecurity.Activity + - PushSecurity.Activity Severity: High Description: Login to application with unauthorized identity provider which could indicate a SAMLjacking attack. Reference: https://github.com/pushsecurity/saas-attacks/blob/main/techniques/samljacking/description.md From 442849c33d007b58544751740fd6b2d6a4de4719 Mon Sep 17 00:00:00 2001 From: Evan Gibler <20933572+egibs@users.noreply.github.com> Date: Wed, 22 May 2024 15:49:46 -0500 Subject: [PATCH 10/35] Remove Node/NPM/Prettier (#1241) * Remove Node/NPM/Prettier Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> * Update README; add removal notes Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> --------- Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> --- .img/panther-logo-github-highres-dark.png | Bin 0 -> 63795 bytes .img/panther-logo-github-highres-light.png | Bin 0 -> 63752 bytes .img/panther-logo-github-highres.png | Bin 79268 -> 0 bytes Dockerfile | 8 ---- Makefile | 4 -- README.md | 14 ++++++- package-lock.json | 43 --------------------- package.json | 9 ----- 8 files changed, 13 insertions(+), 65 deletions(-) create mode 100644 .img/panther-logo-github-highres-dark.png create mode 100644 .img/panther-logo-github-highres-light.png delete mode 100644 .img/panther-logo-github-highres.png delete mode 100644 package-lock.json delete mode 100644 package.json diff --git a/.img/panther-logo-github-highres-dark.png b/.img/panther-logo-github-highres-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..b71175cd8eb2233c65959d1b868878ffd9b81d2c GIT binary patch literal 63795 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

b_l)1Nb$uiJ}l8u%u7mU;teQwEdX)H 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 literal 0 HcmV?d00001 diff --git a/.img/panther-logo-github-highres.png b/.img/panther-logo-github-highres.png deleted file mode 100644 index 03292402e17338fd239daf44995093ccd90ca4e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 79268 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 UNR3iXL1uVTMeS(9k;}LK4@V)EhX4Qo diff --git a/Dockerfile b/Dockerfile index 08073e15d..ea63aff73 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,8 +11,6 @@ RUN apk update \ git \ libffi-dev \ ncurses-dev \ - nodejs \ - npm \ openssl-dev \ readline-dev \ sqlite-dev \ @@ -49,12 +47,6 @@ COPY Pipfile.lock . RUN pipenv uninstall --all RUN pipenv sync --dev -COPY package.json . -COPY package-lock.json . -RUN npm install - -ENV PATH="/home/panther-analysis/node_modules/.bin:$PATH" - # Remove pipfile so it doesn't interfere with local files after install RUN rm Pipfile RUN rm Pipfile.lock diff --git a/Makefile b/Makefile index a4bbcb8e5..8cf5815a1 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,6 @@ lint-pylint: lint-fmt: @echo Checking python file formatting with the black code style checker pipenv run black --line-length=100 --check $(dirs) - npx prettier . --check venv: pipenv sync --dev @@ -53,12 +52,9 @@ pat-update: fmt: pipenv run isort --profile=black $(dirs) pipenv run black --line-length=100 $(dirs) - npx prettier . --write --list-different install: pipenv sync --dev - # install prettier for formatting YAML and Markdown files - npm install test: global-helpers-unit-test pipenv run panther_analysis_tool test $(TEST_ARGS) diff --git a/README.md b/README.md index 95b3db65f..7a600e8e5 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@

- Panther Logo + + + + Displays the dark Panther logo in light mode an the light Panther logo in dark mode. +

Built-in Panther Detections

@@ -255,6 +259,14 @@ git pull panther-upstream main git push ``` +# Remove Deprecated Formatters + +Previously, Node, NPM and Prettier were used for formatting Markdown and YAML files; these are no longer in use. + +Depending on how Node is managed, it will need to be uninstalled or removed if it is no longer needed elsewhere. Refer to your system/package manager's documentation for instructions on removing Node. + +Otherwise, running `npm unintall prettier` will remove Prettier. + # License This repository is licensed under [Apache License, Version 2.0](https://github.com/panther-labs/panther-analysis/blob/main/LICENSE.txt). diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 514d6858f..000000000 --- a/package-lock.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "panther-analysis", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "devDependencies": { - "husky": "^9.0.11", - "prettier": "^3.2.5" - } - }, - "node_modules/husky": { - "version": "9.0.11", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", - "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", - "dev": true, - "bin": { - "husky": "bin.mjs" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" - } - }, - "node_modules/prettier": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", - "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", - "dev": true, - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index 6972ee8f9..000000000 --- a/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "devDependencies": { - "husky": "^9.0.11", - "prettier": "^3.2.5" - }, - "scripts": { - "prepare": "husky" - } -} From c8b23bd9a1e24abc1f033f4cfecd2f68c68f1644 Mon Sep 17 00:00:00 2001 From: Evan Gibler <20933572+egibs@users.noreply.github.com> Date: Wed, 29 May 2024 12:20:28 -0500 Subject: [PATCH 11/35] Small Workflow tweaks (#1243) Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> --- .github/workflows/lint.yml | 2 -- .github/workflows/upload.yml | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 0d2f267bf..465b02649 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -9,8 +9,6 @@ jobs: steps: - name: Checkout panther-analysis uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 - with: - ref: ${{ github.event.pull_request.head.sha }} - name: Set python version uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d #v5.1.0 diff --git a/.github/workflows/upload.yml b/.github/workflows/upload.yml index 4c313e8a3..9e2ab566b 100644 --- a/.github/workflows/upload.yml +++ b/.github/workflows/upload.yml @@ -5,7 +5,7 @@ on: jobs: upload: - name: + name: Upload runs-on: ubuntu-latest env: API_HOST: ${{ secrets.API_HOST }} From dc7070c4caa34ddcfb525a5e7ae7e304454060ae Mon Sep 17 00:00:00 2001 From: Evan Gibler <20933572+egibs@users.noreply.github.com> Date: Wed, 29 May 2024 14:33:03 -0500 Subject: [PATCH 12/35] Use harden-runner Action for all Workflows (#1244) * Use harden-runner Action for all Workflows Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> * Run Docker Workflow Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> * Add blocking policy for docker.yml Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> * Add permissions to Workflow Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> * More permissions Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> --------- Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> --- .github/workflows/check-packs.yml | 13 +++++++++++++ .github/workflows/docker.yml | 18 ++++++++++++++++++ .github/workflows/lint.yml | 11 +++++++++++ .github/workflows/release.yml | 6 ++++++ .github/workflows/test.yml | 12 ++++++++++++ .github/workflows/upload.yml | 6 ++++++ 6 files changed, 66 insertions(+) diff --git a/.github/workflows/check-packs.yml b/.github/workflows/check-packs.yml index c2374d928..ecbe41eb4 100644 --- a/.github/workflows/check-packs.yml +++ b/.github/workflows/check-packs.yml @@ -1,12 +1,25 @@ on: pull_request: +permissions: + contents: read + jobs: check_packs: name: check packs runs-on: ubuntu-latest steps: + - uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0 + with: + disable-sudo: true + egress-policy: block + allowed-endpoints: > + github.com:443 + files.pythonhosted.org:443 + github.com:443 + pypi.org:443 + - name: Checkout panther-analysis uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index d9f205a58..145a8fb5f 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -3,11 +3,29 @@ on: paths: - "Dockerfile" +permissions: + contents: read + jobs: test: name: Build Dockerfile runs-on: ubuntu-latest steps: + - uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0 + with: + disable-sudo: true + egress-policy: block + allowed-endpoints: > + 9236a389bd48b984df91adc1bc924620.r2.cloudflarestorage.com:443 + auth.docker.io:443 + cgr.dev:443 + files.pythonhosted.org:443 + github.com:443 + packages.wolfi.dev:443 + production.cloudflare.docker.com:443 + pypi.org:443 + registry-1.docker.io:443 + www.python.org:443 - name: Checkout panther-analysis uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 - uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 #v3.0.0 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 465b02649..7d14b654c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,12 +1,23 @@ on: pull_request: +permissions: + contents: read + jobs: lint: name: Lint runs-on: ubuntu-latest steps: + - uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0 + with: + disable-sudo: true + egress-policy: block + allowed-endpoints: > + files.pythonhosted.org:443 + github.com:443 + pypi.org:443 - name: Checkout panther-analysis uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3e3af00f1..7cea376f7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,6 +3,9 @@ name: Panther Analysis Release on: workflow_dispatch: +permissions: + contents: read + jobs: release: runs-on: ubuntu-latest @@ -12,6 +15,9 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.PANTHER_BOT_AUTOMATION_TOKEN }} steps: + - uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0 + with: + egress-policy: audit - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 with: fetch-depth: 0 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e4d4c6acc..c8de04080 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,12 +1,24 @@ on: pull_request: +permissions: + contents: read + jobs: test: name: Test runs-on: ubuntu-latest steps: + - uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0 + with: + disable-sudo: true + egress-policy: block + allowed-endpoints: > + files.pythonhosted.org:443 + github.com:443 + ipinfo.io:443 + pypi.org:443 - name: Checkout panther-analysis uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 diff --git a/.github/workflows/upload.yml b/.github/workflows/upload.yml index 9e2ab566b..bf5e49e0b 100644 --- a/.github/workflows/upload.yml +++ b/.github/workflows/upload.yml @@ -3,6 +3,9 @@ on: branches: - main +permissions: + contents: read + jobs: upload: name: Upload @@ -11,6 +14,9 @@ jobs: API_HOST: ${{ secrets.API_HOST }} API_TOKEN: ${{ secrets.API_TOKEN }} steps: + - uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0 + with: + egress-policy: audit - name: Validate Secrets if: ${{ env.API_HOST == '' || env.API_TOKEN == '' }} run: | From 736c2509a2ee55f05113111836b8c60d4a169260 Mon Sep 17 00:00:00 2001 From: akozlovets098 <95437895+akozlovets098@users.noreply.github.com> Date: Thu, 30 May 2024 17:55:39 +0300 Subject: [PATCH 13/35] Threat 319 Replace geoinfo_from_ip with new version (#1242) * Deprecate GreyNoise detections (#1205) * Deprecate GreyNoise detections * Update rules/aws_cloudtrail_rules/aws_s3_activity_greynoise.yml * Update rules/cloudflare_rules/cloudflare_firewall_suspicious_event_greynoise.yml * Update cloudflare_httpreq_bot_high_volume_greynoise.yml --------- Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> * fix - Notion Login From New Location - NoneType error (#1206) * fix - Notion Login From New Location - NoneType error * fix - Notion Login From New Location - NoneType error - linter fix * remove codeowners (#1208) * fix - GCP rules - AttributeError (#1210) * fix - GCP rules - AttributeError * fix - GCP rules - AttributeError - linter fix * MITRE ATT&CK Mappings for MS Rules (#1209) * added MITRE mappings for microsoft rules * fixed formatting on some helper files --------- Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> * traildiscover enrichment with managed schema (#1177) * traildiscover enrichment with managed schema * Add npm install in dockerfile (#1172) * add npm install in dockerfile * Remove Python optimizations; add prettier to PATH --------- Co-authored-by: egibs * schema name: TrailDiscover.CloudTrail * Fix Dockerfile; add Workflow to test image * updated data set * Add MongoDB.2FA.Disabled rule (#1190) Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> * lint and fmt * fmt * add OCSF selector * additional OCSF mappings * Fix Pipfile * Rebase changes --------- Co-authored-by: Panos Sakkos Co-authored-by: egibs Co-authored-by: Oleh Melenevskyi <767472+melenevskyi@users.noreply.github.com> * Update PAT to 0.46.0 (#1216) * THREAT-319 Replace geoinfo_from_ip with new version --------- Co-authored-by: Oleh Melenevskyi <767472+melenevskyi@users.noreply.github.com> Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> Co-authored-by: Panos Sakkos Co-authored-by: ben-githubs <38414634+ben-githubs@users.noreply.github.com> Co-authored-by: egibs Co-authored-by: Evan Gibler Co-authored-by: Evan Gibler <20933572+egibs@users.noreply.github.com> --- rules/standard_rules/brute_force_by_ip.py | 5 +++-- rules/standard_rules/unusual_login_deprecated.py | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/rules/standard_rules/brute_force_by_ip.py b/rules/standard_rules/brute_force_by_ip.py index 098523f17..d431da3e3 100644 --- a/rules/standard_rules/brute_force_by_ip.py +++ b/rules/standard_rules/brute_force_by_ip.py @@ -2,7 +2,8 @@ import panther_event_type_helpers as event_type from panther_default import lookup_aws_account_name -from panther_oss_helpers import add_parse_delay, geoinfo_from_ip +from panther_ipinfo_helpers import geoinfo_from_ip +from panther_oss_helpers import add_parse_delay def rule(event): @@ -22,7 +23,7 @@ def title(event): def alert_context(event): - geoinfo = geoinfo_from_ip(event.udm("source_ip")) + geoinfo = geoinfo_from_ip(event=event, match_field=event.udm_path("source_ip")) if isinstance(geoinfo, str): geoinfo = loads(geoinfo) context = {} diff --git a/rules/standard_rules/unusual_login_deprecated.py b/rules/standard_rules/unusual_login_deprecated.py index c16c9ec38..a2277beaf 100644 --- a/rules/standard_rules/unusual_login_deprecated.py +++ b/rules/standard_rules/unusual_login_deprecated.py @@ -7,7 +7,8 @@ import panther_event_type_helpers as event_type from panther_detection_helpers.caching import get_string_set, put_string_set -from panther_oss_helpers import add_parse_delay, geoinfo_from_ip +from panther_ipinfo_helpers import geoinfo_from_ip +from panther_oss_helpers import add_parse_delay # number of unique geolocation city:region combinations retained in the # panther-kv-table in Dynamo to suppress alerts @@ -34,7 +35,7 @@ def rule(event): # Lookup geo-ip data via API call # Mocked during unit testing - GEO_INFO[log] = geoinfo_from_ip(event.udm("source_ip")) + GEO_INFO[log] = geoinfo_from_ip(event=event, match_field=event.udm_path("source_ip")) # As of Panther 1.19, mocking returns all mocked objects in a string # GEO_INFO must be converted back to a dict to mimic the API call From cec5c8c2e06d7b327a7a5ed4c3eba256a0f42e44 Mon Sep 17 00:00:00 2001 From: Evan Gibler <20933572+egibs@users.noreply.github.com> Date: Thu, 30 May 2024 09:59:24 -0500 Subject: [PATCH 14/35] Use full Action SHAs rather than versioned releases (#1245) Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> --- .github/dependabot.yml | 8 ++++++++ .github/workflows/check-packs.yml | 6 +++--- .github/workflows/docker.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/sync-from-upstream.yml | 2 +- .github/workflows/test.yml | 2 +- .github/workflows/upload.yml | 2 +- 8 files changed, 17 insertions(+), 9 deletions(-) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..0993e395d --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 + +updates: + # Update the GitHub actions used in our CI/CD workflow + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/workflows/check-packs.yml b/.github/workflows/check-packs.yml index ecbe41eb4..beae9b7f4 100644 --- a/.github/workflows/check-packs.yml +++ b/.github/workflows/check-packs.yml @@ -21,7 +21,7 @@ jobs: pypi.org:443 - name: Checkout panther-analysis - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 #v4.1.6 - name: Set python version uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d #v5.1.0 @@ -41,7 +41,7 @@ jobs: panther_analysis_tool check-packs || echo ::set-output name=errors::`cat errors.txt` - name: Comment PR - uses: thollander/actions-comment-pull-request@v2 + uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 if: ${{ steps.check-packs.outputs.errors }} with: mode: upsert @@ -52,7 +52,7 @@ jobs: ${{ steps.check-packs.outputs.errors }} comment_tag: check-packs - name: Delete comment - uses: thollander/actions-comment-pull-request@v2 + uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 if: ${{ !steps.check-packs.outputs.errors }} with: mode: delete diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 145a8fb5f..07eac4382 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -27,7 +27,7 @@ jobs: registry-1.docker.io:443 www.python.org:443 - name: Checkout panther-analysis - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 #v4.1.6 - uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 #v3.0.0 - name: Set up Docker Buildx id: buildx diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 7d14b654c..2e9f7c166 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -19,7 +19,7 @@ jobs: github.com:443 pypi.org:443 - name: Checkout panther-analysis - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 #v4.1.6 - name: Set python version uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d #v5.1.0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7cea376f7..458ec623a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: - uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0 with: egress-policy: audit - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 #v4.1.6 with: fetch-depth: 0 token: ${{ env.GITHUB_TOKEN }} diff --git a/.github/workflows/sync-from-upstream.yml b/.github/workflows/sync-from-upstream.yml index ffbd3faac..fffd5be6b 100644 --- a/.github/workflows/sync-from-upstream.yml +++ b/.github/workflows/sync-from-upstream.yml @@ -37,7 +37,7 @@ jobs: branch: "sync_upstream_${{steps.set_upstream.outputs.latest-release}}" # Checkout this repo into the branch - name: Checkout your local repo in PR branch - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 #v4.1.6 with: ref: "sync_upstream_${{steps.set_upstream.outputs.latest-release}}" token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c8de04080..7921ba94a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,7 +20,7 @@ jobs: ipinfo.io:443 pypi.org:443 - name: Checkout panther-analysis - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 #v4.1.6 - name: Set python version uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d #v5.1.0 diff --git a/.github/workflows/upload.yml b/.github/workflows/upload.yml index bf5e49e0b..ef71a0f76 100644 --- a/.github/workflows/upload.yml +++ b/.github/workflows/upload.yml @@ -24,7 +24,7 @@ jobs: exit 0 - name: Checkout panther-analysis - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 #v4.1.6 - name: Set python version uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d #v5.1.0 From ca6f7de84eee31ef152526039918a3594c72a15a Mon Sep 17 00:00:00 2001 From: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> Date: Thu, 30 May 2024 12:29:54 -0600 Subject: [PATCH 15/35] auth0-cic-credential-stuffing rule and query (#1246) --- .../auth0_cic_credential_stuffing_query.yml | 11 + .../auth0_cic_credential_stuffing.py | 27 +++ .../auth0_cic_credential_stuffing.yml | 229 ++++++++++++++++++ 3 files changed, 267 insertions(+) create mode 100644 queries/auth0_queries/auth0_cic_credential_stuffing_query.yml create mode 100644 rules/auth0_rules/auth0_cic_credential_stuffing.py create mode 100644 rules/auth0_rules/auth0_cic_credential_stuffing.yml diff --git a/queries/auth0_queries/auth0_cic_credential_stuffing_query.yml b/queries/auth0_queries/auth0_cic_credential_stuffing_query.yml new file mode 100644 index 000000000..c5d00e012 --- /dev/null +++ b/queries/auth0_queries/auth0_cic_credential_stuffing_query.yml @@ -0,0 +1,11 @@ +AnalysisType: saved_query +QueryName: "Auth0 CIC Credential Stuffing Query" +Description: Okta has determined that the cross-origin authentication feature in Customer Identity Cloud (CIC) is prone to being targeted by threat actors orchestrating credential-stuffing attacks. Okta has observed suspicious activity that started on April 15, 2024. Review tenant logs for unexpected fcoa, scoa, and pwd_leak events. https://sec.okta.com/articles/2024/05/detecting-cross-origin-authentication-credential-stuffing-attacks +Query: |- + SELECT + * + FROM + panther_logs.public.auth0_events + WHERE + data:type in ('fcoa', 'scoa', 'pwd_leak') + and p_occurs_between('2024-04-14', current_timestamp) diff --git a/rules/auth0_rules/auth0_cic_credential_stuffing.py b/rules/auth0_rules/auth0_cic_credential_stuffing.py new file mode 100644 index 000000000..585f787e9 --- /dev/null +++ b/rules/auth0_rules/auth0_cic_credential_stuffing.py @@ -0,0 +1,27 @@ +from panther_auth0_helpers import auth0_alert_context + +SUSPICIOUS_EVENT_TYPES = ( + "scoa", + "fcoa", + "pwd_leak", +) + + +def rule(event): + return event.deep_get("data", "type") in SUSPICIOUS_EVENT_TYPES + + +def title(event): + event_type = event.deep_get("data", "type") + user = event.deep_get( + "data", "details", "request", "auth", "user", "email", default="" + ) + p_source_label = event.deep_get("p_source_label", default="") + return ( + f"Auth0 User [{user}] had a suspicious [{event_type}] event in " + f"your organization's tenant [{p_source_label}]." + ) + + +def alert_context(event): + return auth0_alert_context(event) diff --git a/rules/auth0_rules/auth0_cic_credential_stuffing.yml b/rules/auth0_rules/auth0_cic_credential_stuffing.yml new file mode 100644 index 000000000..4b68e5cee --- /dev/null +++ b/rules/auth0_rules/auth0_cic_credential_stuffing.yml @@ -0,0 +1,229 @@ +AnalysisType: rule +LogTypes: + - Auth0.Events +RuleID: "Auth0.CIC.Credential.Stuffing" +Filename: auth0_cic_credential_stuffing.py +DisplayName: "Auth0 CIC Credential Stuffing" +Description: Okta has determined that the cross-origin authentication feature in Customer Identity Cloud (CIC) is prone to being targeted by threat actors orchestrating credential-stuffing attacks. Okta has observed suspicious activity that started on April 15, 2024. Review tenant logs for unexpected fcoa, scoa, and pwd_leak events. +Enabled: true +Severity: High +Runbook: If a user password was compromised in a credential stuffing attack, the user's credentials should be rotated immediately out of an abundance of caution. +Reference: https://sec.okta.com/articles/2024/05/detecting-cross-origin-authentication-credential-stuffing-attacks +DedupPeriodMinutes: 60 +Threshold: 1 +Tests: + - ExpectedResult: true + Log: + data: + client_id: 1HXWWGKk1Zj3JF8GvMrnCSirccDs4qvr + client_name: "" + date: "2023-05-23 20:47:51.149000000" + description: Someone behind the IP address ip attempted to login with a leaked password. + details: + request: + auth: + credentials: + jti: e6343ec1d24a41e6bd43a6be748cac11 + strategy: jwt + user: + email: homer.simpson@yourcompany.com + name: Homer Simpson + user_id: google-oauth2|105261262156475850461 + body: + integration_id: 64bee519-818f-4473-ab08-7c380f28da77 + channel: https://manage.auth0.com/ + ip: 12.12.12.12 + method: post + path: /api/v2/integrations/installed + query: {} + userAgent: >- + Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 + (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 + response: + body: + integration_id: 64bee519-818f-4473-ab08-7c380f28da77 + statusCode: 200 + ip: 12.12.12.12 + log_id: "90020230523204756343781000000000000001223372037583230452" + type: pwd_leak + user_agent: >- + Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, + like Gecko) Chrome/113.0.0.0 Safari/537.36 + user_id: google-oauth2|105261262156475850461 + log_id: "90020230523204756343781000000000000001223372037583230452" + Name: Auth0 Credential Stuffing Event + - ExpectedResult: false + Log: + data: + client_id: 1HXWWGKk1Zj3JF8GvMrnCSirccDs4qvr + client_name: "" + date: "2023-05-23 20:47:51.149000000" + description: Install an available integration + details: + request: + auth: + credentials: + jti: 949869e066205b5076e6df203fdd7b9b + scopes: + - create:actions + - create:actions_log_sessions + - create:authentication_methods + - create:client_credentials + - create:client_grants + - create:clients + - create:connections + - create:custom_domains + - create:email_provider + - create:email_templates + - create:guardian_enrollment_tickets + - create:integrations + - create:log_streams + - create:organization_connections + - create:organization_invitations + - create:organization_member_roles + - create:organization_members + - create:organizations + - create:requested_scopes + - create:resource_servers + - create:roles + - create:rules + - create:shields + - create:signing_keys + - create:tenant_invitations + - create:test_email_dispatch + - create:users + - delete:actions + - delete:anomaly_blocks + - delete:authentication_methods + - delete:branding + - delete:client_credentials + - delete:client_grants + - delete:clients + - delete:connections + - delete:custom_domains + - delete:device_credentials + - delete:email_provider + - delete:email_templates + - delete:grants + - delete:guardian_enrollments + - delete:integrations + - delete:log_streams + - delete:organization_connections + - delete:organization_invitations + - delete:organization_member_roles + - delete:organization_members + - delete:organizations + - delete:owners + - delete:requested_scopes + - delete:resource_servers + - delete:roles + - delete:rules + - delete:rules_configs + - delete:shields + - delete:tenant_invitations + - delete:tenant_members + - delete:tenants + - delete:users + - read:actions + - read:anomaly_blocks + - read:attack_protection + - read:authentication_methods + - read:branding + - read:checks + - read:client_credentials + - read:client_grants + - read:client_keys + - read:clients + - read:connections + - read:custom_domains + - read:device_credentials + - read:email_provider + - read:email_templates + - read:email_triggers + - read:entity_counts + - read:grants + - read:guardian_factors + - read:insights + - read:integrations + - read:log_streams + - read:logs + - read:mfa_policies + - read:organization_connections + - read:organization_invitations + - read:organization_member_roles + - read:organization_members + - read:organizations + - read:prompts + - read:requested_scopes + - read:resource_servers + - read:roles + - read:rules + - read:rules_configs + - read:shields + - read:signing_keys + - read:stats + - read:tenant_invitations + - read:tenant_members + - read:tenant_settings + - read:triggers + - read:users + - run:checks + - update:actions + - update:attack_protection + - update:authentication_methods + - update:branding + - update:client_credentials + - update:client_grants + - update:client_keys + - update:clients + - update:connections + - update:custom_domains + - update:email_provider + - update:email_templates + - update:email_triggers + - update:guardian_factors + - update:integrations + - update:log_streams + - update:mfa_policies + - update:organization_connections + - update:organizations + - update:prompts + - update:requested_scopes + - update:resource_servers + - update:roles + - update:rules + - update:rules_configs + - update:shields + - update:signing_keys + - update:tenant_members + - update:tenant_settings + - update:triggers + - update:users + strategy: jwt + user: + email: user.name@yourcompany.io + name: User Name + user_id: google-oauth2|105261262156475850461 + body: + AfterAuthentication: false + channel: https://manage.auth0.com/ + ip: 12.12.12.12 + method: patch + path: /api/v2/risk-assessment/config + query: {} + userAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 + response: + body: + AfterAuthentication: false + BeforeLoginPrompt: false + BeforeLoginPromptMonitoring: false + statusCode: 200 + ip: 12.12.12.12 + log_id: "90020230523204756343781000000000000001223372037583230452" + type: sapi + user_agent: >- + Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, + like Gecko) Chrome/113.0.0.0 Safari/537.36 + user_id: google-oauth2|105261262156475850461 + log_id: "90020230523204756343781000000000000001223372037583230452" + Name: Other Event From 12ff27b73283a32fe7fc39636cd94a97e723da5d Mon Sep 17 00:00:00 2001 From: Evan Gibler <20933572+egibs@users.noreply.github.com> Date: Mon, 3 Jun 2024 18:04:26 -0500 Subject: [PATCH 16/35] Update panther-core to 0.10.1 via PAT (#1249) Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> --- Pipfile.lock | 4052 +++++++++++++++++++++++++------------------------- 1 file changed, 2026 insertions(+), 2026 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 89994b31a..62766de11 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,2029 +1,2029 @@ { - "_meta": { - "hash": { - "sha256": "17b8e970a9987cbf1b1990b9bd6832b6012de2263f46f946b3d22bd42e42d2d8" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.11" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "aiohttp": { - "hashes": [ - "sha256:0605cc2c0088fcaae79f01c913a38611ad09ba68ff482402d3410bf59039bfb8", - "sha256:0a158704edf0abcac8ac371fbb54044f3270bdbc93e254a82b6c82be1ef08f3c", - "sha256:0cbf56238f4bbf49dab8c2dc2e6b1b68502b1e88d335bea59b3f5b9f4c001475", - "sha256:1732102949ff6087589408d76cd6dea656b93c896b011ecafff418c9661dc4ed", - "sha256:18f634d540dd099c262e9f887c8bbacc959847cfe5da7a0e2e1cf3f14dbf2daf", - "sha256:239f975589a944eeb1bad26b8b140a59a3a320067fb3cd10b75c3092405a1372", - "sha256:2faa61a904b83142747fc6a6d7ad8fccff898c849123030f8e75d5d967fd4a81", - "sha256:320e8618eda64e19d11bdb3bd04ccc0a816c17eaecb7e4945d01deee2a22f95f", - "sha256:38d80498e2e169bc61418ff36170e0aad0cd268da8b38a17c4cf29d254a8b3f1", - "sha256:3916c8692dbd9d55c523374a3b8213e628424d19116ac4308e434dbf6d95bbdd", - "sha256:393c7aba2b55559ef7ab791c94b44f7482a07bf7640d17b341b79081f5e5cd1a", - "sha256:3b7b30258348082826d274504fbc7c849959f1989d86c29bc355107accec6cfb", - "sha256:3fcb4046d2904378e3aeea1df51f697b0467f2aac55d232c87ba162709478c46", - "sha256:4109adee842b90671f1b689901b948f347325045c15f46b39797ae1bf17019de", - "sha256:4558e5012ee03d2638c681e156461d37b7a113fe13970d438d95d10173d25f78", - "sha256:45731330e754f5811c314901cebdf19dd776a44b31927fa4b4dbecab9e457b0c", - "sha256:4715a9b778f4293b9f8ae7a0a7cef9829f02ff8d6277a39d7f40565c737d3771", - "sha256:471f0ef53ccedec9995287f02caf0c068732f026455f07db3f01a46e49d76bbb", - "sha256:4d3ebb9e1316ec74277d19c5f482f98cc65a73ccd5430540d6d11682cd857430", - "sha256:4ff550491f5492ab5ed3533e76b8567f4b37bd2995e780a1f46bca2024223233", - "sha256:52c27110f3862a1afbcb2af4281fc9fdc40327fa286c4625dfee247c3ba90156", - "sha256:55b39c8684a46e56ef8c8d24faf02de4a2b2ac60d26cee93bc595651ff545de9", - "sha256:5a7ee16aab26e76add4afc45e8f8206c95d1d75540f1039b84a03c3b3800dd59", - "sha256:5ca51eadbd67045396bc92a4345d1790b7301c14d1848feaac1d6a6c9289e888", - "sha256:5d6b3f1fabe465e819aed2c421a6743d8debbde79b6a8600739300630a01bf2c", - "sha256:60cdbd56f4cad9f69c35eaac0fbbdf1f77b0ff9456cebd4902f3dd1cf096464c", - "sha256:6380c039ec52866c06d69b5c7aad5478b24ed11696f0e72f6b807cfb261453da", - "sha256:639d0042b7670222f33b0028de6b4e2fad6451462ce7df2af8aee37dcac55424", - "sha256:66331d00fb28dc90aa606d9a54304af76b335ae204d1836f65797d6fe27f1ca2", - "sha256:67c3119f5ddc7261d47163ed86d760ddf0e625cd6246b4ed852e82159617b5fb", - "sha256:694d828b5c41255e54bc2dddb51a9f5150b4eefa9886e38b52605a05d96566e8", - "sha256:6ae79c1bc12c34082d92bf9422764f799aee4746fd7a392db46b7fd357d4a17a", - "sha256:702e2c7c187c1a498a4e2b03155d52658fdd6fda882d3d7fbb891a5cf108bb10", - "sha256:714d4e5231fed4ba2762ed489b4aec07b2b9953cf4ee31e9871caac895a839c0", - "sha256:7b179eea70833c8dee51ec42f3b4097bd6370892fa93f510f76762105568cf09", - "sha256:7f64cbd44443e80094309875d4f9c71d0401e966d191c3d469cde4642bc2e031", - "sha256:82a6a97d9771cb48ae16979c3a3a9a18b600a8505b1115cfe354dfb2054468b4", - "sha256:84dabd95154f43a2ea80deffec9cb44d2e301e38a0c9d331cc4aa0166fe28ae3", - "sha256:8676e8fd73141ded15ea586de0b7cda1542960a7b9ad89b2b06428e97125d4fa", - "sha256:88e311d98cc0bf45b62fc46c66753a83445f5ab20038bcc1b8a1cc05666f428a", - "sha256:8b4f72fbb66279624bfe83fd5eb6aea0022dad8eec62b71e7bf63ee1caadeafe", - "sha256:8c64a6dc3fe5db7b1b4d2b5cb84c4f677768bdc340611eca673afb7cf416ef5a", - "sha256:8cf142aa6c1a751fcb364158fd710b8a9be874b81889c2bd13aa8893197455e2", - "sha256:8d1964eb7617907c792ca00b341b5ec3e01ae8c280825deadbbd678447b127e1", - "sha256:93e22add827447d2e26d67c9ac0161756007f152fdc5210277d00a85f6c92323", - "sha256:9c69e77370cce2d6df5d12b4e12bdcca60c47ba13d1cbbc8645dd005a20b738b", - "sha256:9dbc053ac75ccc63dc3a3cc547b98c7258ec35a215a92bd9f983e0aac95d3d5b", - "sha256:9e3a1ae66e3d0c17cf65c08968a5ee3180c5a95920ec2731f53343fac9bad106", - "sha256:a6ea1a5b409a85477fd8e5ee6ad8f0e40bf2844c270955e09360418cfd09abac", - "sha256:a81b1143d42b66ffc40a441379387076243ef7b51019204fd3ec36b9f69e77d6", - "sha256:ad7f2919d7dac062f24d6f5fe95d401597fbb015a25771f85e692d043c9d7832", - "sha256:afc52b8d969eff14e069a710057d15ab9ac17cd4b6753042c407dcea0e40bf75", - "sha256:b3df71da99c98534be076196791adca8819761f0bf6e08e07fd7da25127150d6", - "sha256:c088c4d70d21f8ca5c0b8b5403fe84a7bc8e024161febdd4ef04575ef35d474d", - "sha256:c26959ca7b75ff768e2776d8055bf9582a6267e24556bb7f7bd29e677932be72", - "sha256:c413016880e03e69d166efb5a1a95d40f83d5a3a648d16486592c49ffb76d0db", - "sha256:c6021d296318cb6f9414b48e6a439a7f5d1f665464da507e8ff640848ee2a58a", - "sha256:c671dc117c2c21a1ca10c116cfcd6e3e44da7fcde37bf83b2be485ab377b25da", - "sha256:c7a4b7a6cf5b6eb11e109a9755fd4fda7d57395f8c575e166d363b9fc3ec4678", - "sha256:c8a02fbeca6f63cb1f0475c799679057fc9268b77075ab7cf3f1c600e81dd46b", - "sha256:cd2adf5c87ff6d8b277814a28a535b59e20bfea40a101db6b3bdca7e9926bc24", - "sha256:d1469f228cd9ffddd396d9948b8c9cd8022b6d1bf1e40c6f25b0fb90b4f893ed", - "sha256:d153f652a687a8e95ad367a86a61e8d53d528b0530ef382ec5aaf533140ed00f", - "sha256:d5ab8e1f6bee051a4bf6195e38a5c13e5e161cb7bad83d8854524798bd9fcd6e", - "sha256:da00da442a0e31f1c69d26d224e1efd3a1ca5bcbf210978a2ca7426dfcae9f58", - "sha256:da22dab31d7180f8c3ac7c7635f3bcd53808f374f6aa333fe0b0b9e14b01f91a", - "sha256:e0ae53e33ee7476dd3d1132f932eeb39bf6125083820049d06edcdca4381f342", - "sha256:e7a6a8354f1b62e15d48e04350f13e726fa08b62c3d7b8401c0a1314f02e3558", - "sha256:e9a3d838441bebcf5cf442700e3963f58b5c33f015341f9ea86dcd7d503c07e2", - "sha256:edea7d15772ceeb29db4aff55e482d4bcfb6ae160ce144f2682de02f6d693551", - "sha256:f22eb3a6c1080d862befa0a89c380b4dafce29dc6cd56083f630073d102eb595", - "sha256:f26383adb94da5e7fb388d441bf09c61e5e35f455a3217bfd790c6b6bc64b2ee", - "sha256:f3c2890ca8c59ee683fd09adf32321a40fe1cf164e3387799efb2acebf090c11", - "sha256:f64fd07515dad67f24b6ea4a66ae2876c01031de91c93075b8093f07c0a2d93d", - "sha256:fcde4c397f673fdec23e6b05ebf8d4751314fa7c24f93334bf1f1364c1c69ac7", - "sha256:ff84aeb864e0fac81f676be9f4685f0527b660f1efdc40dcede3c251ef1e867f" - ], - "markers": "python_version >= '3.8'", - "version": "==3.9.5" - }, - "aiosignal": { - "hashes": [ - "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc", - "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17" - ], - "markers": "python_version >= '3.7'", - "version": "==1.3.1" - }, - "anyio": { - "hashes": [ - "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8", - "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6" - ], - "markers": "python_version >= '3.8'", - "version": "==4.3.0" - }, - "appdirs": { - "hashes": [ - "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", - "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" - ], - "version": "==1.4.4" - }, - "attrs": { - "hashes": [ - "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", - "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1" - ], - "markers": "python_version >= '3.7'", - "version": "==23.2.0" - }, - "backoff": { - "hashes": [ - "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba", - "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8" - ], - "markers": "python_version >= '3.7' and python_version < '4.0'", - "version": "==2.2.1" - }, - "boto3": { - "hashes": [ - "sha256:6f600b3fe0bda53476395c902d9af5a47294c93ec52a9cdc2b926a9dc705ce79", - "sha256:b54084d000483b578757df03ce39a819fbba47071c9aa98611beb8806bcecd45" - ], - "markers": "python_version >= '3.8'", - "version": "==1.34.99" - }, - "botocore": { - "hashes": [ - "sha256:18c68bdeb0ffb73290912b0c96204fc36d3128f00a00b5cdc35ac34d66225f1c", - "sha256:cafe569e2136cb33cb0e5dd32fb1c0e1503ddc1413d3be215df8ddf05e69137a" - ], - "markers": "python_version >= '3.8'", - "version": "==1.34.99" - }, - "certifi": { - "hashes": [ - "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", - "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" - ], - "markers": "python_version >= '3.6'", - "version": "==2024.2.2" - }, - "chardet": { - "hashes": [ - "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7", - "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970" - ], - "markers": "python_version >= '3.7'", - "version": "==5.2.0" - }, - "charset-normalizer": { - "hashes": [ - "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", - "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", - "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", - "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", - "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", - "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", - "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", - "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", - "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", - "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", - "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", - "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", - "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", - "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", - "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", - "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", - "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", - "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", - "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", - "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", - "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", - "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", - "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", - "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", - "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", - "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", - "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", - "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", - "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", - "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", - "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", - "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", - "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", - "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", - "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", - "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", - "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", - "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", - "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", - "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", - "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", - "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", - "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", - "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", - "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", - "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", - "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", - "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", - "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", - "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", - "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", - "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", - "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", - "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", - "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", - "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", - "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", - "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", - "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", - "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", - "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", - "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", - "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", - "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", - "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", - "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", - "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", - "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", - "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", - "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", - "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", - "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", - "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", - "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", - "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", - "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", - "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", - "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", - "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", - "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", - "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", - "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", - "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", - "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", - "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", - "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", - "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", - "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", - "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", - "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" - ], - "markers": "python_full_version >= '3.7.0'", - "version": "==3.3.2" - }, - "click": { - "hashes": [ - "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", - "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" - ], - "markers": "python_version >= '3.7'", - "version": "==8.1.7" - }, - "colorama": { - "hashes": [ - "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", - "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", - "version": "==0.4.6" - }, - "datadog": { - "hashes": [ - "sha256:4a56d57490ea699a0dfd9253547485a57b4120e93489defadcf95c66272374d6", - "sha256:4cb7a7991af6cadb868fe450cd456473e65f11fc678b7d7cf61044ff1c6074d8" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", - "version": "==0.49.1" - }, - "diff-cover": { - "hashes": [ - "sha256:1dc851d3f3f320c048d03618e4c0d9861fa4a1506b425d2d09a564b20c95674a", - "sha256:31b308259b79e2cab5f30aff499a3ea3ba9475f0d495d82ba9b6caa7487bca03" - ], - "markers": "python_full_version >= '3.8.10' and python_full_version < '4.0.0'", - "version": "==9.0.0" - }, - "dynaconf": { - "hashes": [ - "sha256:12202fc26546851c05d4194c80bee00197e7c2febcb026e502b0863be9cbbdd8", - "sha256:42c8d936b32332c4b84e4d4df6dd1626b6ef59c5a94eb60c10cd3c59d6b882f2" - ], - "markers": "python_version >= '3.8'", - "version": "==3.2.5" - }, - "frozenlist": { - "hashes": [ - "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7", - "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98", - "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad", - "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5", - "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae", - "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e", - "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a", - "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701", - "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d", - "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6", - "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6", - "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106", - "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75", - "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868", - "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a", - "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0", - "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1", - "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826", - "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec", - "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6", - "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950", - "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19", - "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0", - "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8", - "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a", - "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09", - "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86", - "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c", - "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5", - "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b", - "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b", - "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d", - "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0", - "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea", - "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776", - "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a", - "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897", - "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7", - "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09", - "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9", - "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe", - "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd", - "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742", - "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09", - "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0", - "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932", - "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1", - "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a", - "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49", - "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d", - "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7", - "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480", - "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89", - "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e", - "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b", - "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82", - "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb", - "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068", - "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8", - "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b", - "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb", - "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2", - "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11", - "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b", - "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc", - "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0", - "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497", - "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17", - "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0", - "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2", - "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439", - "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5", - "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac", - "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825", - "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887", - "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced", - "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74" - ], - "markers": "python_version >= '3.8'", - "version": "==1.4.1" - }, - "gql": { - "hashes": [ - "sha256:70dda5694a5b194a8441f077aa5fb70cc94e4ec08016117523f013680901ecb7", - "sha256:ccb9c5db543682b28f577069950488218ed65d4ac70bb03b6929aaadaf636de9" - ], - "version": "==3.5.0" - }, - "graphql-core": { - "hashes": [ - "sha256:06d2aad0ac723e35b1cb47885d3e5c45e956a53bc1b209a9fc5369007fe46676", - "sha256:5766780452bd5ec8ba133f8bf287dc92713e3868ddd83aee4faab9fc3e303dc3" - ], - "markers": "python_version >= '3.6' and python_version < '4'", - "version": "==3.2.3" - }, - "idna": { - "hashes": [ - "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", - "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0" - ], - "markers": "python_version >= '3.5'", - "version": "==3.7" - }, - "iniconfig": { - "hashes": [ - "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", - "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" - ], - "markers": "python_version >= '3.7'", - "version": "==2.0.0" - }, - "jinja2": { - "hashes": [ - "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", - "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d" - ], - "markers": "python_version >= '3.7'", - "version": "==3.1.4" - }, - "jmespath": { - "hashes": [ - "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", - "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe" - ], - "markers": "python_version >= '3.7'", - "version": "==1.0.1" - }, - "jsonlines": { - "hashes": [ - "sha256:0c6d2c09117550c089995247f605ae4cf77dd1533041d366351f6f298822ea74", - "sha256:185b334ff2ca5a91362993f42e83588a360cf95ce4b71a73548502bda52a7c55" - ], - "markers": "python_version >= '3.8'", - "version": "==4.0.0" - }, - "jsonpath-ng": { - "hashes": [ - "sha256:086c37ba4917304850bd837aeab806670224d3f038fe2833ff593a672ef0a5fa", - "sha256:8f22cd8273d7772eea9aaa84d922e0841aa36fdb8a2c6b7f6c3791a16a9bc0be" - ], - "version": "==1.6.1" - }, - "jsonschema": { - "hashes": [ - "sha256:5b22d434a45935119af990552c862e5d6d564e8f6601206b305a61fdf661a2b7", - "sha256:ff4cfd6b1367a40e7bc6411caec72effadd3db0bbe5017de188f2d6108335802" - ], - "markers": "python_version >= '3.8'", - "version": "==4.22.0" - }, - "jsonschema-specifications": { - "hashes": [ - "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc", - "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c" - ], - "markers": "python_version >= '3.8'", - "version": "==2023.12.1" - }, - "markupsafe": { - "hashes": [ - "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf", - "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", - "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", - "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", - "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532", - "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", - "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", - "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df", - "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4", - "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", - "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", - "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", - "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", - "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371", - "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2", - "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", - "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52", - "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", - "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", - "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", - "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", - "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0", - "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029", - "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", - "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a", - "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", - "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", - "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", - "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", - "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9", - "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", - "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", - "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3", - "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", - "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46", - "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", - "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a", - "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", - "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", - "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", - "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", - "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", - "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", - "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", - "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", - "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f", - "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50", - "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", - "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", - "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", - "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff", - "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", - "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", - "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", - "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf", - "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", - "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5", - "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab", - "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", - "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68" - ], - "markers": "python_version >= '3.7'", - "version": "==2.1.5" - }, - "multidict": { - "hashes": [ - "sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556", - "sha256:0275e35209c27a3f7951e1ce7aaf93ce0d163b28948444bec61dd7badc6d3f8c", - "sha256:04bde7a7b3de05732a4eb39c94574db1ec99abb56162d6c520ad26f83267de29", - "sha256:04da1bb8c8dbadf2a18a452639771951c662c5ad03aefe4884775454be322c9b", - "sha256:09a892e4a9fb47331da06948690ae38eaa2426de97b4ccbfafbdcbe5c8f37ff8", - "sha256:0d63c74e3d7ab26de115c49bffc92cc77ed23395303d496eae515d4204a625e7", - "sha256:107c0cdefe028703fb5dafe640a409cb146d44a6ae201e55b35a4af8e95457dd", - "sha256:141b43360bfd3bdd75f15ed811850763555a251e38b2405967f8e25fb43f7d40", - "sha256:14c2976aa9038c2629efa2c148022ed5eb4cb939e15ec7aace7ca932f48f9ba6", - "sha256:19fe01cea168585ba0f678cad6f58133db2aa14eccaf22f88e4a6dccadfad8b3", - "sha256:1d147090048129ce3c453f0292e7697d333db95e52616b3793922945804a433c", - "sha256:1d9ea7a7e779d7a3561aade7d596649fbecfa5c08a7674b11b423783217933f9", - "sha256:215ed703caf15f578dca76ee6f6b21b7603791ae090fbf1ef9d865571039ade5", - "sha256:21fd81c4ebdb4f214161be351eb5bcf385426bf023041da2fd9e60681f3cebae", - "sha256:220dd781e3f7af2c2c1053da9fa96d9cf3072ca58f057f4c5adaaa1cab8fc442", - "sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9", - "sha256:29bfeb0dff5cb5fdab2023a7a9947b3b4af63e9c47cae2a10ad58394b517fddc", - "sha256:2f4848aa3baa109e6ab81fe2006c77ed4d3cd1e0ac2c1fbddb7b1277c168788c", - "sha256:2faa5ae9376faba05f630d7e5e6be05be22913782b927b19d12b8145968a85ea", - "sha256:2ffc42c922dbfddb4a4c3b438eb056828719f07608af27d163191cb3e3aa6cc5", - "sha256:37b15024f864916b4951adb95d3a80c9431299080341ab9544ed148091b53f50", - "sha256:3cc2ad10255f903656017363cd59436f2111443a76f996584d1077e43ee51182", - "sha256:3d25f19500588cbc47dc19081d78131c32637c25804df8414463ec908631e453", - "sha256:403c0911cd5d5791605808b942c88a8155c2592e05332d2bf78f18697a5fa15e", - "sha256:411bf8515f3be9813d06004cac41ccf7d1cd46dfe233705933dd163b60e37600", - "sha256:425bf820055005bfc8aa9a0b99ccb52cc2f4070153e34b701acc98d201693733", - "sha256:435a0984199d81ca178b9ae2c26ec3d49692d20ee29bc4c11a2a8d4514c67eda", - "sha256:4a6a4f196f08c58c59e0b8ef8ec441d12aee4125a7d4f4fef000ccb22f8d7241", - "sha256:4cc0ef8b962ac7a5e62b9e826bd0cd5040e7d401bc45a6835910ed699037a461", - "sha256:51d035609b86722963404f711db441cf7134f1889107fb171a970c9701f92e1e", - "sha256:53689bb4e102200a4fafa9de9c7c3c212ab40a7ab2c8e474491914d2305f187e", - "sha256:55205d03e8a598cfc688c71ca8ea5f66447164efff8869517f175ea632c7cb7b", - "sha256:5c0631926c4f58e9a5ccce555ad7747d9a9f8b10619621f22f9635f069f6233e", - "sha256:5cb241881eefd96b46f89b1a056187ea8e9ba14ab88ba632e68d7a2ecb7aadf7", - "sha256:60d698e8179a42ec85172d12f50b1668254628425a6bd611aba022257cac1386", - "sha256:612d1156111ae11d14afaf3a0669ebf6c170dbb735e510a7438ffe2369a847fd", - "sha256:6214c5a5571802c33f80e6c84713b2c79e024995b9c5897f794b43e714daeec9", - "sha256:6939c95381e003f54cd4c5516740faba40cf5ad3eeff460c3ad1d3e0ea2549bf", - "sha256:69db76c09796b313331bb7048229e3bee7928eb62bab5e071e9f7fcc4879caee", - "sha256:6bf7a982604375a8d49b6cc1b781c1747f243d91b81035a9b43a2126c04766f5", - "sha256:766c8f7511df26d9f11cd3a8be623e59cca73d44643abab3f8c8c07620524e4a", - "sha256:76c0de87358b192de7ea9649beb392f107dcad9ad27276324c24c91774ca5271", - "sha256:76f067f5121dcecf0d63a67f29080b26c43c71a98b10c701b0677e4a065fbd54", - "sha256:7901c05ead4b3fb75113fb1dd33eb1253c6d3ee37ce93305acd9d38e0b5f21a4", - "sha256:79660376075cfd4b2c80f295528aa6beb2058fd289f4c9252f986751a4cd0496", - "sha256:79a6d2ba910adb2cbafc95dad936f8b9386e77c84c35bc0add315b856d7c3abb", - "sha256:7afcdd1fc07befad18ec4523a782cde4e93e0a2bf71239894b8d61ee578c1319", - "sha256:7be7047bd08accdb7487737631d25735c9a04327911de89ff1b26b81745bd4e3", - "sha256:7c6390cf87ff6234643428991b7359b5f59cc15155695deb4eda5c777d2b880f", - "sha256:7df704ca8cf4a073334e0427ae2345323613e4df18cc224f647f251e5e75a527", - "sha256:85f67aed7bb647f93e7520633d8f51d3cbc6ab96957c71272b286b2f30dc70ed", - "sha256:896ebdcf62683551312c30e20614305f53125750803b614e9e6ce74a96232604", - "sha256:92d16a3e275e38293623ebf639c471d3e03bb20b8ebb845237e0d3664914caef", - "sha256:99f60d34c048c5c2fabc766108c103612344c46e35d4ed9ae0673d33c8fb26e8", - "sha256:9fe7b0653ba3d9d65cbe7698cca585bf0f8c83dbbcc710db9c90f478e175f2d5", - "sha256:a3145cb08d8625b2d3fee1b2d596a8766352979c9bffe5d7833e0503d0f0b5e5", - "sha256:aeaf541ddbad8311a87dd695ed9642401131ea39ad7bc8cf3ef3967fd093b626", - "sha256:b55358304d7a73d7bdf5de62494aaf70bd33015831ffd98bc498b433dfe5b10c", - "sha256:b82cc8ace10ab5bd93235dfaab2021c70637005e1ac787031f4d1da63d493c1d", - "sha256:c0868d64af83169e4d4152ec612637a543f7a336e4a307b119e98042e852ad9c", - "sha256:c1c1496e73051918fcd4f58ff2e0f2f3066d1c76a0c6aeffd9b45d53243702cc", - "sha256:c9bf56195c6bbd293340ea82eafd0071cb3d450c703d2c93afb89f93b8386ccc", - "sha256:cbebcd5bcaf1eaf302617c114aa67569dd3f090dd0ce8ba9e35e9985b41ac35b", - "sha256:cd6c8fca38178e12c00418de737aef1261576bd1b6e8c6134d3e729a4e858b38", - "sha256:ceb3b7e6a0135e092de86110c5a74e46bda4bd4fbfeeb3a3bcec79c0f861e450", - "sha256:cf590b134eb70629e350691ecca88eac3e3b8b3c86992042fb82e3cb1830d5e1", - "sha256:d3eb1ceec286eba8220c26f3b0096cf189aea7057b6e7b7a2e60ed36b373b77f", - "sha256:d65f25da8e248202bd47445cec78e0025c0fe7582b23ec69c3b27a640dd7a8e3", - "sha256:d6f6d4f185481c9669b9447bf9d9cf3b95a0e9df9d169bbc17e363b7d5487755", - "sha256:d84a5c3a5f7ce6db1f999fb9438f686bc2e09d38143f2d93d8406ed2dd6b9226", - "sha256:d946b0a9eb8aaa590df1fe082cee553ceab173e6cb5b03239716338629c50c7a", - "sha256:dce1c6912ab9ff5f179eaf6efe7365c1f425ed690b03341911bf4939ef2f3046", - "sha256:de170c7b4fe6859beb8926e84f7d7d6c693dfe8e27372ce3b76f01c46e489fcf", - "sha256:e02021f87a5b6932fa6ce916ca004c4d441509d33bbdbeca70d05dff5e9d2479", - "sha256:e030047e85cbcedbfc073f71836d62dd5dadfbe7531cae27789ff66bc551bd5e", - "sha256:e0e79d91e71b9867c73323a3444724d496c037e578a0e1755ae159ba14f4f3d1", - "sha256:e4428b29611e989719874670fd152b6625500ad6c686d464e99f5aaeeaca175a", - "sha256:e4972624066095e52b569e02b5ca97dbd7a7ddd4294bf4e7247d52635630dd83", - "sha256:e7be68734bd8c9a513f2b0cfd508802d6609da068f40dc57d4e3494cefc92929", - "sha256:e8e94e6912639a02ce173341ff62cc1201232ab86b8a8fcc05572741a5dc7d93", - "sha256:ea1456df2a27c73ce51120fa2f519f1bea2f4a03a917f4a43c8707cf4cbbae1a", - "sha256:ebd8d160f91a764652d3e51ce0d2956b38efe37c9231cd82cfc0bed2e40b581c", - "sha256:eca2e9d0cc5a889850e9bbd68e98314ada174ff6ccd1129500103df7a94a7a44", - "sha256:edd08e6f2f1a390bf137080507e44ccc086353c8e98c657e666c017718561b89", - "sha256:f285e862d2f153a70586579c15c44656f888806ed0e5b56b64489afe4a2dbfba", - "sha256:f2a1dee728b52b33eebff5072817176c172050d44d67befd681609b4746e1c2e", - "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da", - "sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24", - "sha256:fce28b3c8a81b6b36dfac9feb1de115bab619b3c13905b419ec71d03a3fc1423", - "sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef" - ], - "markers": "python_version >= '3.7'", - "version": "==6.0.5" - }, - "nested-lookup": { - "hashes": [ - "sha256:6fa832748c90381f2291d850809e32492519ee5f253d6a5acbc29d937eca02e8" - ], - "version": "==0.2.25" - }, - "packaging": { - "hashes": [ - "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", - "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" - ], - "markers": "python_version >= '3.7'", - "version": "==24.0" - }, - "panther-analysis-tool": { - "hashes": [ - "sha256:b2c80ad4e1ad7a506a581c78fd01df2769970d92c6f70f0cb723cbc70947db6c" - ], - "index": "pypi", - "version": "==0.49.0" - }, - "panther-core": { - "hashes": [ - "sha256:5051fa79e80f908b947f4776dca89df5d8b595bdb09a818eb97a71b0ec8c9c99" - ], - "version": "==0.8.1" - }, - "panther-detection-helpers": { - "hashes": [ - "sha256:151d35778cb2cb1901a35b91326b5b22cca3d7593f31059dc19d13fc5598987a" - ], - "index": "pypi", - "version": "==0.4.0" - }, - "pathspec": { - "hashes": [ - "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", - "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712" - ], - "markers": "python_version >= '3.8'", - "version": "==0.12.1" - }, - "pluggy": { - "hashes": [ - "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", - "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669" - ], - "markers": "python_version >= '3.8'", - "version": "==1.5.0" - }, - "ply": { - "hashes": [ - "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3", - "sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce" - ], - "version": "==3.11" - }, - "policyuniverse": { - "hashes": [ - "sha256:6317928273b18de8ed28ddf9f06faf501e044344d86f86b7681817fb32fff67a", - "sha256:7920896195af163230635f1a5cee0958f56003ef8c421f805ec81f134f80a57c" - ], - "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==1.5.1.20230817" - }, - "pygments": { - "hashes": [ - "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", - "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a" - ], - "markers": "python_version >= '3.8'", - "version": "==2.18.0" - }, - "pytest": { - "hashes": [ - "sha256:1733f0620f6cda4095bbf0d9ff8022486e91892245bb9e7d5542c018f612f233", - "sha256:d507d4482197eac0ba2bae2e9babf0672eb333017bcedaa5fb1a3d42c1174b3f" - ], - "markers": "python_version >= '3.8'", - "version": "==8.2.0" - }, - "python-dateutil": { - "hashes": [ - "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", - "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.9.0.post0" - }, - "pyyaml": { - "hashes": [ - "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", - "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", - "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", - "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", - "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", - "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", - "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595", - "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", - "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", - "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", - "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290", - "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", - "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", - "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6", - "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", - "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", - "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", - "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6", - "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", - "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", - "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", - "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", - "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", - "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", - "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", - "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", - "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", - "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", - "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", - "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef", - "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", - "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", - "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", - "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0", - "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515", - "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c", - "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c", - "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924", - "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34", - "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", - "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", - "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", - "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", - "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", - "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b", - "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", - "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", - "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", - "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585", - "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d", - "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" - ], - "markers": "python_version >= '3.6'", - "version": "==6.0.1" - }, - "referencing": { - "hashes": [ - "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c", - "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de" - ], - "markers": "python_version >= '3.8'", - "version": "==0.35.1" - }, - "regex": { - "hashes": [ - "sha256:05d9b6578a22db7dedb4df81451f360395828b04f4513980b6bd7a1412c679cc", - "sha256:08a1749f04fee2811c7617fdd46d2e46d09106fa8f475c884b65c01326eb15c5", - "sha256:0940038bec2fe9e26b203d636c44d31dd8766abc1fe66262da6484bd82461ccf", - "sha256:0a2a512d623f1f2d01d881513af9fc6a7c46e5cfffb7dc50c38ce959f9246c94", - "sha256:0a54a047b607fd2d2d52a05e6ad294602f1e0dec2291152b745870afc47c1397", - "sha256:0dd3f69098511e71880fb00f5815db9ed0ef62c05775395968299cb400aeab82", - "sha256:1031a5e7b048ee371ab3653aad3030ecfad6ee9ecdc85f0242c57751a05b0ac4", - "sha256:108e2dcf0b53a7c4ab8986842a8edcb8ab2e59919a74ff51c296772e8e74d0ae", - "sha256:144a1fc54765f5c5c36d6d4b073299832aa1ec6a746a6452c3ee7b46b3d3b11d", - "sha256:19d6c11bf35a6ad077eb23852827f91c804eeb71ecb85db4ee1386825b9dc4db", - "sha256:1f687a28640f763f23f8a9801fe9e1b37338bb1ca5d564ddd41619458f1f22d1", - "sha256:224803b74aab56aa7be313f92a8d9911dcade37e5f167db62a738d0c85fdac4b", - "sha256:23a412b7b1a7063f81a742463f38821097b6a37ce1e5b89dd8e871d14dbfd86b", - "sha256:25f87ae6b96374db20f180eab083aafe419b194e96e4f282c40191e71980c666", - "sha256:2630ca4e152c221072fd4a56d4622b5ada876f668ecd24d5ab62544ae6793ed6", - "sha256:28e1f28d07220c0f3da0e8fcd5a115bbb53f8b55cecf9bec0c946eb9a059a94c", - "sha256:2b51739ddfd013c6f657b55a508de8b9ea78b56d22b236052c3a85a675102dc6", - "sha256:2cc1b87bba1dd1a898e664a31012725e48af826bf3971e786c53e32e02adae6c", - "sha256:2fef0b38c34ae675fcbb1b5db760d40c3fc3612cfa186e9e50df5782cac02bcd", - "sha256:36f392dc7763fe7924575475736bddf9ab9f7a66b920932d0ea50c2ded2f5636", - "sha256:374f690e1dd0dbdcddea4a5c9bdd97632cf656c69113f7cd6a361f2a67221cb6", - "sha256:3986217ec830c2109875be740531feb8ddafe0dfa49767cdcd072ed7e8927962", - "sha256:39fb166d2196413bead229cd64a2ffd6ec78ebab83fff7d2701103cf9f4dfd26", - "sha256:4290035b169578ffbbfa50d904d26bec16a94526071ebec3dadbebf67a26b25e", - "sha256:43548ad74ea50456e1c68d3c67fff3de64c6edb85bcd511d1136f9b5376fc9d1", - "sha256:44a22ae1cfd82e4ffa2066eb3390777dc79468f866f0625261a93e44cdf6482b", - "sha256:457c2cd5a646dd4ed536c92b535d73548fb8e216ebee602aa9f48e068fc393f3", - "sha256:459226445c7d7454981c4c0ce0ad1a72e1e751c3e417f305722bbcee6697e06a", - "sha256:47af45b6153522733aa6e92543938e97a70ce0900649ba626cf5aad290b737b6", - "sha256:499334ad139557de97cbc4347ee921c0e2b5e9c0f009859e74f3f77918339257", - "sha256:57ba112e5530530fd175ed550373eb263db4ca98b5f00694d73b18b9a02e7185", - "sha256:5ce479ecc068bc2a74cb98dd8dba99e070d1b2f4a8371a7dfe631f85db70fe6e", - "sha256:5dbc1bcc7413eebe5f18196e22804a3be1bfdfc7e2afd415e12c068624d48247", - "sha256:6277d426e2f31bdbacb377d17a7475e32b2d7d1f02faaecc48d8e370c6a3ff31", - "sha256:66372c2a01782c5fe8e04bff4a2a0121a9897e19223d9eab30c54c50b2ebeb7f", - "sha256:670fa596984b08a4a769491cbdf22350431970d0112e03d7e4eeaecaafcd0fec", - "sha256:6f435946b7bf7a1b438b4e6b149b947c837cb23c704e780c19ba3e6855dbbdd3", - "sha256:7413167c507a768eafb5424413c5b2f515c606be5bb4ef8c5dee43925aa5718b", - "sha256:7c3d389e8d76a49923683123730c33e9553063d9041658f23897f0b396b2386f", - "sha256:7d77b6f63f806578c604dca209280e4c54f0fa9a8128bb8d2cc5fb6f99da4150", - "sha256:7e76b9cfbf5ced1aca15a0e5b6f229344d9b3123439ffce552b11faab0114a02", - "sha256:7f3502f03b4da52bbe8ba962621daa846f38489cae5c4a7b5d738f15f6443d17", - "sha256:7fe9739a686dc44733d52d6e4f7b9c77b285e49edf8570754b322bca6b85b4cc", - "sha256:83ab366777ea45d58f72593adf35d36ca911ea8bd838483c1823b883a121b0e4", - "sha256:84077821c85f222362b72fdc44f7a3a13587a013a45cf14534df1cbbdc9a6796", - "sha256:8bb381f777351bd534462f63e1c6afb10a7caa9fa2a421ae22c26e796fe31b1f", - "sha256:92da587eee39a52c91aebea8b850e4e4f095fe5928d415cb7ed656b3460ae79a", - "sha256:9301cc6db4d83d2c0719f7fcda37229691745168bf6ae849bea2e85fc769175d", - "sha256:965fd0cf4694d76f6564896b422724ec7b959ef927a7cb187fc6b3f4e4f59833", - "sha256:99d6a550425cc51c656331af0e2b1651e90eaaa23fb4acde577cf15068e2e20f", - "sha256:99ef6289b62042500d581170d06e17f5353b111a15aa6b25b05b91c6886df8fc", - "sha256:a1409c4eccb6981c7baabc8888d3550df518add6e06fe74fa1d9312c1838652d", - "sha256:a74fcf77d979364f9b69fcf8200849ca29a374973dc193a7317698aa37d8b01c", - "sha256:aaa179975a64790c1f2701ac562b5eeb733946eeb036b5bcca05c8d928a62f10", - "sha256:ac69b394764bb857429b031d29d9604842bc4cbfd964d764b1af1868eeebc4f0", - "sha256:b45d4503de8f4f3dc02f1d28a9b039e5504a02cc18906cfe744c11def942e9eb", - "sha256:b7d893c8cf0e2429b823ef1a1d360a25950ed11f0e2a9df2b5198821832e1947", - "sha256:b8eb28995771c087a73338f695a08c9abfdf723d185e57b97f6175c5051ff1ae", - "sha256:b91d529b47798c016d4b4c1d06cc826ac40d196da54f0de3c519f5a297c5076a", - "sha256:bc365ce25f6c7c5ed70e4bc674f9137f52b7dd6a125037f9132a7be52b8a252f", - "sha256:bf29304a8011feb58913c382902fde3395957a47645bf848eea695839aa101b7", - "sha256:c06bf3f38f0707592898428636cbb75d0a846651b053a1cf748763e3063a6925", - "sha256:c77d10ec3c1cf328b2f501ca32583625987ea0f23a0c2a49b37a39ee5c4c4630", - "sha256:cd196d056b40af073d95a2879678585f0b74ad35190fac04ca67954c582c6b61", - "sha256:d7a353ebfa7154c871a35caca7bfd8f9e18666829a1dc187115b80e35a29393e", - "sha256:d84308f097d7a513359757c69707ad339da799e53b7393819ec2ea36bc4beb58", - "sha256:dd7ef715ccb8040954d44cfeff17e6b8e9f79c8019daae2fd30a8806ef5435c0", - "sha256:e672cf9caaf669053121f1766d659a8813bd547edef6e009205378faf45c67b8", - "sha256:ecc6148228c9ae25ce403eade13a0961de1cb016bdb35c6eafd8e7b87ad028b1", - "sha256:f1c5742c31ba7d72f2dedf7968998730664b45e38827637e0f04a2ac7de2f5f1", - "sha256:f1d6e4b7b2ae3a6a9df53efbf199e4bfcff0959dbdb5fd9ced34d4407348e39a", - "sha256:f2fc053228a6bd3a17a9b0a3f15c3ab3cf95727b00557e92e1cfe094b88cc662", - "sha256:f57515750d07e14743db55d59759893fdb21d2668f39e549a7d6cad5d70f9fea", - "sha256:f85151ec5a232335f1be022b09fbbe459042ea1951d8a48fef251223fc67eee1", - "sha256:fb0315a2b26fde4005a7c401707c5352df274460f2f85b209cf6024271373013", - "sha256:fc0916c4295c64d6890a46e02d4482bb5ccf33bf1a824c0eaa9e83b148291f90", - "sha256:fd24fd140b69f0b0bcc9165c397e9b2e89ecbeda83303abf2a072609f60239e2", - "sha256:fdae0120cddc839eb8e3c15faa8ad541cc6d906d3eb24d82fb041cfe2807bc1e", - "sha256:fe00f4fe11c8a521b173e6324d862ee7ee3412bf7107570c9b564fe1119b56fb" - ], - "markers": "python_version >= '3.8'", - "version": "==2024.4.28" - }, - "requests": { - "hashes": [ - "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", - "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" - ], - "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==2.31.0" - }, - "rpds-py": { - "hashes": [ - "sha256:05f3d615099bd9b13ecf2fc9cf2d839ad3f20239c678f461c753e93755d629ee", - "sha256:06d218939e1bf2ca50e6b0ec700ffe755e5216a8230ab3e87c059ebb4ea06afc", - "sha256:07f2139741e5deb2c5154a7b9629bc5aa48c766b643c1a6750d16f865a82c5fc", - "sha256:08d74b184f9ab6289b87b19fe6a6d1a97fbfea84b8a3e745e87a5de3029bf944", - "sha256:0abeee75434e2ee2d142d650d1e54ac1f8b01e6e6abdde8ffd6eeac6e9c38e20", - "sha256:154bf5c93d79558b44e5b50cc354aa0459e518e83677791e6adb0b039b7aa6a7", - "sha256:17c6d2155e2423f7e79e3bb18151c686d40db42d8645e7977442170c360194d4", - "sha256:1805d5901779662d599d0e2e4159d8a82c0b05faa86ef9222bf974572286b2b6", - "sha256:19ba472b9606c36716062c023afa2484d1e4220548751bda14f725a7de17b4f6", - "sha256:19e515b78c3fc1039dd7da0a33c28c3154458f947f4dc198d3c72db2b6b5dc93", - "sha256:1d54f74f40b1f7aaa595a02ff42ef38ca654b1469bef7d52867da474243cc633", - "sha256:207c82978115baa1fd8d706d720b4a4d2b0913df1c78c85ba73fe6c5804505f0", - "sha256:2625f03b105328729f9450c8badda34d5243231eef6535f80064d57035738360", - "sha256:27bba383e8c5231cd559affe169ca0b96ec78d39909ffd817f28b166d7ddd4d8", - "sha256:2c3caec4ec5cd1d18e5dd6ae5194d24ed12785212a90b37f5f7f06b8bedd7139", - "sha256:2cc7c1a47f3a63282ab0f422d90ddac4aa3034e39fc66a559ab93041e6505da7", - "sha256:2fc24a329a717f9e2448f8cd1f960f9dac4e45b6224d60734edeb67499bab03a", - "sha256:312fe69b4fe1ffbe76520a7676b1e5ac06ddf7826d764cc10265c3b53f96dbe9", - "sha256:32b7daaa3e9389db3695964ce8e566e3413b0c43e3394c05e4b243a4cd7bef26", - "sha256:338dee44b0cef8b70fd2ef54b4e09bb1b97fc6c3a58fea5db6cc083fd9fc2724", - "sha256:352a88dc7892f1da66b6027af06a2e7e5d53fe05924cc2cfc56495b586a10b72", - "sha256:35b2b771b13eee8729a5049c976197ff58a27a3829c018a04341bcf1ae409b2b", - "sha256:38e14fb4e370885c4ecd734f093a2225ee52dc384b86fa55fe3f74638b2cfb09", - "sha256:3c20f05e8e3d4fc76875fc9cb8cf24b90a63f5a1b4c5b9273f0e8225e169b100", - "sha256:3dd3cd86e1db5aadd334e011eba4e29d37a104b403e8ca24dcd6703c68ca55b3", - "sha256:489bdfe1abd0406eba6b3bb4fdc87c7fa40f1031de073d0cfb744634cc8fa261", - "sha256:48c2faaa8adfacefcbfdb5f2e2e7bdad081e5ace8d182e5f4ade971f128e6bb3", - "sha256:4a98a1f0552b5f227a3d6422dbd61bc6f30db170939bd87ed14f3c339aa6c7c9", - "sha256:4adec039b8e2928983f885c53b7cc4cda8965b62b6596501a0308d2703f8af1b", - "sha256:4e0ee01ad8260184db21468a6e1c37afa0529acc12c3a697ee498d3c2c4dcaf3", - "sha256:51584acc5916212e1bf45edd17f3a6b05fe0cbb40482d25e619f824dccb679de", - "sha256:531796fb842b53f2695e94dc338929e9f9dbf473b64710c28af5a160b2a8927d", - "sha256:5463c47c08630007dc0fe99fb480ea4f34a89712410592380425a9b4e1611d8e", - "sha256:5c45a639e93a0c5d4b788b2613bd637468edd62f8f95ebc6fcc303d58ab3f0a8", - "sha256:6031b25fb1b06327b43d841f33842b383beba399884f8228a6bb3df3088485ff", - "sha256:607345bd5912aacc0c5a63d45a1f73fef29e697884f7e861094e443187c02be5", - "sha256:618916f5535784960f3ecf8111581f4ad31d347c3de66d02e728de460a46303c", - "sha256:636a15acc588f70fda1661234761f9ed9ad79ebed3f2125d44be0862708b666e", - "sha256:673fdbbf668dd958eff750e500495ef3f611e2ecc209464f661bc82e9838991e", - "sha256:6afd80f6c79893cfc0574956f78a0add8c76e3696f2d6a15bca2c66c415cf2d4", - "sha256:6b5ff7e1d63a8281654b5e2896d7f08799378e594f09cf3674e832ecaf396ce8", - "sha256:6c4c4c3f878df21faf5fac86eda32671c27889e13570645a9eea0a1abdd50922", - "sha256:6cd8098517c64a85e790657e7b1e509b9fe07487fd358e19431cb120f7d96338", - "sha256:6d1e42d2735d437e7e80bab4d78eb2e459af48c0a46e686ea35f690b93db792d", - "sha256:6e30ac5e329098903262dc5bdd7e2086e0256aa762cc8b744f9e7bf2a427d3f8", - "sha256:70a838f7754483bcdc830444952fd89645569e7452e3226de4a613a4c1793fb2", - "sha256:720edcb916df872d80f80a1cc5ea9058300b97721efda8651efcd938a9c70a72", - "sha256:732672fbc449bab754e0b15356c077cc31566df874964d4801ab14f71951ea80", - "sha256:740884bc62a5e2bbb31e584f5d23b32320fd75d79f916f15a788d527a5e83644", - "sha256:7700936ef9d006b7ef605dc53aa364da2de5a3aa65516a1f3ce73bf82ecfc7ae", - "sha256:7732770412bab81c5a9f6d20aeb60ae943a9b36dcd990d876a773526468e7163", - "sha256:7750569d9526199c5b97e5a9f8d96a13300950d910cf04a861d96f4273d5b104", - "sha256:7f1944ce16401aad1e3f7d312247b3d5de7981f634dc9dfe90da72b87d37887d", - "sha256:81c5196a790032e0fc2464c0b4ab95f8610f96f1f2fa3d4deacce6a79852da60", - "sha256:8352f48d511de5f973e4f2f9412736d7dea76c69faa6d36bcf885b50c758ab9a", - "sha256:8927638a4d4137a289e41d0fd631551e89fa346d6dbcfc31ad627557d03ceb6d", - "sha256:8c7672e9fba7425f79019db9945b16e308ed8bc89348c23d955c8c0540da0a07", - "sha256:8d2e182c9ee01135e11e9676e9a62dfad791a7a467738f06726872374a83db49", - "sha256:910e71711d1055b2768181efa0a17537b2622afeb0424116619817007f8a2b10", - "sha256:942695a206a58d2575033ff1e42b12b2aece98d6003c6bc739fbf33d1773b12f", - "sha256:9437ca26784120a279f3137ee080b0e717012c42921eb07861b412340f85bae2", - "sha256:967342e045564cef76dfcf1edb700b1e20838d83b1aa02ab313e6a497cf923b8", - "sha256:998125738de0158f088aef3cb264a34251908dd2e5d9966774fdab7402edfab7", - "sha256:9e6934d70dc50f9f8ea47081ceafdec09245fd9f6032669c3b45705dea096b88", - "sha256:a3d456ff2a6a4d2adcdf3c1c960a36f4fd2fec6e3b4902a42a384d17cf4e7a65", - "sha256:a7b28c5b066bca9a4eb4e2f2663012debe680f097979d880657f00e1c30875a0", - "sha256:a888e8bdb45916234b99da2d859566f1e8a1d2275a801bb8e4a9644e3c7e7909", - "sha256:aa3679e751408d75a0b4d8d26d6647b6d9326f5e35c00a7ccd82b78ef64f65f8", - "sha256:aaa71ee43a703c321906813bb252f69524f02aa05bf4eec85f0c41d5d62d0f4c", - "sha256:b646bf655b135ccf4522ed43d6902af37d3f5dbcf0da66c769a2b3938b9d8184", - "sha256:b906b5f58892813e5ba5c6056d6a5ad08f358ba49f046d910ad992196ea61397", - "sha256:b9bb1f182a97880f6078283b3505a707057c42bf55d8fca604f70dedfdc0772a", - "sha256:bd1105b50ede37461c1d51b9698c4f4be6e13e69a908ab7751e3807985fc0346", - "sha256:bf18932d0003c8c4d51a39f244231986ab23ee057d235a12b2684ea26a353590", - "sha256:c273e795e7a0f1fddd46e1e3cb8be15634c29ae8ff31c196debb620e1edb9333", - "sha256:c69882964516dc143083d3795cb508e806b09fc3800fd0d4cddc1df6c36e76bb", - "sha256:c827576e2fa017a081346dce87d532a5310241648eb3700af9a571a6e9fc7e74", - "sha256:cbfbea39ba64f5e53ae2915de36f130588bba71245b418060ec3330ebf85678e", - "sha256:ce0bb20e3a11bd04461324a6a798af34d503f8d6f1aa3d2aa8901ceaf039176d", - "sha256:d0cee71bc618cd93716f3c1bf56653740d2d13ddbd47673efa8bf41435a60daa", - "sha256:d21be4770ff4e08698e1e8e0bce06edb6ea0626e7c8f560bc08222880aca6a6f", - "sha256:d31dea506d718693b6b2cffc0648a8929bdc51c70a311b2770f09611caa10d53", - "sha256:d44607f98caa2961bab4fa3c4309724b185b464cdc3ba6f3d7340bac3ec97cc1", - "sha256:d58ad6317d188c43750cb76e9deacf6051d0f884d87dc6518e0280438648a9ac", - "sha256:d70129cef4a8d979caa37e7fe957202e7eee8ea02c5e16455bc9808a59c6b2f0", - "sha256:d85164315bd68c0806768dc6bb0429c6f95c354f87485ee3593c4f6b14def2bd", - "sha256:d960de62227635d2e61068f42a6cb6aae91a7fe00fca0e3aeed17667c8a34611", - "sha256:dc48b479d540770c811fbd1eb9ba2bb66951863e448efec2e2c102625328e92f", - "sha256:e1735502458621921cee039c47318cb90b51d532c2766593be6207eec53e5c4c", - "sha256:e2be6e9dd4111d5b31ba3b74d17da54a8319d8168890fbaea4b9e5c3de630ae5", - "sha256:e4c39ad2f512b4041343ea3c7894339e4ca7839ac38ca83d68a832fc8b3748ab", - "sha256:ed402d6153c5d519a0faf1bb69898e97fb31613b49da27a84a13935ea9164dfc", - "sha256:ee17cd26b97d537af8f33635ef38be873073d516fd425e80559f4585a7b90c43", - "sha256:f3027be483868c99b4985fda802a57a67fdf30c5d9a50338d9db646d590198da", - "sha256:f5bab211605d91db0e2995a17b5c6ee5edec1270e46223e513eaa20da20076ac", - "sha256:f6f8e3fecca256fefc91bb6765a693d96692459d7d4c644660a9fff32e517843", - "sha256:f7afbfee1157e0f9376c00bb232e80a60e59ed716e3211a80cb8506550671e6e", - "sha256:fa242ac1ff583e4ec7771141606aafc92b361cd90a05c30d93e343a0c2d82a89", - "sha256:fab6ce90574645a0d6c58890e9bcaac8d94dff54fb51c69e5522a7358b80ab64" - ], - "markers": "python_version >= '3.8'", - "version": "==0.18.1" - }, - "ruamel.yaml": { - "hashes": [ - "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636", - "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b" - ], - "markers": "python_version >= '3.7'", - "version": "==0.18.6" - }, - "ruamel.yaml.clib": { - "hashes": [ - "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d", - "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001", - "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462", - "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9", - "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe", - "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b", - "sha256:184565012b60405d93838167f425713180b949e9d8dd0bbc7b49f074407c5a8b", - "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615", - "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62", - "sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15", - "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b", - "sha256:305889baa4043a09e5b76f8e2a51d4ffba44259f6b4c72dec8ca56207d9c6fe1", - "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9", - "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675", - "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899", - "sha256:4ecbf9c3e19f9562c7fdd462e8d18dd902a47ca046a2e64dba80699f0b6c09b7", - "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7", - "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312", - "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa", - "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91", - "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b", - "sha256:77159f5d5b5c14f7c34073862a6b7d34944075d9f93e681638f6d753606c6ce6", - "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3", - "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334", - "sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5", - "sha256:87ea5ff66d8064301a154b3933ae406b0863402a799b16e4a1d24d9fbbcbe0d3", - "sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe", - "sha256:a1a45e0bb052edf6a1d3a93baef85319733a888363938e1fc9924cb00c8df24c", - "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed", - "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337", - "sha256:a75879bacf2c987c003368cf14bed0ffe99e8e85acfa6c0bfffc21a090f16880", - "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f", - "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d", - "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248", - "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d", - "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf", - "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512", - "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069", - "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb", - "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942", - "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d", - "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31", - "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92", - "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5", - "sha256:e2b4c44b60eadec492926a7270abb100ef9f72798e18743939bdbf037aab8c28", - "sha256:e79e5db08739731b0ce4850bed599235d601701d5694c36570a99a0c5ca41a9d", - "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1", - "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2", - "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875", - "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412" - ], - "markers": "python_version < '3.13' and platform_python_implementation == 'CPython'", - "version": "==0.2.8" - }, - "s3transfer": { - "hashes": [ - "sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19", - "sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d" - ], - "markers": "python_version >= '3.8'", - "version": "==0.10.1" - }, - "schema": { - "hashes": [ - "sha256:5d976a5b50f36e74e2157b47097b60002bd4d42e65425fcc9c9befadb4255dde", - "sha256:7da553abd2958a19dc2547c388cde53398b39196175a9be59ea1caf5ab0a1807" - ], - "version": "==0.7.7" - }, - "semver": { - "hashes": [ - "sha256:6253adb39c70f6e51afed2fa7152bcd414c411286088fb4b9effb133885ab4cc", - "sha256:b1ea4686fe70b981f85359eda33199d60c53964284e0cfb4977d243e37cf4bf4" - ], - "markers": "python_version >= '3.7'", - "version": "==3.0.2" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" - }, - "sniffio": { - "hashes": [ - "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", - "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" - ], - "markers": "python_version >= '3.7'", - "version": "==1.3.1" - }, - "sqlfluff": { - "hashes": [ - "sha256:43805e5b1bfa6425d66f2eac3f34007a5bd259cf3bf4cff1bcfa4e2706055656", - "sha256:fa60e2a16e2500368d4ab98b5246ac85d4542c134413a5e650ed4d356adf7ddd" - ], - "markers": "python_version >= '3.8'", - "version": "==3.0.6" - }, - "tblib": { - "hashes": [ - "sha256:80a6c77e59b55e83911e1e607c649836a69c103963c5f28a46cbeef44acf8129", - "sha256:93622790a0a29e04f0346458face1e144dc4d32f493714c6c3dff82a4adb77e6" - ], - "markers": "python_version >= '3.8'", - "version": "==3.0.0" - }, - "tqdm": { - "hashes": [ - "sha256:b75ca56b413b030bc3f00af51fd2c1a1a5eac6a0c1cca83cbb37a5c52abce644", - "sha256:e4d936c9de8727928f3be6079590e97d9abfe8d39a590be678eb5919ffc186bb" - ], - "markers": "python_version >= '3.7'", - "version": "==4.66.4" - }, - "typing-extensions": { - "hashes": [ - "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0", - "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a" - ], - "markers": "python_version >= '3.8'", - "version": "==4.11.0" - }, - "urllib3": { - "hashes": [ - "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d", - "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19" - ], - "markers": "python_version >= '3.8'", - "version": "==2.2.1" - }, - "yarl": { - "hashes": [ - "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51", - "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce", - "sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559", - "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0", - "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81", - "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc", - "sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4", - "sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c", - "sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130", - "sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136", - "sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e", - "sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec", - "sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7", - "sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1", - "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455", - "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099", - "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129", - "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10", - "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142", - "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98", - "sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa", - "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7", - "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525", - "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c", - "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9", - "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c", - "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8", - "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b", - "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf", - "sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23", - "sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd", - "sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27", - "sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f", - "sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece", - "sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434", - "sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec", - "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff", - "sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78", - "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d", - "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863", - "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53", - "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31", - "sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15", - "sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5", - "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b", - "sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57", - "sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3", - "sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1", - "sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f", - "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad", - "sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c", - "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7", - "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2", - "sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b", - "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2", - "sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b", - "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9", - "sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be", - "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e", - "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984", - "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4", - "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074", - "sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2", - "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392", - "sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91", - "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541", - "sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf", - "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572", - "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66", - "sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575", - "sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14", - "sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5", - "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1", - "sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e", - "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551", - "sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17", - "sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead", - "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0", - "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe", - "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234", - "sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0", - "sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7", - "sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34", - "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42", - "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385", - "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78", - "sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be", - "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958", - "sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749", - "sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec" - ], - "markers": "python_version >= '3.7'", - "version": "==1.9.4" - } - }, - "develop": { - "astroid": { - "hashes": [ - "sha256:1aa149fc5c6589e3d0ece885b4491acd80af4f087baafa3fb5203b113e68cd3c", - "sha256:6c107453dffee9055899705de3c9ead36e74119cee151e5a9aaf7f0b0e020a6a" - ], - "markers": "python_full_version >= '3.7.2'", - "version": "==2.15.8" - }, - "bandit": { - "hashes": [ - "sha256:36de50f720856ab24a24dbaa5fee2c66050ed97c1477e0a1159deab1775eab6b", - "sha256:509f7af645bc0cd8fd4587abc1a038fc795636671ee8204d502b933aee44f381" - ], - "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==1.7.8" - }, - "black": { - "hashes": [ - "sha256:2818cf72dfd5d289e48f37ccfa08b460bf469e67fb7c4abb07edc2e9f16fb63f", - "sha256:41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93", - "sha256:4acf672def7eb1725f41f38bf6bf425c8237248bb0804faa3965c036f7672d11", - "sha256:4be5bb28e090456adfc1255e03967fb67ca846a03be7aadf6249096100ee32d0", - "sha256:4f1373a7808a8f135b774039f61d59e4be7eb56b2513d3d2f02a8b9365b8a8a9", - "sha256:56f52cfbd3dabe2798d76dbdd299faa046a901041faf2cf33288bc4e6dae57b5", - "sha256:65b76c275e4c1c5ce6e9870911384bff5ca31ab63d19c76811cb1fb162678213", - "sha256:65c02e4ea2ae09d16314d30912a58ada9a5c4fdfedf9512d23326128ac08ac3d", - "sha256:6905238a754ceb7788a73f02b45637d820b2f5478b20fec82ea865e4f5d4d9f7", - "sha256:79dcf34b33e38ed1b17434693763301d7ccbd1c5860674a8f871bd15139e7837", - "sha256:7bb041dca0d784697af4646d3b62ba4a6b028276ae878e53f6b4f74ddd6db99f", - "sha256:7d5e026f8da0322b5662fa7a8e752b3fa2dac1c1cbc213c3d7ff9bdd0ab12395", - "sha256:9f50ea1132e2189d8dff0115ab75b65590a3e97de1e143795adb4ce317934995", - "sha256:a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f", - "sha256:aadf7a02d947936ee418777e0247ea114f78aff0d0959461057cae8a04f20597", - "sha256:b5991d523eee14756f3c8d5df5231550ae8993e2286b8014e2fdea7156ed0959", - "sha256:bf21b7b230718a5f08bd32d5e4f1db7fc8788345c8aea1d155fc17852b3410f5", - "sha256:c45f8dff244b3c431b36e3224b6be4a127c6aca780853574c00faf99258041eb", - "sha256:c7ed6668cbbfcd231fa0dc1b137d3e40c04c7f786e626b405c62bcd5db5857e4", - "sha256:d7de8d330763c66663661a1ffd432274a2f92f07feeddd89ffd085b5744f85e7", - "sha256:e19cb1c6365fd6dc38a6eae2dcb691d7d83935c10215aef8e6c38edee3f77abd", - "sha256:e2af80566f43c85f5797365077fb64a393861a3730bd110971ab7a0c94e873e7" - ], - "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==24.3.0" - }, - "boto3": { - "hashes": [ - "sha256:6f600b3fe0bda53476395c902d9af5a47294c93ec52a9cdc2b926a9dc705ce79", - "sha256:b54084d000483b578757df03ce39a819fbba47071c9aa98611beb8806bcecd45" - ], - "markers": "python_version >= '3.8'", - "version": "==1.34.99" - }, - "botocore": { - "hashes": [ - "sha256:18c68bdeb0ffb73290912b0c96204fc36d3128f00a00b5cdc35ac34d66225f1c", - "sha256:cafe569e2136cb33cb0e5dd32fb1c0e1503ddc1413d3be215df8ddf05e69137a" - ], - "markers": "python_version >= '3.8'", - "version": "==1.34.99" - }, - "certifi": { - "hashes": [ - "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", - "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" - ], - "markers": "python_version >= '3.6'", - "version": "==2024.2.2" - }, - "cffi": { - "hashes": [ - "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc", - "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a", - "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417", - "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab", - "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520", - "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36", - "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743", - "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8", - "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed", - "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684", - "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56", - "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324", - "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d", - "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235", - "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e", - "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088", - "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000", - "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7", - "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e", - "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673", - "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c", - "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe", - "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2", - "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098", - "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8", - "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a", - "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0", - "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b", - "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896", - "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e", - "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9", - "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2", - "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b", - "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6", - "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404", - "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f", - "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0", - "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4", - "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc", - "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936", - "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba", - "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872", - "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb", - "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614", - "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1", - "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d", - "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969", - "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b", - "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4", - "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627", - "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956", - "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357" - ], - "markers": "platform_python_implementation != 'PyPy'", - "version": "==1.16.0" - }, - "charset-normalizer": { - "hashes": [ - "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", - "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", - "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", - "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", - "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", - "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", - "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", - "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", - "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", - "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", - "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", - "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", - "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", - "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", - "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", - "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", - "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", - "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", - "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", - "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", - "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", - "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", - "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", - "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", - "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", - "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", - "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", - "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", - "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", - "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", - "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", - "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", - "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", - "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", - "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", - "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", - "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", - "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", - "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", - "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", - "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", - "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", - "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", - "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", - "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", - "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", - "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", - "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", - "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", - "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", - "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", - "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", - "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", - "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", - "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", - "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", - "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", - "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", - "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", - "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", - "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", - "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", - "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", - "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", - "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", - "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", - "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", - "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", - "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", - "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", - "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", - "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", - "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", - "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", - "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", - "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", - "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", - "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", - "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", - "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", - "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", - "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", - "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", - "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", - "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", - "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", - "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", - "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", - "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", - "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" - ], - "markers": "python_full_version >= '3.7.0'", - "version": "==3.3.2" - }, - "click": { - "hashes": [ - "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", - "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" - ], - "markers": "python_version >= '3.7'", - "version": "==8.1.7" - }, - "cryptography": { - "hashes": [ - "sha256:02c0eee2d7133bdbbc5e24441258d5d2244beb31da5ed19fbb80315f4bbbff55", - "sha256:0d563795db98b4cd57742a78a288cdbdc9daedac29f2239793071fe114f13785", - "sha256:16268d46086bb8ad5bf0a2b5544d8a9ed87a0e33f5e77dd3c3301e63d941a83b", - "sha256:1a58839984d9cb34c855197043eaae2c187d930ca6d644612843b4fe8513c886", - "sha256:2954fccea107026512b15afb4aa664a5640cd0af630e2ee3962f2602693f0c82", - "sha256:2e47577f9b18723fa294b0ea9a17d5e53a227867a0a4904a1a076d1646d45ca1", - "sha256:31adb7d06fe4383226c3e963471f6837742889b3c4caa55aac20ad951bc8ffda", - "sha256:3577d029bc3f4827dd5bf8bf7710cac13527b470bbf1820a3f394adb38ed7d5f", - "sha256:36017400817987670037fbb0324d71489b6ead6231c9604f8fc1f7d008087c68", - "sha256:362e7197754c231797ec45ee081f3088a27a47c6c01eff2ac83f60f85a50fe60", - "sha256:3de9a45d3b2b7d8088c3fbf1ed4395dfeff79d07842217b38df14ef09ce1d8d7", - "sha256:4f698edacf9c9e0371112792558d2f705b5645076cc0aaae02f816a0171770fd", - "sha256:5482e789294854c28237bba77c4c83be698be740e31a3ae5e879ee5444166582", - "sha256:5e44507bf8d14b36b8389b226665d597bc0f18ea035d75b4e53c7b1ea84583cc", - "sha256:779245e13b9a6638df14641d029add5dc17edbef6ec915688f3acb9e720a5858", - "sha256:789caea816c6704f63f6241a519bfa347f72fbd67ba28d04636b7c6b7da94b0b", - "sha256:7f8b25fa616d8b846aef64b15c606bb0828dbc35faf90566eb139aa9cff67af2", - "sha256:8cb8ce7c3347fcf9446f201dc30e2d5a3c898d009126010cbd1f443f28b52678", - "sha256:93a3209f6bb2b33e725ed08ee0991b92976dfdcf4e8b38646540674fc7508e13", - "sha256:a3a5ac8b56fe37f3125e5b72b61dcde43283e5370827f5233893d461b7360cd4", - "sha256:a47787a5e3649008a1102d3df55424e86606c9bae6fb77ac59afe06d234605f8", - "sha256:a79165431551042cc9d1d90e6145d5d0d3ab0f2d66326c201d9b0e7f5bf43604", - "sha256:a987f840718078212fdf4504d0fd4c6effe34a7e4740378e59d47696e8dfb477", - "sha256:a9bc127cdc4ecf87a5ea22a2556cab6c7eda2923f84e4f3cc588e8470ce4e42e", - "sha256:bd13b5e9b543532453de08bcdc3cc7cebec6f9883e886fd20a92f26940fd3e7a", - "sha256:c65f96dad14f8528a447414125e1fc8feb2ad5a272b8f68477abbcc1ea7d94b9", - "sha256:d8e3098721b84392ee45af2dd554c947c32cc52f862b6a3ae982dbb90f577f14", - "sha256:e6b79d0adb01aae87e8a44c2b64bc3f3fe59515280e00fb6d57a7267a2583cda", - "sha256:e6b8f1881dac458c34778d0a424ae5769de30544fc678eac51c1c8bb2183e9da", - "sha256:e9b2a6309f14c0497f348d08a065d52f3020656f675819fc405fb63bbcd26562", - "sha256:ecbfbc00bf55888edda9868a4cf927205de8499e7fabe6c050322298382953f2", - "sha256:efd0bf5205240182e0f13bcaea41be4fdf5c22c5129fc7ced4a0282ac86998c9" - ], - "markers": "python_version >= '3.7'", - "version": "==42.0.7" - }, - "decorator": { - "hashes": [ - "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330", - "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186" - ], - "index": "pypi", - "markers": "python_version >= '3.5'", - "version": "==5.1.1" - }, - "dill": { - "hashes": [ - "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca", - "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7" - ], - "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==0.3.8" - }, - "idna": { - "hashes": [ - "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", - "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0" - ], - "markers": "python_version >= '3.5'", - "version": "==3.7" - }, - "isort": { - "hashes": [ - "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109", - "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6" - ], - "index": "pypi", - "markers": "python_full_version >= '3.8.0'", - "version": "==5.13.2" - }, - "jinja2": { - "hashes": [ - "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", - "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d" - ], - "markers": "python_version >= '3.7'", - "version": "==3.1.4" - }, - "jmespath": { - "hashes": [ - "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", - "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe" - ], - "markers": "python_version >= '3.7'", - "version": "==1.0.1" - }, - "lazy-object-proxy": { - "hashes": [ - "sha256:009e6bb1f1935a62889ddc8541514b6a9e1fcf302667dcb049a0be5c8f613e56", - "sha256:02c83f957782cbbe8136bee26416686a6ae998c7b6191711a04da776dc9e47d4", - "sha256:0aefc7591920bbd360d57ea03c995cebc204b424524a5bd78406f6e1b8b2a5d8", - "sha256:127a789c75151db6af398b8972178afe6bda7d6f68730c057fbbc2e96b08d282", - "sha256:18dd842b49456aaa9a7cf535b04ca4571a302ff72ed8740d06b5adcd41fe0757", - "sha256:217138197c170a2a74ca0e05bddcd5f1796c735c37d0eee33e43259b192aa424", - "sha256:2297f08f08a2bb0d32a4265e98a006643cd7233fb7983032bd61ac7a02956b3b", - "sha256:2fc0a92c02fa1ca1e84fc60fa258458e5bf89d90a1ddaeb8ed9cc3147f417255", - "sha256:30b339b2a743c5288405aa79a69e706a06e02958eab31859f7f3c04980853b70", - "sha256:366c32fe5355ef5fc8a232c5436f4cc66e9d3e8967c01fb2e6302fd6627e3d94", - "sha256:3ad54b9ddbe20ae9f7c1b29e52f123120772b06dbb18ec6be9101369d63a4074", - "sha256:5ad9e6ed739285919aa9661a5bbed0aaf410aa60231373c5579c6b4801bd883c", - "sha256:5faf03a7d8942bb4476e3b62fd0f4cf94eaf4618e304a19865abf89a35c0bbee", - "sha256:75fc59fc450050b1b3c203c35020bc41bd2695ed692a392924c6ce180c6f1dc9", - "sha256:76a095cfe6045c7d0ca77db9934e8f7b71b14645f0094ffcd842349ada5c5fb9", - "sha256:78247b6d45f43a52ef35c25b5581459e85117225408a4128a3daf8bf9648ac69", - "sha256:782e2c9b2aab1708ffb07d4bf377d12901d7a1d99e5e410d648d892f8967ab1f", - "sha256:7ab7004cf2e59f7c2e4345604a3e6ea0d92ac44e1c2375527d56492014e690c3", - "sha256:80b39d3a151309efc8cc48675918891b865bdf742a8616a337cb0090791a0de9", - "sha256:80fa48bd89c8f2f456fc0765c11c23bf5af827febacd2f523ca5bc1893fcc09d", - "sha256:855e068b0358ab916454464a884779c7ffa312b8925c6f7401e952dcf3b89977", - "sha256:92f09ff65ecff3108e56526f9e2481b8116c0b9e1425325e13245abfd79bdb1b", - "sha256:952c81d415b9b80ea261d2372d2a4a2332a3890c2b83e0535f263ddfe43f0d43", - "sha256:9a3a87cf1e133e5b1994144c12ca4aa3d9698517fe1e2ca82977781b16955658", - "sha256:9e4ed0518a14dd26092614412936920ad081a424bdcb54cc13349a8e2c6d106a", - "sha256:a899b10e17743683b293a729d3a11f2f399e8a90c73b089e29f5d0fe3509f0dd", - "sha256:b1f711e2c6dcd4edd372cf5dec5c5a30d23bba06ee012093267b3376c079ec83", - "sha256:b4f87d4ed9064b2628da63830986c3d2dca7501e6018347798313fcf028e2fd4", - "sha256:cb73507defd385b7705c599a94474b1d5222a508e502553ef94114a143ec6696", - "sha256:dc0d2fc424e54c70c4bc06787e4072c4f3b1aa2f897dfdc34ce1013cf3ceef05", - "sha256:e221060b701e2aa2ea991542900dd13907a5c90fa80e199dbf5a03359019e7a3", - "sha256:e271058822765ad5e3bca7f05f2ace0de58a3f4e62045a8c90a0dfd2f8ad8cc6", - "sha256:e2adb09778797da09d2b5ebdbceebf7dd32e2c96f79da9052b2e87b6ea495895", - "sha256:e333e2324307a7b5d86adfa835bb500ee70bfcd1447384a822e96495796b0ca4", - "sha256:e98c8af98d5707dcdecc9ab0863c0ea6e88545d42ca7c3feffb6b4d1e370c7ba", - "sha256:edb45bb8278574710e68a6b021599a10ce730d156e5b254941754a9cc0b17d03", - "sha256:fec03caabbc6b59ea4a638bee5fce7117be8e99a4103d9d5ad77f15d6f81020c" - ], - "markers": "python_version >= '3.8'", - "version": "==1.10.0" - }, - "markdown-it-py": { - "hashes": [ - "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", - "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb" - ], - "markers": "python_version >= '3.8'", - "version": "==3.0.0" - }, - "markupsafe": { - "hashes": [ - "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf", - "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", - "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", - "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", - "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532", - "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", - "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", - "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df", - "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4", - "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", - "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", - "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", - "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", - "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371", - "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2", - "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", - "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52", - "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", - "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", - "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", - "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", - "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0", - "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029", - "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", - "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a", - "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", - "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", - "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", - "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", - "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9", - "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", - "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", - "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3", - "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", - "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46", - "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", - "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a", - "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", - "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", - "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", - "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", - "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", - "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", - "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", - "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", - "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f", - "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50", - "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", - "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", - "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", - "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff", - "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", - "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", - "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", - "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf", - "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", - "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5", - "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab", - "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", - "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68" - ], - "markers": "python_version >= '3.7'", - "version": "==2.1.5" - }, - "mccabe": { - "hashes": [ - "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", - "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" - ], - "markers": "python_version >= '3.6'", - "version": "==0.7.0" - }, - "mdurl": { - "hashes": [ - "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", - "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" - ], - "markers": "python_version >= '3.7'", - "version": "==0.1.2" - }, - "moto": { - "hashes": [ - "sha256:ad8b23f2b555ad694da8b2432a42b6d96beaaf67a4e7d932196a72193a2eee2c", - "sha256:ca1e22831a741733b581ff2ef4d6ae2e1c6db1eab97af1b78b86ca2c6e88c609" - ], - "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==5.0.6" - }, - "mypy": { - "hashes": [ - "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061", - "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99", - "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de", - "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a", - "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9", - "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec", - "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1", - "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131", - "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f", - "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821", - "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5", - "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee", - "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e", - "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746", - "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2", - "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0", - "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b", - "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53", - "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30", - "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda", - "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051", - "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2", - "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7", - "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee", - "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727", - "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976", - "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4" - ], - "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==1.10.0" - }, - "mypy-extensions": { - "hashes": [ - "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", - "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782" - ], - "markers": "python_version >= '3.5'", - "version": "==1.0.0" - }, - "packaging": { - "hashes": [ - "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", - "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" - ], - "markers": "python_version >= '3.7'", - "version": "==24.0" - }, - "pathspec": { - "hashes": [ - "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", - "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712" - ], - "markers": "python_version >= '3.8'", - "version": "==0.12.1" - }, - "pbr": { - "hashes": [ - "sha256:4a7317d5e3b17a3dccb6a8cfe67dab65b20551404c52c8ed41279fa4f0cb4cda", - "sha256:d1377122a5a00e2f940ee482999518efe16d745d423a670c27773dfbc3c9a7d9" - ], - "markers": "python_version >= '2.6'", - "version": "==6.0.0" - }, - "platformdirs": { - "hashes": [ - "sha256:031cd18d4ec63ec53e82dceaac0417d218a6863f7745dfcc9efe7793b7039bdf", - "sha256:17d5a1161b3fd67b390023cb2d3b026bbd40abde6fdb052dfbd3a29c3ba22ee1" - ], - "markers": "python_version >= '3.8'", - "version": "==4.2.1" - }, - "pycparser": { - "hashes": [ - "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", - "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc" - ], - "markers": "python_version >= '3.8'", - "version": "==2.22" - }, - "pygments": { - "hashes": [ - "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", - "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a" - ], - "markers": "python_version >= '3.8'", - "version": "==2.18.0" - }, - "pylint": { - "hashes": [ - "sha256:27a8d4c7ddc8c2f8c18aa0050148f89ffc09838142193fdbe98f172781a3ff87", - "sha256:f4fcac7ae74cfe36bc8451e931d8438e4a476c20314b1101c458ad0f05191fad" - ], - "index": "pypi", - "markers": "python_full_version >= '3.7.2'", - "version": "==2.17.7" - }, - "pylint-print": { - "hashes": [ - "sha256:30aa207e9718ebf4ceb47fb87012092e6d8743aab932aa07aa14a73e750ad3d0", - "sha256:a2b2599e7887b93e551db2624c523c1e6e9e58c3be8416cd98d41e4427e2669b" - ], - "index": "pypi", - "markers": "python_version >= '3.6'", - "version": "==1.0.1" - }, - "python-dateutil": { - "hashes": [ - "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", - "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.9.0.post0" - }, - "pyyaml": { - "hashes": [ - "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", - "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", - "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", - "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", - "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", - "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", - "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595", - "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", - "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", - "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", - "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290", - "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", - "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", - "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6", - "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", - "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", - "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", - "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6", - "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", - "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", - "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", - "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", - "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", - "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", - "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", - "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", - "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", - "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", - "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", - "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef", - "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", - "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", - "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", - "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0", - "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515", - "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c", - "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c", - "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924", - "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34", - "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", - "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", - "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", - "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", - "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", - "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b", - "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", - "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", - "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", - "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585", - "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d", - "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" - ], - "markers": "python_version >= '3.6'", - "version": "==6.0.1" - }, - "requests": { - "hashes": [ - "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", - "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" - ], - "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==2.31.0" - }, - "responses": { - "hashes": [ - "sha256:01ae6a02b4f34e39bffceb0fc6786b67a25eae919c6368d05eabc8d9576c2a66", - "sha256:2f0b9c2b6437db4b528619a77e5d565e4ec2a9532162ac1a131a83529db7be1a" - ], - "markers": "python_version >= '3.8'", - "version": "==0.25.0" - }, - "rich": { - "hashes": [ - "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222", - "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432" - ], - "markers": "python_full_version >= '3.7.0'", - "version": "==13.7.1" - }, - "s3transfer": { - "hashes": [ - "sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19", - "sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d" - ], - "markers": "python_version >= '3.8'", - "version": "==0.10.1" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" - }, - "stevedore": { - "hashes": [ - "sha256:1c15d95766ca0569cad14cb6272d4d31dae66b011a929d7c18219c176ea1b5c9", - "sha256:46b93ca40e1114cea93d738a6c1e365396981bb6bb78c27045b7587c9473544d" - ], - "markers": "python_version >= '3.8'", - "version": "==5.2.0" - }, - "tomlkit": { - "hashes": [ - "sha256:5cd82d48a3dd89dee1f9d64420aa20ae65cfbd00668d6f094d7578a78efbb77b", - "sha256:7ca1cfc12232806517a8515047ba66a19369e71edf2439d0f5824f91032b6cc3" - ], - "markers": "python_version >= '3.7'", - "version": "==0.12.4" - }, - "typing-extensions": { - "hashes": [ - "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0", - "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a" - ], - "markers": "python_version >= '3.8'", - "version": "==4.11.0" - }, - "urllib3": { - "hashes": [ - "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d", - "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19" - ], - "markers": "python_version >= '3.8'", - "version": "==2.2.1" - }, - "werkzeug": { - "hashes": [ - "sha256:097e5bfda9f0aba8da6b8545146def481d06aa7d3266e7448e2cccf67dd8bd18", - "sha256:fc9645dc43e03e4d630d23143a04a7f947a9a3b5727cd535fdfe155a17cc48c8" - ], - "markers": "python_version >= '3.8'", - "version": "==3.0.3" - }, - "wrapt": { - "hashes": [ - "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc", - "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81", - "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09", - "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e", - "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca", - "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0", - "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb", - "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487", - "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40", - "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c", - "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060", - "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202", - "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41", - "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9", - "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b", - "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664", - "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d", - "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362", - "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00", - "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc", - "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1", - "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267", - "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956", - "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966", - "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1", - "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228", - "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72", - "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d", - "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292", - "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0", - "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0", - "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36", - "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c", - "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5", - "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f", - "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73", - "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b", - "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2", - "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593", - "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39", - "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389", - "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf", - "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf", - "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89", - "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c", - "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c", - "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f", - "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440", - "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465", - "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136", - "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b", - "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8", - "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3", - "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8", - "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6", - "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e", - "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f", - "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c", - "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e", - "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8", - "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2", - "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020", - "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35", - "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d", - "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3", - "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537", - "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809", - "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d", - "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a", - "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4" - ], - "index": "pypi", - "markers": "python_version >= '3.6'", - "version": "==1.16.0" - }, - "xmltodict": { - "hashes": [ - "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56", - "sha256:aa89e8fd76320154a40d19a0df04a4695fb9dc5ba977cbb68ab3e4eb225e7852" - ], - "markers": "python_version >= '3.4'", - "version": "==0.13.0" + "_meta": { + "hash": { + "sha256": "17b8e970a9987cbf1b1990b9bd6832b6012de2263f46f946b3d22bd42e42d2d8" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.11" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "aiohttp": { + "hashes": [ + "sha256:0605cc2c0088fcaae79f01c913a38611ad09ba68ff482402d3410bf59039bfb8", + "sha256:0a158704edf0abcac8ac371fbb54044f3270bdbc93e254a82b6c82be1ef08f3c", + "sha256:0cbf56238f4bbf49dab8c2dc2e6b1b68502b1e88d335bea59b3f5b9f4c001475", + "sha256:1732102949ff6087589408d76cd6dea656b93c896b011ecafff418c9661dc4ed", + "sha256:18f634d540dd099c262e9f887c8bbacc959847cfe5da7a0e2e1cf3f14dbf2daf", + "sha256:239f975589a944eeb1bad26b8b140a59a3a320067fb3cd10b75c3092405a1372", + "sha256:2faa61a904b83142747fc6a6d7ad8fccff898c849123030f8e75d5d967fd4a81", + "sha256:320e8618eda64e19d11bdb3bd04ccc0a816c17eaecb7e4945d01deee2a22f95f", + "sha256:38d80498e2e169bc61418ff36170e0aad0cd268da8b38a17c4cf29d254a8b3f1", + "sha256:3916c8692dbd9d55c523374a3b8213e628424d19116ac4308e434dbf6d95bbdd", + "sha256:393c7aba2b55559ef7ab791c94b44f7482a07bf7640d17b341b79081f5e5cd1a", + "sha256:3b7b30258348082826d274504fbc7c849959f1989d86c29bc355107accec6cfb", + "sha256:3fcb4046d2904378e3aeea1df51f697b0467f2aac55d232c87ba162709478c46", + "sha256:4109adee842b90671f1b689901b948f347325045c15f46b39797ae1bf17019de", + "sha256:4558e5012ee03d2638c681e156461d37b7a113fe13970d438d95d10173d25f78", + "sha256:45731330e754f5811c314901cebdf19dd776a44b31927fa4b4dbecab9e457b0c", + "sha256:4715a9b778f4293b9f8ae7a0a7cef9829f02ff8d6277a39d7f40565c737d3771", + "sha256:471f0ef53ccedec9995287f02caf0c068732f026455f07db3f01a46e49d76bbb", + "sha256:4d3ebb9e1316ec74277d19c5f482f98cc65a73ccd5430540d6d11682cd857430", + "sha256:4ff550491f5492ab5ed3533e76b8567f4b37bd2995e780a1f46bca2024223233", + "sha256:52c27110f3862a1afbcb2af4281fc9fdc40327fa286c4625dfee247c3ba90156", + "sha256:55b39c8684a46e56ef8c8d24faf02de4a2b2ac60d26cee93bc595651ff545de9", + "sha256:5a7ee16aab26e76add4afc45e8f8206c95d1d75540f1039b84a03c3b3800dd59", + "sha256:5ca51eadbd67045396bc92a4345d1790b7301c14d1848feaac1d6a6c9289e888", + "sha256:5d6b3f1fabe465e819aed2c421a6743d8debbde79b6a8600739300630a01bf2c", + "sha256:60cdbd56f4cad9f69c35eaac0fbbdf1f77b0ff9456cebd4902f3dd1cf096464c", + "sha256:6380c039ec52866c06d69b5c7aad5478b24ed11696f0e72f6b807cfb261453da", + "sha256:639d0042b7670222f33b0028de6b4e2fad6451462ce7df2af8aee37dcac55424", + "sha256:66331d00fb28dc90aa606d9a54304af76b335ae204d1836f65797d6fe27f1ca2", + "sha256:67c3119f5ddc7261d47163ed86d760ddf0e625cd6246b4ed852e82159617b5fb", + "sha256:694d828b5c41255e54bc2dddb51a9f5150b4eefa9886e38b52605a05d96566e8", + "sha256:6ae79c1bc12c34082d92bf9422764f799aee4746fd7a392db46b7fd357d4a17a", + "sha256:702e2c7c187c1a498a4e2b03155d52658fdd6fda882d3d7fbb891a5cf108bb10", + "sha256:714d4e5231fed4ba2762ed489b4aec07b2b9953cf4ee31e9871caac895a839c0", + "sha256:7b179eea70833c8dee51ec42f3b4097bd6370892fa93f510f76762105568cf09", + "sha256:7f64cbd44443e80094309875d4f9c71d0401e966d191c3d469cde4642bc2e031", + "sha256:82a6a97d9771cb48ae16979c3a3a9a18b600a8505b1115cfe354dfb2054468b4", + "sha256:84dabd95154f43a2ea80deffec9cb44d2e301e38a0c9d331cc4aa0166fe28ae3", + "sha256:8676e8fd73141ded15ea586de0b7cda1542960a7b9ad89b2b06428e97125d4fa", + "sha256:88e311d98cc0bf45b62fc46c66753a83445f5ab20038bcc1b8a1cc05666f428a", + "sha256:8b4f72fbb66279624bfe83fd5eb6aea0022dad8eec62b71e7bf63ee1caadeafe", + "sha256:8c64a6dc3fe5db7b1b4d2b5cb84c4f677768bdc340611eca673afb7cf416ef5a", + "sha256:8cf142aa6c1a751fcb364158fd710b8a9be874b81889c2bd13aa8893197455e2", + "sha256:8d1964eb7617907c792ca00b341b5ec3e01ae8c280825deadbbd678447b127e1", + "sha256:93e22add827447d2e26d67c9ac0161756007f152fdc5210277d00a85f6c92323", + "sha256:9c69e77370cce2d6df5d12b4e12bdcca60c47ba13d1cbbc8645dd005a20b738b", + "sha256:9dbc053ac75ccc63dc3a3cc547b98c7258ec35a215a92bd9f983e0aac95d3d5b", + "sha256:9e3a1ae66e3d0c17cf65c08968a5ee3180c5a95920ec2731f53343fac9bad106", + "sha256:a6ea1a5b409a85477fd8e5ee6ad8f0e40bf2844c270955e09360418cfd09abac", + "sha256:a81b1143d42b66ffc40a441379387076243ef7b51019204fd3ec36b9f69e77d6", + "sha256:ad7f2919d7dac062f24d6f5fe95d401597fbb015a25771f85e692d043c9d7832", + "sha256:afc52b8d969eff14e069a710057d15ab9ac17cd4b6753042c407dcea0e40bf75", + "sha256:b3df71da99c98534be076196791adca8819761f0bf6e08e07fd7da25127150d6", + "sha256:c088c4d70d21f8ca5c0b8b5403fe84a7bc8e024161febdd4ef04575ef35d474d", + "sha256:c26959ca7b75ff768e2776d8055bf9582a6267e24556bb7f7bd29e677932be72", + "sha256:c413016880e03e69d166efb5a1a95d40f83d5a3a648d16486592c49ffb76d0db", + "sha256:c6021d296318cb6f9414b48e6a439a7f5d1f665464da507e8ff640848ee2a58a", + "sha256:c671dc117c2c21a1ca10c116cfcd6e3e44da7fcde37bf83b2be485ab377b25da", + "sha256:c7a4b7a6cf5b6eb11e109a9755fd4fda7d57395f8c575e166d363b9fc3ec4678", + "sha256:c8a02fbeca6f63cb1f0475c799679057fc9268b77075ab7cf3f1c600e81dd46b", + "sha256:cd2adf5c87ff6d8b277814a28a535b59e20bfea40a101db6b3bdca7e9926bc24", + "sha256:d1469f228cd9ffddd396d9948b8c9cd8022b6d1bf1e40c6f25b0fb90b4f893ed", + "sha256:d153f652a687a8e95ad367a86a61e8d53d528b0530ef382ec5aaf533140ed00f", + "sha256:d5ab8e1f6bee051a4bf6195e38a5c13e5e161cb7bad83d8854524798bd9fcd6e", + "sha256:da00da442a0e31f1c69d26d224e1efd3a1ca5bcbf210978a2ca7426dfcae9f58", + "sha256:da22dab31d7180f8c3ac7c7635f3bcd53808f374f6aa333fe0b0b9e14b01f91a", + "sha256:e0ae53e33ee7476dd3d1132f932eeb39bf6125083820049d06edcdca4381f342", + "sha256:e7a6a8354f1b62e15d48e04350f13e726fa08b62c3d7b8401c0a1314f02e3558", + "sha256:e9a3d838441bebcf5cf442700e3963f58b5c33f015341f9ea86dcd7d503c07e2", + "sha256:edea7d15772ceeb29db4aff55e482d4bcfb6ae160ce144f2682de02f6d693551", + "sha256:f22eb3a6c1080d862befa0a89c380b4dafce29dc6cd56083f630073d102eb595", + "sha256:f26383adb94da5e7fb388d441bf09c61e5e35f455a3217bfd790c6b6bc64b2ee", + "sha256:f3c2890ca8c59ee683fd09adf32321a40fe1cf164e3387799efb2acebf090c11", + "sha256:f64fd07515dad67f24b6ea4a66ae2876c01031de91c93075b8093f07c0a2d93d", + "sha256:fcde4c397f673fdec23e6b05ebf8d4751314fa7c24f93334bf1f1364c1c69ac7", + "sha256:ff84aeb864e0fac81f676be9f4685f0527b660f1efdc40dcede3c251ef1e867f" + ], + "markers": "python_version >= '3.8'", + "version": "==3.9.5" + }, + "aiosignal": { + "hashes": [ + "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc", + "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17" + ], + "markers": "python_version >= '3.7'", + "version": "==1.3.1" + }, + "anyio": { + "hashes": [ + "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94", + "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7" + ], + "markers": "python_version >= '3.8'", + "version": "==4.4.0" + }, + "appdirs": { + "hashes": [ + "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", + "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" + ], + "version": "==1.4.4" + }, + "attrs": { + "hashes": [ + "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", + "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1" + ], + "markers": "python_version >= '3.7'", + "version": "==23.2.0" + }, + "backoff": { + "hashes": [ + "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba", + "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8" + ], + "markers": "python_version >= '3.7' and python_version < '4.0'", + "version": "==2.2.1" + }, + "boto3": { + "hashes": [ + "sha256:4eb8019421cb664a6fcbbee6152aa95a28ce8bbc1c4ee263871c09cdd58bf8ee", + "sha256:e9edaf979fbe59737e158f2f0f3f0861ff1d61233f18f6be8ebb483905f24587" + ], + "markers": "python_version >= '3.8'", + "version": "==1.34.118" + }, + "botocore": { + "hashes": [ + "sha256:0a3d1ec0186f8b516deb39474de3d226d531f77f92a0f56ad79b80219db3ae9e", + "sha256:e3f6c5636a4394768e81e33a16f5c6ae7f364f512415d423f9b9dc67fc638df4" + ], + "markers": "python_version >= '3.8'", + "version": "==1.34.118" + }, + "certifi": { + "hashes": [ + "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516", + "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56" + ], + "markers": "python_version >= '3.6'", + "version": "==2024.6.2" + }, + "chardet": { + "hashes": [ + "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7", + "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970" + ], + "markers": "python_version >= '3.7'", + "version": "==5.2.0" + }, + "charset-normalizer": { + "hashes": [ + "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", + "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", + "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", + "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", + "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", + "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", + "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", + "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", + "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", + "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", + "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", + "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", + "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", + "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", + "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", + "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", + "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", + "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", + "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", + "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", + "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", + "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", + "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", + "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", + "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", + "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", + "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", + "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", + "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", + "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", + "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", + "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", + "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", + "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", + "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", + "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", + "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", + "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", + "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", + "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", + "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", + "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", + "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", + "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", + "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", + "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", + "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", + "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", + "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", + "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", + "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", + "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", + "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", + "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", + "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", + "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", + "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", + "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", + "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", + "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", + "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", + "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", + "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", + "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", + "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", + "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", + "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", + "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", + "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", + "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", + "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", + "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", + "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", + "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", + "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", + "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", + "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", + "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", + "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", + "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", + "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", + "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", + "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", + "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", + "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", + "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", + "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", + "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", + "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", + "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.3.2" + }, + "click": { + "hashes": [ + "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" + ], + "markers": "python_version >= '3.7'", + "version": "==8.1.7" + }, + "colorama": { + "hashes": [ + "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", + "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", + "version": "==0.4.6" + }, + "datadog": { + "hashes": [ + "sha256:4a56d57490ea699a0dfd9253547485a57b4120e93489defadcf95c66272374d6", + "sha256:4cb7a7991af6cadb868fe450cd456473e65f11fc678b7d7cf61044ff1c6074d8" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", + "version": "==0.49.1" + }, + "diff-cover": { + "hashes": [ + "sha256:1dc851d3f3f320c048d03618e4c0d9861fa4a1506b425d2d09a564b20c95674a", + "sha256:31b308259b79e2cab5f30aff499a3ea3ba9475f0d495d82ba9b6caa7487bca03" + ], + "markers": "python_full_version >= '3.8.10' and python_full_version < '4.0.0'", + "version": "==9.0.0" + }, + "dynaconf": { + "hashes": [ + "sha256:12202fc26546851c05d4194c80bee00197e7c2febcb026e502b0863be9cbbdd8", + "sha256:42c8d936b32332c4b84e4d4df6dd1626b6ef59c5a94eb60c10cd3c59d6b882f2" + ], + "markers": "python_version >= '3.8'", + "version": "==3.2.5" + }, + "frozenlist": { + "hashes": [ + "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7", + "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98", + "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad", + "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5", + "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae", + "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e", + "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a", + "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701", + "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d", + "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6", + "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6", + "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106", + "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75", + "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868", + "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a", + "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0", + "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1", + "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826", + "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec", + "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6", + "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950", + "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19", + "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0", + "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8", + "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a", + "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09", + "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86", + "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c", + "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5", + "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b", + "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b", + "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d", + "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0", + "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea", + "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776", + "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a", + "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897", + "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7", + "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09", + "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9", + "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe", + "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd", + "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742", + "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09", + "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0", + "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932", + "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1", + "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a", + "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49", + "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d", + "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7", + "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480", + "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89", + "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e", + "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b", + "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82", + "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb", + "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068", + "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8", + "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b", + "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb", + "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2", + "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11", + "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b", + "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc", + "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0", + "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497", + "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17", + "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0", + "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2", + "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439", + "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5", + "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac", + "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825", + "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887", + "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced", + "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74" + ], + "markers": "python_version >= '3.8'", + "version": "==1.4.1" + }, + "gql": { + "hashes": [ + "sha256:70dda5694a5b194a8441f077aa5fb70cc94e4ec08016117523f013680901ecb7", + "sha256:ccb9c5db543682b28f577069950488218ed65d4ac70bb03b6929aaadaf636de9" + ], + "version": "==3.5.0" + }, + "graphql-core": { + "hashes": [ + "sha256:06d2aad0ac723e35b1cb47885d3e5c45e956a53bc1b209a9fc5369007fe46676", + "sha256:5766780452bd5ec8ba133f8bf287dc92713e3868ddd83aee4faab9fc3e303dc3" + ], + "markers": "python_version >= '3.6' and python_version < '4'", + "version": "==3.2.3" + }, + "idna": { + "hashes": [ + "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", + "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0" + ], + "markers": "python_version >= '3.5'", + "version": "==3.7" + }, + "iniconfig": { + "hashes": [ + "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", + "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" + ], + "markers": "python_version >= '3.7'", + "version": "==2.0.0" + }, + "jinja2": { + "hashes": [ + "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", + "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d" + ], + "markers": "python_version >= '3.7'", + "version": "==3.1.4" + }, + "jmespath": { + "hashes": [ + "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", + "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe" + ], + "markers": "python_version >= '3.7'", + "version": "==1.0.1" + }, + "jsonlines": { + "hashes": [ + "sha256:0c6d2c09117550c089995247f605ae4cf77dd1533041d366351f6f298822ea74", + "sha256:185b334ff2ca5a91362993f42e83588a360cf95ce4b71a73548502bda52a7c55" + ], + "markers": "python_version >= '3.8'", + "version": "==4.0.0" + }, + "jsonpath-ng": { + "hashes": [ + "sha256:086c37ba4917304850bd837aeab806670224d3f038fe2833ff593a672ef0a5fa", + "sha256:8f22cd8273d7772eea9aaa84d922e0841aa36fdb8a2c6b7f6c3791a16a9bc0be" + ], + "version": "==1.6.1" + }, + "jsonschema": { + "hashes": [ + "sha256:5b22d434a45935119af990552c862e5d6d564e8f6601206b305a61fdf661a2b7", + "sha256:ff4cfd6b1367a40e7bc6411caec72effadd3db0bbe5017de188f2d6108335802" + ], + "markers": "python_version >= '3.8'", + "version": "==4.22.0" + }, + "jsonschema-specifications": { + "hashes": [ + "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc", + "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c" + ], + "markers": "python_version >= '3.8'", + "version": "==2023.12.1" + }, + "markupsafe": { + "hashes": [ + "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf", + "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", + "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", + "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", + "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532", + "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", + "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", + "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df", + "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4", + "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", + "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", + "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", + "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", + "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371", + "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2", + "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", + "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52", + "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", + "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", + "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", + "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", + "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0", + "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029", + "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", + "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a", + "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", + "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", + "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", + "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", + "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9", + "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", + "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", + "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3", + "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", + "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46", + "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", + "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a", + "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", + "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", + "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", + "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", + "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", + "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", + "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", + "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", + "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f", + "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50", + "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", + "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", + "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", + "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff", + "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", + "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", + "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", + "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf", + "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", + "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5", + "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab", + "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", + "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68" + ], + "markers": "python_version >= '3.7'", + "version": "==2.1.5" + }, + "multidict": { + "hashes": [ + "sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556", + "sha256:0275e35209c27a3f7951e1ce7aaf93ce0d163b28948444bec61dd7badc6d3f8c", + "sha256:04bde7a7b3de05732a4eb39c94574db1ec99abb56162d6c520ad26f83267de29", + "sha256:04da1bb8c8dbadf2a18a452639771951c662c5ad03aefe4884775454be322c9b", + "sha256:09a892e4a9fb47331da06948690ae38eaa2426de97b4ccbfafbdcbe5c8f37ff8", + "sha256:0d63c74e3d7ab26de115c49bffc92cc77ed23395303d496eae515d4204a625e7", + "sha256:107c0cdefe028703fb5dafe640a409cb146d44a6ae201e55b35a4af8e95457dd", + "sha256:141b43360bfd3bdd75f15ed811850763555a251e38b2405967f8e25fb43f7d40", + "sha256:14c2976aa9038c2629efa2c148022ed5eb4cb939e15ec7aace7ca932f48f9ba6", + "sha256:19fe01cea168585ba0f678cad6f58133db2aa14eccaf22f88e4a6dccadfad8b3", + "sha256:1d147090048129ce3c453f0292e7697d333db95e52616b3793922945804a433c", + "sha256:1d9ea7a7e779d7a3561aade7d596649fbecfa5c08a7674b11b423783217933f9", + "sha256:215ed703caf15f578dca76ee6f6b21b7603791ae090fbf1ef9d865571039ade5", + "sha256:21fd81c4ebdb4f214161be351eb5bcf385426bf023041da2fd9e60681f3cebae", + "sha256:220dd781e3f7af2c2c1053da9fa96d9cf3072ca58f057f4c5adaaa1cab8fc442", + "sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9", + "sha256:29bfeb0dff5cb5fdab2023a7a9947b3b4af63e9c47cae2a10ad58394b517fddc", + "sha256:2f4848aa3baa109e6ab81fe2006c77ed4d3cd1e0ac2c1fbddb7b1277c168788c", + "sha256:2faa5ae9376faba05f630d7e5e6be05be22913782b927b19d12b8145968a85ea", + "sha256:2ffc42c922dbfddb4a4c3b438eb056828719f07608af27d163191cb3e3aa6cc5", + "sha256:37b15024f864916b4951adb95d3a80c9431299080341ab9544ed148091b53f50", + "sha256:3cc2ad10255f903656017363cd59436f2111443a76f996584d1077e43ee51182", + "sha256:3d25f19500588cbc47dc19081d78131c32637c25804df8414463ec908631e453", + "sha256:403c0911cd5d5791605808b942c88a8155c2592e05332d2bf78f18697a5fa15e", + "sha256:411bf8515f3be9813d06004cac41ccf7d1cd46dfe233705933dd163b60e37600", + "sha256:425bf820055005bfc8aa9a0b99ccb52cc2f4070153e34b701acc98d201693733", + "sha256:435a0984199d81ca178b9ae2c26ec3d49692d20ee29bc4c11a2a8d4514c67eda", + "sha256:4a6a4f196f08c58c59e0b8ef8ec441d12aee4125a7d4f4fef000ccb22f8d7241", + "sha256:4cc0ef8b962ac7a5e62b9e826bd0cd5040e7d401bc45a6835910ed699037a461", + "sha256:51d035609b86722963404f711db441cf7134f1889107fb171a970c9701f92e1e", + "sha256:53689bb4e102200a4fafa9de9c7c3c212ab40a7ab2c8e474491914d2305f187e", + "sha256:55205d03e8a598cfc688c71ca8ea5f66447164efff8869517f175ea632c7cb7b", + "sha256:5c0631926c4f58e9a5ccce555ad7747d9a9f8b10619621f22f9635f069f6233e", + "sha256:5cb241881eefd96b46f89b1a056187ea8e9ba14ab88ba632e68d7a2ecb7aadf7", + "sha256:60d698e8179a42ec85172d12f50b1668254628425a6bd611aba022257cac1386", + "sha256:612d1156111ae11d14afaf3a0669ebf6c170dbb735e510a7438ffe2369a847fd", + "sha256:6214c5a5571802c33f80e6c84713b2c79e024995b9c5897f794b43e714daeec9", + "sha256:6939c95381e003f54cd4c5516740faba40cf5ad3eeff460c3ad1d3e0ea2549bf", + "sha256:69db76c09796b313331bb7048229e3bee7928eb62bab5e071e9f7fcc4879caee", + "sha256:6bf7a982604375a8d49b6cc1b781c1747f243d91b81035a9b43a2126c04766f5", + "sha256:766c8f7511df26d9f11cd3a8be623e59cca73d44643abab3f8c8c07620524e4a", + "sha256:76c0de87358b192de7ea9649beb392f107dcad9ad27276324c24c91774ca5271", + "sha256:76f067f5121dcecf0d63a67f29080b26c43c71a98b10c701b0677e4a065fbd54", + "sha256:7901c05ead4b3fb75113fb1dd33eb1253c6d3ee37ce93305acd9d38e0b5f21a4", + "sha256:79660376075cfd4b2c80f295528aa6beb2058fd289f4c9252f986751a4cd0496", + "sha256:79a6d2ba910adb2cbafc95dad936f8b9386e77c84c35bc0add315b856d7c3abb", + "sha256:7afcdd1fc07befad18ec4523a782cde4e93e0a2bf71239894b8d61ee578c1319", + "sha256:7be7047bd08accdb7487737631d25735c9a04327911de89ff1b26b81745bd4e3", + "sha256:7c6390cf87ff6234643428991b7359b5f59cc15155695deb4eda5c777d2b880f", + "sha256:7df704ca8cf4a073334e0427ae2345323613e4df18cc224f647f251e5e75a527", + "sha256:85f67aed7bb647f93e7520633d8f51d3cbc6ab96957c71272b286b2f30dc70ed", + "sha256:896ebdcf62683551312c30e20614305f53125750803b614e9e6ce74a96232604", + "sha256:92d16a3e275e38293623ebf639c471d3e03bb20b8ebb845237e0d3664914caef", + "sha256:99f60d34c048c5c2fabc766108c103612344c46e35d4ed9ae0673d33c8fb26e8", + "sha256:9fe7b0653ba3d9d65cbe7698cca585bf0f8c83dbbcc710db9c90f478e175f2d5", + "sha256:a3145cb08d8625b2d3fee1b2d596a8766352979c9bffe5d7833e0503d0f0b5e5", + "sha256:aeaf541ddbad8311a87dd695ed9642401131ea39ad7bc8cf3ef3967fd093b626", + "sha256:b55358304d7a73d7bdf5de62494aaf70bd33015831ffd98bc498b433dfe5b10c", + "sha256:b82cc8ace10ab5bd93235dfaab2021c70637005e1ac787031f4d1da63d493c1d", + "sha256:c0868d64af83169e4d4152ec612637a543f7a336e4a307b119e98042e852ad9c", + "sha256:c1c1496e73051918fcd4f58ff2e0f2f3066d1c76a0c6aeffd9b45d53243702cc", + "sha256:c9bf56195c6bbd293340ea82eafd0071cb3d450c703d2c93afb89f93b8386ccc", + "sha256:cbebcd5bcaf1eaf302617c114aa67569dd3f090dd0ce8ba9e35e9985b41ac35b", + "sha256:cd6c8fca38178e12c00418de737aef1261576bd1b6e8c6134d3e729a4e858b38", + "sha256:ceb3b7e6a0135e092de86110c5a74e46bda4bd4fbfeeb3a3bcec79c0f861e450", + "sha256:cf590b134eb70629e350691ecca88eac3e3b8b3c86992042fb82e3cb1830d5e1", + "sha256:d3eb1ceec286eba8220c26f3b0096cf189aea7057b6e7b7a2e60ed36b373b77f", + "sha256:d65f25da8e248202bd47445cec78e0025c0fe7582b23ec69c3b27a640dd7a8e3", + "sha256:d6f6d4f185481c9669b9447bf9d9cf3b95a0e9df9d169bbc17e363b7d5487755", + "sha256:d84a5c3a5f7ce6db1f999fb9438f686bc2e09d38143f2d93d8406ed2dd6b9226", + "sha256:d946b0a9eb8aaa590df1fe082cee553ceab173e6cb5b03239716338629c50c7a", + "sha256:dce1c6912ab9ff5f179eaf6efe7365c1f425ed690b03341911bf4939ef2f3046", + "sha256:de170c7b4fe6859beb8926e84f7d7d6c693dfe8e27372ce3b76f01c46e489fcf", + "sha256:e02021f87a5b6932fa6ce916ca004c4d441509d33bbdbeca70d05dff5e9d2479", + "sha256:e030047e85cbcedbfc073f71836d62dd5dadfbe7531cae27789ff66bc551bd5e", + "sha256:e0e79d91e71b9867c73323a3444724d496c037e578a0e1755ae159ba14f4f3d1", + "sha256:e4428b29611e989719874670fd152b6625500ad6c686d464e99f5aaeeaca175a", + "sha256:e4972624066095e52b569e02b5ca97dbd7a7ddd4294bf4e7247d52635630dd83", + "sha256:e7be68734bd8c9a513f2b0cfd508802d6609da068f40dc57d4e3494cefc92929", + "sha256:e8e94e6912639a02ce173341ff62cc1201232ab86b8a8fcc05572741a5dc7d93", + "sha256:ea1456df2a27c73ce51120fa2f519f1bea2f4a03a917f4a43c8707cf4cbbae1a", + "sha256:ebd8d160f91a764652d3e51ce0d2956b38efe37c9231cd82cfc0bed2e40b581c", + "sha256:eca2e9d0cc5a889850e9bbd68e98314ada174ff6ccd1129500103df7a94a7a44", + "sha256:edd08e6f2f1a390bf137080507e44ccc086353c8e98c657e666c017718561b89", + "sha256:f285e862d2f153a70586579c15c44656f888806ed0e5b56b64489afe4a2dbfba", + "sha256:f2a1dee728b52b33eebff5072817176c172050d44d67befd681609b4746e1c2e", + "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da", + "sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24", + "sha256:fce28b3c8a81b6b36dfac9feb1de115bab619b3c13905b419ec71d03a3fc1423", + "sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef" + ], + "markers": "python_version >= '3.7'", + "version": "==6.0.5" + }, + "nested-lookup": { + "hashes": [ + "sha256:6fa832748c90381f2291d850809e32492519ee5f253d6a5acbc29d937eca02e8" + ], + "version": "==0.2.25" + }, + "packaging": { + "hashes": [ + "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" + ], + "markers": "python_version >= '3.7'", + "version": "==24.0" + }, + "panther-analysis-tool": { + "hashes": [ + "sha256:34d6bfc59b695475aa0c74e0dbefc1e9c64363dfc9e52779f082b17780733b27" + ], + "index": "pypi", + "version": "==0.49.2" + }, + "panther-core": { + "hashes": [ + "sha256:892891eefe731a15ab187a8fbeb2f64c77a76423b6185dffc4f268ce7a4940e6" + ], + "version": "==0.10.1" + }, + "panther-detection-helpers": { + "hashes": [ + "sha256:151d35778cb2cb1901a35b91326b5b22cca3d7593f31059dc19d13fc5598987a" + ], + "index": "pypi", + "version": "==0.4.0" + }, + "pathspec": { + "hashes": [ + "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", + "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712" + ], + "markers": "python_version >= '3.8'", + "version": "==0.12.1" + }, + "pluggy": { + "hashes": [ + "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", + "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669" + ], + "markers": "python_version >= '3.8'", + "version": "==1.5.0" + }, + "ply": { + "hashes": [ + "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3", + "sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce" + ], + "version": "==3.11" + }, + "policyuniverse": { + "hashes": [ + "sha256:6317928273b18de8ed28ddf9f06faf501e044344d86f86b7681817fb32fff67a", + "sha256:7920896195af163230635f1a5cee0958f56003ef8c421f805ec81f134f80a57c" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==1.5.1.20230817" + }, + "pygments": { + "hashes": [ + "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", + "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a" + ], + "markers": "python_version >= '3.8'", + "version": "==2.18.0" + }, + "pytest": { + "hashes": [ + "sha256:5046e5b46d8e4cac199c373041f26be56fdb81eb4e67dc11d4e10811fc3408fd", + "sha256:faccc5d332b8c3719f40283d0d44aa5cf101cec36f88cde9ed8f2bc0538612b1" + ], + "markers": "python_version >= '3.8'", + "version": "==8.2.1" + }, + "python-dateutil": { + "hashes": [ + "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", + "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.9.0.post0" + }, + "pyyaml": { + "hashes": [ + "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", + "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", + "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", + "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", + "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", + "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", + "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595", + "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", + "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", + "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", + "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290", + "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", + "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", + "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6", + "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", + "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", + "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", + "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6", + "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", + "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", + "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", + "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", + "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", + "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", + "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", + "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", + "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", + "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", + "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", + "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef", + "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", + "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", + "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", + "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0", + "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515", + "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c", + "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c", + "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924", + "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34", + "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", + "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", + "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", + "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", + "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", + "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b", + "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", + "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", + "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", + "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585", + "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d", + "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" + ], + "markers": "python_version >= '3.6'", + "version": "==6.0.1" + }, + "referencing": { + "hashes": [ + "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c", + "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de" + ], + "markers": "python_version >= '3.8'", + "version": "==0.35.1" + }, + "regex": { + "hashes": [ + "sha256:0721931ad5fe0dda45d07f9820b90b2148ccdd8e45bb9e9b42a146cb4f695649", + "sha256:10002e86e6068d9e1c91eae8295ef690f02f913c57db120b58fdd35a6bb1af35", + "sha256:10e4ce0dca9ae7a66e6089bb29355d4432caed736acae36fef0fdd7879f0b0cb", + "sha256:119af6e56dce35e8dfb5222573b50c89e5508d94d55713c75126b753f834de68", + "sha256:1337b7dbef9b2f71121cdbf1e97e40de33ff114801263b275aafd75303bd62b5", + "sha256:13cdaf31bed30a1e1c2453ef6015aa0983e1366fad2667657dbcac7b02f67133", + "sha256:1595f2d10dff3d805e054ebdc41c124753631b6a471b976963c7b28543cf13b0", + "sha256:16093f563098448ff6b1fa68170e4acbef94e6b6a4e25e10eae8598bb1694b5d", + "sha256:1878b8301ed011704aea4c806a3cadbd76f84dece1ec09cc9e4dc934cfa5d4da", + "sha256:19068a6a79cf99a19ccefa44610491e9ca02c2be3305c7760d3831d38a467a6f", + "sha256:19dfb1c504781a136a80ecd1fff9f16dddf5bb43cec6871778c8a907a085bb3d", + "sha256:1b5269484f6126eee5e687785e83c6b60aad7663dafe842b34691157e5083e53", + "sha256:1c1c174d6ec38d6c8a7504087358ce9213d4332f6293a94fbf5249992ba54efa", + "sha256:2431b9e263af1953c55abbd3e2efca67ca80a3de8a0437cb58e2421f8184717a", + "sha256:287eb7f54fc81546346207c533ad3c2c51a8d61075127d7f6d79aaf96cdee890", + "sha256:2b4c884767504c0e2401babe8b5b7aea9148680d2e157fa28f01529d1f7fcf67", + "sha256:35cb514e137cb3488bce23352af3e12fb0dbedd1ee6e60da053c69fb1b29cc6c", + "sha256:391d7f7f1e409d192dba8bcd42d3e4cf9e598f3979cdaed6ab11288da88cb9f2", + "sha256:3ad070b823ca5890cab606c940522d05d3d22395d432f4aaaf9d5b1653e47ced", + "sha256:3cd7874d57f13bf70078f1ff02b8b0aa48d5b9ed25fc48547516c6aba36f5741", + "sha256:3e507ff1e74373c4d3038195fdd2af30d297b4f0950eeda6f515ae3d84a1770f", + "sha256:455705d34b4154a80ead722f4f185b04c4237e8e8e33f265cd0798d0e44825fa", + "sha256:4a605586358893b483976cffc1723fb0f83e526e8f14c6e6614e75919d9862cf", + "sha256:4babf07ad476aaf7830d77000874d7611704a7fcf68c9c2ad151f5d94ae4bfc4", + "sha256:4eee78a04e6c67e8391edd4dad3279828dd66ac4b79570ec998e2155d2e59fd5", + "sha256:5397de3219a8b08ae9540c48f602996aa6b0b65d5a61683e233af8605c42b0f2", + "sha256:5b5467acbfc153847d5adb21e21e29847bcb5870e65c94c9206d20eb4e99a384", + "sha256:5eaa7ddaf517aa095fa8da0b5015c44d03da83f5bd49c87961e3c997daed0de7", + "sha256:632b01153e5248c134007209b5c6348a544ce96c46005d8456de1d552455b014", + "sha256:64c65783e96e563103d641760664125e91bd85d8e49566ee560ded4da0d3e704", + "sha256:64f18a9a3513a99c4bef0e3efd4c4a5b11228b48aa80743be822b71e132ae4f5", + "sha256:673b5a6da4557b975c6c90198588181029c60793835ce02f497ea817ff647cb2", + "sha256:68811ab14087b2f6e0fc0c2bae9ad689ea3584cad6917fc57be6a48bbd012c49", + "sha256:6e8d717bca3a6e2064fc3a08df5cbe366369f4b052dcd21b7416e6d71620dca1", + "sha256:71a455a3c584a88f654b64feccc1e25876066c4f5ef26cd6dd711308aa538694", + "sha256:72d7a99cd6b8f958e85fc6ca5b37c4303294954eac1376535b03c2a43eb72629", + "sha256:7b59138b219ffa8979013be7bc85bb60c6f7b7575df3d56dc1e403a438c7a3f6", + "sha256:7dbe2467273b875ea2de38ded4eba86cbcbc9a1a6d0aa11dcf7bd2e67859c435", + "sha256:833616ddc75ad595dee848ad984d067f2f31be645d603e4d158bba656bbf516c", + "sha256:87e2a9c29e672fc65523fb47a90d429b70ef72b901b4e4b1bd42387caf0d6835", + "sha256:8fe45aa3f4aa57faabbc9cb46a93363edd6197cbc43523daea044e9ff2fea83e", + "sha256:9e717956dcfd656f5055cc70996ee2cc82ac5149517fc8e1b60261b907740201", + "sha256:9efa1a32ad3a3ea112224897cdaeb6aa00381627f567179c0314f7b65d354c62", + "sha256:9ff11639a8d98969c863d4617595eb5425fd12f7c5ef6621a4b74b71ed8726d5", + "sha256:a094801d379ab20c2135529948cb84d417a2169b9bdceda2a36f5f10977ebc16", + "sha256:a0981022dccabca811e8171f913de05720590c915b033b7e601f35ce4ea7019f", + "sha256:a0bd000c6e266927cb7a1bc39d55be95c4b4f65c5be53e659537537e019232b1", + "sha256:a32b96f15c8ab2e7d27655969a23895eb799de3665fa94349f3b2fbfd547236f", + "sha256:a81e3cfbae20378d75185171587cbf756015ccb14840702944f014e0d93ea09f", + "sha256:ac394ff680fc46b97487941f5e6ae49a9f30ea41c6c6804832063f14b2a5a145", + "sha256:ada150c5adfa8fbcbf321c30c751dc67d2f12f15bd183ffe4ec7cde351d945b3", + "sha256:b2b6f1b3bb6f640c1a92be3bbfbcb18657b125b99ecf141fb3310b5282c7d4ed", + "sha256:b802512f3e1f480f41ab5f2cfc0e2f761f08a1f41092d6718868082fc0d27143", + "sha256:ba68168daedb2c0bab7fd7e00ced5ba90aebf91024dea3c88ad5063c2a562cca", + "sha256:bfc4f82cabe54f1e7f206fd3d30fda143f84a63fe7d64a81558d6e5f2e5aaba9", + "sha256:c0c18345010870e58238790a6779a1219b4d97bd2e77e1140e8ee5d14df071aa", + "sha256:c3bea0ba8b73b71b37ac833a7f3fd53825924165da6a924aec78c13032f20850", + "sha256:c486b4106066d502495b3025a0a7251bf37ea9540433940a23419461ab9f2a80", + "sha256:c49e15eac7c149f3670b3e27f1f28a2c1ddeccd3a2812cba953e01be2ab9b5fe", + "sha256:c6a2b494a76983df8e3d3feea9b9ffdd558b247e60b92f877f93a1ff43d26656", + "sha256:cab12877a9bdafde5500206d1020a584355a97884dfd388af3699e9137bf7388", + "sha256:cac27dcaa821ca271855a32188aa61d12decb6fe45ffe3e722401fe61e323cd1", + "sha256:cdd09d47c0b2efee9378679f8510ee6955d329424c659ab3c5e3a6edea696294", + "sha256:cf2430df4148b08fb4324b848672514b1385ae3807651f3567871f130a728cc3", + "sha256:d0a3d8d6acf0c78a1fff0e210d224b821081330b8524e3e2bc5a68ef6ab5803d", + "sha256:d0c0c0003c10f54a591d220997dd27d953cd9ccc1a7294b40a4be5312be8797b", + "sha256:d1f059a4d795e646e1c37665b9d06062c62d0e8cc3c511fe01315973a6542e40", + "sha256:d347a741ea871c2e278fde6c48f85136c96b8659b632fb57a7d1ce1872547600", + "sha256:d3ee02d9e5f482cc8309134a91eeaacbdd2261ba111b0fef3748eeb4913e6a2c", + "sha256:d99ceffa25ac45d150e30bd9ed14ec6039f2aad0ffa6bb87a5936f5782fc1569", + "sha256:e38a7d4e8f633a33b4c7350fbd8bad3b70bf81439ac67ac38916c4a86b465456", + "sha256:e4682f5ba31f475d58884045c1a97a860a007d44938c4c0895f41d64481edbc9", + "sha256:e5bb9425fe881d578aeca0b2b4b3d314ec88738706f66f219c194d67179337cb", + "sha256:e64198f6b856d48192bf921421fdd8ad8eb35e179086e99e99f711957ffedd6e", + "sha256:e6662686aeb633ad65be2a42b4cb00178b3fbf7b91878f9446075c404ada552f", + "sha256:ec54d5afa89c19c6dd8541a133be51ee1017a38b412b1321ccb8d6ddbeb4cf7d", + "sha256:f5b1dff3ad008dccf18e652283f5e5339d70bf8ba7c98bf848ac33db10f7bc7a", + "sha256:f8ec0c2fea1e886a19c3bee0cd19d862b3aa75dcdfb42ebe8ed30708df64687a", + "sha256:f9ebd0a36102fcad2f03696e8af4ae682793a5d30b46c647eaf280d6cfb32796" + ], + "markers": "python_version >= '3.8'", + "version": "==2024.5.15" + }, + "requests": { + "hashes": [ + "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", + "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==2.31.0" + }, + "rpds-py": { + "hashes": [ + "sha256:05f3d615099bd9b13ecf2fc9cf2d839ad3f20239c678f461c753e93755d629ee", + "sha256:06d218939e1bf2ca50e6b0ec700ffe755e5216a8230ab3e87c059ebb4ea06afc", + "sha256:07f2139741e5deb2c5154a7b9629bc5aa48c766b643c1a6750d16f865a82c5fc", + "sha256:08d74b184f9ab6289b87b19fe6a6d1a97fbfea84b8a3e745e87a5de3029bf944", + "sha256:0abeee75434e2ee2d142d650d1e54ac1f8b01e6e6abdde8ffd6eeac6e9c38e20", + "sha256:154bf5c93d79558b44e5b50cc354aa0459e518e83677791e6adb0b039b7aa6a7", + "sha256:17c6d2155e2423f7e79e3bb18151c686d40db42d8645e7977442170c360194d4", + "sha256:1805d5901779662d599d0e2e4159d8a82c0b05faa86ef9222bf974572286b2b6", + "sha256:19ba472b9606c36716062c023afa2484d1e4220548751bda14f725a7de17b4f6", + "sha256:19e515b78c3fc1039dd7da0a33c28c3154458f947f4dc198d3c72db2b6b5dc93", + "sha256:1d54f74f40b1f7aaa595a02ff42ef38ca654b1469bef7d52867da474243cc633", + "sha256:207c82978115baa1fd8d706d720b4a4d2b0913df1c78c85ba73fe6c5804505f0", + "sha256:2625f03b105328729f9450c8badda34d5243231eef6535f80064d57035738360", + "sha256:27bba383e8c5231cd559affe169ca0b96ec78d39909ffd817f28b166d7ddd4d8", + "sha256:2c3caec4ec5cd1d18e5dd6ae5194d24ed12785212a90b37f5f7f06b8bedd7139", + "sha256:2cc7c1a47f3a63282ab0f422d90ddac4aa3034e39fc66a559ab93041e6505da7", + "sha256:2fc24a329a717f9e2448f8cd1f960f9dac4e45b6224d60734edeb67499bab03a", + "sha256:312fe69b4fe1ffbe76520a7676b1e5ac06ddf7826d764cc10265c3b53f96dbe9", + "sha256:32b7daaa3e9389db3695964ce8e566e3413b0c43e3394c05e4b243a4cd7bef26", + "sha256:338dee44b0cef8b70fd2ef54b4e09bb1b97fc6c3a58fea5db6cc083fd9fc2724", + "sha256:352a88dc7892f1da66b6027af06a2e7e5d53fe05924cc2cfc56495b586a10b72", + "sha256:35b2b771b13eee8729a5049c976197ff58a27a3829c018a04341bcf1ae409b2b", + "sha256:38e14fb4e370885c4ecd734f093a2225ee52dc384b86fa55fe3f74638b2cfb09", + "sha256:3c20f05e8e3d4fc76875fc9cb8cf24b90a63f5a1b4c5b9273f0e8225e169b100", + "sha256:3dd3cd86e1db5aadd334e011eba4e29d37a104b403e8ca24dcd6703c68ca55b3", + "sha256:489bdfe1abd0406eba6b3bb4fdc87c7fa40f1031de073d0cfb744634cc8fa261", + "sha256:48c2faaa8adfacefcbfdb5f2e2e7bdad081e5ace8d182e5f4ade971f128e6bb3", + "sha256:4a98a1f0552b5f227a3d6422dbd61bc6f30db170939bd87ed14f3c339aa6c7c9", + "sha256:4adec039b8e2928983f885c53b7cc4cda8965b62b6596501a0308d2703f8af1b", + "sha256:4e0ee01ad8260184db21468a6e1c37afa0529acc12c3a697ee498d3c2c4dcaf3", + "sha256:51584acc5916212e1bf45edd17f3a6b05fe0cbb40482d25e619f824dccb679de", + "sha256:531796fb842b53f2695e94dc338929e9f9dbf473b64710c28af5a160b2a8927d", + "sha256:5463c47c08630007dc0fe99fb480ea4f34a89712410592380425a9b4e1611d8e", + "sha256:5c45a639e93a0c5d4b788b2613bd637468edd62f8f95ebc6fcc303d58ab3f0a8", + "sha256:6031b25fb1b06327b43d841f33842b383beba399884f8228a6bb3df3088485ff", + "sha256:607345bd5912aacc0c5a63d45a1f73fef29e697884f7e861094e443187c02be5", + "sha256:618916f5535784960f3ecf8111581f4ad31d347c3de66d02e728de460a46303c", + "sha256:636a15acc588f70fda1661234761f9ed9ad79ebed3f2125d44be0862708b666e", + "sha256:673fdbbf668dd958eff750e500495ef3f611e2ecc209464f661bc82e9838991e", + "sha256:6afd80f6c79893cfc0574956f78a0add8c76e3696f2d6a15bca2c66c415cf2d4", + "sha256:6b5ff7e1d63a8281654b5e2896d7f08799378e594f09cf3674e832ecaf396ce8", + "sha256:6c4c4c3f878df21faf5fac86eda32671c27889e13570645a9eea0a1abdd50922", + "sha256:6cd8098517c64a85e790657e7b1e509b9fe07487fd358e19431cb120f7d96338", + "sha256:6d1e42d2735d437e7e80bab4d78eb2e459af48c0a46e686ea35f690b93db792d", + "sha256:6e30ac5e329098903262dc5bdd7e2086e0256aa762cc8b744f9e7bf2a427d3f8", + "sha256:70a838f7754483bcdc830444952fd89645569e7452e3226de4a613a4c1793fb2", + "sha256:720edcb916df872d80f80a1cc5ea9058300b97721efda8651efcd938a9c70a72", + "sha256:732672fbc449bab754e0b15356c077cc31566df874964d4801ab14f71951ea80", + "sha256:740884bc62a5e2bbb31e584f5d23b32320fd75d79f916f15a788d527a5e83644", + "sha256:7700936ef9d006b7ef605dc53aa364da2de5a3aa65516a1f3ce73bf82ecfc7ae", + "sha256:7732770412bab81c5a9f6d20aeb60ae943a9b36dcd990d876a773526468e7163", + "sha256:7750569d9526199c5b97e5a9f8d96a13300950d910cf04a861d96f4273d5b104", + "sha256:7f1944ce16401aad1e3f7d312247b3d5de7981f634dc9dfe90da72b87d37887d", + "sha256:81c5196a790032e0fc2464c0b4ab95f8610f96f1f2fa3d4deacce6a79852da60", + "sha256:8352f48d511de5f973e4f2f9412736d7dea76c69faa6d36bcf885b50c758ab9a", + "sha256:8927638a4d4137a289e41d0fd631551e89fa346d6dbcfc31ad627557d03ceb6d", + "sha256:8c7672e9fba7425f79019db9945b16e308ed8bc89348c23d955c8c0540da0a07", + "sha256:8d2e182c9ee01135e11e9676e9a62dfad791a7a467738f06726872374a83db49", + "sha256:910e71711d1055b2768181efa0a17537b2622afeb0424116619817007f8a2b10", + "sha256:942695a206a58d2575033ff1e42b12b2aece98d6003c6bc739fbf33d1773b12f", + "sha256:9437ca26784120a279f3137ee080b0e717012c42921eb07861b412340f85bae2", + "sha256:967342e045564cef76dfcf1edb700b1e20838d83b1aa02ab313e6a497cf923b8", + "sha256:998125738de0158f088aef3cb264a34251908dd2e5d9966774fdab7402edfab7", + "sha256:9e6934d70dc50f9f8ea47081ceafdec09245fd9f6032669c3b45705dea096b88", + "sha256:a3d456ff2a6a4d2adcdf3c1c960a36f4fd2fec6e3b4902a42a384d17cf4e7a65", + "sha256:a7b28c5b066bca9a4eb4e2f2663012debe680f097979d880657f00e1c30875a0", + "sha256:a888e8bdb45916234b99da2d859566f1e8a1d2275a801bb8e4a9644e3c7e7909", + "sha256:aa3679e751408d75a0b4d8d26d6647b6d9326f5e35c00a7ccd82b78ef64f65f8", + "sha256:aaa71ee43a703c321906813bb252f69524f02aa05bf4eec85f0c41d5d62d0f4c", + "sha256:b646bf655b135ccf4522ed43d6902af37d3f5dbcf0da66c769a2b3938b9d8184", + "sha256:b906b5f58892813e5ba5c6056d6a5ad08f358ba49f046d910ad992196ea61397", + "sha256:b9bb1f182a97880f6078283b3505a707057c42bf55d8fca604f70dedfdc0772a", + "sha256:bd1105b50ede37461c1d51b9698c4f4be6e13e69a908ab7751e3807985fc0346", + "sha256:bf18932d0003c8c4d51a39f244231986ab23ee057d235a12b2684ea26a353590", + "sha256:c273e795e7a0f1fddd46e1e3cb8be15634c29ae8ff31c196debb620e1edb9333", + "sha256:c69882964516dc143083d3795cb508e806b09fc3800fd0d4cddc1df6c36e76bb", + "sha256:c827576e2fa017a081346dce87d532a5310241648eb3700af9a571a6e9fc7e74", + "sha256:cbfbea39ba64f5e53ae2915de36f130588bba71245b418060ec3330ebf85678e", + "sha256:ce0bb20e3a11bd04461324a6a798af34d503f8d6f1aa3d2aa8901ceaf039176d", + "sha256:d0cee71bc618cd93716f3c1bf56653740d2d13ddbd47673efa8bf41435a60daa", + "sha256:d21be4770ff4e08698e1e8e0bce06edb6ea0626e7c8f560bc08222880aca6a6f", + "sha256:d31dea506d718693b6b2cffc0648a8929bdc51c70a311b2770f09611caa10d53", + "sha256:d44607f98caa2961bab4fa3c4309724b185b464cdc3ba6f3d7340bac3ec97cc1", + "sha256:d58ad6317d188c43750cb76e9deacf6051d0f884d87dc6518e0280438648a9ac", + "sha256:d70129cef4a8d979caa37e7fe957202e7eee8ea02c5e16455bc9808a59c6b2f0", + "sha256:d85164315bd68c0806768dc6bb0429c6f95c354f87485ee3593c4f6b14def2bd", + "sha256:d960de62227635d2e61068f42a6cb6aae91a7fe00fca0e3aeed17667c8a34611", + "sha256:dc48b479d540770c811fbd1eb9ba2bb66951863e448efec2e2c102625328e92f", + "sha256:e1735502458621921cee039c47318cb90b51d532c2766593be6207eec53e5c4c", + "sha256:e2be6e9dd4111d5b31ba3b74d17da54a8319d8168890fbaea4b9e5c3de630ae5", + "sha256:e4c39ad2f512b4041343ea3c7894339e4ca7839ac38ca83d68a832fc8b3748ab", + "sha256:ed402d6153c5d519a0faf1bb69898e97fb31613b49da27a84a13935ea9164dfc", + "sha256:ee17cd26b97d537af8f33635ef38be873073d516fd425e80559f4585a7b90c43", + "sha256:f3027be483868c99b4985fda802a57a67fdf30c5d9a50338d9db646d590198da", + "sha256:f5bab211605d91db0e2995a17b5c6ee5edec1270e46223e513eaa20da20076ac", + "sha256:f6f8e3fecca256fefc91bb6765a693d96692459d7d4c644660a9fff32e517843", + "sha256:f7afbfee1157e0f9376c00bb232e80a60e59ed716e3211a80cb8506550671e6e", + "sha256:fa242ac1ff583e4ec7771141606aafc92b361cd90a05c30d93e343a0c2d82a89", + "sha256:fab6ce90574645a0d6c58890e9bcaac8d94dff54fb51c69e5522a7358b80ab64" + ], + "markers": "python_version >= '3.8'", + "version": "==0.18.1" + }, + "ruamel.yaml": { + "hashes": [ + "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636", + "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b" + ], + "markers": "python_version >= '3.7'", + "version": "==0.18.6" + }, + "ruamel.yaml.clib": { + "hashes": [ + "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d", + "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001", + "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462", + "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9", + "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe", + "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b", + "sha256:184565012b60405d93838167f425713180b949e9d8dd0bbc7b49f074407c5a8b", + "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615", + "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62", + "sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15", + "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b", + "sha256:305889baa4043a09e5b76f8e2a51d4ffba44259f6b4c72dec8ca56207d9c6fe1", + "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9", + "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675", + "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899", + "sha256:4ecbf9c3e19f9562c7fdd462e8d18dd902a47ca046a2e64dba80699f0b6c09b7", + "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7", + "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312", + "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa", + "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91", + "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b", + "sha256:77159f5d5b5c14f7c34073862a6b7d34944075d9f93e681638f6d753606c6ce6", + "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3", + "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334", + "sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5", + "sha256:87ea5ff66d8064301a154b3933ae406b0863402a799b16e4a1d24d9fbbcbe0d3", + "sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe", + "sha256:a1a45e0bb052edf6a1d3a93baef85319733a888363938e1fc9924cb00c8df24c", + "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed", + "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337", + "sha256:a75879bacf2c987c003368cf14bed0ffe99e8e85acfa6c0bfffc21a090f16880", + "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f", + "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d", + "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248", + "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d", + "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf", + "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512", + "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069", + "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb", + "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942", + "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d", + "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31", + "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92", + "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5", + "sha256:e2b4c44b60eadec492926a7270abb100ef9f72798e18743939bdbf037aab8c28", + "sha256:e79e5db08739731b0ce4850bed599235d601701d5694c36570a99a0c5ca41a9d", + "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1", + "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2", + "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875", + "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412" + ], + "markers": "python_version < '3.13' and platform_python_implementation == 'CPython'", + "version": "==0.2.8" + }, + "s3transfer": { + "hashes": [ + "sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19", + "sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d" + ], + "markers": "python_version >= '3.8'", + "version": "==0.10.1" + }, + "schema": { + "hashes": [ + "sha256:5d976a5b50f36e74e2157b47097b60002bd4d42e65425fcc9c9befadb4255dde", + "sha256:7da553abd2958a19dc2547c388cde53398b39196175a9be59ea1caf5ab0a1807" + ], + "version": "==0.7.7" + }, + "semver": { + "hashes": [ + "sha256:6253adb39c70f6e51afed2fa7152bcd414c411286088fb4b9effb133885ab4cc", + "sha256:b1ea4686fe70b981f85359eda33199d60c53964284e0cfb4977d243e37cf4bf4" + ], + "markers": "python_version >= '3.7'", + "version": "==3.0.2" + }, + "six": { + "hashes": [ + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.16.0" + }, + "sniffio": { + "hashes": [ + "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", + "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" + ], + "markers": "python_version >= '3.7'", + "version": "==1.3.1" + }, + "sqlfluff": { + "hashes": [ + "sha256:82c9cb9ea4a67ac0d69540af214e39d7e4dc63d92922bc164d526dae1e08ee02", + "sha256:d49b52c4577ce113ef6318a933c7a7fedd25852dea5e9fe0981cf301c6b73927" + ], + "markers": "python_version >= '3.8'", + "version": "==3.0.7" + }, + "tblib": { + "hashes": [ + "sha256:80a6c77e59b55e83911e1e607c649836a69c103963c5f28a46cbeef44acf8129", + "sha256:93622790a0a29e04f0346458face1e144dc4d32f493714c6c3dff82a4adb77e6" + ], + "markers": "python_version >= '3.8'", + "version": "==3.0.0" + }, + "tqdm": { + "hashes": [ + "sha256:b75ca56b413b030bc3f00af51fd2c1a1a5eac6a0c1cca83cbb37a5c52abce644", + "sha256:e4d936c9de8727928f3be6079590e97d9abfe8d39a590be678eb5919ffc186bb" + ], + "markers": "python_version >= '3.7'", + "version": "==4.66.4" + }, + "typing-extensions": { + "hashes": [ + "sha256:6024b58b69089e5a89c347397254e35f1bf02a907728ec7fee9bf0fe837d203a", + "sha256:915f5e35ff76f56588223f15fdd5938f9a1cf9195c0de25130c627e4d597f6d1" + ], + "markers": "python_version >= '3.8'", + "version": "==4.12.1" + }, + "urllib3": { + "hashes": [ + "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d", + "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19" + ], + "markers": "python_version >= '3.8'", + "version": "==2.2.1" + }, + "yarl": { + "hashes": [ + "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51", + "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce", + "sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559", + "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0", + "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81", + "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc", + "sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4", + "sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c", + "sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130", + "sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136", + "sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e", + "sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec", + "sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7", + "sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1", + "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455", + "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099", + "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129", + "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10", + "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142", + "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98", + "sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa", + "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7", + "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525", + "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c", + "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9", + "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c", + "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8", + "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b", + "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf", + "sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23", + "sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd", + "sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27", + "sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f", + "sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece", + "sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434", + "sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec", + "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff", + "sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78", + "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d", + "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863", + "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53", + "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31", + "sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15", + "sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5", + "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b", + "sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57", + "sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3", + "sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1", + "sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f", + "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad", + "sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c", + "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7", + "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2", + "sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b", + "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2", + "sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b", + "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9", + "sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be", + "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e", + "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984", + "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4", + "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074", + "sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2", + "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392", + "sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91", + "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541", + "sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf", + "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572", + "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66", + "sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575", + "sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14", + "sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5", + "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1", + "sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e", + "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551", + "sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17", + "sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead", + "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0", + "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe", + "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234", + "sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0", + "sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7", + "sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34", + "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42", + "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385", + "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78", + "sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be", + "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958", + "sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749", + "sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec" + ], + "markers": "python_version >= '3.7'", + "version": "==1.9.4" + } + }, + "develop": { + "astroid": { + "hashes": [ + "sha256:1aa149fc5c6589e3d0ece885b4491acd80af4f087baafa3fb5203b113e68cd3c", + "sha256:6c107453dffee9055899705de3c9ead36e74119cee151e5a9aaf7f0b0e020a6a" + ], + "markers": "python_full_version >= '3.7.2'", + "version": "==2.15.8" + }, + "bandit": { + "hashes": [ + "sha256:36de50f720856ab24a24dbaa5fee2c66050ed97c1477e0a1159deab1775eab6b", + "sha256:509f7af645bc0cd8fd4587abc1a038fc795636671ee8204d502b933aee44f381" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==1.7.8" + }, + "black": { + "hashes": [ + "sha256:2818cf72dfd5d289e48f37ccfa08b460bf469e67fb7c4abb07edc2e9f16fb63f", + "sha256:41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93", + "sha256:4acf672def7eb1725f41f38bf6bf425c8237248bb0804faa3965c036f7672d11", + "sha256:4be5bb28e090456adfc1255e03967fb67ca846a03be7aadf6249096100ee32d0", + "sha256:4f1373a7808a8f135b774039f61d59e4be7eb56b2513d3d2f02a8b9365b8a8a9", + "sha256:56f52cfbd3dabe2798d76dbdd299faa046a901041faf2cf33288bc4e6dae57b5", + "sha256:65b76c275e4c1c5ce6e9870911384bff5ca31ab63d19c76811cb1fb162678213", + "sha256:65c02e4ea2ae09d16314d30912a58ada9a5c4fdfedf9512d23326128ac08ac3d", + "sha256:6905238a754ceb7788a73f02b45637d820b2f5478b20fec82ea865e4f5d4d9f7", + "sha256:79dcf34b33e38ed1b17434693763301d7ccbd1c5860674a8f871bd15139e7837", + "sha256:7bb041dca0d784697af4646d3b62ba4a6b028276ae878e53f6b4f74ddd6db99f", + "sha256:7d5e026f8da0322b5662fa7a8e752b3fa2dac1c1cbc213c3d7ff9bdd0ab12395", + "sha256:9f50ea1132e2189d8dff0115ab75b65590a3e97de1e143795adb4ce317934995", + "sha256:a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f", + "sha256:aadf7a02d947936ee418777e0247ea114f78aff0d0959461057cae8a04f20597", + "sha256:b5991d523eee14756f3c8d5df5231550ae8993e2286b8014e2fdea7156ed0959", + "sha256:bf21b7b230718a5f08bd32d5e4f1db7fc8788345c8aea1d155fc17852b3410f5", + "sha256:c45f8dff244b3c431b36e3224b6be4a127c6aca780853574c00faf99258041eb", + "sha256:c7ed6668cbbfcd231fa0dc1b137d3e40c04c7f786e626b405c62bcd5db5857e4", + "sha256:d7de8d330763c66663661a1ffd432274a2f92f07feeddd89ffd085b5744f85e7", + "sha256:e19cb1c6365fd6dc38a6eae2dcb691d7d83935c10215aef8e6c38edee3f77abd", + "sha256:e2af80566f43c85f5797365077fb64a393861a3730bd110971ab7a0c94e873e7" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==24.3.0" + }, + "boto3": { + "hashes": [ + "sha256:4eb8019421cb664a6fcbbee6152aa95a28ce8bbc1c4ee263871c09cdd58bf8ee", + "sha256:e9edaf979fbe59737e158f2f0f3f0861ff1d61233f18f6be8ebb483905f24587" + ], + "markers": "python_version >= '3.8'", + "version": "==1.34.118" + }, + "botocore": { + "hashes": [ + "sha256:0a3d1ec0186f8b516deb39474de3d226d531f77f92a0f56ad79b80219db3ae9e", + "sha256:e3f6c5636a4394768e81e33a16f5c6ae7f364f512415d423f9b9dc67fc638df4" + ], + "markers": "python_version >= '3.8'", + "version": "==1.34.118" + }, + "certifi": { + "hashes": [ + "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516", + "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56" + ], + "markers": "python_version >= '3.6'", + "version": "==2024.6.2" + }, + "cffi": { + "hashes": [ + "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc", + "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a", + "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417", + "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab", + "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520", + "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36", + "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743", + "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8", + "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed", + "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684", + "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56", + "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324", + "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d", + "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235", + "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e", + "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088", + "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000", + "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7", + "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e", + "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673", + "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c", + "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe", + "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2", + "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098", + "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8", + "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a", + "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0", + "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b", + "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896", + "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e", + "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9", + "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2", + "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b", + "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6", + "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404", + "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f", + "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0", + "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4", + "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc", + "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936", + "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba", + "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872", + "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb", + "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614", + "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1", + "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d", + "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969", + "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b", + "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4", + "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627", + "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956", + "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357" + ], + "markers": "platform_python_implementation != 'PyPy'", + "version": "==1.16.0" + }, + "charset-normalizer": { + "hashes": [ + "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", + "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", + "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", + "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", + "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", + "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", + "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", + "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", + "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", + "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", + "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", + "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", + "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", + "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", + "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", + "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", + "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", + "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", + "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", + "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", + "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", + "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", + "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", + "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", + "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", + "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", + "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", + "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", + "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", + "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", + "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", + "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", + "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", + "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", + "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", + "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", + "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", + "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", + "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", + "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", + "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", + "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", + "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", + "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", + "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", + "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", + "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", + "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", + "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", + "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", + "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", + "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", + "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", + "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", + "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", + "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", + "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", + "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", + "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", + "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", + "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", + "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", + "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", + "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", + "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", + "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", + "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", + "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", + "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", + "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", + "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", + "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", + "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", + "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", + "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", + "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", + "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", + "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", + "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", + "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", + "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", + "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", + "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", + "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", + "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", + "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", + "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", + "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", + "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", + "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.3.2" + }, + "click": { + "hashes": [ + "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" + ], + "markers": "python_version >= '3.7'", + "version": "==8.1.7" + }, + "cryptography": { + "hashes": [ + "sha256:02c0eee2d7133bdbbc5e24441258d5d2244beb31da5ed19fbb80315f4bbbff55", + "sha256:0d563795db98b4cd57742a78a288cdbdc9daedac29f2239793071fe114f13785", + "sha256:16268d46086bb8ad5bf0a2b5544d8a9ed87a0e33f5e77dd3c3301e63d941a83b", + "sha256:1a58839984d9cb34c855197043eaae2c187d930ca6d644612843b4fe8513c886", + "sha256:2954fccea107026512b15afb4aa664a5640cd0af630e2ee3962f2602693f0c82", + "sha256:2e47577f9b18723fa294b0ea9a17d5e53a227867a0a4904a1a076d1646d45ca1", + "sha256:31adb7d06fe4383226c3e963471f6837742889b3c4caa55aac20ad951bc8ffda", + "sha256:3577d029bc3f4827dd5bf8bf7710cac13527b470bbf1820a3f394adb38ed7d5f", + "sha256:36017400817987670037fbb0324d71489b6ead6231c9604f8fc1f7d008087c68", + "sha256:362e7197754c231797ec45ee081f3088a27a47c6c01eff2ac83f60f85a50fe60", + "sha256:3de9a45d3b2b7d8088c3fbf1ed4395dfeff79d07842217b38df14ef09ce1d8d7", + "sha256:4f698edacf9c9e0371112792558d2f705b5645076cc0aaae02f816a0171770fd", + "sha256:5482e789294854c28237bba77c4c83be698be740e31a3ae5e879ee5444166582", + "sha256:5e44507bf8d14b36b8389b226665d597bc0f18ea035d75b4e53c7b1ea84583cc", + "sha256:779245e13b9a6638df14641d029add5dc17edbef6ec915688f3acb9e720a5858", + "sha256:789caea816c6704f63f6241a519bfa347f72fbd67ba28d04636b7c6b7da94b0b", + "sha256:7f8b25fa616d8b846aef64b15c606bb0828dbc35faf90566eb139aa9cff67af2", + "sha256:8cb8ce7c3347fcf9446f201dc30e2d5a3c898d009126010cbd1f443f28b52678", + "sha256:93a3209f6bb2b33e725ed08ee0991b92976dfdcf4e8b38646540674fc7508e13", + "sha256:a3a5ac8b56fe37f3125e5b72b61dcde43283e5370827f5233893d461b7360cd4", + "sha256:a47787a5e3649008a1102d3df55424e86606c9bae6fb77ac59afe06d234605f8", + "sha256:a79165431551042cc9d1d90e6145d5d0d3ab0f2d66326c201d9b0e7f5bf43604", + "sha256:a987f840718078212fdf4504d0fd4c6effe34a7e4740378e59d47696e8dfb477", + "sha256:a9bc127cdc4ecf87a5ea22a2556cab6c7eda2923f84e4f3cc588e8470ce4e42e", + "sha256:bd13b5e9b543532453de08bcdc3cc7cebec6f9883e886fd20a92f26940fd3e7a", + "sha256:c65f96dad14f8528a447414125e1fc8feb2ad5a272b8f68477abbcc1ea7d94b9", + "sha256:d8e3098721b84392ee45af2dd554c947c32cc52f862b6a3ae982dbb90f577f14", + "sha256:e6b79d0adb01aae87e8a44c2b64bc3f3fe59515280e00fb6d57a7267a2583cda", + "sha256:e6b8f1881dac458c34778d0a424ae5769de30544fc678eac51c1c8bb2183e9da", + "sha256:e9b2a6309f14c0497f348d08a065d52f3020656f675819fc405fb63bbcd26562", + "sha256:ecbfbc00bf55888edda9868a4cf927205de8499e7fabe6c050322298382953f2", + "sha256:efd0bf5205240182e0f13bcaea41be4fdf5c22c5129fc7ced4a0282ac86998c9" + ], + "markers": "python_version >= '3.7'", + "version": "==42.0.7" + }, + "decorator": { + "hashes": [ + "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330", + "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186" + ], + "index": "pypi", + "markers": "python_version >= '3.5'", + "version": "==5.1.1" + }, + "dill": { + "hashes": [ + "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca", + "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==0.3.8" + }, + "idna": { + "hashes": [ + "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", + "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0" + ], + "markers": "python_version >= '3.5'", + "version": "==3.7" + }, + "isort": { + "hashes": [ + "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109", + "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6" + ], + "index": "pypi", + "markers": "python_full_version >= '3.8.0'", + "version": "==5.13.2" + }, + "jinja2": { + "hashes": [ + "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", + "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d" + ], + "markers": "python_version >= '3.7'", + "version": "==3.1.4" + }, + "jmespath": { + "hashes": [ + "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", + "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe" + ], + "markers": "python_version >= '3.7'", + "version": "==1.0.1" + }, + "lazy-object-proxy": { + "hashes": [ + "sha256:009e6bb1f1935a62889ddc8541514b6a9e1fcf302667dcb049a0be5c8f613e56", + "sha256:02c83f957782cbbe8136bee26416686a6ae998c7b6191711a04da776dc9e47d4", + "sha256:0aefc7591920bbd360d57ea03c995cebc204b424524a5bd78406f6e1b8b2a5d8", + "sha256:127a789c75151db6af398b8972178afe6bda7d6f68730c057fbbc2e96b08d282", + "sha256:18dd842b49456aaa9a7cf535b04ca4571a302ff72ed8740d06b5adcd41fe0757", + "sha256:217138197c170a2a74ca0e05bddcd5f1796c735c37d0eee33e43259b192aa424", + "sha256:2297f08f08a2bb0d32a4265e98a006643cd7233fb7983032bd61ac7a02956b3b", + "sha256:2fc0a92c02fa1ca1e84fc60fa258458e5bf89d90a1ddaeb8ed9cc3147f417255", + "sha256:30b339b2a743c5288405aa79a69e706a06e02958eab31859f7f3c04980853b70", + "sha256:366c32fe5355ef5fc8a232c5436f4cc66e9d3e8967c01fb2e6302fd6627e3d94", + "sha256:3ad54b9ddbe20ae9f7c1b29e52f123120772b06dbb18ec6be9101369d63a4074", + "sha256:5ad9e6ed739285919aa9661a5bbed0aaf410aa60231373c5579c6b4801bd883c", + "sha256:5faf03a7d8942bb4476e3b62fd0f4cf94eaf4618e304a19865abf89a35c0bbee", + "sha256:75fc59fc450050b1b3c203c35020bc41bd2695ed692a392924c6ce180c6f1dc9", + "sha256:76a095cfe6045c7d0ca77db9934e8f7b71b14645f0094ffcd842349ada5c5fb9", + "sha256:78247b6d45f43a52ef35c25b5581459e85117225408a4128a3daf8bf9648ac69", + "sha256:782e2c9b2aab1708ffb07d4bf377d12901d7a1d99e5e410d648d892f8967ab1f", + "sha256:7ab7004cf2e59f7c2e4345604a3e6ea0d92ac44e1c2375527d56492014e690c3", + "sha256:80b39d3a151309efc8cc48675918891b865bdf742a8616a337cb0090791a0de9", + "sha256:80fa48bd89c8f2f456fc0765c11c23bf5af827febacd2f523ca5bc1893fcc09d", + "sha256:855e068b0358ab916454464a884779c7ffa312b8925c6f7401e952dcf3b89977", + "sha256:92f09ff65ecff3108e56526f9e2481b8116c0b9e1425325e13245abfd79bdb1b", + "sha256:952c81d415b9b80ea261d2372d2a4a2332a3890c2b83e0535f263ddfe43f0d43", + "sha256:9a3a87cf1e133e5b1994144c12ca4aa3d9698517fe1e2ca82977781b16955658", + "sha256:9e4ed0518a14dd26092614412936920ad081a424bdcb54cc13349a8e2c6d106a", + "sha256:a899b10e17743683b293a729d3a11f2f399e8a90c73b089e29f5d0fe3509f0dd", + "sha256:b1f711e2c6dcd4edd372cf5dec5c5a30d23bba06ee012093267b3376c079ec83", + "sha256:b4f87d4ed9064b2628da63830986c3d2dca7501e6018347798313fcf028e2fd4", + "sha256:cb73507defd385b7705c599a94474b1d5222a508e502553ef94114a143ec6696", + "sha256:dc0d2fc424e54c70c4bc06787e4072c4f3b1aa2f897dfdc34ce1013cf3ceef05", + "sha256:e221060b701e2aa2ea991542900dd13907a5c90fa80e199dbf5a03359019e7a3", + "sha256:e271058822765ad5e3bca7f05f2ace0de58a3f4e62045a8c90a0dfd2f8ad8cc6", + "sha256:e2adb09778797da09d2b5ebdbceebf7dd32e2c96f79da9052b2e87b6ea495895", + "sha256:e333e2324307a7b5d86adfa835bb500ee70bfcd1447384a822e96495796b0ca4", + "sha256:e98c8af98d5707dcdecc9ab0863c0ea6e88545d42ca7c3feffb6b4d1e370c7ba", + "sha256:edb45bb8278574710e68a6b021599a10ce730d156e5b254941754a9cc0b17d03", + "sha256:fec03caabbc6b59ea4a638bee5fce7117be8e99a4103d9d5ad77f15d6f81020c" + ], + "markers": "python_version >= '3.8'", + "version": "==1.10.0" + }, + "markdown-it-py": { + "hashes": [ + "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", + "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb" + ], + "markers": "python_version >= '3.8'", + "version": "==3.0.0" + }, + "markupsafe": { + "hashes": [ + "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf", + "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", + "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", + "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", + "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532", + "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", + "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", + "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df", + "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4", + "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", + "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", + "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", + "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", + "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371", + "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2", + "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", + "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52", + "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", + "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", + "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", + "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", + "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0", + "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029", + "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", + "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a", + "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", + "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", + "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", + "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", + "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9", + "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", + "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", + "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3", + "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", + "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46", + "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", + "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a", + "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", + "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", + "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", + "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", + "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", + "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", + "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", + "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", + "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f", + "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50", + "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", + "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", + "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", + "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff", + "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", + "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", + "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", + "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf", + "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", + "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5", + "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab", + "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", + "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68" + ], + "markers": "python_version >= '3.7'", + "version": "==2.1.5" + }, + "mccabe": { + "hashes": [ + "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", + "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" + ], + "markers": "python_version >= '3.6'", + "version": "==0.7.0" + }, + "mdurl": { + "hashes": [ + "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", + "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" + ], + "markers": "python_version >= '3.7'", + "version": "==0.1.2" + }, + "moto": { + "hashes": [ + "sha256:21a13e02f83d6a18cfcd99949c96abb2e889f4bd51c4c6a3ecc8b78765cb854e", + "sha256:eb71f1cba01c70fff1f16086acb24d6d9aeb32830d646d8989f98a29aeae24ba" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==5.0.9" + }, + "mypy": { + "hashes": [ + "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061", + "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99", + "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de", + "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a", + "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9", + "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec", + "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1", + "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131", + "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f", + "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821", + "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5", + "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee", + "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e", + "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746", + "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2", + "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0", + "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b", + "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53", + "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30", + "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda", + "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051", + "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2", + "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7", + "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee", + "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727", + "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976", + "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==1.10.0" + }, + "mypy-extensions": { + "hashes": [ + "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", + "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782" + ], + "markers": "python_version >= '3.5'", + "version": "==1.0.0" + }, + "packaging": { + "hashes": [ + "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" + ], + "markers": "python_version >= '3.7'", + "version": "==24.0" + }, + "pathspec": { + "hashes": [ + "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", + "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712" + ], + "markers": "python_version >= '3.8'", + "version": "==0.12.1" + }, + "pbr": { + "hashes": [ + "sha256:4a7317d5e3b17a3dccb6a8cfe67dab65b20551404c52c8ed41279fa4f0cb4cda", + "sha256:d1377122a5a00e2f940ee482999518efe16d745d423a670c27773dfbc3c9a7d9" + ], + "markers": "python_version >= '2.6'", + "version": "==6.0.0" + }, + "platformdirs": { + "hashes": [ + "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee", + "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3" + ], + "markers": "python_version >= '3.8'", + "version": "==4.2.2" + }, + "pycparser": { + "hashes": [ + "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", + "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc" + ], + "markers": "python_version >= '3.8'", + "version": "==2.22" + }, + "pygments": { + "hashes": [ + "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", + "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a" + ], + "markers": "python_version >= '3.8'", + "version": "==2.18.0" + }, + "pylint": { + "hashes": [ + "sha256:27a8d4c7ddc8c2f8c18aa0050148f89ffc09838142193fdbe98f172781a3ff87", + "sha256:f4fcac7ae74cfe36bc8451e931d8438e4a476c20314b1101c458ad0f05191fad" + ], + "index": "pypi", + "markers": "python_full_version >= '3.7.2'", + "version": "==2.17.7" + }, + "pylint-print": { + "hashes": [ + "sha256:30aa207e9718ebf4ceb47fb87012092e6d8743aab932aa07aa14a73e750ad3d0", + "sha256:a2b2599e7887b93e551db2624c523c1e6e9e58c3be8416cd98d41e4427e2669b" + ], + "index": "pypi", + "markers": "python_version >= '3.6'", + "version": "==1.0.1" + }, + "python-dateutil": { + "hashes": [ + "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", + "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.9.0.post0" + }, + "pyyaml": { + "hashes": [ + "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", + "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", + "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", + "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", + "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", + "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", + "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595", + "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", + "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", + "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", + "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290", + "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", + "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", + "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6", + "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", + "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", + "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", + "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6", + "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", + "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", + "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", + "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", + "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", + "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", + "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", + "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", + "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", + "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", + "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", + "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef", + "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", + "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", + "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", + "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0", + "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515", + "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c", + "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c", + "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924", + "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34", + "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", + "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", + "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", + "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", + "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", + "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b", + "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", + "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", + "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", + "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585", + "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d", + "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" + ], + "markers": "python_version >= '3.6'", + "version": "==6.0.1" + }, + "requests": { + "hashes": [ + "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", + "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==2.31.0" + }, + "responses": { + "hashes": [ + "sha256:01ae6a02b4f34e39bffceb0fc6786b67a25eae919c6368d05eabc8d9576c2a66", + "sha256:2f0b9c2b6437db4b528619a77e5d565e4ec2a9532162ac1a131a83529db7be1a" + ], + "markers": "python_version >= '3.8'", + "version": "==0.25.0" + }, + "rich": { + "hashes": [ + "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222", + "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==13.7.1" + }, + "s3transfer": { + "hashes": [ + "sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19", + "sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d" + ], + "markers": "python_version >= '3.8'", + "version": "==0.10.1" + }, + "six": { + "hashes": [ + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.16.0" + }, + "stevedore": { + "hashes": [ + "sha256:1c15d95766ca0569cad14cb6272d4d31dae66b011a929d7c18219c176ea1b5c9", + "sha256:46b93ca40e1114cea93d738a6c1e365396981bb6bb78c27045b7587c9473544d" + ], + "markers": "python_version >= '3.8'", + "version": "==5.2.0" + }, + "tomlkit": { + "hashes": [ + "sha256:af914f5a9c59ed9d0762c7b64d3b5d5df007448eb9cd2edc8a46b1eafead172f", + "sha256:eef34fba39834d4d6b73c9ba7f3e4d1c417a4e56f89a7e96e090dd0d24b8fb3c" + ], + "markers": "python_version >= '3.7'", + "version": "==0.12.5" + }, + "typing-extensions": { + "hashes": [ + "sha256:6024b58b69089e5a89c347397254e35f1bf02a907728ec7fee9bf0fe837d203a", + "sha256:915f5e35ff76f56588223f15fdd5938f9a1cf9195c0de25130c627e4d597f6d1" + ], + "markers": "python_version >= '3.8'", + "version": "==4.12.1" + }, + "urllib3": { + "hashes": [ + "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d", + "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19" + ], + "markers": "python_version >= '3.8'", + "version": "==2.2.1" + }, + "werkzeug": { + "hashes": [ + "sha256:097e5bfda9f0aba8da6b8545146def481d06aa7d3266e7448e2cccf67dd8bd18", + "sha256:fc9645dc43e03e4d630d23143a04a7f947a9a3b5727cd535fdfe155a17cc48c8" + ], + "markers": "python_version >= '3.8'", + "version": "==3.0.3" + }, + "wrapt": { + "hashes": [ + "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc", + "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81", + "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09", + "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e", + "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca", + "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0", + "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb", + "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487", + "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40", + "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c", + "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060", + "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202", + "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41", + "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9", + "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b", + "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664", + "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d", + "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362", + "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00", + "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc", + "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1", + "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267", + "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956", + "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966", + "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1", + "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228", + "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72", + "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d", + "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292", + "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0", + "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0", + "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36", + "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c", + "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5", + "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f", + "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73", + "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b", + "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2", + "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593", + "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39", + "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389", + "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf", + "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf", + "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89", + "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c", + "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c", + "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f", + "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440", + "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465", + "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136", + "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b", + "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8", + "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3", + "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8", + "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6", + "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e", + "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f", + "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c", + "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e", + "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8", + "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2", + "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020", + "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35", + "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d", + "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3", + "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537", + "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809", + "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d", + "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a", + "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4" + ], + "index": "pypi", + "markers": "python_version >= '3.6'", + "version": "==1.16.0" + }, + "xmltodict": { + "hashes": [ + "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56", + "sha256:aa89e8fd76320154a40d19a0df04a4695fb9dc5ba977cbb68ab3e4eb225e7852" + ], + "markers": "python_version >= '3.4'", + "version": "==0.13.0" + } } - } } From aa5ae8bd9ff83542bd65bd39cc898c869befa2ed Mon Sep 17 00:00:00 2001 From: Evan Gibler <20933572+egibs@users.noreply.github.com> Date: Tue, 4 Jun 2024 13:26:39 -0500 Subject: [PATCH 17/35] Tweak Snowflake queries (#1250) * Tweak Snowflake queries Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> * Remove configuration drift query from Pack Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> * Threat Hunting queries are okay Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> * Fix comment Workflow Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> * 12 hours -> 1 day Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> * Update queries/snowflake_queries/snowflake_0108977_configuration_drift.yml --------- Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> --- .github/workflows/check-packs.yml | 3 + packs/snowflake.yml | 3 - .../snowflake_0108977_configuration_drift.yml | 4 +- ...lake_0108977_configuration_drift_query.yml | 3 + .../snowflake_0108977_ip_query.yml | 1 + ...ke_0108977_suspected_user_access_query.yml | 1 + ...owflake_0108977_suspected_user_activity.py | 9 --- ...wflake_0108977_suspected_user_activity.yml | 78 ------------------- ..._0108977_suspected_user_activity_query.yml | 24 ------ 9 files changed, 11 insertions(+), 115 deletions(-) delete mode 100644 queries/snowflake_queries/snowflake_0108977_suspected_user_activity.py delete mode 100644 queries/snowflake_queries/snowflake_0108977_suspected_user_activity.yml delete mode 100644 queries/snowflake_queries/snowflake_0108977_suspected_user_activity_query.yml diff --git a/.github/workflows/check-packs.yml b/.github/workflows/check-packs.yml index beae9b7f4..00d8f4bd7 100644 --- a/.github/workflows/check-packs.yml +++ b/.github/workflows/check-packs.yml @@ -3,6 +3,7 @@ on: permissions: contents: read + pull-requests: write jobs: check_packs: @@ -50,6 +51,7 @@ jobs: looks like some things could be wrong with the packs ```diff ${{ steps.check-packs.outputs.errors }} + ``` comment_tag: check-packs - name: Delete comment uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 @@ -61,4 +63,5 @@ jobs: looks like some things could be wrong with the packs ```diff ${{ steps.check-packs.outputs.errors }} + ``` comment_tag: check-packs diff --git a/packs/snowflake.yml b/packs/snowflake.yml index 8b1911f00..f68eab223 100644 --- a/packs/snowflake.yml +++ b/packs/snowflake.yml @@ -13,12 +13,10 @@ PackDefinition: - Query.Snowflake.BruteForceByIp - Query.Snowflake.BruteForceByUsername - Query.Snowflake.ClientIp - - Query.Snowflake.ConfigurationDrift - Query.Snowflake.External.Shares - Query.Snowflake.KeyUserPasswordLogin - Query.Snowflake.Multiple.Logins.Followed.By.Success - Query.Snowflake.SuspectedUserAccess - - Query.Snowflake.SuspectedUserActivity - Query.Snowflake.UserCreated - Query.Snowflake.UserEnabled # Rules @@ -31,7 +29,6 @@ PackDefinition: - Snowflake.KeyUserPasswordLogin - Snowflake.Multiple.Failed.Logins.Followed.By.Success - Snowflake.User.Access - - Snowflake.User.Activity - Snowflake.UserCreated - Snowflake.UserEnabled # Threat Hunting Queries diff --git a/queries/snowflake_queries/snowflake_0108977_configuration_drift.yml b/queries/snowflake_queries/snowflake_0108977_configuration_drift.yml index 258a601a9..5c4c5ae2b 100644 --- a/queries/snowflake_queries/snowflake_0108977_configuration_drift.yml +++ b/queries/snowflake_queries/snowflake_0108977_configuration_drift.yml @@ -8,7 +8,9 @@ Enabled: false Runbook: Determine if this occurred as a result of a valid business request. ScheduledQueries: - Query.Snowflake.ConfigurationDrift -Severity: High +Tags: + - Configuration Required +Severity: Medium Tests: - Name: Configuration Drift ExpectedResult: true diff --git a/queries/snowflake_queries/snowflake_0108977_configuration_drift_query.yml b/queries/snowflake_queries/snowflake_0108977_configuration_drift_query.yml index b66eaf833..c7959a43f 100644 --- a/queries/snowflake_queries/snowflake_0108977_configuration_drift_query.yml +++ b/queries/snowflake_queries/snowflake_0108977_configuration_drift_query.yml @@ -3,6 +3,8 @@ Enabled: false QueryName: "Query.Snowflake.ConfigurationDrift" Description: > Monitor for configuration drift made by malicious actors as part of ongoing cyber threat activity reported May 31st, 2024 +Tags: + - Configuration Required SnowflakeQuery: > -- https://community.snowflake.com/s/article/Communication-ID-0108977-Additional-Information @@ -44,6 +46,7 @@ SnowflakeQuery: > AND query_type = 'GRANT' AND execution_status = 'SUCCESS' ) + AND p_occurs_since('1 day') ORDER BY end_time desc LIMIT 100; Schedule: diff --git a/queries/snowflake_queries/snowflake_0108977_ip_query.yml b/queries/snowflake_queries/snowflake_0108977_ip_query.yml index c6851607b..0302e901d 100644 --- a/queries/snowflake_queries/snowflake_0108977_ip_query.yml +++ b/queries/snowflake_queries/snowflake_0108977_ip_query.yml @@ -79,6 +79,7 @@ SnowflakeQuery: > '146.70.119.24', '138.199.34.144' ) + AND p_occurs_since('1 day') ORDER BY event_timestamp LIMIT 100; diff --git a/queries/snowflake_queries/snowflake_0108977_suspected_user_access_query.yml b/queries/snowflake_queries/snowflake_0108977_suspected_user_access_query.yml index 7ab82c4a8..775ce9eea 100644 --- a/queries/snowflake_queries/snowflake_0108977_suspected_user_access_query.yml +++ b/queries/snowflake_queries/snowflake_0108977_suspected_user_access_query.yml @@ -18,6 +18,7 @@ SnowflakeQuery: > AND PARSE_JSON(CLIENT_ENVIRONMENT):OS = 'Windows Server 2022' ) + AND p_occurs_since('1 day') ORDER BY CREATED_ON LIMIT 100; Schedule: diff --git a/queries/snowflake_queries/snowflake_0108977_suspected_user_activity.py b/queries/snowflake_queries/snowflake_0108977_suspected_user_activity.py deleted file mode 100644 index 9f45a9b26..000000000 --- a/queries/snowflake_queries/snowflake_0108977_suspected_user_activity.py +++ /dev/null @@ -1,9 +0,0 @@ -def rule(_): - return True - - -def title(event): - query_id = event.get("query_id", "") - role_name = event.get("role_name", "") - user_name = event.get("user_name", "") - return f"{user_name} with role {role_name} performed query {query_id}" diff --git a/queries/snowflake_queries/snowflake_0108977_suspected_user_activity.yml b/queries/snowflake_queries/snowflake_0108977_suspected_user_activity.yml deleted file mode 100644 index 172d5573e..000000000 --- a/queries/snowflake_queries/snowflake_0108977_suspected_user_activity.yml +++ /dev/null @@ -1,78 +0,0 @@ -AnalysisType: scheduled_rule -Filename: snowflake_0108977_suspected_user_activity.py -RuleID: "Snowflake.User.Activity" -Description: > - Return actions/queries made by suspected users as part of ongoing cyber threat activity reported May 31st, 2024 -DisplayName: "Snowflake User Activity" -Enabled: false -Runbook: Determine if this occurred as a result of a valid business request. -ScheduledQueries: - - Query.Snowflake.SuspectedUserActivity -Severity: High -Tests: - - Name: User Activity - ExpectedResult: true - Log: - { - "bytes_deleted": 0, - "bytes_read_from_result": 0, - "bytes_scanned": 0, - "bytes_sent_over_the_network": 0, - "bytes_spilled_to_local_storage": 0, - "bytes_spilled_to_remote_storage": 0, - "bytes_written": 0, - "bytes_written_to_result": 496, - "child_queries_wait_time": 0, - "compilation_time": 88, - "credits_used_cloud_services": 0.000013, - "database_id": 4, - "database_name": "PANTHER_LOGS", - "end_time": "2024-04-01 00:11:04.463Z", - "execution_status": "SUCCESS", - "execution_time": 1, - "external_function_total_invocations": 0, - "external_function_total_received_bytes": 0, - "external_function_total_received_rows": 0, - "external_function_total_sent_bytes": 0, - "external_function_total_sent_rows": 0, - "inbound_data_transfer_bytes": 0, - "is_client_generated_statement": false, - "list_external_files_time": 0, - "outbound_data_transfer_bytes": 0, - "partitions_scanned": 0, - "partitions_total": 0, - "percentage_scanned_from_cache": 0, - "query_acceleration_bytes_scanned": 0, - "query_acceleration_partitions_scanned": 0, - "query_acceleration_upper_limit_scale_factor": 0, - "query_hash": "b6ee76a5529464a34eca48936c3f8f15", - "query_hash_version": 2, - "query_id": "01b35dcb-0205-0bc0-0002-00eb00fed6de", - "query_parameterized_hash": "b6ee76a5529464a34eca48936c3f8f15", - "query_parameterized_hash_version": 1, - "query_tag": "", - "query_text": "SELECT 1", - "query_type": "SELECT", - "queued_overload_time": 0, - "queued_provisioning_time": 0, - "queued_repair_time": 0, - "release_version": "8.12.2", - "role_name": "ADMIN", - "role_type": "ROLE", - "rows_deleted": 0, - "rows_inserted": 0, - "rows_unloaded": 0, - "rows_updated": 0, - "rows_written_to_result": 1, - "secondary_role_stats": - { "roleNames": [], "roleCount": 0, "roleIds": [] }, - "session_id": 563959287514918, - "start_time": "2024-04-01 00:11:04.374Z", - "total_elapsed_time": 89, - "transaction_blocked_time": 0, - "transaction_id": 0, - "user_name": "USER_NAME", - "warehouse_id": 4, - "warehouse_name": "WAREHOUSE", - "warehouse_type": "STANDARD", - } diff --git a/queries/snowflake_queries/snowflake_0108977_suspected_user_activity_query.yml b/queries/snowflake_queries/snowflake_0108977_suspected_user_activity_query.yml deleted file mode 100644 index bbcfece8d..000000000 --- a/queries/snowflake_queries/snowflake_0108977_suspected_user_activity_query.yml +++ /dev/null @@ -1,24 +0,0 @@ -AnalysisType: scheduled_query -Enabled: false -QueryName: "Query.Snowflake.SuspectedUserActivity" -Description: > - Return actions/queries made by suspected users as part of ongoing cyber threat activity reported May 31st, 2024 -SnowflakeQuery: > - -- https://community.snowflake.com/s/article/Communication-ID-0108977-Additional-Information - - -- replace with actual user name - - SELECT - * - FROM - snowflake.account_usage.query_history - WHERE - user_name = '' - AND start_time BETWEEN '2024-04-01' - AND CURRENT_TIMESTAMP - ORDER BY - start_time - LIMIT 100; -Schedule: - RateMinutes: 1440 - TimeoutMinutes: 3 From d7009255c37e57d8945af6a7facfd5b188144ce9 Mon Sep 17 00:00:00 2001 From: JPhenglavong Date: Fri, 7 Jun 2024 16:29:36 -0700 Subject: [PATCH 18/35] Fixed typo in README.md (#1253) fixed 'unintall' typo to 'npm uninstall prettier' --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7a600e8e5..8dbcff86d 100644 --- a/README.md +++ b/README.md @@ -265,7 +265,7 @@ Previously, Node, NPM and Prettier were used for formatting Markdown and YAML fi Depending on how Node is managed, it will need to be uninstalled or removed if it is no longer needed elsewhere. Refer to your system/package manager's documentation for instructions on removing Node. -Otherwise, running `npm unintall prettier` will remove Prettier. +Otherwise, running `npm uninstall prettier` will remove Prettier. # License From 915633853a4f32208b46350fbf9ba26d91a894ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 06:47:09 -0500 Subject: [PATCH 19/35] build(deps): bump step-security/harden-runner from 2.8.0 to 2.8.1 (#1254) Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.8.0 to 2.8.1. - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/f086349bfa2bd1361f7909c78558e816508cdc10...17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/check-packs.yml | 2 +- .github/workflows/docker.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 2 +- .github/workflows/upload.yml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/check-packs.yml b/.github/workflows/check-packs.yml index 00d8f4bd7..765221386 100644 --- a/.github/workflows/check-packs.yml +++ b/.github/workflows/check-packs.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0 + - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 with: disable-sudo: true egress-policy: block diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 07eac4382..4853a0846 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -11,7 +11,7 @@ jobs: name: Build Dockerfile runs-on: ubuntu-latest steps: - - uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0 + - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 with: disable-sudo: true egress-policy: block diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 2e9f7c166..43bdfab72 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0 + - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 with: disable-sudo: true egress-policy: block diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 458ec623a..08433b6d6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.PANTHER_BOT_AUTOMATION_TOKEN }} steps: - - uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0 + - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 with: egress-policy: audit - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 #v4.1.6 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7921ba94a..d6be44170 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0 + - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 with: disable-sudo: true egress-policy: block diff --git a/.github/workflows/upload.yml b/.github/workflows/upload.yml index ef71a0f76..3cf548ab8 100644 --- a/.github/workflows/upload.yml +++ b/.github/workflows/upload.yml @@ -14,7 +14,7 @@ jobs: API_HOST: ${{ secrets.API_HOST }} API_TOKEN: ${{ secrets.API_TOKEN }} steps: - - uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0 + - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 with: egress-policy: audit - name: Validate Secrets From 2f8c64f548a11ee1fcd2420008f1d86398423408 Mon Sep 17 00:00:00 2001 From: BJ Maldonado Date: Mon, 10 Jun 2024 11:12:00 -0400 Subject: [PATCH 20/35] Using GITHUB_OUTPUT env var instead of old ::set-output shorthand (#1255) --- .github/workflows/check-packs.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/check-packs.yml b/.github/workflows/check-packs.yml index 765221386..280f706f3 100644 --- a/.github/workflows/check-packs.yml +++ b/.github/workflows/check-packs.yml @@ -2,7 +2,7 @@ on: pull_request: permissions: - contents: read + contents: read pull-requests: write jobs: @@ -20,7 +20,7 @@ jobs: files.pythonhosted.org:443 github.com:443 pypi.org:443 - + - name: Checkout panther-analysis uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 #v4.1.6 @@ -39,7 +39,7 @@ jobs: panther_analysis_tool check-packs 2> errors.txt || true # run again to get exit code - panther_analysis_tool check-packs || echo ::set-output name=errors::`cat errors.txt` + panther_analysis_tool check-packs || echo "errors=`cat errors.txt`" >> $GITHUB_OUTPUT - name: Comment PR uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 From 41e0c469401542d5963288fc17fdcf5f3bea666d Mon Sep 17 00:00:00 2001 From: akozlovets098 <95437895+akozlovets098@users.noreply.github.com> Date: Mon, 10 Jun 2024 18:20:51 +0300 Subject: [PATCH 21/35] OCSF data model, VPC/DNS (#1214) * Deprecate GreyNoise detections (#1205) * Deprecate GreyNoise detections * Update rules/aws_cloudtrail_rules/aws_s3_activity_greynoise.yml * Update rules/cloudflare_rules/cloudflare_firewall_suspicious_event_greynoise.yml * Update cloudflare_httpreq_bot_high_volume_greynoise.yml --------- Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> * fix - Notion Login From New Location - NoneType error (#1206) * fix - Notion Login From New Location - NoneType error * fix - Notion Login From New Location - NoneType error - linter fix * remove codeowners (#1208) * fix - GCP rules - AttributeError (#1210) * fix - GCP rules - AttributeError * fix - GCP rules - AttributeError - linter fix * MITRE ATT&CK Mappings for MS Rules (#1209) * added MITRE mappings for microsoft rules * fixed formatting on some helper files --------- Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> * traildiscover enrichment with managed schema (#1177) * traildiscover enrichment with managed schema * Add npm install in dockerfile (#1172) * add npm install in dockerfile * Remove Python optimizations; add prettier to PATH --------- Co-authored-by: egibs * schema name: TrailDiscover.CloudTrail * Fix Dockerfile; add Workflow to test image * updated data set * Add MongoDB.2FA.Disabled rule (#1190) Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> * lint and fmt * fmt * add OCSF selector * additional OCSF mappings * Fix Pipfile * Rebase changes --------- Co-authored-by: Panos Sakkos Co-authored-by: egibs Co-authored-by: Oleh Melenevskyi <767472+melenevskyi@users.noreply.github.com> * Update PAT to 0.46.0 (#1216) * THREAT-278 OCSF data model, VPC --------- Co-authored-by: Oleh Melenevskyi <767472+melenevskyi@users.noreply.github.com> Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> Co-authored-by: Panos Sakkos Co-authored-by: ben-githubs <38414634+ben-githubs@users.noreply.github.com> Co-authored-by: egibs Co-authored-by: Evan Gibler --- data_models/aws_vpcflow_data_model.yml | 2 + data_models/ocsf_dnsactivity_data_model.yml | 13 + .../ocsf_networkactivity_data_model.yml | 17 + packs/aws.yml | 2 + .../aws_dns_crypto_domain.py | 10 +- .../aws_dns_crypto_domain.yml | 408 +++++++++++------- .../aws_vpc_healthy_log_status.py | 2 +- .../aws_vpc_healthy_log_status.yml | 12 +- .../aws_vpc_inbound_traffic_port_allowlist.py | 10 +- ...aws_vpc_inbound_traffic_port_allowlist.yml | 42 +- .../aws_vpc_inbound_traffic_port_blocklist.py | 8 +- ...aws_vpc_inbound_traffic_port_blocklist.yml | 42 +- .../aws_vpc_unapproved_outbound_dns.py | 10 +- .../aws_vpc_unapproved_outbound_dns.yml | 42 +- 14 files changed, 434 insertions(+), 186 deletions(-) create mode 100644 data_models/ocsf_dnsactivity_data_model.yml create mode 100644 data_models/ocsf_networkactivity_data_model.yml diff --git a/data_models/aws_vpcflow_data_model.yml b/data_models/aws_vpcflow_data_model.yml index a4099a401..3707220d9 100644 --- a/data_models/aws_vpcflow_data_model.yml +++ b/data_models/aws_vpcflow_data_model.yml @@ -15,3 +15,5 @@ Mappings: Path: srcPort - Name: user_agent Path: userAgent + - Name: log_status + Path: log-status diff --git a/data_models/ocsf_dnsactivity_data_model.yml b/data_models/ocsf_dnsactivity_data_model.yml new file mode 100644 index 000000000..55fb2d7af --- /dev/null +++ b/data_models/ocsf_dnsactivity_data_model.yml @@ -0,0 +1,13 @@ +AnalysisType: datamodel +LogTypes: + - OCSF.DnsActivity +DataModelID: "Standard.OCSF.DnsActivity" +DisplayName: "OCSF DNS Activity" +Enabled: true +Mappings: + - Name: source_ip + Path: $.src_endpoint.ip + - Name: source_port + Path: $.src_endpoint.port + - Name: dns_query + Path: $.query.hostname diff --git a/data_models/ocsf_networkactivity_data_model.yml b/data_models/ocsf_networkactivity_data_model.yml new file mode 100644 index 000000000..4fe4b5628 --- /dev/null +++ b/data_models/ocsf_networkactivity_data_model.yml @@ -0,0 +1,17 @@ +AnalysisType: datamodel +LogTypes: + - OCSF.NetworkActivity +DataModelID: "Standard.OCSF.NetworkActivity" +DisplayName: "OCSF Network Activity" +Enabled: true +Mappings: + - Name: destination_ip + Path: $.dst_endpoint.ip + - Name: destination_port + Path: $.dst_endpoint.port + - Name: source_ip + Path: $.src_endpoint.ip + - Name: source_port + Path: $.src_endpoint.port + - Name: log_status + Path: status_code diff --git a/packs/aws.yml b/packs/aws.yml index 333d26005..5fd6dc10a 100644 --- a/packs/aws.yml +++ b/packs/aws.yml @@ -167,6 +167,8 @@ PackDefinition: - Standard.AWS.CloudTrail - Standard.AWS.S3ServerAccess - Standard.AWS.VPCFlow + - Standard.OCSF.NetworkActivity + - Standard.OCSF.DnsActivity # Globals used in these rules/policies - panther_base_helpers - panther_config diff --git a/rules/aws_vpc_flow_rules/aws_dns_crypto_domain.py b/rules/aws_vpc_flow_rules/aws_dns_crypto_domain.py index 256bbbacc..85f890195 100644 --- a/rules/aws_vpc_flow_rules/aws_dns_crypto_domain.py +++ b/rules/aws_vpc_flow_rules/aws_dns_crypto_domain.py @@ -2,7 +2,9 @@ def rule(event): - query_name = event.get("query_name") + query_name = event.udm("dns_query") + if not query_name: + return False for domain in CRYPTO_MINING_DOMAINS: if query_name.rstrip(".").endswith(domain): return True @@ -11,11 +13,11 @@ def rule(event): def title(event): return ( - f"[{event.get('srcaddr')}:{event.get('srcport')}] " + f"[{event.udm('source_ip')}:{event.udm('source_port')}] " "made a DNS query for crypto mining domain: " - f"[{event.get('query_name')}]." + f"[{event.udm('dns_query')}]." ) def dedup(event): - return f"{event.get('srcaddr')}" + return f"{event.udm('source_ip')}" diff --git a/rules/aws_vpc_flow_rules/aws_dns_crypto_domain.yml b/rules/aws_vpc_flow_rules/aws_dns_crypto_domain.yml index f90e41ec6..8ecc81c1a 100644 --- a/rules/aws_vpc_flow_rules/aws_dns_crypto_domain.yml +++ b/rules/aws_vpc_flow_rules/aws_dns_crypto_domain.yml @@ -9,176 +9,264 @@ Reports: Reference: https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html Severity: High Tests: - - ExpectedResult: false + - Name: Non Crypto Query + ExpectedResult: false Log: - account_id: "0123456789" - answers: - - Class: IN - Rdata: 1.2.3.4 - Type: A - query_class: IN - query_name: dynamodb.us-west-2.amazonaws.com - query_timestamp: "2022-06-25 00:27:53" - query_type: A - rcode: NOERROR - region: us-west-2 - srcaddr: 5.6.7.8 - srcids: - instance: i-0abc234 - srcport: "8888" - transport: UDP - version: "1.100000" - vpc_id: vpc-abc123 - Name: Non Crypto Query - - ExpectedResult: false + { + "account_id": "0123456789", + "answers": { "Class": "IN", "Rdata": "1.2.3.4", "Type": "A" }, + "query_class": "IN", + "query_name": "dynamodb.us-west-2.amazonaws.com", + "query_timestamp": "2022-06-25 00:27:53", + "query_type": "A", + "rcode": "NOERROR", + "region": "us-west-2", + "srcaddr": "5.6.7.8", + "srcids": { instance: "i-0abc234" }, + "srcport": "8888", + "transport": "UDP", + "version": "1.100000", + "vpc_id": "vpc-abc123", + "p_log_type": "AWS.VPCDns", + } + - Name: Non Crypto Query Trailing Period + ExpectedResult: false Log: - account_id: "0123456789" - answers: - - Class: IN - Rdata: 1.2.3.4 - Type: A - query_class: IN - query_name: dynamodb.us-west-2.amazonaws.com. - query_timestamp: "2022-06-25 00:27:53" - query_type: A - rcode: NOERROR - region: us-west-2 - srcaddr: 5.6.7.8 - srcids: - instance: i-0abc234 - srcport: "8888" - transport: UDP - version: "1.100000" - vpc_id: vpc-abc123 - Name: Non Crypto Query Trailing Period - - ExpectedResult: true + { + "account_id": "0123456789", + "answers": { "Class": "IN", "Rdata": "1.2.3.4", "Type": "A" }, + "query_class": "IN", + "query_name": "dynamodb.us-west-2.amazonaws.com.", + "query_timestamp": "2022-06-25 00:27:53", + "query_type": "A", + "rcode": "NOERROR", + "region": "us-west-2", + "srcaddr": "5.6.7.8", + "srcids": { "instance": "i-0abc234" }, + "srcport": "8888", + "transport": "UDP", + "version": "1.100000", + "vpc_id": "vpc-abc123", + "p_log_type": "AWS.VPCDns", + } + - Name: Crypto Query + ExpectedResult: true Log: - account_id: "0123456789" - answers: - - Class: IN - Rdata: 1.2.3.4 - Type: A - query_class: IN - query_name: moneropool.ru - query_timestamp: "2022-06-25 00:27:53" - query_type: A - rcode: NOERROR - region: us-west-2 - srcaddr: 5.6.7.8 - srcids: - instance: i-0abc234 - srcport: "8888" - transport: UDP - version: "1.100000" - vpc_id: vpc-abc123 - Name: Crypto Query - - ExpectedResult: true + { + "account_id": "0123456789", + "answers": { "Class": "IN", "Rdata": "1.2.3.4", "Type": "A" }, + "query_class": "IN", + "query_name": "moneropool.ru", + "query_timestamp": "2022-06-25 00:27:53", + "query_type": "A", + "rcode": "NOERROR", + "region": "us-west-2", + "srcaddr": "5.6.7.8", + "srcids": { "instance": "i-0abc234" }, + "srcport": "8888", + "transport": "UDP", + "version": "1.100000", + "vpc_id": "vpc-abc123", + "p_log_type": "AWS.VPCDns", + } + - Name: Crypto Query Subdomain + ExpectedResult: true Log: - account_id: "0123456789" - answers: - - Class: IN - Rdata: 1.2.3.4 - Type: A - query_class: IN - query_name: abc.abc.moneropool.ru - query_timestamp: "2022-06-25 00:27:53" - query_type: A - rcode: NOERROR - region: us-west-2 - srcaddr: 5.6.7.8 - srcids: - instance: i-0abc234 - srcport: "8888" - transport: UDP - version: "1.100000" - vpc_id: vpc-abc123 - Name: Crypto Query Subdomain - - ExpectedResult: true + { + "account_id": "0123456789", + "answers": { "Class": "IN", "Rdata": "1.2.3.4", "Type": "A" }, + "query_class": "IN", + "query_name": "abc.abc.moneropool.ru", + "query_timestamp": "2022-06-25 00:27:53", + "query_type": "A", + "rcode": "NOERROR", + "region": "us-west-2", + "srcaddr": "5.6.7.8", + "srcids": { "instance": "i-0abc234" }, + "srcport": "8888", + "transport": "UDP", + "version": "1.100000", + "vpc_id": "vpc-abc123", + "p_log_type": "AWS.VPCDns", + } + - Name: Crypto Query Trailing Period + ExpectedResult: true Log: - account_id: "0123456789" - answers: - - Class: IN - Rdata: 1.2.3.4 - Type: A - query_class: IN - query_name: moneropool.ru. - query_timestamp: "2022-06-25 00:27:53" - query_type: A - rcode: NOERROR - region: us-west-2 - srcaddr: 5.6.7.8 - srcids: - instance: i-0abc234 - srcport: "8888" - transport: UDP - version: "1.100000" - vpc_id: vpc-abc123 - Name: Crypto Query Trailing Period - - ExpectedResult: true + { + "account_id": "0123456789", + "answers": { "Class": "IN", "Rdata": "1.2.3.4", "Type": "A" }, + "query_class": "IN", + "query_name": "moneropool.ru.", + "query_timestamp": "2022-06-25 00:27:53", + "query_type": "A", + "rcode": "NOERROR", + "region": "us-west-2", + "srcaddr": "5.6.7.8", + "srcids": { "instance": "i-0abc234" }, + "srcport": "8888", + "transport": "UDP", + "version": "1.100000", + "vpc_id": "vpc-abc123", + "p_log_type": "AWS.VPCDns", + } + - Name: Crypto Query Subdomain Trailing Period + ExpectedResult: true Log: - account_id: "0123456789" - answers: - - Class: IN - Rdata: 1.2.3.4 - Type: A - query_class: IN - query_name: abc.abc.moneropool.ru. - query_timestamp: "2022-06-25 00:27:53" - query_type: A - rcode: NOERROR - region: us-west-2 - srcaddr: 5.6.7.8 - srcids: - instance: i-0abc234 - srcport: "8888" - transport: UDP - version: "1.100000" - vpc_id: vpc-abc123 - Name: Crypto Query Subdomain Trailing Period - - ExpectedResult: true + { + "account_id": "0123456789", + "answers": { "Class": "IN", "Rdata": "1.2.3.4", "Type": "A" }, + "query_class": "IN", + "query_name": "abc.abc.moneropool.ru.", + "query_timestamp": "2022-06-25 00:27:53", + "query_type": "A", + "rcode": "NOERROR", + "region": "us-west-2", + "srcaddr": "5.6.7.8", + "srcids": { "instance": "i-0abc234" }, + "srcport": "8888", + "transport": "UDP", + "version": "1.100000", + "vpc_id": "vpc-abc123", + "p_log_type": "AWS.VPCDns", + } + - Name: Checking Against Subdomain IOC + ExpectedResult: true Log: - account_id: "0123456789" - answers: - - Class: IN - Rdata: 1.2.3.4 - Type: A - query_class: IN - query_name: webservicepag.webhop.net - query_timestamp: "2022-06-25 00:27:53" - query_type: A - rcode: NOERROR - region: us-west-2 - srcaddr: 5.6.7.8 - srcids: - instance: i-0abc234 - srcport: "8888" - transport: UDP - version: "1.100000" - vpc_id: vpc-abc123 - Name: Checking Against Subdomain IOC - - ExpectedResult: true + { + "account_id": "0123456789", + "answers": { "Class": "IN", "Rdata": "1.2.3.4", "Type": "A" }, + "query_class": "IN", + "query_name": "webservicepag.webhop.net", + "query_timestamp": "2022-06-25 00:27:53", + "query_type": "A", + "rcode": "NOERROR", + "region": "us-west-2", + "srcaddr": "5.6.7.8", + "srcids": { "instance": "i-0abc234" }, + "srcport": "8888", + "transport": "UDP", + "version": "1.100000", + "vpc_id": "vpc-abc123", + "p_log_type": "AWS.VPCDns", + } + - Name: Checking Against Subdomain IOC Trailing Period + ExpectedResult: true Log: - account_id: "0123456789" - answers: - - Class: IN - Rdata: 1.2.3.4 - Type: A - query_class: IN - query_name: webservicepag.webhop.net. - query_timestamp: "2022-06-25 00:27:53" - query_type: A - rcode: NOERROR - region: us-west-2 - srcaddr: 5.6.7.8 - srcids: - instance: i-0abc234 - srcport: "8888" - transport: UDP - version: "1.100000" - vpc_id: vpc-abc123 - Name: Checking Against Subdomain IOC Trailing Period + { + "account_id": "0123456789", + "answers": { "Class": "IN", "Rdata": "1.2.3.4", "Type": "A" }, + "query_class": "IN", + "query_name": "webservicepag.webhop.net.", + "query_timestamp": "2022-06-25 00:27:53", + "query_type": "A", + "rcode": "NOERROR", + "region": "us-west-2", + "srcaddr": "5.6.7.8", + "srcids": { "instance": "i-0abc234" }, + "srcport": "8888", + "transport": "UDP", + "version": "1.100000", + "vpc_id": "vpc-abc123", + "p_log_type": "AWS.VPCDns", + } + - Name: Non Crypto Query Trailing Period - OCSF + ExpectedResult: false + Log: + { + "activity_id": 2, + "activity_name": "Response", + "answers": [{ "class": "IN", "rdata": "1.2.3.4", "type": "AAAA" }], + "category_name": "Network Activity", + "category_uid": 4, + "class_name": "DNS Activity", + "class_uid": 4003, + "cloud": { "provider": "AWS", "region": "us-west-2" }, + "connection_info": + { "direction": "Unknown", "direction_id": 0, "protocol_name": "UDP" }, + "disposition": "Unknown", + "disposition_id": 0, + "metadata": + { + "product": + { + "feature": { "name": "Resolver Query Logs" }, + "name": "Route 53", + "vendor_name": "AWS", + "version": "1.100000", + }, + "profiles": ["cloud", "security_control"], + "version": "1.100000", + }, + "query": + { + "class": "IN", + "hostname": "dynamodb.us-west-2.amazonaws.com.", + "type": "AAAA", + }, + "rcode": "NoError", + "rcode_id": 0, + "severity": "Informational", + "severity_id": 1, + "src_endpoint": + { + "instance_uid": "i-0abc234", + "ip": "5.6.7.8", + "port": "8888", + "vpc_uid": "vpc-abc123", + }, + "time": "2022-06-25 00:27:53", + "type_name": "DNS Activity: Response", + "type_uid": 400302, + "p_log_type": "OCSF.DnsActivity", + } + - Name: Crypto Query - OCSF + ExpectedResult: true + Log: + { + "activity_id": 2, + "activity_name": "Response", + "answers": [{ "class": "IN", "rdata": "1.2.3.4", "type": "AAAA" }], + "category_name": "Network Activity", + "category_uid": 4, + "class_name": "DNS Activity", + "class_uid": 4003, + "cloud": { "provider": "AWS", "region": "us-west-2" }, + "connection_info": + { "direction": "Unknown", "direction_id": 0, "protocol_name": "UDP" }, + "disposition": "Unknown", + "disposition_id": 0, + "metadata": + { + "product": + { + "feature": { "name": "Resolver Query Logs" }, + "name": "Route 53", + "vendor_name": "AWS", + "version": "1.100000", + }, + "profiles": ["cloud", "security_control"], + "version": "1.100000", + }, + "query": { "class": "IN", "hostname": "moneropool.ru", "type": "AAAA" }, + "rcode": "NoError", + "rcode_id": 0, + "severity": "Informational", + "severity_id": 1, + "src_endpoint": + { + "instance_uid": "i-0abc234", + "ip": "5.6.7.8", + "port": "8888", + "vpc_uid": "vpc-abc123", + }, + "time": "2022-06-25 00:27:53", + "type_name": "DNS Activity: Response", + "type_uid": 400302, + "p_log_type": "OCSF.DnsActivity", + } DedupPeriodMinutes: 60 LogTypes: - AWS.VPCDns + - OCSF.DnsActivity RuleID: "AWS.DNS.Crypto.Domain" Threshold: 1 diff --git a/rules/aws_vpc_flow_rules/aws_vpc_healthy_log_status.py b/rules/aws_vpc_flow_rules/aws_vpc_healthy_log_status.py index 9ba16def7..cda033337 100644 --- a/rules/aws_vpc_flow_rules/aws_vpc_healthy_log_status.py +++ b/rules/aws_vpc_flow_rules/aws_vpc_healthy_log_status.py @@ -2,7 +2,7 @@ def rule(event): - return event.get("log-status") == "SKIPDATA" + return event.udm("log_status") == "SKIPDATA" def alert_context(event): diff --git a/rules/aws_vpc_flow_rules/aws_vpc_healthy_log_status.yml b/rules/aws_vpc_flow_rules/aws_vpc_healthy_log_status.yml index 8788007a7..7c317c29a 100644 --- a/rules/aws_vpc_flow_rules/aws_vpc_healthy_log_status.yml +++ b/rules/aws_vpc_flow_rules/aws_vpc_healthy_log_status.yml @@ -5,8 +5,10 @@ DisplayName: "AWS VPC Healthy Log Status" Enabled: true LogTypes: - AWS.VPCFlow + - OCSF.NetworkActivity Tags: - AWS + - DataModel - Security Control Severity: Low Description: > @@ -17,7 +19,13 @@ Runbook: > Tests: - Name: Healthy Log Status ExpectedResult: false - Log: { "log-status": "OK" } + Log: { "log-status": "OK", "p_log_type": "AWS.VPCFlow" } - Name: Unhealthy Log Status ExpectedResult: true - Log: { "log-status": "SKIPDATA" } + Log: { "log-status": "SKIPDATA", "p_log_type": "AWS.VPCFlow" } + - Name: Healthy Log Status - OCSF + ExpectedResult: false + Log: { "status_code": "OK", "p_log_type": "OCSF.NetworkActivity" } + - Name: Unhealthy Log Status - OCSF + ExpectedResult: true + Log: { "status_code": "SKIPDATA", "p_log_type": "OCSF.NetworkActivity" } diff --git a/rules/aws_vpc_flow_rules/aws_vpc_inbound_traffic_port_allowlist.py b/rules/aws_vpc_flow_rules/aws_vpc_inbound_traffic_port_allowlist.py index cd8c389c7..b64bad67e 100644 --- a/rules/aws_vpc_flow_rules/aws_vpc_inbound_traffic_port_allowlist.py +++ b/rules/aws_vpc_flow_rules/aws_vpc_inbound_traffic_port_allowlist.py @@ -10,23 +10,25 @@ def rule(event): # Can't perform this check without a destination port - if "dstport" not in event: + if not event.udm("destination_port"): return False # Only monitor for non allowlisted ports - if event.get("dstport") in APPROVED_PORTS: + if event.udm("destination_port") in APPROVED_PORTS: return False # Only monitor for traffic coming from non-private IP space # # Defaults to True (no alert) if 'srcaddr' key is not present - if not ip_network(event.get("srcaddr", "0.0.0.0/32")).is_global: + source_ip = event.udm("source_ip") or "0.0.0.0/32" + if not ip_network(source_ip).is_global: return False # Alert if the traffic is destined for internal IP addresses # # Defaults to False (no alert) if 'dstaddr' key is not present - return not ip_network(event.get("dstaddr", "1.0.0.0/32")).is_global + destination_ip = event.udm("destination_ip") or "1.0.0.0/32" + return not ip_network(destination_ip).is_global def alert_context(event): diff --git a/rules/aws_vpc_flow_rules/aws_vpc_inbound_traffic_port_allowlist.yml b/rules/aws_vpc_flow_rules/aws_vpc_inbound_traffic_port_allowlist.yml index 60162ceeb..b1ca67aca 100644 --- a/rules/aws_vpc_flow_rules/aws_vpc_inbound_traffic_port_allowlist.yml +++ b/rules/aws_vpc_flow_rules/aws_vpc_inbound_traffic_port_allowlist.yml @@ -5,8 +5,10 @@ DisplayName: "VPC Flow Logs Inbound Port Allowlist" Enabled: false LogTypes: - AWS.VPCFlow + - OCSF.NetworkActivity Tags: - AWS + - DataModel - Configuration Required - Security Control - Command and Control:Non-Standard Port @@ -26,10 +28,44 @@ SummaryAttributes: Tests: - Name: Public to Private IP on Restricted Port ExpectedResult: true - Log: { "dstport": 22, "dstaddr": "10.0.0.1", "srcaddr": "1.1.1.1" } + Log: + { + "dstPort": 22, + "dstAddr": "10.0.0.1", + "srcAddr": "1.1.1.1", + "p_log_type": "AWS.VPCFlow", + } - Name: Public to Private IP on Allowed Port ExpectedResult: false - Log: { "dstport": 443, "dstaddr": "10.0.0.1", "srcaddr": "1.1.1.1" } + Log: + { + "dstPort": 443, + "dstAddr": "10.0.0.1", + "srcAddr": "1.1.1.1", + "p_log_type": "AWS.VPCFlow", + } - Name: Private to Private IP on Restricted Port ExpectedResult: false - Log: { "dstport": 22, "dstaddr": "10.0.0.1", "srcaddr": "10.10.10.1" } + Log: + { + "dstPort": 22, + "dstAddr": "10.0.0.1", + "srcAddr": "10.10.10.1", + "p_log_type": "AWS.VPCFlow", + } + - Name: Public to Private IP on Restricted Port - OCSF + ExpectedResult: true + Log: + { + "dst_endpoint": { "ip": "10.0.0.1", "port": 22 }, + "src_endpoint": { "ip": "1.1.1.1" }, + "p_log_type": "OCSF.NetworkActivity", + } + - Name: Public to Private IP on Allowed Port - OCSF + ExpectedResult: false + Log: + { + "dst_endpoint": { "ip": "10.0.0.1", "port": 443 }, + "src_endpoint": { "ip": "1.1.1.1" }, + "p_log_type": "OCSF.NetworkActivity", + } diff --git a/rules/aws_vpc_flow_rules/aws_vpc_inbound_traffic_port_blocklist.py b/rules/aws_vpc_flow_rules/aws_vpc_inbound_traffic_port_blocklist.py index 533c01908..b1f331514 100644 --- a/rules/aws_vpc_flow_rules/aws_vpc_inbound_traffic_port_blocklist.py +++ b/rules/aws_vpc_flow_rules/aws_vpc_inbound_traffic_port_blocklist.py @@ -12,19 +12,21 @@ def rule(event): # Only monitor for blocklisted ports # # Defaults to True (no alert) if 'dstport' is not present - if event.get("dstport") not in CONTROLLED_PORTS: + if event.udm("destination_port") not in CONTROLLED_PORTS: return False # Only monitor for traffic coming from non-private IP space # # Defaults to True (no alert) if 'srcaddr' key is not present - if not ip_network(event.get("srcaddr", "0.0.0.0/32")).is_global: + source_ip = event.udm("source_ip") or "0.0.0.0/32" + if not ip_network(source_ip).is_global: return False # Alert if the traffic is destined for internal IP addresses # # Defaults to False(no alert) if 'dstaddr' key is not present - return not ip_network(event.get("dstaddr", "1.0.0.0/32")).is_global + destination_ip = event.udm("destination_ip") or "1.0.0.0/32" + return not ip_network(destination_ip).is_global def alert_context(event): diff --git a/rules/aws_vpc_flow_rules/aws_vpc_inbound_traffic_port_blocklist.yml b/rules/aws_vpc_flow_rules/aws_vpc_inbound_traffic_port_blocklist.yml index 57345ba8c..a2fe44ab0 100644 --- a/rules/aws_vpc_flow_rules/aws_vpc_inbound_traffic_port_blocklist.yml +++ b/rules/aws_vpc_flow_rules/aws_vpc_inbound_traffic_port_blocklist.yml @@ -5,8 +5,10 @@ DisplayName: "VPC Flow Logs Inbound Port Blocklist" Enabled: false LogTypes: - AWS.VPCFlow + - OCSF.NetworkActivity Tags: - AWS + - DataModel - Configuration Required - Security Control - Command and Control:Non-Standard Port @@ -26,10 +28,44 @@ SummaryAttributes: Tests: - Name: Public to Private IP on Restricted Port ExpectedResult: true - Log: { "dstport": 22, "dstaddr": "10.0.0.1", "srcaddr": "1.1.1.1" } + Log: + { + "dstPort": 22, + "dstAddr": "10.0.0.1", + "srcAddr": "1.1.1.1", + "p_log_type": "AWS.VPCFlow", + } - Name: Public to Private IP on Allowed Port ExpectedResult: false - Log: { "dstport": 443, "dstaddr": "10.0.0.1", "srcaddr": "1.1.1.1" } + Log: + { + "dstPort": 443, + "dstAddr": "10.0.0.1", + "srcAddr": "1.1.1.1", + "p_log_type": "AWS.VPCFlow", + } - Name: Private to Private IP on Restricted Port ExpectedResult: false - Log: { "dstport": 22, "dstaddr": "10.0.0.1", "srcaddr": "10.10.10.1" } + Log: + { + "dstPort": 22, + "dstAddr": "10.0.0.1", + "srcAddr": "10.10.10.1", + "p_log_type": "AWS.VPCFlow", + } + - Name: Public to Private IP on Restricted Port - OCSF + ExpectedResult: true + Log: + { + "dst_endpoint": { "ip": "10.0.0.1", "port": 22 }, + "src_endpoint": { "ip": "1.1.1.1" }, + "p_log_type": "OCSF.NetworkActivity", + } + - Name: Public to Private IP on Allowed Port - OCSF + ExpectedResult: false + Log: + { + "dst_endpoint": { "ip": "10.0.0.1", "port": 443 }, + "src_endpoint": { "ip": "1.1.1.1" }, + "p_log_type": "OCSF.NetworkActivity", + } diff --git a/rules/aws_vpc_flow_rules/aws_vpc_unapproved_outbound_dns.py b/rules/aws_vpc_flow_rules/aws_vpc_unapproved_outbound_dns.py index 51743aa01..d7d462be6 100644 --- a/rules/aws_vpc_flow_rules/aws_vpc_unapproved_outbound_dns.py +++ b/rules/aws_vpc_flow_rules/aws_vpc_unapproved_outbound_dns.py @@ -13,17 +13,21 @@ def rule(event): # Common DNS ports, for better security use an application layer aware network monitor # # Defaults to True (no alert) if 'dstport' key is not present - if event.get("dstport") != 53 and event.get("dstport") != 5353: + if event.udm("destination_port") != 53 and event.udm("destination_port") != 5353: return False # Only monitor traffic that is originating internally # # Defaults to True (no alert) if 'srcaddr' key is not present - if ip_network(event.get("srcaddr", "0.0.0.0/32")).is_global: + source_ip = event.udm("source_ip") or "0.0.0.0/32" + if ip_network(source_ip).is_global: return False # No clean way to default to False (no alert), so explicitly check for key - return "dstaddr" in event and event.get("dstaddr") not in APPROVED_DNS_SERVERS + return ( + bool(event.udm("destination_ip")) + and event.udm("destination_ip") not in APPROVED_DNS_SERVERS + ) def alert_context(event): diff --git a/rules/aws_vpc_flow_rules/aws_vpc_unapproved_outbound_dns.yml b/rules/aws_vpc_flow_rules/aws_vpc_unapproved_outbound_dns.yml index 652e6339a..54177c81a 100644 --- a/rules/aws_vpc_flow_rules/aws_vpc_unapproved_outbound_dns.yml +++ b/rules/aws_vpc_flow_rules/aws_vpc_unapproved_outbound_dns.yml @@ -5,8 +5,10 @@ DisplayName: "VPC Flow Logs Unapproved Outbound DNS Traffic" Enabled: false LogTypes: - AWS.VPCFlow + - OCSF.NetworkActivity Tags: - AWS + - DataModel - Configuration Required - Security Control - Command and Control:Application Layer Protocol @@ -26,10 +28,44 @@ SummaryAttributes: Tests: - Name: Approved Outbound DNS Traffic ExpectedResult: false - Log: { "dstport": 53, "dstaddr": "1.1.1.1", "srcaddr": "10.0.0.1" } + Log: + { + "dstPort": 53, + "dstAddr": "1.1.1.1", + "srcAddr": "10.0.0.1", + "p_log_type": "AWS.VPCFlow", + } - Name: Unapproved Outbound DNS Traffic ExpectedResult: true - Log: { "dstport": 53, "dstaddr": "100.100.100.100", "srcaddr": "10.0.0.1" } + Log: + { + "dstPort": 53, + "dstAddr": "100.100.100.100", + "srcAddr": "10.0.0.1", + "p_log_type": "AWS.VPCFlow", + } - Name: Outbound Non-DNS Traffic ExpectedResult: false - Log: { "dstport": 80, "dstaddr": "100.100.100.100", "srcaddr": "10.0.0.1" } + Log: + { + "dstPort": 80, + "dstAddr": "100.100.100.100", + "srcAddr": "10.0.0.1", + "p_log_type": "AWS.VPCFlow", + } + - Name: Approved Outbound DNS Traffic - OCSF + ExpectedResult: false + Log: + { + "dst_endpoint": { "ip": "1.1.1.1", "port": 53 }, + "src_endpoint": { "ip": "10.0.0.1" }, + "p_log_type": "OCSF.NetworkActivity", + } + - Name: Unapproved Outbound DNS Traffic - OCSF + ExpectedResult: true + Log: + { + "dst_endpoint": { "ip": "100.100.100.100", "port": 53 }, + "src_endpoint": { "ip": "10.0.0.1" }, + "p_log_type": "OCSF.NetworkActivity", + } From 2b80d9441bc51bb2c0ea7522485c8ebdfbc51af4 Mon Sep 17 00:00:00 2001 From: Eli Skeggs <1348991+skeggse@users.noreply.github.com> Date: Mon, 10 Jun 2024 09:38:22 -0700 Subject: [PATCH 22/35] fix: consider deny rules for ssh network acl policy (#1236) * fix: consider deny rules for ssh network acl policy * Update policies/aws_vpc_policies/aws_network_acl_restricted_ssh.py * Update policies/aws_vpc_policies/aws_network_acl_restricted_ssh.py --------- Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> --- .../aws_network_acl_restricted_ssh.py | 44 +++-- .../aws_network_acl_restricted_ssh.yml | 156 +++++++++++++++++- 2 files changed, 184 insertions(+), 16 deletions(-) diff --git a/policies/aws_vpc_policies/aws_network_acl_restricted_ssh.py b/policies/aws_vpc_policies/aws_network_acl_restricted_ssh.py index 503100504..69b40b6e4 100644 --- a/policies/aws_vpc_policies/aws_network_acl_restricted_ssh.py +++ b/policies/aws_vpc_policies/aws_network_acl_restricted_ssh.py @@ -1,19 +1,33 @@ +import ipaddress + +GLOBAL_IPV6 = ipaddress.IPv6Network("::/0") +# Choose an arbitrary sentinel value that isn't equivalent to the GLOBAL_IPV6 value. +IPV6_SENTINEL = ipaddress.IPv6Network("::1/128") + + def policy(resource): - for entry in resource["Entries"]: - # Look for ingress rules from any IP. - # This could be modified in the future to inspect the size - # of the source network with the ipaddress.ip_network.num_addresses call. + # Enumerate the entries in the network ACL, in evaluation order. + ingress_entries = sorted( + (entry for entry in resource["Entries"] if not entry["Egress"]), + key=lambda x: x["RuleNumber"], + ) + for entry in ingress_entries: + # Look for SSH ingress rules from wildcard IPs. if ( - not entry["Egress"] - and entry["CidrBlock"] == "0.0.0.0/0" - and entry["RuleAction"] == "allow" + entry.get("CidrBlock") == "0.0.0.0/0" + # Handle non-standard representations like `"0::/0"`. + or ipaddress.IPv6Network(entry.get("Ipv6CidrBlock") or IPV6_SENTINEL) == GLOBAL_IPV6 + ) and ( + not entry.get("PortRange") + or entry["PortRange"]["From"] <= 22 <= entry["PortRange"]["To"] ): - # Check within a range of ports, normally the From/To would be set to 22, - # but this covers the case where it could be 0-1024. - if ( - "PortRange" not in entry - or not entry["PortRange"] - or entry["PortRange"]["From"] <= 22 <= entry["PortRange"]["To"] - ): - return False + # If this is a deny rule, then the ACL has an explicit deny rule with a lower (more + # important) precedence than any rule that would allow SSH from arbitrary IPs. If it's + # an allow rule, then the opposite is true. Either way, this rule determines the + # entire outcome of the policy evaluation. + # + # Another way to read this: pass the policy check if the SSH rule here is a deny. + return entry["RuleAction"] == "deny" + + # Found no SSH ingress rules from wildcard IPs. return True diff --git a/policies/aws_vpc_policies/aws_network_acl_restricted_ssh.yml b/policies/aws_vpc_policies/aws_network_acl_restricted_ssh.yml index 5196cf987..44d5b286b 100644 --- a/policies/aws_vpc_policies/aws_network_acl_restricted_ssh.yml +++ b/policies/aws_vpc_policies/aws_network_acl_restricted_ssh.yml @@ -49,7 +49,7 @@ Tests: "PortRange": { "From": 22, "To": 22 }, "Protocol": "-1", "RuleAction": "allow", - "RuleNumber": 100, + "RuleNumber": 99, }, { "CidrBlock": "0.0.0.0/0", @@ -105,6 +105,44 @@ Tests: "OwnerId": "123456789012", "VpcId": "vpc-6aa60b12", } + - Name: Global IPv6 VPC SSH Access + ExpectedResult: false + Resource: + { + "AccountID": "123456789012", + "Region": "ap-southeast-2", + "ARN": "arn:aws:ec2:ap-southeast-2:123456789012:network-acl/acl-111222333", + "ID": "acl-111222333", + "Tags": {}, + "ResourceID": "arn:aws:ec2:ap-southeast-2:123456789012:network-acl/acl-111222333", + "ResourceType": "AWS.EC2.NetworkACL", + "TimeCreated": null, + "Associations": + [ + { + "NetworkAclAssociationId": "aclassoc-111222333", + "NetworkAclId": "acl-111222333", + "SubnetId": "subnet-111222333", + }, + ], + "Entries": + [ + { + "CidrBlock": null, + "Egress": false, + "IcmpTypeCode": null, + "Ipv6CidrBlock": "::/0", + "PortRange": { "From": 22, "To": 22 }, + "Protocol": "-1", + "RuleAction": "allow", + "RuleNumber": 100, + }, + ], + "IsDefault": true, + "NetworkAclId": "acl-111222333", + "OwnerId": "123456789012", + "VpcId": "vpc-6aa60b12", + } - Name: Global VPC SSH Access From Range ExpectedResult: false Resource: @@ -180,3 +218,119 @@ Tests: "OwnerId": "123456789012", "VpcId": "vpc-6aa60b12", } + - Name: Selective SSH Access + ExpectedResult: true + Resource: + { + "AccountID": "123456789012", + "Region": "ap-southeast-2", + "ARN": "arn:aws:ec2:ap-southeast-2:123456789012:network-acl/acl-111222333", + "ID": "acl-111222333", + "Tags": {}, + "ResourceID": "arn:aws:ec2:ap-southeast-2:123456789012:network-acl/acl-111222333", + "ResourceType": "AWS.EC2.NetworkACL", + "TimeCreated": null, + "Associations": + [ + { + "NetworkAclAssociationId": "aclassoc-111222333", + "NetworkAclId": "acl-111222333", + "SubnetId": "subnet-111222333", + }, + ], + "Entries": + [ + { + "CidrBlock": "0.0.0.0/0", + "Egress": false, + "IcmpTypeCode": null, + "Ipv6CidrBlock": null, + "PortRange": null, + "Protocol": "-1", + "RuleAction": "allow", + "RuleNumber": 100, + }, + { + "CidrBlock": "1.1.1.1/32", + "Egress": false, + "IcmpTypeCode": null, + "Ipv6CidrBlock": null, + "PortRange": { "From": 22, "To": 22 }, + "Protocol": "-1", + "RuleAction": "allow", + "RuleNumber": 30, + }, + { + "CidrBlock": "0.0.0.0/0", + "Egress": false, + "IcmpTypeCode": null, + "Ipv6CidrBlock": null, + "PortRange": { "From": 22, "To": 22 }, + "Protocol": "-1", + "RuleAction": "deny", + "RuleNumber": 50, + }, + ], + "IsDefault": true, + "NetworkAclId": "acl-111222333", + "OwnerId": "123456789012", + "VpcId": "vpc-6aa60b12", + } + - Name: Selective SSH Access From Port Range + ExpectedResult: true + Resource: + { + "AccountID": "123456789012", + "Region": "ap-southeast-2", + "ARN": "arn:aws:ec2:ap-southeast-2:123456789012:network-acl/acl-111222333", + "ID": "acl-111222333", + "Tags": {}, + "ResourceID": "arn:aws:ec2:ap-southeast-2:123456789012:network-acl/acl-111222333", + "ResourceType": "AWS.EC2.NetworkACL", + "TimeCreated": null, + "Associations": + [ + { + "NetworkAclAssociationId": "aclassoc-111222333", + "NetworkAclId": "acl-111222333", + "SubnetId": "subnet-111222333", + }, + ], + "Entries": + [ + { + "CidrBlock": "0.0.0.0/0", + "Egress": false, + "IcmpTypeCode": null, + "Ipv6CidrBlock": null, + "PortRange": null, + "Protocol": "-1", + "RuleAction": "allow", + "RuleNumber": 100, + }, + { + "CidrBlock": "1.1.1.1/32", + "Egress": false, + "IcmpTypeCode": null, + "Ipv6CidrBlock": null, + "PortRange": { "From": 0, "To": 1024 }, + "Protocol": "-1", + "RuleAction": "allow", + "RuleNumber": 30, + }, + { + "CidrBlock": "0.0.0.0/0", + "Egress": false, + "IcmpTypeCode": null, + "Ipv6CidrBlock": null, + "PortRange": { "From": 22, "To": 22 }, + "Protocol": "-1", + "RuleAction": "deny", + "RuleNumber": 50, + }, + ], + "IsDefault": true, + "NetworkAclId": "acl-111222333", + "OwnerId": "123456789012", + "VpcId": "vpc-6aa60b12", + } From 1772ca0b4710a1ad43b69ce62ae80547fea3b963 Mon Sep 17 00:00:00 2001 From: JPhenglavong Date: Mon, 10 Jun 2024 10:09:37 -0700 Subject: [PATCH 23/35] AWS Honeypot Detections threat-306 (#1252) * AWS Honeypot Detections threat-306 AWS Security Finding rules on decoy AWS resources: https://aws.amazon.com/blogs/security/how-to-detect-suspicious-activity-in-your-aws-account-by-using-private-decoy-resources/ * Update decoy_dynamodb_accessed.py * Update decoy_iam_assumed.py * Update decoy_s3_accessed.py * Update decoy_secret_accessed.py * Update decoy_systems_manager_parameter_accessed.py * Update decoy_dynamodb_accessed.py * Update decoy_iam_assumed.py * Update decoy_s3_accessed.py * Update decoy_secret_accessed.py * Update decoy_systems_manager_parameter_accessed.py * Update decoy_systems_manager_parameter_accessed.py * Update decoy_systems_manager_parameter_accessed.py * Update decoy_secret_accessed.py * Update decoy_s3_accessed.py * Update decoy_iam_assumed.py * Update decoy_dynamodb_accessed.py * Update decoy_systems_manager_parameter_accessed.py * reformatted and linted * removed unused methods * fixed trailing lines * add decoy rules as a pack --------- Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> --- packs/aws_decoy.yml | 11 + .../decoy_dynamodb_accessed.py | 36 +++ .../decoy_dynamodb_accessed.yml | 219 ++++++++++++++++ .../decoy_iam_assumed.py | 22 ++ .../decoy_iam_assumed.yml | 217 ++++++++++++++++ .../decoy_s3_accessed.py | 42 ++++ .../decoy_s3_accessed.yml | 237 ++++++++++++++++++ .../decoy_secret_accessed.py | 22 ++ .../decoy_secret_accessed.yml | 223 ++++++++++++++++ ...ecoy_systems_manager_parameter_accessed.py | 23 ++ ...coy_systems_manager_parameter_accessed.yml | 215 ++++++++++++++++ 11 files changed, 1267 insertions(+) create mode 100644 packs/aws_decoy.yml create mode 100644 rules/aws_securityfinding_rules/decoy_dynamodb_accessed.py create mode 100644 rules/aws_securityfinding_rules/decoy_dynamodb_accessed.yml create mode 100644 rules/aws_securityfinding_rules/decoy_iam_assumed.py create mode 100644 rules/aws_securityfinding_rules/decoy_iam_assumed.yml create mode 100644 rules/aws_securityfinding_rules/decoy_s3_accessed.py create mode 100644 rules/aws_securityfinding_rules/decoy_s3_accessed.yml create mode 100644 rules/aws_securityfinding_rules/decoy_secret_accessed.py create mode 100644 rules/aws_securityfinding_rules/decoy_secret_accessed.yml create mode 100644 rules/aws_securityfinding_rules/decoy_systems_manager_parameter_accessed.py create mode 100644 rules/aws_securityfinding_rules/decoy_systems_manager_parameter_accessed.yml diff --git a/packs/aws_decoy.yml b/packs/aws_decoy.yml new file mode 100644 index 000000000..6da4e93ae --- /dev/null +++ b/packs/aws_decoy.yml @@ -0,0 +1,11 @@ +AnalysisType: pack +PackID: PantherManaged.AWSDecoy +Description: Group of all AWS Decoy resources detections +PackDefinition: + IDs: + - Decoy.S3.Accessed + - Decoy.Systems.Manager.Parameter.Accessed + - Decoy.DynamoDB.Accessed + - Decoy.IAM.Assumed + - Decoy.Secret.Accessed +DisplayName: "Panther AWS Decoy Detections" diff --git a/rules/aws_securityfinding_rules/decoy_dynamodb_accessed.py b/rules/aws_securityfinding_rules/decoy_dynamodb_accessed.py new file mode 100644 index 000000000..67af73cc9 --- /dev/null +++ b/rules/aws_securityfinding_rules/decoy_dynamodb_accessed.py @@ -0,0 +1,36 @@ +def rule(event): + # List of suspicious API events + # NOTE: There may be more API events that's not listed + suspicious_api_events = [ + "BatchExecuteStatement", + "BatchGetItem", + "BatchWriteItem", + "DeleteItem", + "ExecuteStatement", + "ExecuteTransaction", + "GetItem", + "PutItem", + "Query", + "Scan", + "TransactGetItems", + "TransactWriteItems", + "UpdateItem", + ] + + # Return True if the API value is in the list of suspicious API events + if event["GeneratorId"] == "dynamodb.amazonaws.com": + # Extract the API value from the event + api_value = event["Action"]["AwsApiCallAction"]["Api"] + + return api_value in suspicious_api_events + return False + + +def title(event): + # (Optional) Return a string which will be shown as the alert title. + # If no 'dedup' function is defined, the return value of this method will act as dedup string. + + # NOTE: Not sure if the offending actor Id will always be in the 0th index of Resources + # It's possible to just return the Title as a whole string + secret = event["Resources"][0]["Id"] + return f"Suspicious activity detected accessing private decoy DynamoDB table {secret}" diff --git a/rules/aws_securityfinding_rules/decoy_dynamodb_accessed.yml b/rules/aws_securityfinding_rules/decoy_dynamodb_accessed.yml new file mode 100644 index 000000000..2012eaa95 --- /dev/null +++ b/rules/aws_securityfinding_rules/decoy_dynamodb_accessed.yml @@ -0,0 +1,219 @@ +AnalysisType: rule +Filename: decoy_dynamodb_accessed.py +RuleID: "Decoy.DynamoDB.Accessed" +DisplayName: "Decoy DynamoDB Accessed" +Enabled: false +LogTypes: + - AWS.SecurityFindingFormat +Severity: High +Description: Actor accessed Decoy DynamoDB +DedupPeriodMinutes: 60 +Threshold: 1 +Reference: https://aws.amazon.com/blogs/security/how-to-detect-suspicious-activity-in-your-aws-account-by-using-private-decoy-resources/ +InlineFilters: + - All: [] +Tests: + - Name: DynamoDB-Decoy-Accessed + ExpectedResult: true + Log: + Action: + ActionType: AWS_API_CALL + AwsApiCallAction: + Api: Scan + CallerType: remoteIp + DomainDetails: {} + RemoteIpDetails: + City: {} + Country: {} + GeoLocation: {} + IpAddressV4: 11.111.11.111 + Organization: {} + ServiceName: dynamodb.amazonaws.com + DnsRequestAction: {} + NetworkConnectionAction: + LocalPortDetails: {} + RemotePortDetails: {} + PortProbeAction: {} + AwsAccountId: "123456789012" + CompanyName: Custom + CreatedAt: "2024-05-24 22:53:24.000000000" + Description: Private decoy DynamoDB table arn:aws:dynamodb:us-east-1:123456789012:table/Panther-DataTable was accessed by arn:aws:iam::123456789012:user/tester. This DynamoDB table has been provisioned to monitor and generate security events when accessed and can be an indicator of unintended or unauthorized access to your AWS Account. + FindingProviderFields: + Severity: + Label: HIGH + Normalized: 70 + Types: + - Unusual Behaviors + GeneratorId: dynamodb.amazonaws.com + Id: 1abc2de3-69ea-4e15-91c6-27eb4a07bd21 + ProcessedAt: "2024-05-24T22:53:41.884Z" + ProductArn: arn:aws:securityhub:us-east-1:123456789012:product/123456789012/default + ProductFields: + Custom/DecoyDetector/apiResult: SUCCESS + Custom/DecoyDetector/requestID: ab1cd234-1986-4c45-8546-fdb1776e23b0 + Custom/DecoyDetector/userAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 + aws/securityhub/CompanyName: Personal + aws/securityhub/FindingId: arn:aws:securityhub:us-east-1:123456789012:product/123456789012/default/1abc2de3-69ea-4e15-91c6-27eb4a07bd21 + aws/securityhub/ProductName: Default + ProductName: DecoyDetector + RecordState: ACTIVE + Region: us-east-1 + Resources: + - Id: + Partition: aws + Region: us-east-1 + ResourceRole: Target + Type: AwsDynamoDbTable + - Details: + AwsIamAccessKey: + AccessKeyId: ABC9ONWNS3155VIEJC8U + AccountId: "123456789012" + PrincipalId: ABC9ONWNS3155VIEJC8U:john.doe + PrincipalType: AssumedRole + SessionContext: + Attributes: + CreationDate: "2024-05-24T22:32:38Z" + MfaAuthenticated: false + SessionIssuer: + AccountId: "123456789012" + Arn: arn:aws:iam::123456789012:user/tester + PrincipalId: tester + Type: Role + UserName: user/tester + Id: ABC9ONWNS3155VIEJC8U + Partition: aws + Region: us-east-1 + ResourceRole: Actor + Type: AwsIamAccessKey + - Id: arn:aws:iam::123456789012:user/tester + Partition: aws + Region: us-east-1 + ResourceRole: Actor + Type: AwsIamRole + SchemaVersion: "2018-10-08" + Severity: + Label: HIGH + Normalized: 70 + Title: Suspicious activity detected accessing private decoy DynamoDB table arn:aws:dynamodb:us-east-1:123456789012:table/Panther-DataTable + Types: + - Unusual Behaviors + UpdatedAt: "2024-05-24 22:53:24.000000000" + Workflow: + Status: NEW + WorkflowState: NEW + p_any_actor_ids: [] + p_any_aws_account_ids: [] + p_any_aws_arns: [] + p_any_ip_addresses: [] + p_any_trace_ids: [] + p_any_usernames: [] + p_event_time: "2024-05-24 22:53:24.000000000" + p_log_type: AWS.SecurityFindingFormat + p_parse_time: "2024-05-24 22:55:04.312964001" + p_row_id: 8e1c8ebd709fb49e9eb5a1c61ff1a303 + p_schema_version: 0 + p_source_id: e29fd64f-53d9-43ab-92ca-575a8af289e6 + p_source_label: AWS Security Hub + p_udm: {} + - Name: DynamoDB-Decoy-Not-Accessed + ExpectedResult: false + Log: + Action: + ActionType: AWS_API_CALL + AwsApiCallAction: + Api: DescribeEndpoints + CallerType: remoteIp + DomainDetails: {} + RemoteIpDetails: + City: {} + Country: {} + GeoLocation: {} + IpAddressV4: 11.111.11.111 + Organization: {} + ServiceName: dynamodb.amazonaws.com + DnsRequestAction: {} + NetworkConnectionAction: + LocalPortDetails: {} + RemotePortDetails: {} + PortProbeAction: {} + AwsAccountId: "123456789012" + CompanyName: Custom + CreatedAt: "2024-05-24 22:53:24.000000000" + Description: Private decoy DynamoDB table arn:aws:dynamodb:us-east-1:123456789012:table/Panther-DataTable was not accessed by arn:aws:iam::123456789012:user/tester. This DynamoDB table has been provisioned to monitor and generate security events when accessed and can be an indicator of unintended or unauthorized access to your AWS Account. + FindingProviderFields: + Severity: + Label: HIGH + Normalized: 70 + Types: + - Unusual Behaviors + GeneratorId: dynamodb.amazonaws.com + Id: 1abc2de3-69ea-4e15-91c6-27eb4a07bd21 + ProcessedAt: "2024-05-24T22:53:41.884Z" + ProductArn: arn:aws:securityhub:us-east-1:123456789012:product/123456789012/default + ProductFields: + Custom/DecoyDetector/apiResult: SUCCESS + Custom/DecoyDetector/requestID: ab1cd234-1986-4c45-8546-fdb1776e23b0 + Custom/DecoyDetector/userAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 + aws/securityhub/CompanyName: Personal + aws/securityhub/FindingId: arn:aws:securityhub:us-east-1:123456789012:product/123456789012/default/1abc2de3-69ea-4e15-91c6-27eb4a07bd21 + aws/securityhub/ProductName: Default + ProductName: DecoyDetector + RecordState: ACTIVE + Region: us-east-1 + Resources: + - Id: + Partition: aws + Region: us-east-1 + ResourceRole: Target + Type: AwsDynamoDbTable + - Details: + AwsIamAccessKey: + AccessKeyId: ABC9ONWNS3155VIEJC8U + AccountId: "123456789012" + PrincipalId: ABC9ONWNS3155VIEJC8U:john.doe + PrincipalType: AssumedRole + SessionContext: + Attributes: + CreationDate: "2024-05-24T22:32:38Z" + MfaAuthenticated: false + SessionIssuer: + AccountId: "123456789012" + Arn: arn:aws:iam::123456789012:user/tester + PrincipalId: tester + Type: Role + UserName: user/tester + Id: ABC9ONWNS3155VIEJC8U + Partition: aws + Region: us-east-1 + ResourceRole: Actor + Type: AwsIamAccessKey + - Id: arn:aws:iam::123456789012:user/tester + Partition: aws + Region: us-east-1 + ResourceRole: Actor + Type: AwsIamRole + SchemaVersion: "2018-10-08" + Severity: + Label: HIGH + Normalized: 70 + Title: Non-Suspicious activity detected accessing private decoy DynamoDB table arn:aws:dynamodb:us-east-1:123456789012:table/Panther-DataTable + Types: + - Unusual Behaviors + UpdatedAt: "2024-05-24 22:53:24.000000000" + Workflow: + Status: NEW + WorkflowState: NEW + p_any_actor_ids: [] + p_any_aws_account_ids: [] + p_any_aws_arns: [] + p_any_ip_addresses: [] + p_any_trace_ids: [] + p_any_usernames: [] + p_event_time: "2024-05-24 22:53:24.000000000" + p_log_type: AWS.SecurityFindingFormat + p_parse_time: "2024-05-24 22:55:04.312964001" + p_row_id: 8e1c8ebd709fb49e9eb5a1c61ff1a303 + p_schema_version: 0 + p_source_id: e29fd64f-53d9-43ab-92ca-575a8af289e6 + p_source_label: AWS Security Hub + p_udm: {} diff --git a/rules/aws_securityfinding_rules/decoy_iam_assumed.py b/rules/aws_securityfinding_rules/decoy_iam_assumed.py new file mode 100644 index 000000000..7b9c0d166 --- /dev/null +++ b/rules/aws_securityfinding_rules/decoy_iam_assumed.py @@ -0,0 +1,22 @@ +def rule(event): + # List of suspicious API events + # NOTE: There may be more API events that's not listed + suspicious_api_events = ["AssumeRole"] + + # Return True if the API value is in the list of suspicious API events + if event["GeneratorId"] == "sts.amazonaws.com": + # Extract the API value from the event + api_value = event["Action"]["AwsApiCallAction"]["Api"] + + return api_value in suspicious_api_events + return False + + +def title(event): + # (Optional) Return a string which will be shown as the alert title. + # If no 'dedup' function is defined, the return value of this method will act as dedup string. + + # NOTE: Not sure if the offending actor Id will always be in the 0th index of Resources + # It's possible to just return the Title as a whole string + secret = event["Resources"][0]["Id"] + return f"Suspicious activity detected accessing private decoy IAM role {secret}" diff --git a/rules/aws_securityfinding_rules/decoy_iam_assumed.yml b/rules/aws_securityfinding_rules/decoy_iam_assumed.yml new file mode 100644 index 000000000..45fb02923 --- /dev/null +++ b/rules/aws_securityfinding_rules/decoy_iam_assumed.yml @@ -0,0 +1,217 @@ +AnalysisType: rule +Filename: decoy_iam_assumed.py +RuleID: "Decoy.IAM.Assumed" +DisplayName: "Decoy IAM Assumed" +Enabled: false +LogTypes: + - AWS.SecurityFindingFormat +Severity: High +Description: Actor assumed decoy IAM role +DedupPeriodMinutes: 60 +Threshold: 1 +Reference: https://aws.amazon.com/blogs/security/how-to-detect-suspicious-activity-in-your-aws-account-by-using-private-decoy-resources/ +InlineFilters: + - All: [] +Tests: + - Name: IAM-Decoy-Assumed + ExpectedResult: true + Log: + Action: + ActionType: AWS_API_CALL + AwsApiCallAction: + Api: AssumeRole + CallerType: remoteIp + DomainDetails: {} + RemoteIpDetails: + City: {} + Country: {} + GeoLocation: {} + IpAddressV4: 11.1.111.11 + Organization: {} + ServiceName: sts.amazonaws.com + DnsRequestAction: {} + NetworkConnectionAction: + LocalPortDetails: {} + RemotePortDetails: {} + PortProbeAction: {} + AwsAccountId: "123456789012" + CompanyName: Custom + CreatedAt: "2024-05-24 13:17:15.000000000" + Description: Private decoy IAM role arn:aws:iam::123456789012:role/Dummy-Test-InfoRole-ab21cde50f was accessed by arn:aws:iam::123456789012:user/tester. This IAM role has been provisioned to monitor and generate security events when accessed and can be an indicator of unintended or unauthorized access to your AWS Account. + FindingProviderFields: + Severity: + Label: HIGH + Normalized: 70 + Types: + - Unusual Behaviors + GeneratorId: sts.amazonaws.com + Id: 1abc2de3-69ea-4e15-91c6-27eb4a07bd21 + ProcessedAt: "2024-05-24T13:17:21.469Z" + ProductArn: arn:aws:securityhub:us-east-1:123456789012:product/123456789012/default + ProductFields: + Custom/DecoyDetector/apiResult: SUCCESS + Custom/DecoyDetector/requestID: ab1cd123-1986-4c45-8546-fdb1776e23b0 + Custom/DecoyDetector/userAgent: AWS Signin, aws-internal/3 aws-sdk-java/1.12.720 Linux/5.10.215-181.850.amzn2int.x86_64 OpenJDK_64-Bit_Server_VM/17.0.11+10-LTS java/17.0.11 kotlin/1.3.72 vendor/Amazon.com_Inc. cfg/retry-mode/standard cfg/auth-source#unknown + aws/securityhub/CompanyName: Personal + aws/securityhub/FindingId: arn:aws:service:region:123456789012:resource/12345ab9-436d-4d59-ac58-ed6b3127e440 + aws/securityhub/ProductName: Default + ProductName: DecoyDetector + RecordState: ACTIVE + Region: us-east-1 + Resources: + - Id: arn:aws:iam::123456789012:role/Dummy-Test-InfoRole-ab21cde50f + Partition: aws + Region: us-east-1 + ResourceRole: Target + Type: AwsIamRole + - Details: + AwsIamAccessKey: + AccessKeyId: ABC9ONWNS3155VIEJC8U + AccountId: "123456789012" + PrincipalId: ABCDEFGH0TOGJSGNQKI0:john.doe + PrincipalType: AssumedRole + SessionContext: + Attributes: + CreationDate: "2024-05-24T22:32:38Z" + MfaAuthenticated: false + SessionIssuer: + AccountId: "123456789012" + Arn: arn:aws:iam::123456789012:user/tester + PrincipalId: ABCDEFGH0TOGJSGNQKI0 + Type: Role + UserName: user_ab21cde50f + Id: ABC9ONWNS3155VIEJC8U + Partition: aws + Region: us-east-1 + ResourceRole: Actor + Type: AwsIamAccessKey + - Id: arn:aws:iam::123456789012:user/tester + Partition: aws + Region: us-east-1 + ResourceRole: Actor + Type: AwsIamRole + SchemaVersion: "2018-10-08" + Severity: + Label: HIGH + Normalized: 70 + Title: Suspicious activity detected accessing private decoy IAM role arn:aws:iam::123456789012:role/Dummy-Test-InfoRole-ab21cde50f + Types: + - Unusual Behaviors + UpdatedAt: "2024-05-24 13:17:15.000000000" + Workflow: + Status: NEW + WorkflowState: NEW + p_any_actor_ids: [] + p_any_aws_account_ids: [] + p_any_aws_arns: [] + p_any_trace_ids: [] + p_any_usernames: [] + p_event_time: "2024-05-24 22:34:07.000000000" + p_log_type: AWS.SecurityFindingFormat + p_parse_time: "2024-05-24 22:35:04.272574202" + p_row_id: zjj8nmnw9f90uulxfa3bmen8rv5stlcx + p_schema_version: 0 + p_source_id: bb4e16c5-43dd-450c-9227-39f0d152659c + p_source_label: AWS Security Hub + p_udm: {} + - Name: IAM-Decoy-Not-Assumed + ExpectedResult: false + Log: + Action: + ActionType: AWS_API_CALL + AwsApiCallAction: + Api: ListRoles + CallerType: remoteIp + DomainDetails: {} + RemoteIpDetails: + City: {} + Country: {} + GeoLocation: {} + IpAddressV4: 99.6.134.57 + Organization: {} + ServiceName: sts.amazonaws.com + DnsRequestAction: {} + NetworkConnectionAction: + LocalPortDetails: {} + RemotePortDetails: {} + PortProbeAction: {} + AwsAccountId: "123456789012" + CompanyName: Custom + CreatedAt: "2024-05-24 13:17:15.000000000" + Description: Private decoy IAM role arn:aws:iam::123456789012:role/Dummy-Test-InfoRole-ab21cde50f was not accessed by arn:aws:iam::123456789012:user/tester. This IAM role has been provisioned to monitor and generate security events when accessed and can be an indicator of unintended or unauthorized access to your AWS Account. + FindingProviderFields: + Severity: + Label: HIGH + Normalized: 70 + Types: + - Unusual Behaviors + GeneratorId: sts.amazonaws.com + Id: 1abc2de3-69ea-4e15-91c6-27eb4a07bd21 + ProcessedAt: "2024-05-24T13:17:21.469Z" + ProductArn: arn:aws:securityhub:us-east-1:123456789012:product/123456789012/default + ProductFields: + Custom/DecoyDetector/apiResult: SUCCESS + Custom/DecoyDetector/requestID: ab1cd123-1986-4c45-8546-fdb1776e23b0 + Custom/DecoyDetector/userAgent: AWS Signin, aws-internal/3 aws-sdk-java/1.12.720 Linux/5.10.215-181.850.amzn2int.x86_64 OpenJDK_64-Bit_Server_VM/17.0.11+10-LTS java/17.0.11 kotlin/1.3.72 vendor/Amazon.com_Inc. cfg/retry-mode/standard cfg/auth-source#unknown + aws/securityhub/CompanyName: Personal + aws/securityhub/FindingId: arn:aws:service:region:123456789012:resource/12345ab9-436d-4d59-ac58-ed6b3127e440 + aws/securityhub/ProductName: Default + ProductName: DecoyDetector + RecordState: ACTIVE + Region: us-east-1 + Resources: + - Id: arn:aws:iam::123456789012:role/Dummy-Test-InfoRole-ab21cde50f + Partition: aws + Region: us-east-1 + ResourceRole: Target + Type: AwsIamRole + - Details: + AwsIamAccessKey: + AccessKeyId: ABC9ONWNS3155VIEJC8U + AccountId: "123456789012" + PrincipalId: ABCDEFGH0TOGJSGNQKI0:john.doe + PrincipalType: AssumedRole + SessionContext: + Attributes: + CreationDate: "2024-05-24T22:32:38Z" + MfaAuthenticated: false + SessionIssuer: + AccountId: "123456789012" + Arn: arn:aws:iam::123456789012:user/tester + PrincipalId: ABCDEFGH0TOGJSGNQKI0 + Type: Role + UserName: user_ab21cde50f + Id: ABC9ONWNS3155VIEJC8U + Partition: aws + Region: us-east-1 + ResourceRole: Actor + Type: AwsIamAccessKey + - Id: arn:aws:iam::123456789012:user/tester + Partition: aws + Region: us-east-1 + ResourceRole: Actor + Type: AwsIamRole + SchemaVersion: "2018-10-08" + Severity: + Label: HIGH + Normalized: 70 + Title: Non-Suspicious activity detected accessing private decoy IAM role arn:aws:iam::123456789012:role/Dummy-Test-InfoRole-ab21cde50f + Types: + - Unusual Behaviors + UpdatedAt: "2024-05-24 13:17:15.000000000" + Workflow: + Status: NEW + WorkflowState: NEW + p_any_actor_ids: [] + p_any_aws_account_ids: [] + p_any_aws_arns: [] + p_any_trace_ids: [] + p_any_usernames: [] + p_event_time: "2024-05-24 22:34:07.000000000" + p_log_type: AWS.SecurityFindingFormat + p_parse_time: "2024-05-24 22:35:04.272574202" + p_row_id: zjj8nmnw9f90uulxfa3bmen8rv5stlcx + p_schema_version: 0 + p_source_id: bb4e16c5-43dd-450c-9227-39f0d152659c + p_source_label: AWS Security Hub + p_udm: {} diff --git a/rules/aws_securityfinding_rules/decoy_s3_accessed.py b/rules/aws_securityfinding_rules/decoy_s3_accessed.py new file mode 100644 index 000000000..79fbd036b --- /dev/null +++ b/rules/aws_securityfinding_rules/decoy_s3_accessed.py @@ -0,0 +1,42 @@ +def rule(event): + # List of suspicious API events + # NOTE: There may be more API events that's not listed + suspicious_api_events = [ + "HeadObject", + "GetObject", + "GetObjectAcl", + "GetObjectAttributes", + "GetObjectLegalHold", + "GetObjectLockConfiguration", + "GetObjectRetention", + "GetObjectTagging", + "GetObjectTorrent", + "PutObject", + "PutObjectAcl", + "PutObjectLegalHold", + "PutObjectLockConfiguration", + "PutObjectRetention", + "PutObjectTagging", + "SelectObjectContent", + "DeleteObject", + "DeleteObjects", + "DeleteObjectTagging", + ] + + # Return True if the API value is in the list of suspicious API events + if event["GeneratorId"] == "s3.amazonaws.com": + # Extract the API value from the event + api_value = event["Action"]["AwsApiCallAction"]["Api"] + + return api_value in suspicious_api_events + return False + + +def title(event): + # (Optional) Return a string which will be shown as the alert title. + # If no 'dedup' function is defined, the return value of this method will act as dedup string. + + # NOTE: Not sure if the offending actor Id will always be in the 0th index of Resources + # It's possible to just return the Title as a whole string + secret = event["Resources"][0]["Id"] + return f"Suspicious activity detected accessing private decoy S3 bucket {secret}" diff --git a/rules/aws_securityfinding_rules/decoy_s3_accessed.yml b/rules/aws_securityfinding_rules/decoy_s3_accessed.yml new file mode 100644 index 000000000..f4795645c --- /dev/null +++ b/rules/aws_securityfinding_rules/decoy_s3_accessed.yml @@ -0,0 +1,237 @@ +AnalysisType: rule +Filename: decoy_s3_accessed.py +RuleID: "Decoy.S3.Accessed" +DisplayName: "Decoy S3 Accessed" +Enabled: false +LogTypes: + - AWS.SecurityFindingFormat +Severity: High +Description: Actor accessed S3 Manager decoy secret +DedupPeriodMinutes: 60 +Threshold: 1 +Reference: https://aws.amazon.com/blogs/security/how-to-detect-suspicious-activity-in-your-aws-account-by-using-private-decoy-resources/ +InlineFilters: + - All: [] +Tests: + - Name: S3-Decoy-Accessed + ExpectedResult: true + Log: + Action: + ActionType: AWS_API_CALL + AwsApiCallAction: + Api: GetObject + CallerType: remoteIp + DomainDetails: {} + RemoteIpDetails: + City: {} + Country: {} + GeoLocation: {} + IpAddressV4: 111.111.111.111 + Organization: {} + ServiceName: s3.amazonaws.com + DnsRequestAction: {} + NetworkConnectionAction: + LocalPortDetails: {} + RemotePortDetails: {} + PortProbeAction: {} + AwsAccountId: "123456789012" + CompanyName: Custom + CreatedAt: "2024-05-24 00:26:57.000000000" + Description: Private decoy S3 bucket panther-databucket was accessed by arn:aws:iam::123456789012:user/tester. This S3 bucket has been provisioned to monitor and generate security events when accessed and can be an indicator of unintended or unauthorized access to your AWS Account. + FindingProviderFields: + Severity: + Label: HIGH + Normalized: 70 + Types: + - Unusual Behaviors + GeneratorId: s3.amazonaws.com + Id: ABC9ONWNS3155VIEJC8U + ProcessedAt: "2024-05-24T00:27:12.237Z" + ProductArn: arn:aws:securityhub:us-east-1:123456789012:product/123456789012/default + ProductFields: + Custom/DecoyDetector/apiResult: SUCCESS + Custom/DecoyDetector/requestID: ab1cd234-1986-4c45-8546-fdb1776e23b0 + Custom/DecoyDetector/userAgent: '[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36]' + aws/securityhub/CompanyName: Personal + aws/securityhub/FindingId: arn:aws:service:region:123456789012:resource/12345ab6-436d-4d59-ac58-ed6b3127e440 + aws/securityhub/ProductName: Default + ProductName: DecoyDetector + RecordState: ACTIVE + Region: us-east-1 + Resources: + - Id: arn:aws:s3:::panther-databucket + Partition: aws + Region: us-east-1 + ResourceRole: Target + Tags: + aws:cloudformation:logical-id: DataBucket + aws:cloudformation:stack-id: arn:aws:cloudformation:us-east-1:123456789012:stack/Panther/a1b2c345-12f6-11ef-8c74-12deb08d9ef1 + aws:cloudformation:stack-name: Panther + Type: AwsS3Bucket + - Id: arn:aws:s3:::panther-databucket/object + Partition: aws + Region: us-east-1 + ResourceRole: Target + Type: AwsS3Object + - Details: + AwsIamAccessKey: + AccessKeyId: ABCDEFG1HIJ2KLMNOPQR + AccountId: "123456789012" + PrincipalId: ABCDEFG1HIJ2KLMNOPQR:john.doe + PrincipalType: AssumedRole + SessionContext: + Attributes: + CreationDate: "2024-05-23T20:20:57Z" + MfaAuthenticated: false + SessionIssuer: + AccountId: "123456789012" + Arn: arn:aws:iam::123456789012:role/tester + PrincipalId: ABCDEFG1HIJ2KLMNOPQR + Type: Role + UserName: tester + Id: ABCDEFG1HIJ2KLMNOPQR + Partition: aws + Region: us-east-1 + ResourceRole: Actor + Type: AwsIamAccessKey + - Id: ABCDEFG1HIJ2KLMNOPQR + Partition: aws + Region: us-east-1 + ResourceRole: Actor + Type: AwsIamRole + SchemaVersion: "2018-10-08" + Severity: + Label: HIGH + Normalized: 70 + Title: Suspicious activity detected accessing private decoy S3 bucket panther-databucket + Types: + - Unusual Behaviors + UpdatedAt: "2024-05-24 00:26:57.000000000" + Workflow: + Status: NEW + WorkflowState: NEW + p_any_actor_ids: [] + p_any_aws_account_ids: [] + p_any_aws_arns: [] + p_any_ip_addresses: [] + p_any_trace_ids: [] + p_any_usernames: [] + p_event_time: "2024-05-24 00:26:57.000000000" + p_log_type: AWS.SecurityFindingFormat + p_parse_time: "2024-05-24 00:30:04.569556803" + p_row_id: 624c79c882affe88a1dce9c31fb68f0e + p_schema_version: 0 + p_source_id: e29fd64f-53d9-43ab-92ca-575a8af289e6 + p_source_label: AWS Security Hub + p_udm: {} + - Name: S3-Decoy-Not-Accessed + ExpectedResult: false + Log: + Action: + ActionType: AWS_API_CALL + AwsApiCallAction: + Api: ListBuckets + CallerType: remoteIp + DomainDetails: {} + RemoteIpDetails: + City: {} + Country: {} + GeoLocation: {} + IpAddressV4: 111.111.111.111 + Organization: {} + ServiceName: s3.amazonaws.com + DnsRequestAction: {} + NetworkConnectionAction: + LocalPortDetails: {} + RemotePortDetails: {} + PortProbeAction: {} + AwsAccountId: "123456789012" + CompanyName: Custom + CreatedAt: "2024-05-24 00:26:57.000000000" + Description: Private decoy S3 bucket panther-databucket was not accessed by arn:aws:iam::123456789012:user/tester. This S3 bucket has been provisioned to monitor and generate security events when accessed and can be an indicator of unintended or unauthorized access to your AWS Account. + FindingProviderFields: + Severity: + Label: HIGH + Normalized: 70 + Types: + - Unusual Behaviors + GeneratorId: s3.amazonaws.com + Id: ABC9ONWNS3155VIEJC8U + ProcessedAt: "2024-05-24T00:27:12.237Z" + ProductArn: arn:aws:securityhub:us-east-1:123456789012:product/123456789012/default + ProductFields: + Custom/DecoyDetector/apiResult: SUCCESS + Custom/DecoyDetector/requestID: ab1cd234-1986-4c45-8546-fdb1776e23b0 + Custom/DecoyDetector/userAgent: '[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36]' + aws/securityhub/CompanyName: Personal + aws/securityhub/FindingId: arn:aws:service:region:123456789012:resource/12345ab6-436d-4d59-ac58-ed6b3127e440 + aws/securityhub/ProductName: Default + ProductName: DecoyDetector + RecordState: ACTIVE + Region: us-east-1 + Resources: + - Id: arn:aws:s3:::panther-databucket + Partition: aws + Region: us-east-1 + ResourceRole: Target + Tags: + aws:cloudformation:logical-id: DataBucket + aws:cloudformation:stack-id: arn:aws:cloudformation:us-east-1:123456789012:stack/Panther/a1b2c345-12f6-11ef-8c74-12deb08d9ef1 + aws:cloudformation:stack-name: Panther + Type: AwsS3Bucket + - Id: arn:aws:s3:::panther-databucket/object + Partition: aws + Region: us-east-1 + ResourceRole: Target + Type: AwsS3Object + - Details: + AwsIamAccessKey: + AccessKeyId: ABCDEFG1HIJ2KLMNOPQR + AccountId: "123456789012" + PrincipalId: ABCDEFG1HIJ2KLMNOPQR:john.doe + PrincipalType: AssumedRole + SessionContext: + Attributes: + CreationDate: "2024-05-23T20:20:57Z" + MfaAuthenticated: false + SessionIssuer: + AccountId: "123456789012" + Arn: arn:aws:iam::123456789012:role/tester + PrincipalId: ABCDEFG1HIJ2KLMNOPQR + Type: Role + UserName: tester + Id: ABCDEFG1HIJ2KLMNOPQR + Partition: aws + Region: us-east-1 + ResourceRole: Actor + Type: AwsIamAccessKey + - Id: ABCDEFG1HIJ2KLMNOPQR + Partition: aws + Region: us-east-1 + ResourceRole: Actor + Type: AwsIamRole + SchemaVersion: "2018-10-08" + Severity: + Label: HIGH + Normalized: 70 + Title: Non-Suspicious activity detected accessing private decoy S3 bucket panther-databucket + Types: + - Unusual Behaviors + UpdatedAt: "2024-05-24 00:26:57.000000000" + Workflow: + Status: NEW + WorkflowState: NEW + p_any_actor_ids: [] + p_any_aws_account_ids: [] + p_any_aws_arns: [] + p_any_ip_addresses: [] + p_any_trace_ids: [] + p_any_usernames: [] + p_event_time: "2024-05-24 00:26:57.000000000" + p_log_type: AWS.SecurityFindingFormat + p_parse_time: "2024-05-24 00:30:04.569556803" + p_row_id: 624c79c882affe88a1dce9c31fb68f0e + p_schema_version: 0 + p_source_id: e29fd64f-53d9-43ab-92ca-575a8af289e6 + p_source_label: AWS Security Hub + p_udm: {} diff --git a/rules/aws_securityfinding_rules/decoy_secret_accessed.py b/rules/aws_securityfinding_rules/decoy_secret_accessed.py new file mode 100644 index 000000000..e55946c45 --- /dev/null +++ b/rules/aws_securityfinding_rules/decoy_secret_accessed.py @@ -0,0 +1,22 @@ +def rule(event): + # List of suspicious API events + # NOTE: There may be more API events that's not listed + suspicious_api_events = ["Decrypt", "Encrypt", "GenerateDataKey"] + + # Return True if the API value is in the list of suspicious API events + if event["GeneratorId"] == "secretsmanager.amazonaws.com": + # Extract the API value from the event + api_value = event["Action"]["AwsApiCallAction"]["Api"] + + return api_value in suspicious_api_events + return False + + +def title(event): + # (Optional) Return a string which will be shown as the alert title. + # If no 'dedup' function is defined, the return value of this method will act as dedup string. + + # NOTE: Not sure if the offending actor Id will always be in the 0th index of Resources + # It's possible to just return the Title as a whole string + secret = event["Resources"][0]["Id"] + return f"Suspicious activity detected accessing private decoy secret {secret}" diff --git a/rules/aws_securityfinding_rules/decoy_secret_accessed.yml b/rules/aws_securityfinding_rules/decoy_secret_accessed.yml new file mode 100644 index 000000000..0410c2266 --- /dev/null +++ b/rules/aws_securityfinding_rules/decoy_secret_accessed.yml @@ -0,0 +1,223 @@ +AnalysisType: rule +Filename: decoy_secret_accessed.py +RuleID: "Decoy.Secret.Accessed" +DisplayName: "Decoy Secret Accessed" +Enabled: false +LogTypes: + - AWS.SecurityFindingFormat +Severity: High +Description: Actor accessed Secrets Manager decoy secret +DedupPeriodMinutes: 60 +Threshold: 1 +Reference: https://aws.amazon.com/blogs/security/how-to-detect-suspicious-activity-in-your-aws-account-by-using-private-decoy-resources/ +InlineFilters: + - All: [] +Tests: + - Name: Secret-Decoy-Accessed + ExpectedResult: true + Log: + Action: + ActionType: AWS_API_CALL + AwsApiCallAction: + Api: Decrypt + CallerType: remoteIp + DomainDetails: {} + ServiceName: kms.amazonaws.com + DnsRequestAction: {} + NetworkConnectionAction: + LocalPortDetails: {} + RemotePortDetails: {} + PortProbeAction: {} + AwsAccountId: "123456789012" + CompanyName: Custom + CreatedAt: "2024-05-23 20:49:02.000000000" + Description: Private decoy secret arn:aws:secretsmanager:us-east-1:123456789012:secret:Dummy-Secret-ab12cde34f was accessed by arn:aws:iam::123456789012:user/tester. This secret has been provisioned to monitor and generate security events when accessed and can be an indicator of unintended or unauthorized access to your AWS Account. + FindingProviderFields: + Severity: + Label: HIGH + Normalized: 70 + Types: + - Unusual Behaviors + GeneratorId: secretsmanager.amazonaws.com + Id: 1abc2de3-69ea-4e15-91c6-27eb4a07bd21 + ProcessedAt: "2024-05-23T20:49:08.396Z" + ProductArn: arn:aws:securityhub:us-east-1:123456789012:product/123456789012/default + ProductFields: + Custom/DecoyDetector/apiResult: SUCCESS + Custom/DecoyDetector/requestID: ab1cd234-1986-4c45-8546-fdb1776e23b0 + Custom/DecoyDetector/userAgent: secretsmanager.amazonaws.com + aws/securityhub/CompanyName: Personal + aws/securityhub/FindingId: arn:aws:securityhub:us-east-1:123456789012:product/123456789012/default/1abc2de3-69ea-4e15-91c6-27eb4a07bd21 + aws/securityhub/ProductName: Default + ProductName: DecoyDetector + RecordState: ACTIVE + Region: us-east-1 + Resources: + - Id: arn:aws:secretsmanager:us-east-1:123456789012:secret:Dummy-Secret-ab12cde34f + Partition: aws + Region: us-east-1 + ResourceRole: Target + Tags: + aws:cloudformation:logical-id: DummySecret + aws:cloudformation:stack-id: arn:aws:cloudformation:us-east-1:123456789012:stack/Panther/ab1cd123-1986-4c45-8546-fdb1776e23b0 + aws:cloudformation:stack-name: Panther + Type: AwsSecretsManagerSecret + - Id: arn:aws:kms:us-east-1:123456789012:key/1abc2de3-69ea-4e15-91c6-27eb4a07bd21 + Partition: aws + Region: us-east-1 + ResourceRole: Target + Type: AwsKmsKey + - Details: + AwsIamAccessKey: + AccessKeyId: ABC12DEFSG3455VIEJC8U + AccountId: "123456789012" + PrincipalId: ABC12DEFSG3455VIEJC8U:john.doe + PrincipalType: AssumedRole + SessionContext: + Attributes: + CreationDate: "2024-05-23T20:20:57Z" + MfaAuthenticated: false + SessionIssuer: + AccountId: "123456789012" + Arn: arn:aws:iam::123456789012:user/tester + PrincipalId: ABC12DEFSG3455VIEJC8U + Type: Role + UserName: tester + Id: ABC12DEFSG3455VIEJC8U + Partition: aws + Region: us-east-1 + ResourceRole: Actor + Type: AwsIamAccessKey + - Id: arn:aws:iam::123456789012:user/tester + Partition: aws + Region: us-east-1 + ResourceRole: Actor + Type: AwsIamRole + SchemaVersion: "2018-10-08" + Severity: + Label: HIGH + Normalized: 70 + Title: Suspicious activity detected accessing private decoy secret arn:aws:secretsmanager:us-east-1:123456789012:secret:Dummy-Secret-ab12cde34f + Types: + - Unusual Behaviors + UpdatedAt: "2024-05-23 20:49:02.000000000" + Workflow: + Status: NEW + WorkflowState: NEW + p_any_actor_ids: [] + p_any_aws_account_ids: [] + p_any_aws_arns: [] + p_any_trace_ids: [] + p_any_usernames: [] + p_event_time: "2024-05-23 20:49:02.000000000" + p_log_type: AWS.SecurityFindingFormat + p_parse_time: "2024-05-23 20:55:04.316376687" + p_row_id: d2b6e541507bace8c6c2b6c31fcedc10 + p_schema_version: 0 + p_source_id: e29fd64f-53d9-43ab-92ca-575a8af289e6 + p_source_label: AWS Security Hub test events + p_udm: {} + - Name: Secret-Decoy-Listed-Not-Accessed + ExpectedResult: false + Log: + Action: + ActionType: AWS_API_CALL + AwsApiCallAction: + Api: ListKeys + CallerType: remoteIp + DomainDetails: {} + ServiceName: kms.amazonaws.com + DnsRequestAction: {} + NetworkConnectionAction: + LocalPortDetails: {} + RemotePortDetails: {} + PortProbeAction: {} + AwsAccountId: "123456789012" + CompanyName: Custom + CreatedAt: "2024-05-23 20:49:02.000000000" + Description: Private decoy secret arn:aws:secretsmanager:us-east-1:123456789012:secret:Dummy-Secret-ab12cde34f was not accessed by arn:aws:iam::123456789012:user/tester. This secret has been provisioned to monitor and generate security events when accessed and can be an indicator of unintended or unauthorized access to your AWS Account. + FindingProviderFields: + Severity: + Label: HIGH + Normalized: 70 + Types: + - Unusual Behaviors + GeneratorId: secretsmanager.amazonaws.com + Id: 1abc2de3-69ea-4e15-91c6-27eb4a07bd21 + ProcessedAt: "2024-05-23T20:49:08.396Z" + ProductArn: arn:aws:securityhub:us-east-1:123456789012:product/123456789012/default + ProductFields: + Custom/DecoyDetector/apiResult: SUCCESS + Custom/DecoyDetector/requestID: ab1cd234-1986-4c45-8546-fdb1776e23b0 + Custom/DecoyDetector/userAgent: secretsmanager.amazonaws.com + aws/securityhub/CompanyName: Personal + aws/securityhub/FindingId: arn:aws:securityhub:us-east-1:123456789012:product/123456789012/default/1abc2de3-69ea-4e15-91c6-27eb4a07bd21 + aws/securityhub/ProductName: Default + ProductName: DecoyDetector + RecordState: ACTIVE + Region: us-east-1 + Resources: + - Id: arn:aws:secretsmanager:us-east-1:123456789012:secret:Dummy-Secret-ab12cde34f + Partition: aws + Region: us-east-1 + ResourceRole: Target + Tags: + aws:cloudformation:logical-id: DummySecret + aws:cloudformation:stack-id: arn:aws:cloudformation:us-east-1:123456789012:stack/Panther/ab1cd123-1986-4c45-8546-fdb1776e23b0 + aws:cloudformation:stack-name: Panther + Type: AwsSecretsManagerSecret + - Id: arn:aws:kms:us-east-1:123456789012:key/1abc2de3-69ea-4e15-91c6-27eb4a07bd21 + Partition: aws + Region: us-east-1 + ResourceRole: Target + Type: AwsKmsKey + - Details: + AwsIamAccessKey: + AccessKeyId: ABC12DEFSG3455VIEJC8U + AccountId: "123456789012" + PrincipalId: ABC12DEFSG3455VIEJC8U:john.doe + PrincipalType: AssumedRole + SessionContext: + Attributes: + CreationDate: "2024-05-23T20:20:57Z" + MfaAuthenticated: false + SessionIssuer: + AccountId: "123456789012" + Arn: arn:aws:iam::123456789012:user/tester + PrincipalId: ABC12DEFSG3455VIEJC8U + Type: Role + UserName: tester + Id: ABC12DEFSG3455VIEJC8U + Partition: aws + Region: us-east-1 + ResourceRole: Actor + Type: AwsIamAccessKey + - Id: arn:aws:iam::123456789012:user/tester + Partition: aws + Region: us-east-1 + ResourceRole: Actor + Type: AwsIamRole + SchemaVersion: "2018-10-08" + Severity: + Label: HIGH + Normalized: 70 + Title: Non-Suspicious activity detected accessing private decoy secret arn:aws:secretsmanager:us-east-1:123456789012:secret:Dummy-Secret-ab12cde34f + Types: + - Unusual Behaviors + UpdatedAt: "2024-05-23 20:49:02.000000000" + Workflow: + Status: NEW + WorkflowState: NEW + p_any_actor_ids: [] + p_any_aws_account_ids: [] + p_any_aws_arns: [] + p_any_trace_ids: [] + p_any_usernames: [] + p_event_time: "2024-05-23 20:49:02.000000000" + p_log_type: AWS.SecurityFindingFormat + p_parse_time: "2024-05-23 20:55:04.316376687" + p_row_id: d2b6e541507bace8c6c2b6c31fcedc10 + p_schema_version: 0 + p_source_id: e29fd64f-53d9-43ab-92ca-575a8af289e6 + p_source_label: AWS Security Hub test events + p_udm: {} diff --git a/rules/aws_securityfinding_rules/decoy_systems_manager_parameter_accessed.py b/rules/aws_securityfinding_rules/decoy_systems_manager_parameter_accessed.py new file mode 100644 index 000000000..33627080d --- /dev/null +++ b/rules/aws_securityfinding_rules/decoy_systems_manager_parameter_accessed.py @@ -0,0 +1,23 @@ +def rule(event): + # List of suspicious API events + # NOTE: There may be more API events that's not listed + suspicious_api_events = ["Decrypt"] + + # Return True if the API value is in the list of suspicious API events + if event["GeneratorId"] == "ssm.amazonaws.com": + # Extract the API value from the event + api_value = event["Action"]["AwsApiCallAction"]["Api"] + + return api_value in suspicious_api_events + return False + + +def title(event): + # (Optional) Return a string which will be shown as the alert title. + # If no 'dedup' function is defined, the return value of this method will act as dedup string. + + # NOTE: Not sure if the offending actor Id will always be in the 0th index of Resources + # It's possible to just return the Title as a whole string + secret = event["Resources"][0]["Id"] + return f"Suspicious activity detected accessing \ + private decoy Systems Manager parameter {secret}" diff --git a/rules/aws_securityfinding_rules/decoy_systems_manager_parameter_accessed.yml b/rules/aws_securityfinding_rules/decoy_systems_manager_parameter_accessed.yml new file mode 100644 index 000000000..84a09233e --- /dev/null +++ b/rules/aws_securityfinding_rules/decoy_systems_manager_parameter_accessed.yml @@ -0,0 +1,215 @@ +AnalysisType: rule +Filename: decoy_systems_manager_parameter_accessed.py +RuleID: "Decoy.Systems.Manager.Parameter.Accessed" +DisplayName: "Decoy Systems Manager Parameter Accessed" +Enabled: false +LogTypes: + - AWS.SecurityFindingFormat +Severity: High +Description: Actor accessed Decoy Systems Manager parameter +DedupPeriodMinutes: 60 +Threshold: 1 +Reference: https://aws.amazon.com/blogs/security/how-to-detect-suspicious-activity-in-your-aws-account-by-using-private-decoy-resources/ +InlineFilters: + - All: [] +Tests: + - Name: Systems-Manager-Parameter-Decoy-Accessed + ExpectedResult: true + Log: + Action: + ActionType: AWS_API_CALL + AwsApiCallAction: + Api: Decrypt + CallerType: remoteIp + DomainDetails: {} + ServiceName: kms.amazonaws.com + DnsRequestAction: {} + NetworkConnectionAction: + LocalPortDetails: {} + RemotePortDetails: {} + PortProbeAction: {} + AwsAccountId: "123456789012" + CompanyName: Custom + CreatedAt: "2024-05-24 22:34:07.000000000" + Description: Private decoy Systems Manager parameter arn:aws:ssm:us-east-1:123456789012:parameter/info-parameter was accessed by arn:aws:iam::123456789012:user/tester. This Systems Manager parameter has been provisioned to monitor and generate security events when accessed and can be an indicator of unintended or unauthorized access to your AWS Account. + FindingProviderFields: + Severity: + Label: HIGH + Normalized: 70 + Types: + - Unusual Behaviors + GeneratorId: ssm.amazonaws.com + Id: 6abc0de0-69ea-4e15-91c6-27eb4a07bd21 + ProcessedAt: "2024-05-24T22:34:15.644Z" + ProductArn: arn:aws:securityhub:us-east-1:123456789012:product/123456789012/default + ProductFields: + Custom/DecoyDetector/apiResult: SUCCESS + Custom/DecoyDetector/requestID: ab8cd646-1986-4c45-8546-fdb1776e23b0 + Custom/DecoyDetector/userAgent: AWS Internal + aws/securityhub/CompanyName: Personal + aws/securityhub/FindingId: arn:aws:service:region:123456789012:resource/12345ab6-436d-4d59-ac58-ed6b3127e440 + aws/securityhub/ProductName: Default + ProductName: DecoyDetector + RecordState: ACTIVE + Region: us-east-1 + Resources: + - Id: arn:aws:ssm:us-east-1:123456789012:parameter/info-parameter + Partition: aws + Region: us-east-1 + ResourceRole: Target + Type: Other + - Id: arn:aws:kms:us-east-1:123456789012:key/007ab31c-bf66-2264-a916-49f6d2ebd1db + Partition: aws + Region: us-east-1 + ResourceRole: Target + Type: AwsKmsKey + - Details: + AwsIamAccessKey: + AccessKeyId: ABC9ONWNS3155VIEJC8U + AccountId: "123456789012" + PrincipalId: ABCDEFG0TOGJSGNQKI0:john.doe + PrincipalType: AssumedRole + SessionContext: + Attributes: + CreationDate: "2024-05-24T22:32:38Z" + MfaAuthenticated: false + SessionIssuer: + AccountId: "123456789012" + Arn: arn:aws:iam::123456789012:user/tester + PrincipalId: ABCDEFG0TOGJSGNQKI0 + Type: Role + UserName: user_ab21cde50f + Id: ABC9ONWNS3155VIEJC8U + Partition: aws + Region: us-east-1 + ResourceRole: Actor + Type: AwsIamAccessKey + - Id: arn:aws:iam::123456789012:user/tester + Partition: aws + Region: us-east-1 + ResourceRole: Actor + Type: AwsIamRole + SchemaVersion: "2018-10-08" + Severity: + Label: HIGH + Normalized: 70 + Title: Suspicious activity detected accessing private decoy Systems Manager parameter arn:aws:ssm:us-east-1:123456789012:parameter/info-parameter + Types: + - Unusual Behaviors + UpdatedAt: "2024-05-24 22:34:07.000000000" + Workflow: + Status: NEW + WorkflowState: NEW + p_any_actor_ids: [] + p_any_aws_account_ids: [] + p_any_aws_arns: [] + p_any_trace_ids: [] + p_any_usernames: [] + p_event_time: "2024-05-24 22:34:07.000000000" + p_log_type: AWS.SecurityFindingFormat + p_parse_time: "2024-05-24 22:35:04.272574202" + p_row_id: zjj8nmnw9f90uulxfa3bmen8rv5stlcx + p_schema_version: 0 + p_source_id: bb4e16c5-43dd-450c-9227-39f0d152659c + p_source_label: AWS Security Hub + p_udm: {} + - Name: Systems-Manager-Parameter-Decoy-Not-Accessed + ExpectedResult: false + Log: + Action: + ActionType: AWS_API_CALL + AwsApiCallAction: + Api: DescribeParameters + CallerType: remoteIp + DomainDetails: {} + ServiceName: kms.amazonaws.com + DnsRequestAction: {} + NetworkConnectionAction: + LocalPortDetails: {} + RemotePortDetails: {} + PortProbeAction: {} + AwsAccountId: "123456789012" + CompanyName: Custom + CreatedAt: "2024-05-24 22:34:07.000000000" + Description: Private decoy Systems Manager parameter arn:aws:ssm:us-east-1:123456789012:parameter/info-parameter was not accessed by arn:aws:iam::123456789012:user/tester. This Systems Manager parameter has been provisioned to monitor and generate security events when accessed and can be an indicator of unintended or unauthorized access to your AWS Account. + FindingProviderFields: + Severity: + Label: HIGH + Normalized: 70 + Types: + - Unusual Behaviors + GeneratorId: ssm.amazonaws.com + Id: 6abc0de0-69ea-4e15-91c6-27eb4a07bd21 + ProcessedAt: "2024-05-24T22:34:15.644Z" + ProductArn: arn:aws:securityhub:us-east-1:123456789012:product/123456789012/default + ProductFields: + Custom/DecoyDetector/apiResult: SUCCESS + Custom/DecoyDetector/requestID: ab1cd234-1986-4c45-8546-fdb1776e23b0 + Custom/DecoyDetector/userAgent: AWS Internal + aws/securityhub/CompanyName: Personal + aws/securityhub/FindingId: arn:aws:service:region:123456789012:resource/12345ab6-436d-4d59-ac58-ed6b3127e440 + aws/securityhub/ProductName: Default + ProductName: DecoyDetector + RecordState: ACTIVE + Region: us-east-1 + Resources: + - Id: arn:aws:ssm:us-east-1:123456789012:parameter/info-parameter + Partition: aws + Region: us-east-1 + ResourceRole: Target + Type: Other + - Id: arn:aws:kms:us-east-1:123456789012:key/007ab31c-bf66-2264-a916-49f6d2ebd1db + Partition: aws + Region: us-east-1 + ResourceRole: Target + Type: AwsKmsKey + - Details: + AwsIamAccessKey: + AccessKeyId: ABC9ONWNS3155VIEJC8U + AccountId: "123456789012" + PrincipalId: ABCDEFG0TOGJSGNQKI0:john.doe + PrincipalType: AssumedRole + SessionContext: + Attributes: + CreationDate: "2024-05-24T22:32:38Z" + MfaAuthenticated: false + SessionIssuer: + AccountId: "123456789012" + Arn: arn:aws:iam::123456789012:user/tester + PrincipalId: ABCDEFG0TOGJSGNQKI0 + Type: Role + UserName: user_ab21cde50f + Id: ABC9ONWNS3155VIEJC8U + Partition: aws + Region: us-east-1 + ResourceRole: Actor + Type: AwsIamAccessKey + - Id: arn:aws:iam::123456789012:user/tester + Partition: aws + Region: us-east-1 + ResourceRole: Actor + Type: AwsIamRole + SchemaVersion: "2018-10-08" + Severity: + Label: HIGH + Normalized: 70 + Title: Non-Suspicious activity detected accessing private decoy Systems Manager parameter arn:aws:ssm:us-east-1:123456789012:parameter/info-parameter + Types: + - Unusual Behaviors + UpdatedAt: "2024-05-24 22:34:07.000000000" + Workflow: + Status: NEW + WorkflowState: NEW + p_any_actor_ids: [] + p_any_aws_account_ids: [] + p_any_aws_arns: [] + p_any_trace_ids: [] + p_any_usernames: [] + p_event_time: "2024-05-24 22:34:07.000000000" + p_log_type: AWS.SecurityFindingFormat + p_parse_time: "2024-05-24 22:35:04.272574202" + p_row_id: zjj8nmnw9f90uulxfa3bmen8rv5stlcx + p_schema_version: 0 + p_source_id: bb4e16c5-43dd-450c-9227-39f0d152659c + p_source_label: AWS Security Hub + p_udm: {} From a15c5e67115380db075901b9a623605675c8852b Mon Sep 17 00:00:00 2001 From: JPhenglavong Date: Mon, 10 Jun 2024 11:41:04 -0700 Subject: [PATCH 24/35] Update aws_console_login_without_mfa.py (#1237) * Update aws_console_login_without_mfa.py is_new_account has been checking with only recipientAccountId but our new aws account indicator creation rule has been checking for "new_account - recipientAccountId" * Update aws_console_login_without_mfa.py Casted str to account for NoneType * Update new_user_account_logging.py Added an alternative string in the case udm user is empty * Update new_user_account_logging.yml add mock test * Standard user creation fixes (#1256) * Prepare for `3.53.0` (#1232) * Replace panther_analysis_tool import with updated import (#1230) * Update Action versions; use SHAs (#1231) * Update Action versions; use SHAs * Add dependabot.yml to keep Actions updated * Update PAT to 0.49.0 * auth0-cic-credential-stuffing rule and query (#1246) * Add saved queries for ongoing Snowflake threats (#1248) * Add saved queries for ongoing Snowflake threats * Add limits Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> * snowflake pack * Add scheduled queries and rules Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> * pack update * ruleID fix * make fmt Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> * Fix merge conflicts Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> * Turn off by default Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> --------- Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> Co-authored-by: Ariel Ropek * Update panther-core to 0.10.1 via PAT (#1249) Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> * Tweak Snowflake queries (#1250) * Tweak Snowflake queries Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> * Remove configuration drift query from Pack Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> * Threat Hunting queries are okay Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> * Fix comment Workflow Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> * 12 hours -> 1 day Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> * Update queries/snowflake_queries/snowflake_0108977_configuration_drift.yml --------- Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> * Fixed typo in README.md (#1253) fixed 'unintall' typo to 'npm uninstall prettier' * build(deps): bump step-security/harden-runner from 2.8.0 to 2.8.1 (#1254) Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.8.0 to 2.8.1. - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/f086349bfa2bd1361f7909c78558e816508cdc10...17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Using GITHUB_OUTPUT env var instead of old ::set-output shorthand (#1255) * OCSF data model, VPC/DNS (#1214) * Deprecate GreyNoise detections (#1205) * Deprecate GreyNoise detections * Update rules/aws_cloudtrail_rules/aws_s3_activity_greynoise.yml * Update rules/cloudflare_rules/cloudflare_firewall_suspicious_event_greynoise.yml * Update cloudflare_httpreq_bot_high_volume_greynoise.yml --------- Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> * fix - Notion Login From New Location - NoneType error (#1206) * fix - Notion Login From New Location - NoneType error * fix - Notion Login From New Location - NoneType error - linter fix * remove codeowners (#1208) * fix - GCP rules - AttributeError (#1210) * fix - GCP rules - AttributeError * fix - GCP rules - AttributeError - linter fix * MITRE ATT&CK Mappings for MS Rules (#1209) * added MITRE mappings for microsoft rules * fixed formatting on some helper files --------- Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> * traildiscover enrichment with managed schema (#1177) * traildiscover enrichment with managed schema * Add npm install in dockerfile (#1172) * add npm install in dockerfile * Remove Python optimizations; add prettier to PATH --------- Co-authored-by: egibs * schema name: TrailDiscover.CloudTrail * Fix Dockerfile; add Workflow to test image * updated data set * Add MongoDB.2FA.Disabled rule (#1190) Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> * lint and fmt * fmt * add OCSF selector * additional OCSF mappings * Fix Pipfile * Rebase changes --------- Co-authored-by: Panos Sakkos Co-authored-by: egibs Co-authored-by: Oleh Melenevskyi <767472+melenevskyi@users.noreply.github.com> * Update PAT to 0.46.0 (#1216) * THREAT-278 OCSF data model, VPC --------- Co-authored-by: Oleh Melenevskyi <767472+melenevskyi@users.noreply.github.com> Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> Co-authored-by: Panos Sakkos Co-authored-by: ben-githubs <38414634+ben-githubs@users.noreply.github.com> Co-authored-by: egibs Co-authored-by: Evan Gibler * fix: consider deny rules for ssh network acl policy (#1236) * fix: consider deny rules for ssh network acl policy * Update policies/aws_vpc_policies/aws_network_acl_restricted_ssh.py * Update policies/aws_vpc_policies/aws_network_acl_restricted_ssh.py --------- Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> * AWS Honeypot Detections threat-306 (#1252) * AWS Honeypot Detections threat-306 AWS Security Finding rules on decoy AWS resources: https://aws.amazon.com/blogs/security/how-to-detect-suspicious-activity-in-your-aws-account-by-using-private-decoy-resources/ * Update decoy_dynamodb_accessed.py * Update decoy_iam_assumed.py * Update decoy_s3_accessed.py * Update decoy_secret_accessed.py * Update decoy_systems_manager_parameter_accessed.py * Update decoy_dynamodb_accessed.py * Update decoy_iam_assumed.py * Update decoy_s3_accessed.py * Update decoy_secret_accessed.py * Update decoy_systems_manager_parameter_accessed.py * Update decoy_systems_manager_parameter_accessed.py * Update decoy_systems_manager_parameter_accessed.py * Update decoy_secret_accessed.py * Update decoy_s3_accessed.py * Update decoy_iam_assumed.py * Update decoy_dynamodb_accessed.py * Update decoy_systems_manager_parameter_accessed.py * reformatted and linted * removed unused methods * fixed trailing lines * add decoy rules as a pack --------- Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> --------- Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> Signed-off-by: dependabot[bot] Co-authored-by: Evan Gibler Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> Co-authored-by: Evan Gibler <20933572+egibs@users.noreply.github.com> Co-authored-by: Ariel Ropek Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: BJ Maldonado Co-authored-by: akozlovets098 <95437895+akozlovets098@users.noreply.github.com> Co-authored-by: Oleh Melenevskyi <767472+melenevskyi@users.noreply.github.com> Co-authored-by: Panos Sakkos Co-authored-by: ben-githubs <38414634+ben-githubs@users.noreply.github.com> Co-authored-by: egibs Co-authored-by: Eli Skeggs <1348991+skeggse@users.noreply.github.com> --------- Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> Signed-off-by: dependabot[bot] Co-authored-by: Evan Gibler Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> Co-authored-by: Evan Gibler <20933572+egibs@users.noreply.github.com> Co-authored-by: Ariel Ropek Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: BJ Maldonado Co-authored-by: akozlovets098 <95437895+akozlovets098@users.noreply.github.com> Co-authored-by: Oleh Melenevskyi <767472+melenevskyi@users.noreply.github.com> Co-authored-by: Panos Sakkos Co-authored-by: ben-githubs <38414634+ben-githubs@users.noreply.github.com> Co-authored-by: egibs Co-authored-by: Eli Skeggs <1348991+skeggse@users.noreply.github.com> --- rules/aws_cloudtrail_rules/aws_console_login_without_mfa.py | 3 ++- rules/indicator_creation_rules/new_user_account_logging.py | 2 +- rules/indicator_creation_rules/new_user_account_logging.yml | 3 +++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/rules/aws_cloudtrail_rules/aws_console_login_without_mfa.py b/rules/aws_cloudtrail_rules/aws_console_login_without_mfa.py index 2bc45020c..9524e5e51 100644 --- a/rules/aws_cloudtrail_rules/aws_console_login_without_mfa.py +++ b/rules/aws_cloudtrail_rules/aws_console_login_without_mfa.py @@ -55,7 +55,8 @@ def rule(event): if is_new_user: return False - is_new_account = check_account_age(event.get("recipientAccountId")) + new_account_string = "new_account - " + str(event.get("recipientAccountId")) + is_new_account = check_account_age(new_account_string) if isinstance(is_new_account, str): logging.debug("check_account_age is a mocked string for unit testing") if is_new_account == "False": diff --git a/rules/indicator_creation_rules/new_user_account_logging.py b/rules/indicator_creation_rules/new_user_account_logging.py index 3b39618b9..9f7d563c7 100644 --- a/rules/indicator_creation_rules/new_user_account_logging.py +++ b/rules/indicator_creation_rules/new_user_account_logging.py @@ -13,7 +13,7 @@ def rule(event): return False user_event_id = f"new_user_{event.get('p_row_id')}" - new_user = event.udm("user") + new_user = event.udm("user") or "" new_account = event.udm("user_account_id") or "" event_time = resolve_timestamp_string(event.get("p_event_time")) expiry_time = event_time + TTL diff --git a/rules/indicator_creation_rules/new_user_account_logging.yml b/rules/indicator_creation_rules/new_user_account_logging.yml index 5747f8234..4d0db5918 100644 --- a/rules/indicator_creation_rules/new_user_account_logging.yml +++ b/rules/indicator_creation_rules/new_user_account_logging.yml @@ -84,6 +84,9 @@ Tests: } - Name: User Creation Event - Zoom ExpectedResult: true + Mocks: + - objectName: put_string_set + returnValue: >- Log: { "action": "Add", From 3fa12daec26739b23bffd6c63af7d891b8559a89 Mon Sep 17 00:00:00 2001 From: Evan Gibler <20933572+egibs@users.noreply.github.com> Date: Wed, 12 Jun 2024 10:45:25 -0500 Subject: [PATCH 25/35] Update PAT to 0.50.0 (#1259) Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> --- Pipfile | 2 +- Pipfile.lock | 136 +++++++++++++++++++++++++-------------------------- 2 files changed, 69 insertions(+), 69 deletions(-) diff --git a/Pipfile b/Pipfile index 300548ead..1dee28c07 100644 --- a/Pipfile +++ b/Pipfile @@ -19,7 +19,7 @@ wrapt = "~=1.15" [packages] policyuniverse = "==1.5.1.20230817" requests = "==2.31.0" -panther-analysis-tool = "~=0.49" +panther-analysis-tool = "~=0.50" panther-detection-helpers = "==0.4.0" [requires] diff --git a/Pipfile.lock b/Pipfile.lock index 62766de11..8f81d3efa 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "17b8e970a9987cbf1b1990b9bd6832b6012de2263f46f946b3d22bd42e42d2d8" + "sha256": "bea576d06bb3842cc5550e9eea8b427b30e4f434c6d95a6a2298bab9978dfe61" }, "pipfile-spec": 6, "requires": { @@ -139,19 +139,19 @@ }, "boto3": { "hashes": [ - "sha256:4eb8019421cb664a6fcbbee6152aa95a28ce8bbc1c4ee263871c09cdd58bf8ee", - "sha256:e9edaf979fbe59737e158f2f0f3f0861ff1d61233f18f6be8ebb483905f24587" + "sha256:549d9735bbb7cf8e1a2f4b3b676be32946717c59f33c47234586835dc904d04e", + "sha256:a91ee58fa54b170f17b2e144f038e155f92cf515f1c073ac2595e9ee45f125a8" ], "markers": "python_version >= '3.8'", - "version": "==1.34.118" + "version": "==1.34.124" }, "botocore": { "hashes": [ - "sha256:0a3d1ec0186f8b516deb39474de3d226d531f77f92a0f56ad79b80219db3ae9e", - "sha256:e3f6c5636a4394768e81e33a16f5c6ae7f364f512415d423f9b9dc67fc638df4" + "sha256:3f0bf79c17d656acdfdb53581224f6a38867ff2829f7428c586198f67a90ea26", + "sha256:fede092c7f8f414f78f3e7991e47cb0cf2279d90c027606ad7cba79fa370b827" ], "markers": "python_version >= '3.8'", - "version": "==1.34.118" + "version": "==1.34.124" }, "certifi": { "hashes": [ @@ -636,18 +636,18 @@ }, "packaging": { "hashes": [ - "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", - "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" + "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", + "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124" ], - "markers": "python_version >= '3.7'", - "version": "==24.0" + "markers": "python_version >= '3.8'", + "version": "==24.1" }, "panther-analysis-tool": { "hashes": [ - "sha256:34d6bfc59b695475aa0c74e0dbefc1e9c64363dfc9e52779f082b17780733b27" + "sha256:0b32db433df8ae2f05e476f83981263e2e7718b24b2241c8a42316d5b3c15afb" ], "index": "pypi", - "version": "==0.49.2" + "version": "==0.50.0" }, "panther-core": { "hashes": [ @@ -704,11 +704,11 @@ }, "pytest": { "hashes": [ - "sha256:5046e5b46d8e4cac199c373041f26be56fdb81eb4e67dc11d4e10811fc3408fd", - "sha256:faccc5d332b8c3719f40283d0d44aa5cf101cec36f88cde9ed8f2bc0538612b1" + "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343", + "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977" ], "markers": "python_version >= '3.8'", - "version": "==8.2.1" + "version": "==8.2.2" }, "python-dateutil": { "hashes": [ @@ -1111,11 +1111,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:6024b58b69089e5a89c347397254e35f1bf02a907728ec7fee9bf0fe837d203a", - "sha256:915f5e35ff76f56588223f15fdd5938f9a1cf9195c0de25130c627e4d597f6d1" + "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", + "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8" ], "markers": "python_version >= '3.8'", - "version": "==4.12.1" + "version": "==4.12.2" }, "urllib3": { "hashes": [ @@ -1271,19 +1271,19 @@ }, "boto3": { "hashes": [ - "sha256:4eb8019421cb664a6fcbbee6152aa95a28ce8bbc1c4ee263871c09cdd58bf8ee", - "sha256:e9edaf979fbe59737e158f2f0f3f0861ff1d61233f18f6be8ebb483905f24587" + "sha256:549d9735bbb7cf8e1a2f4b3b676be32946717c59f33c47234586835dc904d04e", + "sha256:a91ee58fa54b170f17b2e144f038e155f92cf515f1c073ac2595e9ee45f125a8" ], "markers": "python_version >= '3.8'", - "version": "==1.34.118" + "version": "==1.34.124" }, "botocore": { "hashes": [ - "sha256:0a3d1ec0186f8b516deb39474de3d226d531f77f92a0f56ad79b80219db3ae9e", - "sha256:e3f6c5636a4394768e81e33a16f5c6ae7f364f512415d423f9b9dc67fc638df4" + "sha256:3f0bf79c17d656acdfdb53581224f6a38867ff2829f7428c586198f67a90ea26", + "sha256:fede092c7f8f414f78f3e7991e47cb0cf2279d90c027606ad7cba79fa370b827" ], "markers": "python_version >= '3.8'", - "version": "==1.34.118" + "version": "==1.34.124" }, "certifi": { "hashes": [ @@ -1457,41 +1457,41 @@ }, "cryptography": { "hashes": [ - "sha256:02c0eee2d7133bdbbc5e24441258d5d2244beb31da5ed19fbb80315f4bbbff55", - "sha256:0d563795db98b4cd57742a78a288cdbdc9daedac29f2239793071fe114f13785", - "sha256:16268d46086bb8ad5bf0a2b5544d8a9ed87a0e33f5e77dd3c3301e63d941a83b", - "sha256:1a58839984d9cb34c855197043eaae2c187d930ca6d644612843b4fe8513c886", - "sha256:2954fccea107026512b15afb4aa664a5640cd0af630e2ee3962f2602693f0c82", - "sha256:2e47577f9b18723fa294b0ea9a17d5e53a227867a0a4904a1a076d1646d45ca1", - "sha256:31adb7d06fe4383226c3e963471f6837742889b3c4caa55aac20ad951bc8ffda", - "sha256:3577d029bc3f4827dd5bf8bf7710cac13527b470bbf1820a3f394adb38ed7d5f", - "sha256:36017400817987670037fbb0324d71489b6ead6231c9604f8fc1f7d008087c68", - "sha256:362e7197754c231797ec45ee081f3088a27a47c6c01eff2ac83f60f85a50fe60", - "sha256:3de9a45d3b2b7d8088c3fbf1ed4395dfeff79d07842217b38df14ef09ce1d8d7", - "sha256:4f698edacf9c9e0371112792558d2f705b5645076cc0aaae02f816a0171770fd", - "sha256:5482e789294854c28237bba77c4c83be698be740e31a3ae5e879ee5444166582", - "sha256:5e44507bf8d14b36b8389b226665d597bc0f18ea035d75b4e53c7b1ea84583cc", - "sha256:779245e13b9a6638df14641d029add5dc17edbef6ec915688f3acb9e720a5858", - "sha256:789caea816c6704f63f6241a519bfa347f72fbd67ba28d04636b7c6b7da94b0b", - "sha256:7f8b25fa616d8b846aef64b15c606bb0828dbc35faf90566eb139aa9cff67af2", - "sha256:8cb8ce7c3347fcf9446f201dc30e2d5a3c898d009126010cbd1f443f28b52678", - "sha256:93a3209f6bb2b33e725ed08ee0991b92976dfdcf4e8b38646540674fc7508e13", - "sha256:a3a5ac8b56fe37f3125e5b72b61dcde43283e5370827f5233893d461b7360cd4", - "sha256:a47787a5e3649008a1102d3df55424e86606c9bae6fb77ac59afe06d234605f8", - "sha256:a79165431551042cc9d1d90e6145d5d0d3ab0f2d66326c201d9b0e7f5bf43604", - "sha256:a987f840718078212fdf4504d0fd4c6effe34a7e4740378e59d47696e8dfb477", - "sha256:a9bc127cdc4ecf87a5ea22a2556cab6c7eda2923f84e4f3cc588e8470ce4e42e", - "sha256:bd13b5e9b543532453de08bcdc3cc7cebec6f9883e886fd20a92f26940fd3e7a", - "sha256:c65f96dad14f8528a447414125e1fc8feb2ad5a272b8f68477abbcc1ea7d94b9", - "sha256:d8e3098721b84392ee45af2dd554c947c32cc52f862b6a3ae982dbb90f577f14", - "sha256:e6b79d0adb01aae87e8a44c2b64bc3f3fe59515280e00fb6d57a7267a2583cda", - "sha256:e6b8f1881dac458c34778d0a424ae5769de30544fc678eac51c1c8bb2183e9da", - "sha256:e9b2a6309f14c0497f348d08a065d52f3020656f675819fc405fb63bbcd26562", - "sha256:ecbfbc00bf55888edda9868a4cf927205de8499e7fabe6c050322298382953f2", - "sha256:efd0bf5205240182e0f13bcaea41be4fdf5c22c5129fc7ced4a0282ac86998c9" + "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad", + "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583", + "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b", + "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c", + "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1", + "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648", + "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949", + "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba", + "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c", + "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9", + "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d", + "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c", + "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e", + "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2", + "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d", + "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7", + "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70", + "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2", + "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7", + "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14", + "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe", + "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e", + "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71", + "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961", + "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7", + "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c", + "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28", + "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842", + "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902", + "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801", + "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a", + "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e" ], "markers": "python_version >= '3.7'", - "version": "==42.0.7" + "version": "==42.0.8" }, "decorator": { "hashes": [ @@ -1730,11 +1730,11 @@ }, "packaging": { "hashes": [ - "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", - "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" + "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", + "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124" ], - "markers": "python_version >= '3.7'", - "version": "==24.0" + "markers": "python_version >= '3.8'", + "version": "==24.1" }, "pathspec": { "hashes": [ @@ -1870,11 +1870,11 @@ }, "responses": { "hashes": [ - "sha256:01ae6a02b4f34e39bffceb0fc6786b67a25eae919c6368d05eabc8d9576c2a66", - "sha256:2f0b9c2b6437db4b528619a77e5d565e4ec2a9532162ac1a131a83529db7be1a" + "sha256:77a61ad7e6016ed2ac00739b7efa5f35c42351d5b9b5d26bb1be87f197632487", + "sha256:b59707ea25de536d324670791ab073fafd41f3a351cec9c51cb6147089a9a30a" ], "markers": "python_version >= '3.8'", - "version": "==0.25.0" + "version": "==0.25.2" }, "rich": { "hashes": [ @@ -1918,11 +1918,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:6024b58b69089e5a89c347397254e35f1bf02a907728ec7fee9bf0fe837d203a", - "sha256:915f5e35ff76f56588223f15fdd5938f9a1cf9195c0de25130c627e4d597f6d1" + "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", + "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8" ], "markers": "python_version >= '3.8'", - "version": "==4.12.1" + "version": "==4.12.2" }, "urllib3": { "hashes": [ From 69ad58307504b3cc70ee66d25720d231619cbb46 Mon Sep 17 00:00:00 2001 From: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> Date: Wed, 12 Jun 2024 10:08:41 -0600 Subject: [PATCH 26/35] schema rename (#1258) --- rules/push_security_rules/push_security_phishing_attack.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/push_security_rules/push_security_phishing_attack.yml b/rules/push_security_rules/push_security_phishing_attack.yml index 7aa4c4070..42df4bd45 100644 --- a/rules/push_security_rules/push_security_phishing_attack.yml +++ b/rules/push_security_rules/push_security_phishing_attack.yml @@ -4,7 +4,7 @@ RuleID: "Push.Security.Phishing.Attack" DisplayName: "Push Security Phishing Attack" Enabled: true LogTypes: - - PushSecurity.AttackDetection + - PushSecurity.Controls Severity: High DedupPeriodMinutes: 60 Threshold: 1 From 73cdbdeade0eb0f2cbbf20103b824989090d4746 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Jun 2024 07:09:20 -0500 Subject: [PATCH 27/35] build(deps): bump actions/checkout from 4.1.6 to 4.1.7 (#1263) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.6 to 4.1.7. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/a5ac7e51b41094c92402da3b24376905380afc29...692973e3d937129bcbf40652eb9f2f61becf3332) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/check-packs.yml | 2 +- .github/workflows/docker.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/sync-from-upstream.yml | 2 +- .github/workflows/test.yml | 2 +- .github/workflows/upload.yml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/check-packs.yml b/.github/workflows/check-packs.yml index 280f706f3..9912599be 100644 --- a/.github/workflows/check-packs.yml +++ b/.github/workflows/check-packs.yml @@ -22,7 +22,7 @@ jobs: pypi.org:443 - name: Checkout panther-analysis - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 #v4.1.6 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7 - name: Set python version uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d #v5.1.0 diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 4853a0846..83512e4f9 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -27,7 +27,7 @@ jobs: registry-1.docker.io:443 www.python.org:443 - name: Checkout panther-analysis - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 #v4.1.6 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7 - uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 #v3.0.0 - name: Set up Docker Buildx id: buildx diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 43bdfab72..81cbfb35c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -19,7 +19,7 @@ jobs: github.com:443 pypi.org:443 - name: Checkout panther-analysis - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 #v4.1.6 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7 - name: Set python version uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d #v5.1.0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 08433b6d6..4ef6f3a9e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 with: egress-policy: audit - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 #v4.1.6 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7 with: fetch-depth: 0 token: ${{ env.GITHUB_TOKEN }} diff --git a/.github/workflows/sync-from-upstream.yml b/.github/workflows/sync-from-upstream.yml index fffd5be6b..92581d96f 100644 --- a/.github/workflows/sync-from-upstream.yml +++ b/.github/workflows/sync-from-upstream.yml @@ -37,7 +37,7 @@ jobs: branch: "sync_upstream_${{steps.set_upstream.outputs.latest-release}}" # Checkout this repo into the branch - name: Checkout your local repo in PR branch - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 #v4.1.6 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7 with: ref: "sync_upstream_${{steps.set_upstream.outputs.latest-release}}" token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d6be44170..83a13ba05 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,7 +20,7 @@ jobs: ipinfo.io:443 pypi.org:443 - name: Checkout panther-analysis - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 #v4.1.6 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7 - name: Set python version uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d #v5.1.0 diff --git a/.github/workflows/upload.yml b/.github/workflows/upload.yml index 3cf548ab8..9cd5f85de 100644 --- a/.github/workflows/upload.yml +++ b/.github/workflows/upload.yml @@ -24,7 +24,7 @@ jobs: exit 0 - name: Checkout panther-analysis - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 #v4.1.6 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7 - name: Set python version uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d #v5.1.0 From 1aaef4e1b9908b2646d89e7a513974e1ecb450e2 Mon Sep 17 00:00:00 2001 From: Evan Gibler <20933572+egibs@users.noreply.github.com> Date: Thu, 13 Jun 2024 12:28:04 -0500 Subject: [PATCH 28/35] Update PAT to 0.50.1 (#1261) Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> --- Pipfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 8f81d3efa..9daad1d7a 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -644,10 +644,10 @@ }, "panther-analysis-tool": { "hashes": [ - "sha256:0b32db433df8ae2f05e476f83981263e2e7718b24b2241c8a42316d5b3c15afb" + "sha256:d85f5e26703b2b485125e49a323ca82c125767f9deabdb6eda6e92974b320356" ], "index": "pypi", - "version": "==0.50.0" + "version": "==0.50.1" }, "panther-core": { "hashes": [ From 327008e4d91b520eac2035ef2883d761d81e2d43 Mon Sep 17 00:00:00 2001 From: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> Date: Thu, 13 Jun 2024 12:37:56 -0600 Subject: [PATCH 29/35] improve error handling for dynamic functions (#1262) * improve error handling for dynamic functions * remove unused import * additional fixes * more fixes --- rules/appomni_rules/appomni_alert_passthrough.py | 11 ++++++----- rules/auth0_rules/auth0_mfa_policy_enabled.py | 2 ++ rules/auth0_rules/auth0_user_invitation_created.py | 2 +- .../aws_modify_cloud_compute_infrastructure.py | 8 ++++++-- .../aws_cloudtrail_rules/aws_s3_bucket_deleted.py | 2 +- .../aws_cloudtrail_rules/aws_software_discovery.py | 2 +- .../gcp_workforce_pool_created_or_updated.py | 6 +++--- .../gcp_k8s_privileged_pod_created.py | 2 +- ...google_workspace_advanced_protection_program.py | 4 ++-- .../google_workspace_apps_marketplace_allowlist.py | 4 ++-- .../gsuite_drive_external_share.py | 4 ++-- rules/okta_rules/okta_idp_create_modify.py | 2 +- .../okta_org2org_creation_modification.py | 2 +- .../panther_detection_deleted.py | 2 +- rules/standard_rules/brute_force_by_ip.py | 14 +++++++++++--- rules/standard_rules/impossible_travel_login.py | 4 ++-- rules/standard_rules/malicious_sso_dns_lookup.py | 4 +++- 17 files changed, 46 insertions(+), 29 deletions(-) diff --git a/rules/appomni_rules/appomni_alert_passthrough.py b/rules/appomni_rules/appomni_alert_passthrough.py index 9cbc07a6b..15299ce50 100644 --- a/rules/appomni_rules/appomni_alert_passthrough.py +++ b/rules/appomni_rules/appomni_alert_passthrough.py @@ -1,3 +1,6 @@ +SEV_DICT = {0: "Critical", 1: "High", 2: "Medium", 3: "Low", 4: "Info"} + + def rule(event): # Only alert where event.kind == "alert" if event.deep_get("event", "kind") == "alert": @@ -7,11 +10,10 @@ def rule(event): def title(event): # Create title that includes severity and message - sev_dict = {0: "Critical", 1: "High", 2: "Medium", 3: "Low", 4: "Informational"} - sev = sev_dict[event.deep_get("event", "severity")] + sev = SEV_DICT.get(event.deep_get("event", "severity")) # Use type service in title if only one field, label as 'Multiple Services' if more than one. - if len(event.deep_get("related", "services", "type")) == 1: + if len(event.deep_get("related", "services", "type", default=[])) == 1: service = event.deep_get("related", "services", "type")[0] else: service = "Multiple Services" @@ -21,8 +23,7 @@ def title(event): def severity(event): # Update Panther alert severity based on severity from AppOmni Alert - sev = {0: "Critical", 1: "High", 2: "Medium", 3: "Low", 4: "Informational"} - return sev[event.deep_get("event", "severity")] + return SEV_DICT[event.deep_get("event", "severity", default=4)] def dedup(event): diff --git a/rules/auth0_rules/auth0_mfa_policy_enabled.py b/rules/auth0_rules/auth0_mfa_policy_enabled.py index 6c3d6e269..331ebf192 100644 --- a/rules/auth0_rules/auth0_mfa_policy_enabled.py +++ b/rules/auth0_rules/auth0_mfa_policy_enabled.py @@ -29,6 +29,8 @@ def title(event): setting_change = "Always Require" if "confidence-score" in request_body: setting_change = "Use Adaptive MFA" + else: + setting_change = "Unknown" return ( f"Auth0 user [{user_email}] set the " diff --git a/rules/auth0_rules/auth0_user_invitation_created.py b/rules/auth0_rules/auth0_user_invitation_created.py index af460c4a5..12c71a2b4 100644 --- a/rules/auth0_rules/auth0_user_invitation_created.py +++ b/rules/auth0_rules/auth0_user_invitation_created.py @@ -30,7 +30,7 @@ def title(event): event, "data", "details", "request", "auth", "user", "email", default="" ) source = deep_get(event, "p_source_label", default="") - return f"Auth0 User [{inviter}] invited [{invitee}] to {inv_type.title()} [{source}]]" + return f"Auth0 User [{inviter}] invited [{invitee}] to {inv_type} [{source}]]" def invitation_type(event): diff --git a/rules/aws_cloudtrail_rules/aws_modify_cloud_compute_infrastructure.py b/rules/aws_cloudtrail_rules/aws_modify_cloud_compute_infrastructure.py index f74c7d4b1..eea7e3a1d 100644 --- a/rules/aws_cloudtrail_rules/aws_modify_cloud_compute_infrastructure.py +++ b/rules/aws_cloudtrail_rules/aws_modify_cloud_compute_infrastructure.py @@ -64,7 +64,9 @@ def rule(event): def title(event): - items = deep_get(event, "requestParameters", "instancesSet", "items") + items = deep_get( + event, "requestParameters", "instancesSet", "items", default=[{"instanceId": "none"}] + ) return ( f"AWS Event [{event.get('eventName')}] Instance ID " f"[{items[0].get('instanceId')}] AWS Account ID [{event.get('recipientAccountId')}]" @@ -72,7 +74,9 @@ def title(event): def alert_context(event): - items = deep_get(event, "requestParameters", "instancesSet", "items") + items = deep_get( + event, "requestParameters", "instancesSet", "items", default=[{"instanceId": "none"}] + ) return { "awsRegion": event.get("awsRegion"), "eventName": event.get("eventName"), diff --git a/rules/aws_cloudtrail_rules/aws_s3_bucket_deleted.py b/rules/aws_cloudtrail_rules/aws_s3_bucket_deleted.py index 35ecf5836..73e57f59e 100644 --- a/rules/aws_cloudtrail_rules/aws_s3_bucket_deleted.py +++ b/rules/aws_cloudtrail_rules/aws_s3_bucket_deleted.py @@ -19,7 +19,7 @@ def dedup(event): user_identity = event.get("userIdentity", {}) if user_identity.get("type") == "AssumedRole": return helper_strip_role_session_id(user_identity.get("arn", "")) - return user_identity.get("arn") + return user_identity.get("arn", "") def title(event): diff --git a/rules/aws_cloudtrail_rules/aws_software_discovery.py b/rules/aws_cloudtrail_rules/aws_software_discovery.py index 56cc09178..7439361f2 100644 --- a/rules/aws_cloudtrail_rules/aws_software_discovery.py +++ b/rules/aws_cloudtrail_rules/aws_software_discovery.py @@ -36,7 +36,7 @@ def title(event): def dedup(event): - return deep_get(event, "userIdentity", "principalId") + return deep_get(event, "userIdentity", "principalId", default="NO_PRINCIPAL_ID_FOUND") def alert_context(event): diff --git a/rules/gcp_audit_rules/gcp_workforce_pool_created_or_updated.py b/rules/gcp_audit_rules/gcp_workforce_pool_created_or_updated.py index b797d88cc..77df5fba9 100644 --- a/rules/gcp_audit_rules/gcp_workforce_pool_created_or_updated.py +++ b/rules/gcp_audit_rules/gcp_workforce_pool_created_or_updated.py @@ -12,9 +12,9 @@ def title(event): actor = event.deep_get( "protoPayload", "authenticationInfo", "principalEmail", default="" ) - workforce_pool = event.deep_get("protoPayload", "request", "workforcePool", "name").split("/")[ - -1 - ] + workforce_pool = event.deep_get( + "protoPayload", "request", "workforcePool", "name", default="" + ).split("/")[-1] resource = organization_id = event.deep_get("logName", default="").split( "/" diff --git a/rules/gcp_k8s_rules/gcp_k8s_privileged_pod_created.py b/rules/gcp_k8s_rules/gcp_k8s_privileged_pod_created.py index ea202b642..5b7b50782 100644 --- a/rules/gcp_k8s_rules/gcp_k8s_privileged_pod_created.py +++ b/rules/gcp_k8s_rules/gcp_k8s_privileged_pod_created.py @@ -37,6 +37,6 @@ def title(event): def alert_context(event): context = gcp_alert_context(event) - containers_info = deep_walk(event, "protoPayload", "response", "spec", "containers") + containers_info = deep_walk(event, "protoPayload", "response", "spec", "containers", default=[]) context["pod_security_context"] = [i.get("securityContext") for i in containers_info] return context diff --git a/rules/gsuite_activityevent_rules/google_workspace_advanced_protection_program.py b/rules/gsuite_activityevent_rules/google_workspace_advanced_protection_program.py index b87fccadf..1c5cceddb 100644 --- a/rules/gsuite_activityevent_rules/google_workspace_advanced_protection_program.py +++ b/rules/gsuite_activityevent_rules/google_workspace_advanced_protection_program.py @@ -15,10 +15,10 @@ def rule(event): def title(event): # If no 'dedup' function is defined, the return value of this # method will act as deduplication string. - setting = event.get("parameters", {}).get("SETTING_NAME", "NO_SETTING_NAME") + setting = event.deep_get("parameters", "SETTING_NAME", default="NO_SETTING_NAME") setting_name = setting.split("-")[-1].strip() return ( f"Google Workspace Advanced Protection Program settings have been updated to " f"[{setting_name}] by Google Workspace User " - f"[{event.get('actor',{}).get('email','')}]." + f"[{event.deep_get('actor', 'email', default='')}]." ) diff --git a/rules/gsuite_activityevent_rules/google_workspace_apps_marketplace_allowlist.py b/rules/gsuite_activityevent_rules/google_workspace_apps_marketplace_allowlist.py index c5380bd42..ac74286e9 100644 --- a/rules/gsuite_activityevent_rules/google_workspace_apps_marketplace_allowlist.py +++ b/rules/gsuite_activityevent_rules/google_workspace_apps_marketplace_allowlist.py @@ -24,6 +24,6 @@ def title(event): actor = deep_get(event, "actor", "email", default="") return ( f"Google Workspace User [{actor}] " - f"made an application allowlist setting change from [{value_dict.get(old_val)}] " - f"to [{value_dict.get(new_val)}]" + f"made an application allowlist setting change from [{value_dict.get(str(old_val))}] " + f"to [{value_dict.get(str(new_val))}]" ) diff --git a/rules/gsuite_reports_rules/gsuite_drive_external_share.py b/rules/gsuite_reports_rules/gsuite_drive_external_share.py index ac427233a..03992ecdd 100644 --- a/rules/gsuite_reports_rules/gsuite_drive_external_share.py +++ b/rules/gsuite_reports_rules/gsuite_drive_external_share.py @@ -1,6 +1,6 @@ import datetime -from panther_base_helpers import PantherUnexpectedAlert, deep_get, pattern_match, pattern_match_list +from panther_base_helpers import deep_get, pattern_match, pattern_match_list COMPANY_DOMAIN = "your-company-name.com" EXCEPTION_PATTERNS = { @@ -96,4 +96,4 @@ def title(event): + f'"{doc_title}" to {target_user}' ) return f'Dangerous file share by [{actor}]: "{doc_title}" to {target_user}' - raise PantherUnexpectedAlert("No matching events, but DangerousShares still fired") + return "No matching events, but DangerousShares still fired" diff --git a/rules/okta_rules/okta_idp_create_modify.py b/rules/okta_rules/okta_idp_create_modify.py index c851bf2f7..d62f22aa0 100644 --- a/rules/okta_rules/okta_idp_create_modify.py +++ b/rules/okta_rules/okta_idp_create_modify.py @@ -6,7 +6,7 @@ def rule(event): def title(event): - action = event.get("eventType").split(".")[3] + action = event.get("eventType").split(".")[-1] target = deep_walk( event, "target", "displayName", default="", return_val="first" ) diff --git a/rules/okta_rules/okta_org2org_creation_modification.py b/rules/okta_rules/okta_org2org_creation_modification.py index 578169692..41bf07a70 100644 --- a/rules/okta_rules/okta_org2org_creation_modification.py +++ b/rules/okta_rules/okta_org2org_creation_modification.py @@ -15,7 +15,7 @@ def rule(event): def title(event): - action = event.get("eventType").split(".")[2] + action = event.get("eventType").split(".")[-1] target = deep_walk( event, "target", "alternateId", default="", return_val="first" ) diff --git a/rules/panther_audit_rules/panther_detection_deleted.py b/rules/panther_audit_rules/panther_detection_deleted.py index 55a29f365..57452e95e 100644 --- a/rules/panther_audit_rules/panther_detection_deleted.py +++ b/rules/panther_audit_rules/panther_detection_deleted.py @@ -24,7 +24,7 @@ def title(event): def alert_context(event): detections_list = deep_get(event, "actionParams", "dynamic", "input", "detections") if detections_list is None: - detections_list = deep_get(event, "actionParams", "input", "detections") + detections_list = deep_get(event, "actionParams", "input", "detections", default=[]) return { "deleted_detections_list": [x.get("id") for x in detections_list], "user": event.udm("actor_user"), diff --git a/rules/standard_rules/brute_force_by_ip.py b/rules/standard_rules/brute_force_by_ip.py index d431da3e3..144bea770 100644 --- a/rules/standard_rules/brute_force_by_ip.py +++ b/rules/standard_rules/brute_force_by_ip.py @@ -2,7 +2,7 @@ import panther_event_type_helpers as event_type from panther_default import lookup_aws_account_name -from panther_ipinfo_helpers import geoinfo_from_ip +from panther_ipinfo_helpers import PantherIPInfoException, geoinfo_from_ip from panther_oss_helpers import add_parse_delay @@ -23,7 +23,10 @@ def title(event): def alert_context(event): - geoinfo = geoinfo_from_ip(event=event, match_field=event.udm_path("source_ip")) + try: + geoinfo = geoinfo_from_ip(event=event, match_field=event.udm_path("source_ip")) + except PantherIPInfoException: + geoinfo = {} if isinstance(geoinfo, str): geoinfo = loads(geoinfo) context = {} @@ -33,5 +36,10 @@ def alert_context(event): context["ip"] = geoinfo.get("ip") context["reverse_lookup"] = geoinfo.get("hostname", "No reverse lookup hostname") context["ip_org"] = geoinfo.get("org", "No organization listed") - context = add_parse_delay(event, context) + try: + context = add_parse_delay(event, context) + except TypeError: + pass + except AttributeError: + pass return context diff --git a/rules/standard_rules/impossible_travel_login.py b/rules/standard_rules/impossible_travel_login.py index 8e4db4450..1546f51c5 100644 --- a/rules/standard_rules/impossible_travel_login.py +++ b/rules/standard_rules/impossible_travel_login.py @@ -33,7 +33,7 @@ def rule(event): global IS_PRIVATE_RELAY EVENT_CITY_TRACKING = {} - CACHE_KEY = None + CACHE_KEY = "" IS_VPN = False IS_PRIVATE_RELAY = False @@ -99,7 +99,7 @@ def rule(event): # Generate a unique cache key for each user per log type CACHE_KEY = gen_key(event) - if CACHE_KEY is None: + if not CACHE_KEY: # We can't save without a cache key return False # Retrieve the prior login info from the cache, if any diff --git a/rules/standard_rules/malicious_sso_dns_lookup.py b/rules/standard_rules/malicious_sso_dns_lookup.py index 3c1b5971e..a6b88d9ae 100644 --- a/rules/standard_rules/malicious_sso_dns_lookup.py +++ b/rules/standard_rules/malicious_sso_dns_lookup.py @@ -57,4 +57,6 @@ def rule(event): def title(event): - return f"Potential Malicious SSO Domain - {event.get('p_any_domain_names','')[0]}" + return ( + f"Potential Malicious SSO Domain - {event.get('p_any_domain_names',['NO_DOMAINs_FOUND'])}" + ) From bcf908850538f0d8f1025c6cfeb6013eb4692ae4 Mon Sep 17 00:00:00 2001 From: nskobov <93276498+nskobov@users.noreply.github.com> Date: Mon, 17 Jun 2024 09:52:41 -0500 Subject: [PATCH 30/35] update vscode schema to honor correlation rules (#1264) Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> --- .vscode/rule_jsonschema.json | 66 ++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/.vscode/rule_jsonschema.json b/.vscode/rule_jsonschema.json index 0f7f576df..d49d8ca76 100644 --- a/.vscode/rule_jsonschema.json +++ b/.vscode/rule_jsonschema.json @@ -61,15 +61,18 @@ "$ref": "#/definitions/ScheduledQueries" } }, - "required": [ - "AnalysisType", - "DisplayName", - "Enabled", - "RuleID", - "Severity", - "Tests" - ], + "required": ["AnalysisType", "DisplayName", "Enabled", "RuleID", "Severity"], "additionalProperties": false, + "allOf": [ + { + "if": { + "properties": { "AnalysisType": { "enum": ["rule", "scheduled_rule"] } } + }, + "then": { + "required": ["Tests"] + } + } + ], "anyOf": [ { "required": ["Filename"] @@ -82,7 +85,7 @@ "AnalysisType": { "description": "what kind of detection", "type": "string", - "enum": ["rule", "scheduled_rule"], + "enum": ["rule", "scheduled_rule", "correlation_rule"], "default": "rule" }, "DisplayName": { @@ -177,6 +180,23 @@ "type": "string", "minLength": 1 }, + "RuleMatch": { + "$comment": "https://docs.panther.com/detections/correlation-rules/correlation-rule-reference#ruleoutput-fields", + "description": "The Match that occurred for 1 of the rules in this test case", + "type": "object", + "required": ["ID"], + "properties": { + "ID": { + "type": "string", + "description": "The ID of the Rule from the Sequence/Group section above to simulate matches on" + }, + "Matches": { + "type": "object", + "description": "The Match definition for this rule. Key: field that matched. value: mapping of the value that was matched on to the timestamps that the match(es) occurred. See docs for more details", + "$comment": "https://docs.panther.com/detections/correlation-rules/correlation-rule-reference#matchvalue-fields" + } + } + }, "Tests": { "$comment": "https://docs.panther.com/detections/writing-and-editing-detections", "description": "Unit test cases", @@ -225,9 +245,27 @@ "else": false } ] + }, + "RuleOutputs": { + "anyOf": [ + { + "if": { + "properties": { + "AnalysisType": { "enum": ["correlation_rule"] } + } + }, + "then": { + "type": "array", + "description": "List of Rule Matches that occurred for this test case", + "items": { "$ref": "#/definitions/RuleMatch" }, + "minItems": 1 + }, + "else": false + } + ] } }, - "allOf": [ + "oneOf": [ { "if": { "properties": { "AnalysisType": { "enum": ["rule"] } } @@ -235,6 +273,14 @@ "then": { "required": ["Name", "ExpectedResult", "Log"] } + }, + { + "if": { + "properties": { "AnalysisType": { "enum": ["correlation_rule"] } } + }, + "then": { + "required": ["Name", "ExpectedResult", "RuleOutputs"] + } } ] } From fbdd0c462fdd219a3eec4ea21ad439354d0510fc Mon Sep 17 00:00:00 2001 From: Panos Sakkos Date: Tue, 18 Jun 2024 17:37:34 +0300 Subject: [PATCH 31/35] remove .husky directory (#1266) --- .husky/pre-commit | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .husky/pre-commit diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100644 index 9ed1f911c..000000000 --- a/.husky/pre-commit +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -make fmt From 33335ca21729af4f63fa50ff5466d834573a45f2 Mon Sep 17 00:00:00 2001 From: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> Date: Tue, 18 Jun 2024 09:15:59 -0600 Subject: [PATCH 32/35] update snowflake queries with p_occurs_since (#1265) * update snowflake queries with p_occurs_since * a few more fixes * typo --- .../snowflake_0108977_configuration_drift_query.yml | 2 +- ...lake_0108977_configuration_drift_threat_hunting.yml | 2 +- .../snowflake_queries/snowflake_0108977_ip_query.yml | 4 ++-- .../snowflake_0108977_ip_threat_hunting.yml | 4 ++-- .../snowflake_0108977_suspected_user_access_query.yml | 3 ++- ...ke_0108977_suspected_user_access_threat_hunting.yml | 3 ++- .../snowflake_account_admin_assigned_query.yml | 6 +++--- .../snowflake_external_shares_query.yml | 7 ++++--- .../snowflake_queries/snowflake_login_without_mfa.py | 2 +- .../snowflake_login_without_mfa_query.yml | 6 +++--- ...ultiple_failed_logins_followed_by_success_query.yml | 10 +++++----- .../snowflake_public_role_grant_query.yml | 3 ++- .../snowflake_queries/snowflake_user_created_query.yml | 3 ++- .../snowflake_queries/snowflake_user_enabled_query.yml | 3 ++- 14 files changed, 32 insertions(+), 26 deletions(-) diff --git a/queries/snowflake_queries/snowflake_0108977_configuration_drift_query.yml b/queries/snowflake_queries/snowflake_0108977_configuration_drift_query.yml index c7959a43f..24a2168d1 100644 --- a/queries/snowflake_queries/snowflake_0108977_configuration_drift_query.yml +++ b/queries/snowflake_queries/snowflake_0108977_configuration_drift_query.yml @@ -14,7 +14,7 @@ SnowflakeQuery: > query_text, user_name, role_name, - start_time, + start_time as p_event_time, end_time FROM snowflake.account_usage.query_history WHERE execution_status = 'SUCCESS' diff --git a/queries/snowflake_queries/snowflake_0108977_configuration_drift_threat_hunting.yml b/queries/snowflake_queries/snowflake_0108977_configuration_drift_threat_hunting.yml index c826072c8..fedeab15c 100644 --- a/queries/snowflake_queries/snowflake_0108977_configuration_drift_threat_hunting.yml +++ b/queries/snowflake_queries/snowflake_0108977_configuration_drift_threat_hunting.yml @@ -11,7 +11,7 @@ SnowflakeQuery: > query_text, user_name, role_name, - start_time, + start_time as p_event_time, end_time FROM snowflake.account_usage.query_history WHERE execution_status = 'SUCCESS' diff --git a/queries/snowflake_queries/snowflake_0108977_ip_query.yml b/queries/snowflake_queries/snowflake_0108977_ip_query.yml index 0302e901d..60de35aea 100644 --- a/queries/snowflake_queries/snowflake_0108977_ip_query.yml +++ b/queries/snowflake_queries/snowflake_0108977_ip_query.yml @@ -7,6 +7,7 @@ SnowflakeQuery: > -- https://community.snowflake.com/s/article/Communication-ID-0108977-Additional-Information SELECT + event_timestamp as p_event_time, * FROM snowflake.account_usage.login_history @@ -80,8 +81,7 @@ SnowflakeQuery: > '138.199.34.144' ) AND p_occurs_since('1 day') - ORDER BY - event_timestamp + ORDER BY p_event_time LIMIT 100; Schedule: RateMinutes: 1440 diff --git a/queries/snowflake_queries/snowflake_0108977_ip_threat_hunting.yml b/queries/snowflake_queries/snowflake_0108977_ip_threat_hunting.yml index 855041cba..a0ce3f0f3 100644 --- a/queries/snowflake_queries/snowflake_0108977_ip_threat_hunting.yml +++ b/queries/snowflake_queries/snowflake_0108977_ip_threat_hunting.yml @@ -6,6 +6,7 @@ SnowflakeQuery: > -- https://community.snowflake.com/s/article/Communication-ID-0108977-Additional-Information SELECT + event_timestamp as p_event_time, * FROM snowflake.account_usage.login_history @@ -78,6 +79,5 @@ SnowflakeQuery: > '146.70.119.24', '138.199.34.144' ) - ORDER BY - event_timestamp + ORDER BY p_event_time LIMIT 100; diff --git a/queries/snowflake_queries/snowflake_0108977_suspected_user_access_query.yml b/queries/snowflake_queries/snowflake_0108977_suspected_user_access_query.yml index 775ce9eea..884fcf85f 100644 --- a/queries/snowflake_queries/snowflake_0108977_suspected_user_access_query.yml +++ b/queries/snowflake_queries/snowflake_0108977_suspected_user_access_query.yml @@ -7,6 +7,7 @@ SnowflakeQuery: > -- https://community.snowflake.com/s/article/Communication-ID-0108977-Additional-Information SELECT + CREATED_ON as p_event_time, * FROM snowflake.account_usage.sessions @@ -19,7 +20,7 @@ SnowflakeQuery: > PARSE_JSON(CLIENT_ENVIRONMENT):OS = 'Windows Server 2022' ) AND p_occurs_since('1 day') - ORDER BY CREATED_ON + ORDER BY p_event_time LIMIT 100; Schedule: RateMinutes: 1440 diff --git a/queries/snowflake_queries/snowflake_0108977_suspected_user_access_threat_hunting.yml b/queries/snowflake_queries/snowflake_0108977_suspected_user_access_threat_hunting.yml index df5677ee3..d8549351a 100644 --- a/queries/snowflake_queries/snowflake_0108977_suspected_user_access_threat_hunting.yml +++ b/queries/snowflake_queries/snowflake_0108977_suspected_user_access_threat_hunting.yml @@ -6,6 +6,7 @@ SnowflakeQuery: > -- https://community.snowflake.com/s/article/Communication-ID-0108977-Additional-Information SELECT + CREATED_ON as p_event_time, * FROM snowflake.account_usage.sessions @@ -17,5 +18,5 @@ SnowflakeQuery: > AND PARSE_JSON(CLIENT_ENVIRONMENT):OS = 'Windows Server 2022' ) - ORDER BY CREATED_ON + ORDER BY p_event_time LIMIT 100; diff --git a/queries/snowflake_queries/snowflake_account_admin_assigned_query.yml b/queries/snowflake_queries/snowflake_account_admin_assigned_query.yml index 5ab609bf2..109c99ca9 100644 --- a/queries/snowflake_queries/snowflake_account_admin_assigned_query.yml +++ b/queries/snowflake_queries/snowflake_account_admin_assigned_query.yml @@ -12,18 +12,18 @@ SnowflakeQuery: > --this was adapted from a Security Feature Checklist query SELECT - created_on, + created_on as p_event_time, role, grantee_name as granted_to, granted_by FROM snowflake.account_usage.grants_to_users WHERE - created_on is NOT NULL + p_event_time is NOT NULL AND grantee_name is NOT NULL AND granted_to is NOT NULL AND role ILIKE '%admin%' AND deleted_on is NULL - AND DATEDIFF(HOUR, created_on, CURRENT_TIMESTAMP) < 24 + AND p_occurs_since('1 day') Schedule: RateMinutes: 1440 TimeoutMinutes: 3 diff --git a/queries/snowflake_queries/snowflake_external_shares_query.yml b/queries/snowflake_queries/snowflake_external_shares_query.yml index 81c1f9d0a..f752529b7 100644 --- a/queries/snowflake_queries/snowflake_external_shares_query.yml +++ b/queries/snowflake_queries/snowflake_external_shares_query.yml @@ -12,15 +12,16 @@ SnowflakeQuery: > --this was adapted from a Security Feature Checklist query SELECT + start_time as p_event_time, * FROM snowflake.account_usage.data_transfer_history WHERE - DATEDIFF(HOUR, start_time, CURRENT_TIMESTAMP) < 24 - AND start_time IS NOT NULL + p_occurs_since('1 day') + AND p_event_time IS NOT NULL AND source_cloud IS NOT NULL AND target_cloud IS NOT NULL AND bytes_transferred > 0 - ORDER BY start_time desc + ORDER BY p_event_time desc Schedule: CronExpression: "0 0 * * *" TimeoutMinutes: 2 diff --git a/queries/snowflake_queries/snowflake_login_without_mfa.py b/queries/snowflake_queries/snowflake_login_without_mfa.py index 9e7361d40..f25ec5c9c 100644 --- a/queries/snowflake_queries/snowflake_login_without_mfa.py +++ b/queries/snowflake_queries/snowflake_login_without_mfa.py @@ -1,4 +1,4 @@ -MFA_EXCEPTIONS = {"PANTHER_READONLY", "PANTHER_ADMIN"} +MFA_EXCEPTIONS = {"PANTHER_READONLY", "PANTHER_ADMIN", "PANTHERACCOUNTADMIN"} def rule(event): diff --git a/queries/snowflake_queries/snowflake_login_without_mfa_query.yml b/queries/snowflake_queries/snowflake_login_without_mfa_query.yml index fa462a34b..952b3284e 100644 --- a/queries/snowflake_queries/snowflake_login_without_mfa_query.yml +++ b/queries/snowflake_queries/snowflake_login_without_mfa_query.yml @@ -12,7 +12,7 @@ SnowflakeQuery: > --this was adapted from a Security Feature Checklist query SELECT - event_timestamp, + event_timestamp as p_event_time, user_name, client_ip, reported_client_type, @@ -21,11 +21,11 @@ SnowflakeQuery: > second_authentication_factor FROM snowflake.account_usage.login_history WHERE - DATEDIFF(HOUR, event_timestamp, CURRENT_TIMESTAMP) < 24 + p_occurs_since('1 day') AND event_type = 'LOGIN' AND first_authentication_factor = 'PASSWORD' AND second_authentication_factor IS null - ORDER BY event_timestamp desc + ORDER BY p_event_time desc Schedule: RateMinutes: 1440 TimeoutMinutes: 3 diff --git a/queries/snowflake_queries/snowflake_multiple_failed_logins_followed_by_success_query.yml b/queries/snowflake_queries/snowflake_multiple_failed_logins_followed_by_success_query.yml index e8e6c01aa..baa3fbfa0 100644 --- a/queries/snowflake_queries/snowflake_multiple_failed_logins_followed_by_success_query.yml +++ b/queries/snowflake_queries/snowflake_multiple_failed_logins_followed_by_success_query.yml @@ -17,10 +17,10 @@ SnowflakeQuery: > error_code, error_message, event_id, - event_timestamp + event_timestamp as p_event_time FROM snowflake.account_usage.login_history WHERE - DATEDIFF(HOUR, event_timestamp, CURRENT_TIMESTAMP) < 24 + p_occurs_since('1 day') AND event_type = 'LOGIN' AND client_ip != '0.0.0.0' -- filtering out unnecessary 'elided' snowflake entries ) @@ -29,11 +29,11 @@ SnowflakeQuery: > FROM login_attempts MATCH_RECOGNIZE( PARTITION BY client_ip, user_name - ORDER BY event_timestamp DESC -- backwards in time + ORDER BY p_event_time DESC -- backwards in time MEASURES match_number() as match_number, - first(event_timestamp) as successful_login_time, - last(event_timestamp) as start_of_unsuccessful_logins_time, + first(p_event_time) as successful_login_time, + last(p_event_time) as start_of_unsuccessful_logins_time, count(*) as rows_in_sequence, count(row_with_success.*) as num_successes, count(row_with_fail.*) as num_fails, diff --git a/queries/snowflake_queries/snowflake_public_role_grant_query.yml b/queries/snowflake_queries/snowflake_public_role_grant_query.yml index 1a40bda87..01cd6d0a2 100644 --- a/queries/snowflake_queries/snowflake_public_role_grant_query.yml +++ b/queries/snowflake_queries/snowflake_public_role_grant_query.yml @@ -15,10 +15,11 @@ SnowflakeQuery: > user_name, role_name, query_text, + start_time as p_event_time, end_time FROM snowflake.account_usage.query_history WHERE - DATEDIFF(HOUR, start_time, CURRENT_TIMESTAMP) < 24 + p_occurs_since('1 day') AND execution_status = 'SUCCESS' AND query_type = 'GRANT' AND query_text ILIKE '%to%public%' diff --git a/queries/snowflake_queries/snowflake_user_created_query.yml b/queries/snowflake_queries/snowflake_user_created_query.yml index 5889892e5..55195fbf4 100644 --- a/queries/snowflake_queries/snowflake_user_created_query.yml +++ b/queries/snowflake_queries/snowflake_user_created_query.yml @@ -12,6 +12,7 @@ SnowflakeQuery: > --this was adapted from a Security Feature Checklist query SELECT + start_time as p_event_time, end_time, query_type, query_text, @@ -19,7 +20,7 @@ SnowflakeQuery: > role_name FROM snowflake.account_usage.query_history WHERE - DATEDIFF(HOUR, start_time, CURRENT_TIMESTAMP) < 24 + p_occurs_since('1 day') AND execution_status = 'SUCCESS' AND query_type = 'CREATE_USER' AND query_text ILIKE '%create%user%' diff --git a/queries/snowflake_queries/snowflake_user_enabled_query.yml b/queries/snowflake_queries/snowflake_user_enabled_query.yml index 61fff6e8a..4b4ff6c5a 100644 --- a/queries/snowflake_queries/snowflake_user_enabled_query.yml +++ b/queries/snowflake_queries/snowflake_user_enabled_query.yml @@ -12,6 +12,7 @@ SnowflakeQuery: > --this was adapted from a Security Feature Checklist query SELECT + start_time as p_event_time, end_time, query_type, query_text, @@ -19,7 +20,7 @@ SnowflakeQuery: > role_name FROM snowflake.account_usage.query_history WHERE - DATEDIFF(HOUR, start_time, CURRENT_TIMESTAMP) < 24 + p_occurs_since('1 day') AND execution_status = 'SUCCESS' AND query_type = 'ALTER_USER' AND (query_text ILIKE '%alter user%set disabled = false%' From 7ff3c9f719c931831600663a68f344ad284c9c3d Mon Sep 17 00:00:00 2001 From: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> Date: Tue, 18 Jun 2024 09:54:52 -0600 Subject: [PATCH 33/35] remove greynoise luts (#1267) --- .../greynoise/advanced/noise_advanced.yml | 492 ------------------ .../greynoise/advanced/riot_advanced.yml | 492 ------------------ lookup_tables/greynoise/basic/noise_basic.yml | 492 ------------------ lookup_tables/greynoise/basic/riot_basic.yml | 492 ------------------ 4 files changed, 1968 deletions(-) delete mode 100644 lookup_tables/greynoise/advanced/noise_advanced.yml delete mode 100644 lookup_tables/greynoise/advanced/riot_advanced.yml delete mode 100644 lookup_tables/greynoise/basic/noise_basic.yml delete mode 100644 lookup_tables/greynoise/basic/riot_basic.yml diff --git a/lookup_tables/greynoise/advanced/noise_advanced.yml b/lookup_tables/greynoise/advanced/noise_advanced.yml deleted file mode 100644 index 867080234..000000000 --- a/lookup_tables/greynoise/advanced/noise_advanced.yml +++ /dev/null @@ -1,492 +0,0 @@ -AnalysisType: lookup_table -LookupName: "greynoise_noise_advanced" -Schema: GreyNoise.Noise -Refresh: - RoleARN: arn:aws:iam::893421435052:role/panther-greynoise-full-access-role - ObjectPath: s3://panther-greynoise-m5qt4p8qa7nnu5ij6orgsgpd4w58yusw2a-s3alias/luts/data/greynoise/noise_full.jsonl.gz - PeriodMinutes: 60 -Description: GreyNoise NOISE Advanced classifies the intent of IPs seen scanning the internet, including tags, CVEs, geo-data and detailed context. This version of NOISE requires an additional license - please contact your Panther or GreyNoise representative for more information. -Reference: https://docs.panther.com/enrichment/greynoise -Enabled: false -LogTypeMap: - PrimaryKey: ip - AssociatedLogTypes: - - LogType: AlphaSOC.Alert - Selectors: - - "$.event.srcIP" - - LogType: Amazon.EKS.Audit - Selectors: - - "$.sourceIPs" - - "$.spec.clusterIP" - - "$.requestObject.spec.clusterIP" - - LogType: Anomali.Indicator - Selectors: - - "ip" - - LogType: Apache.AccessCombined - Selectors: - - "remote_host_ip_address" - - LogType: Apache.AccessCommon - Selectors: - - "remote_host_ip_address" - - LogType: Atlassian.Audit - Selectors: - - "$.attributes.location.ip" - - LogType: Asana.Audit - Selectors: - - "$.context.client_ip_address" - - LogType: Auth0.Events - Selectors: - - "$.data.ip" - - "$.data.client_ip" - - LogType: AWS.ALB - Selectors: - - "clientIp" - - LogType: AWS.CloudTrail - Selectors: - # add p_any_ip_addresses because we extract ip addresses from polymorphic events - - "sourceIPAddress" - - "p_any_ip_addresses" - - LogType: AWS.GuardDuty - Selectors: - # use p_any_ip_addresses because we extract ip addresses from polymorphic events - - "p_any_ip_addresses" - - LogType: AWS.S3ServerAccess - Selectors: - - "remoteip" - - LogType: AWS.SecurityFindingFormat - Selectors: - - "$.Action.AwsApiCallAction.RemoteIpDetails.IpAddressV4" - - "$.Action.NetworkConnectionAction.RemoteIpDetails.IpAddressV4" - - LogType: AWS.TransitGatewayFlow - Selectors: - - "srcAddr" - - "dstAddr" - - LogType: AWS.VPCDns - Selectors: - # use p_any_ip_addresses because the answers are variable and not always ip addresses - - "p_any_ip_addresses" - - LogType: AWS.VPCFlow - Selectors: - - "dstAddr" - - "srcAddr" - - LogType: AWS.WAFWebACL - Selectors: - - "$.httpRequest.clientIp" - - LogType: Azure.Audit - Selectors: - - "callerIpAddress" - - "$.properties.initiatedBy.user.ipAddress" - - LogType: Azure.MonitorActivity - Selectors: - - "callerIpAddress" - - LogType: Bitwarden.Events - Selectors: - - "ipAddress" - - LogType: Box.Event - Selectors: - - "ip_address" - - LogType: CarbonBlack.AlertV2 - Selectors: - - "device_external_ip" - - "device_internal_ip" - - "netconn_local_ip" - - "netconn_local_ipv4" - - "netconn_local_ipv6" - - "netconn_remote_ip" - - "netconn_remote_ipv4" - - "netconn_remote_ipv6" - - LogType: CarbonBlack.Audit - Selectors: - - "clientIp" - - LogType: CarbonBlack.EndpointEvent - Selectors: - - "device_external_ip" - - "local_ip" - - "remote_ip" - - "netconn_proxy_ip" - - LogType: CarbonBlack.WatchlistHit - Selectors: - - "device_external_ip" - - "device_internal_ip" - - LogType: CiscoUmbrella.CloudFirewall - Selectors: - - "destinationIp" - - "sourceIp" - - LogType: CiscoUmbrella.DNS - Selectors: - - "externalIp" - - "internalIp" - - LogType: CiscoUmbrella.IP - Selectors: - - "destinationIp" - - "sourceIp" - - LogType: CiscoUmbrella.Proxy - Selectors: - - "destinationIp" - - "externalIp" - - "internalIp" - - LogType: Cloudflare.Audit - Selectors: - - "ActorIP" - - LogType: Cloudflare.HttpRequest - Selectors: - - "ClientIP" - - "EdgeServerIP" - - "OriginIP" - - LogType: Cloudflare.Firewall - Selectors: - - "ClientIP" - - LogType: Cloudflare.Spectrum - Selectors: - - "ClientIP" - - "OriginIP" - - LogType: Crowdstrike.CriticalFile - Selectors: - - "aip" - - LogType: Crowdstrike.ActivityAudit - Selectors: - - "UserIp" - - LogType: Crowdstrike.DetectionSummary - Selectors: - - "LocalIP" - - "OriginSourceIpAddress" - - LogType: Crowdstrike.DNSRequest - Selectors: - - "IpAddress" - - LogType: Crowdstrike.GroupIdentity - Selectors: - - "aip" - - LogType: Crowdstrike.AIDMaster - Selectors: - - "aip" - - LogType: Crowdstrike.ManagedAssets - Selectors: - - "GatewayIP" - - LogType: Crowdstrike.NetworkConnect - Selectors: - - "LocalAddressIP4" - - "LocalAddressIP6" - - "RemoteAddressIP4" - - "RemoteAddressIP6" - - LogType: Crowdstrike.NetworkListen - Selectors: - - "LocalAddressIP4" - - "LocalAddressIP6" - - "RemoteAddressIP4" - - "RemoteAddressIP6" - - LogType: Crowdstrike.NotManagedAssets - Selectors: - - "aip" - - "CurrentLocalIP" - - LogType: Crowdstrike.ProcessRollup2 - Selectors: - - "aip" - - LogType: Crowdstrike.ProcessRollup2Stats - Selectors: - - "aip" - - LogType: Crowdstrike.SyntheticProcessRollup2 - Selectors: - - "aip" - - LogType: Crowdstrike.Unknown - Selectors: - - "aip" - - LogType: Crowdstrike.UserIdentity - Selectors: - - "aip" - - LogType: Crowdstrike.UserLogonLogoff - Selectors: - - "aip" - - LogType: Crowdstrike.FDREvent - Selectors: - - "p_any_ip_addresses" - - LogType: Dropbox.TeamEvent - Selectors: - - "$.origin.geo_location.ip_address" - - LogType: Duo.Authentication - Selectors: - - "$.access_device.ip" - - "$.auth_device.ip" - - LogType: GCP.AuditLog - Selectors: - - "$.protoPayload.requestMetadata.callerIP" - - "$.httpRequest.remoteIP" - - "$.httpRequest.serverIP" - - LogType: GCP.HTTPLoadBalancer - Selectors: - - "$.jsonPayload.removeIp" - - "$.httpRequest.remoteIp" - - "$.httpRequest.serverIp" - - LogType: GitHub.Audit - Selectors: - - "actor_ip" - - LogType: GitLab.API - Selectors: - - "remote_ip" - - LogType: GitLab.Audit - Selectors: - - "ip_address" - - LogType: GitLab.Production - Selectors: - - "remote_ip" - - LogType: Gravitational.TeleportAudit - Selectors: - - "dst_addr" - - "src_addr" - - LogType: GSuite.ActivityEvent - Selectors: - - "ipAddress" - - LogType: GSuite.Reports - Selectors: - - "ipAddress" - - LogType: Jamfpro.ComplianceReporter - Selectors: - - "$.process.terminal_id.ip_address" - - "$.socket_inet.ip_address" - - LogType: Jamfpro.Login - Selectors: - - "ipAddress" - - LogType: Juniper.Access - Selectors: - # use p_any_ip_addresses because we extract ip addresses but have no fields - - "p_any_ip_addresses" - - LogType: Juniper.Audit - Selectors: - - "login_ip" - - LogType: Juniper.Firewall - Selectors: - - "SRC" - - "DST" - - LogType: Juniper.Security - Selectors: - - "source_ip" - - LogType: Lacework.AgentManagement - Selectors: - - "IP_ADDR" - - LogType: Lacework.Applications - Selectors: - - "$.PROPS_MACHINE.ip_addr" - - LogType: Lacework.DNSQuery - Selectors: - - "DNS_SERVER_IP" - - "HOST_IP_ADDR" - - LogType: Lacework.Events - Selectors: - # use p_any_ip_addresses because we extract ip addresses but fields are variable - - "p_any_ip_addresses" - - LogType: Lacework.Interfaces - Selectors: - - "IP_ADDR" - - LogType: Lacework.InternalIPA - Selectors: - - "IP_ADDR" - - LogType: Lacework.MachineSummary - Selectors: - - "PRIMARY_IP_ADDR" - - LogType: Lacework.PodSummary - Selectors: - - "PRIMARY_IP_ADDR" - - LogType: Lacework.UserLogin - Selectors: - - "SOURCE_IP_ADDR" - - LogType: Linux.Auditd - Selectors: - - "addr" - - "ip" - - LogType: Microsoft365.Audit.AzureActiveDirectory - Selectors: - - "ActorIpAddress" - - "ClientIP" - - LogType: Microsoft365.Audit.Exchange - Selectors: - - "ClientIP" - - "ClientIPAddress" - - LogType: Microsoft365.Audit.SharePoint - Selectors: - - "ClientIP" - - LogType: Microsoft365.Audit.General - Selectors: - - "ClientIP" - - LogType: Microsoft365.DLP.All - Selectors: - - "ClientIP" - - LogType: MicrosoftGraph.SecurityAlert - Selectors: - # use p_any_ip_addresses because we extract ip addresses but fields are variable - - "p_any_ip_addresses" - - LogType: MongoDB.OrganizationEvent - Selectors: - - "remoteAddress" - - LogType: MongoDB.ProjectEvent - Selectors: - - "remoteAddress" - - LogType: Nginx.Access - Selectors: - - "remoteAddr" - - LogType: Notion.AuditLogs - Selectors: - - "$.event.ip_address" - - LogType: Okta.SystemLog - Selectors: - - "$.client.ipAddress" - - LogType: OneLogin.Events - Selectors: - - "ipaddr" - - LogType: OnePassword.AuditEvent - Selectors: - - "$.session.ip" - - LogType: OnePassword.ItemUsage - Selectors: - - "$.client.ip_address" - - LogType: OnePassword.SignInAttempt - Selectors: - - "$.client.ip_address" - - LogType: OSSEC.EventInfo - Selectors: - - "agentip" - - "dstip" - - "srcip" - - LogType: Panther.Audit - Selectors: - - "sourceIP" - - LogType: Tenable.Vulnerability - Selectors: - - "$.asset.ipv6" - - "$.asset.ipv4" - - LogType: Salesforce.Login - Selectors: - - "CLIENT_IP" - - "SOURCE_IP" - - LogType: Salesforce.LoginAs - Selectors: - - "CLIENT_IP" - - LogType: Salesforce.Logout - Selectors: - - "CLIENT_IP" - - LogType: Salesforce.URI - Selectors: - - "CLIENT_IP" - - LogType: SentinelOne.DeepVisibility - Selectors: - - "$.event.sourceAddress.address" - - "$.event.destinationAddress.address" - - "$.event.local.address" - - LogType: SentinelOne.DeepVisibilityV2 - Selectors: - - "src_ip_address" - - "dst_ip_address" - - "src_endpoint_ip_address" - - LogType: Slack.AccessLogs - Selectors: - - "ip" - - LogType: Slack.AuditLogs - Selectors: - - "$.context.ip_address" - - LogType: Sophos.Central - Selectors: - - "$.source_info.ip" - - LogType: Suricata.Alert - Selectors: - - "$.tls.sni" - - "$.dest_ip" - - "$.src_ip" - - LogType: Suricata.Anomaly - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.DHCP - Selectors: - - "$.dest_ip" - - "$.dhcp.assigned_ip" - - "$.src_ip" - - LogType: Suricata.DNS - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.FileInfo - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.Flow - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.HTTP - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.SSH - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.TLS - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Sysdig.Audit - Selectors: - - "$.content.userOriginIP" - - LogType: Tines.Audit - Selectors: - - "request_ip" - - LogType: Workday.Activity - Selectors: - - "ipAddress" - - LogType: Workday.SignOnAttempt - Selectors: - - "Session_IP_Address" - - LogType: Zeek.Conn - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.DHCP - Selectors: - - "requested_addr" - - LogType: Zeek.DNS - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.DPD - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.HTTP - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.Notice - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.NTP - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.SIP - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.Software - Selectors: - - "host" - - LogType: Zeek.Ssh - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.Ssl - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.Tunnel - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.Weird - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zendesk.Audit - Selectors: - - "ip_address" - - LogType: Zoom.Activity - Selectors: - - "ip_address" diff --git a/lookup_tables/greynoise/advanced/riot_advanced.yml b/lookup_tables/greynoise/advanced/riot_advanced.yml deleted file mode 100644 index b3dd4aac1..000000000 --- a/lookup_tables/greynoise/advanced/riot_advanced.yml +++ /dev/null @@ -1,492 +0,0 @@ -AnalysisType: lookup_table -LookupName: "greynoise_riot_advanced" -Schema: GreyNoise.RIOT -Refresh: - RoleARN: arn:aws:iam::893421435052:role/panther-greynoise-full-access-role - ObjectPath: s3://panther-greynoise-m5qt4p8qa7nnu5ij6orgsgpd4w58yusw2a-s3alias/luts/data/greynoise/riot_full.jsonl.gz - PeriodMinutes: 240 -Description: GreyNoise RIOT Advanced identifies unpublished or dynamic IPs of common business services that are difficult for security teams to track, with detailed context. This version of RIOT requires an additional license - please contact your Panther or GreyNoise representative for more information. -Reference: https://docs.panther.com/enrichment/greynoise -Enabled: false -LogTypeMap: - PrimaryKey: ip_cidr - AssociatedLogTypes: - - LogType: AlphaSOC.Alert - Selectors: - - "$.event.srcIP" - - LogType: Amazon.EKS.Audit - Selectors: - - "$.sourceIPs" - - "$.spec.clusterIP" - - "$.requestObject.spec.clusterIP" - - LogType: Anomali.Indicator - Selectors: - - "ip" - - LogType: Apache.AccessCombined - Selectors: - - "remote_host_ip_address" - - LogType: Apache.AccessCommon - Selectors: - - "remote_host_ip_address" - - LogType: Atlassian.Audit - Selectors: - - "$.attributes.location.ip" - - LogType: Asana.Audit - Selectors: - - "$.context.client_ip_address" - - LogType: Auth0.Events - Selectors: - - "$.data.ip" - - "$.data.client_ip" - - LogType: AWS.ALB - Selectors: - - "clientIp" - - LogType: AWS.CloudTrail - Selectors: - # add p_any_ip_addresses because we extract ip addresses from polymorphic events - - "sourceIPAddress" - - "p_any_ip_addresses" - - LogType: AWS.GuardDuty - Selectors: - # use p_any_ip_addresses because we extract ip addresses from polymorphic events - - "p_any_ip_addresses" - - LogType: AWS.S3ServerAccess - Selectors: - - "remoteip" - - LogType: AWS.SecurityFindingFormat - Selectors: - - "$.Action.AwsApiCallAction.RemoteIpDetails.IpAddressV4" - - "$.Action.NetworkConnectionAction.RemoteIpDetails.IpAddressV4" - - LogType: AWS.TransitGatewayFlow - Selectors: - - "srcAddr" - - "dstAddr" - - LogType: AWS.VPCDns - Selectors: - # use p_any_ip_addresses because the answers are variable and not always ip addresses - - "p_any_ip_addresses" - - LogType: AWS.VPCFlow - Selectors: - - "dstAddr" - - "srcAddr" - - LogType: AWS.WAFWebACL - Selectors: - - "$.httpRequest.clientIp" - - LogType: Azure.Audit - Selectors: - - "callerIpAddress" - - "$.properties.initiatedBy.user.ipAddress" - - LogType: Azure.MonitorActivity - Selectors: - - "callerIpAddress" - - LogType: Bitwarden.Events - Selectors: - - "ipAddress" - - LogType: Box.Event - Selectors: - - "ip_address" - - LogType: CarbonBlack.AlertV2 - Selectors: - - "device_external_ip" - - "device_internal_ip" - - "netconn_local_ip" - - "netconn_local_ipv4" - - "netconn_local_ipv6" - - "netconn_remote_ip" - - "netconn_remote_ipv4" - - "netconn_remote_ipv6" - - LogType: CarbonBlack.Audit - Selectors: - - "clientIp" - - LogType: CarbonBlack.EndpointEvent - Selectors: - - "device_external_ip" - - "local_ip" - - "remote_ip" - - "netconn_proxy_ip" - - LogType: CarbonBlack.WatchlistHit - Selectors: - - "device_external_ip" - - "device_internal_ip" - - LogType: CiscoUmbrella.CloudFirewall - Selectors: - - "destinationIp" - - "sourceIp" - - LogType: CiscoUmbrella.DNS - Selectors: - - "externalIp" - - "internalIp" - - LogType: CiscoUmbrella.IP - Selectors: - - "destinationIp" - - "sourceIp" - - LogType: CiscoUmbrella.Proxy - Selectors: - - "destinationIp" - - "externalIp" - - "internalIp" - - LogType: Cloudflare.Audit - Selectors: - - "ActorIP" - - LogType: Cloudflare.HttpRequest - Selectors: - - "ClientIP" - - "EdgeServerIP" - - "OriginIP" - - LogType: Cloudflare.Firewall - Selectors: - - "ClientIP" - - LogType: Cloudflare.Spectrum - Selectors: - - "ClientIP" - - "OriginIP" - - LogType: Crowdstrike.CriticalFile - Selectors: - - "aip" - - LogType: Crowdstrike.ActivityAudit - Selectors: - - "UserIp" - - LogType: Crowdstrike.DetectionSummary - Selectors: - - "LocalIP" - - "OriginSourceIpAddress" - - LogType: Crowdstrike.DNSRequest - Selectors: - - "IpAddress" - - LogType: Crowdstrike.GroupIdentity - Selectors: - - "aip" - - LogType: Crowdstrike.AIDMaster - Selectors: - - "aip" - - LogType: Crowdstrike.ManagedAssets - Selectors: - - "GatewayIP" - - LogType: Crowdstrike.NetworkConnect - Selectors: - - "LocalAddressIP4" - - "LocalAddressIP6" - - "RemoteAddressIP4" - - "RemoteAddressIP6" - - LogType: Crowdstrike.NetworkListen - Selectors: - - "LocalAddressIP4" - - "LocalAddressIP6" - - "RemoteAddressIP4" - - "RemoteAddressIP6" - - LogType: Crowdstrike.NotManagedAssets - Selectors: - - "aip" - - "CurrentLocalIP" - - LogType: Crowdstrike.ProcessRollup2 - Selectors: - - "aip" - - LogType: Crowdstrike.ProcessRollup2Stats - Selectors: - - "aip" - - LogType: Crowdstrike.SyntheticProcessRollup2 - Selectors: - - "aip" - - LogType: Crowdstrike.Unknown - Selectors: - - "aip" - - LogType: Crowdstrike.UserIdentity - Selectors: - - "aip" - - LogType: Crowdstrike.UserLogonLogoff - Selectors: - - "aip" - - LogType: Crowdstrike.FDREvent - Selectors: - - "p_any_ip_addresses" - - LogType: Dropbox.TeamEvent - Selectors: - - "$.origin.geo_location.ip_address" - - LogType: Duo.Authentication - Selectors: - - "$.access_device.ip" - - "$.auth_device.ip" - - LogType: GCP.AuditLog - Selectors: - - "$.protoPayload.requestMetadata.callerIP" - - "$.httpRequest.remoteIP" - - "$.httpRequest.serverIP" - - LogType: GCP.HTTPLoadBalancer - Selectors: - - "$.jsonPayload.removeIp" - - "$.httpRequest.remoteIp" - - "$.httpRequest.serverIp" - - LogType: GitHub.Audit - Selectors: - - "actor_ip" - - LogType: GitLab.API - Selectors: - - "remote_ip" - - LogType: GitLab.Audit - Selectors: - - "ip_address" - - LogType: GitLab.Production - Selectors: - - "remote_ip" - - LogType: Gravitational.TeleportAudit - Selectors: - - "dst_addr" - - "src_addr" - - LogType: GSuite.ActivityEvent - Selectors: - - "ipAddress" - - LogType: GSuite.Reports - Selectors: - - "ipAddress" - - LogType: Jamfpro.ComplianceReporter - Selectors: - - "$.process.terminal_id.ip_address" - - "$.socket_inet.ip_address" - - LogType: Jamfpro.Login - Selectors: - - "ipAddress" - - LogType: Juniper.Access - Selectors: - # use p_any_ip_addresses because we extract ip addresses but have no fields - - "p_any_ip_addresses" - - LogType: Juniper.Audit - Selectors: - - "login_ip" - - LogType: Juniper.Firewall - Selectors: - - "SRC" - - "DST" - - LogType: Juniper.Security - Selectors: - - "source_ip" - - LogType: Lacework.AgentManagement - Selectors: - - "IP_ADDR" - - LogType: Lacework.Applications - Selectors: - - "$.PROPS_MACHINE.ip_addr" - - LogType: Lacework.DNSQuery - Selectors: - - "DNS_SERVER_IP" - - "HOST_IP_ADDR" - - LogType: Lacework.Events - Selectors: - # use p_any_ip_addresses because we extract ip addresses but fields are variable - - "p_any_ip_addresses" - - LogType: Lacework.Interfaces - Selectors: - - "IP_ADDR" - - LogType: Lacework.InternalIPA - Selectors: - - "IP_ADDR" - - LogType: Lacework.MachineSummary - Selectors: - - "PRIMARY_IP_ADDR" - - LogType: Lacework.PodSummary - Selectors: - - "PRIMARY_IP_ADDR" - - LogType: Lacework.UserLogin - Selectors: - - "SOURCE_IP_ADDR" - - LogType: Linux.Auditd - Selectors: - - "addr" - - "ip" - - LogType: Microsoft365.Audit.AzureActiveDirectory - Selectors: - - "ActorIpAddress" - - "ClientIP" - - LogType: Microsoft365.Audit.Exchange - Selectors: - - "ClientIP" - - "ClientIPAddress" - - LogType: Microsoft365.Audit.SharePoint - Selectors: - - "ClientIP" - - LogType: Microsoft365.Audit.General - Selectors: - - "ClientIP" - - LogType: Microsoft365.DLP.All - Selectors: - - "ClientIP" - - LogType: MicrosoftGraph.SecurityAlert - Selectors: - # use p_any_ip_addresses because we extract ip addresses but fields are variable - - "p_any_ip_addresses" - - LogType: MongoDB.OrganizationEvent - Selectors: - - "remoteAddress" - - LogType: MongoDB.ProjectEvent - Selectors: - - "remoteAddress" - - LogType: Nginx.Access - Selectors: - - "remoteAddr" - - LogType: Notion.AuditLogs - Selectors: - - "$.event.ip_address" - - LogType: Okta.SystemLog - Selectors: - - "$.client.ipAddress" - - LogType: OneLogin.Events - Selectors: - - "ipaddr" - - LogType: OnePassword.AuditEvent - Selectors: - - "$.session.ip" - - LogType: OnePassword.ItemUsage - Selectors: - - "$.client.ip_address" - - LogType: OnePassword.SignInAttempt - Selectors: - - "$.client.ip_address" - - LogType: OSSEC.EventInfo - Selectors: - - "agentip" - - "dstip" - - "srcip" - - LogType: Panther.Audit - Selectors: - - "sourceIP" - - LogType: Tenable.Vulnerability - Selectors: - - "$.asset.ipv6" - - "$.asset.ipv4" - - LogType: Salesforce.Login - Selectors: - - "CLIENT_IP" - - "SOURCE_IP" - - LogType: Salesforce.LoginAs - Selectors: - - "CLIENT_IP" - - LogType: Salesforce.Logout - Selectors: - - "CLIENT_IP" - - LogType: Salesforce.URI - Selectors: - - "CLIENT_IP" - - LogType: SentinelOne.DeepVisibility - Selectors: - - "$.event.sourceAddress.address" - - "$.event.destinationAddress.address" - - "$.event.local.address" - - LogType: SentinelOne.DeepVisibilityV2 - Selectors: - - "src_ip_address" - - "dst_ip_address" - - "src_endpoint_ip_address" - - LogType: Slack.AccessLogs - Selectors: - - "ip" - - LogType: Slack.AuditLogs - Selectors: - - "$.context.ip_address" - - LogType: Sophos.Central - Selectors: - - "$.source_info.ip" - - LogType: Suricata.Alert - Selectors: - - "$.tls.sni" - - "$.dest_ip" - - "$.src_ip" - - LogType: Suricata.Anomaly - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.DHCP - Selectors: - - "$.dest_ip" - - "$.dhcp.assigned_ip" - - "$.src_ip" - - LogType: Suricata.DNS - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.FileInfo - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.Flow - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.HTTP - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.SSH - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.TLS - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Sysdig.Audit - Selectors: - - "$.content.userOriginIP" - - LogType: Tines.Audit - Selectors: - - "request_ip" - - LogType: Workday.Activity - Selectors: - - "ipAddress" - - LogType: Workday.SignOnAttempt - Selectors: - - "Session_IP_Address" - - LogType: Zeek.Conn - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.DHCP - Selectors: - - "requested_addr" - - LogType: Zeek.DNS - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.DPD - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.HTTP - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.Notice - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.NTP - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.SIP - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.Software - Selectors: - - "host" - - LogType: Zeek.Ssh - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.Ssl - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.Tunnel - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.Weird - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zendesk.Audit - Selectors: - - "ip_address" - - LogType: Zoom.Activity - Selectors: - - "ip_address" diff --git a/lookup_tables/greynoise/basic/noise_basic.yml b/lookup_tables/greynoise/basic/noise_basic.yml deleted file mode 100644 index 0a3310bb3..000000000 --- a/lookup_tables/greynoise/basic/noise_basic.yml +++ /dev/null @@ -1,492 +0,0 @@ -AnalysisType: lookup_table -LookupName: "greynoise_noise_basic" -Schema: GreyNoise.Noise -Refresh: - RoleARN: arn:aws:iam::893421435052:role/panther-greynoise-basic-access-role - ObjectPath: s3://panther-greynoise-m5qt4p8qa7nnu5ij6orgsgpd4w58yusw2a-s3alias/luts/data/greynoise/noise_basic.jsonl.gz - PeriodMinutes: 60 -Description: GreyNoise NOISE Basic classifies IPs seen scanning the internet based on intent - benign, malicious, and unknown. This version of NOISE is free with Panther. -Reference: https://docs.panther.com/enrichment/greynoise -Enabled: true -LogTypeMap: - PrimaryKey: ip - AssociatedLogTypes: - - LogType: AlphaSOC.Alert - Selectors: - - "$.event.srcIP" - - LogType: Amazon.EKS.Audit - Selectors: - - "$.sourceIPs" - - "$.spec.clusterIP" - - "$.requestObject.spec.clusterIP" - - LogType: Anomali.Indicator - Selectors: - - "ip" - - LogType: Apache.AccessCombined - Selectors: - - "remote_host_ip_address" - - LogType: Apache.AccessCommon - Selectors: - - "remote_host_ip_address" - - LogType: Atlassian.Audit - Selectors: - - "$.attributes.location.ip" - - LogType: Asana.Audit - Selectors: - - "$.context.client_ip_address" - - LogType: Auth0.Events - Selectors: - - "$.data.ip" - - "$.data.client_ip" - - LogType: AWS.ALB - Selectors: - - "clientIp" - - LogType: AWS.CloudTrail - Selectors: - # add p_any_ip_addresses because we extract ip addresses from polymorphic events - - "sourceIPAddress" - - "p_any_ip_addresses" - - LogType: AWS.GuardDuty - Selectors: - # use p_any_ip_addresses because we extract ip addresses from polymorphic events - - "p_any_ip_addresses" - - LogType: AWS.S3ServerAccess - Selectors: - - "remoteip" - - LogType: AWS.SecurityFindingFormat - Selectors: - - "$.Action.AwsApiCallAction.RemoteIpDetails.IpAddressV4" - - "$.Action.NetworkConnectionAction.RemoteIpDetails.IpAddressV4" - - LogType: AWS.TransitGatewayFlow - Selectors: - - "srcAddr" - - "dstAddr" - - LogType: AWS.VPCDns - Selectors: - # use p_any_ip_addresses because the answers are variable and not always ip addresses - - "p_any_ip_addresses" - - LogType: AWS.VPCFlow - Selectors: - - "dstAddr" - - "srcAddr" - - LogType: AWS.WAFWebACL - Selectors: - - "$.httpRequest.clientIp" - - LogType: Azure.Audit - Selectors: - - "callerIpAddress" - - "$.properties.initiatedBy.user.ipAddress" - - LogType: Azure.MonitorActivity - Selectors: - - "callerIpAddress" - - LogType: Bitwarden.Events - Selectors: - - "ipAddress" - - LogType: Box.Event - Selectors: - - "ip_address" - - LogType: CarbonBlack.AlertV2 - Selectors: - - "device_external_ip" - - "device_internal_ip" - - "netconn_local_ip" - - "netconn_local_ipv4" - - "netconn_local_ipv6" - - "netconn_remote_ip" - - "netconn_remote_ipv4" - - "netconn_remote_ipv6" - - LogType: CarbonBlack.Audit - Selectors: - - "clientIp" - - LogType: CarbonBlack.EndpointEvent - Selectors: - - "device_external_ip" - - "local_ip" - - "remote_ip" - - "netconn_proxy_ip" - - LogType: CarbonBlack.WatchlistHit - Selectors: - - "device_external_ip" - - "device_internal_ip" - - LogType: CiscoUmbrella.CloudFirewall - Selectors: - - "destinationIp" - - "sourceIp" - - LogType: CiscoUmbrella.DNS - Selectors: - - "externalIp" - - "internalIp" - - LogType: CiscoUmbrella.IP - Selectors: - - "destinationIp" - - "sourceIp" - - LogType: CiscoUmbrella.Proxy - Selectors: - - "destinationIp" - - "externalIp" - - "internalIp" - - LogType: Cloudflare.Audit - Selectors: - - "ActorIP" - - LogType: Cloudflare.HttpRequest - Selectors: - - "ClientIP" - - "EdgeServerIP" - - "OriginIP" - - LogType: Cloudflare.Firewall - Selectors: - - "ClientIP" - - LogType: Cloudflare.Spectrum - Selectors: - - "ClientIP" - - "OriginIP" - - LogType: Crowdstrike.CriticalFile - Selectors: - - "aip" - - LogType: Crowdstrike.ActivityAudit - Selectors: - - "UserIp" - - LogType: Crowdstrike.DetectionSummary - Selectors: - - "LocalIP" - - "OriginSourceIpAddress" - - LogType: Crowdstrike.DNSRequest - Selectors: - - "IpAddress" - - LogType: Crowdstrike.GroupIdentity - Selectors: - - "aip" - - LogType: Crowdstrike.AIDMaster - Selectors: - - "aip" - - LogType: Crowdstrike.ManagedAssets - Selectors: - - "GatewayIP" - - LogType: Crowdstrike.NetworkConnect - Selectors: - - "LocalAddressIP4" - - "LocalAddressIP6" - - "RemoteAddressIP4" - - "RemoteAddressIP6" - - LogType: Crowdstrike.NetworkListen - Selectors: - - "LocalAddressIP4" - - "LocalAddressIP6" - - "RemoteAddressIP4" - - "RemoteAddressIP6" - - LogType: Crowdstrike.NotManagedAssets - Selectors: - - "aip" - - "CurrentLocalIP" - - LogType: Crowdstrike.ProcessRollup2 - Selectors: - - "aip" - - LogType: Crowdstrike.ProcessRollup2Stats - Selectors: - - "aip" - - LogType: Crowdstrike.SyntheticProcessRollup2 - Selectors: - - "aip" - - LogType: Crowdstrike.Unknown - Selectors: - - "aip" - - LogType: Crowdstrike.UserIdentity - Selectors: - - "aip" - - LogType: Crowdstrike.UserLogonLogoff - Selectors: - - "aip" - - LogType: Crowdstrike.FDREvent - Selectors: - - "p_any_ip_addresses" - - LogType: Dropbox.TeamEvent - Selectors: - - "$.origin.geo_location.ip_address" - - LogType: Duo.Authentication - Selectors: - - "$.access_device.ip" - - "$.auth_device.ip" - - LogType: GCP.AuditLog - Selectors: - - "$.protoPayload.requestMetadata.callerIP" - - "$.httpRequest.remoteIP" - - "$.httpRequest.serverIP" - - LogType: GCP.HTTPLoadBalancer - Selectors: - - "$.jsonPayload.removeIp" - - "$.httpRequest.remoteIp" - - "$.httpRequest.serverIp" - - LogType: GitHub.Audit - Selectors: - - "actor_ip" - - LogType: GitLab.API - Selectors: - - "remote_ip" - - LogType: GitLab.Audit - Selectors: - - "ip_address" - - LogType: GitLab.Production - Selectors: - - "remote_ip" - - LogType: Gravitational.TeleportAudit - Selectors: - - "dst_addr" - - "src_addr" - - LogType: GSuite.ActivityEvent - Selectors: - - "ipAddress" - - LogType: GSuite.Reports - Selectors: - - "ipAddress" - - LogType: Jamfpro.ComplianceReporter - Selectors: - - "$.process.terminal_id.ip_address" - - "$.socket_inet.ip_address" - - LogType: Jamfpro.Login - Selectors: - - "ipAddress" - - LogType: Juniper.Access - Selectors: - # use p_any_ip_addresses because we extract ip addresses but have no fields - - "p_any_ip_addresses" - - LogType: Juniper.Audit - Selectors: - - "login_ip" - - LogType: Juniper.Firewall - Selectors: - - "SRC" - - "DST" - - LogType: Juniper.Security - Selectors: - - "source_ip" - - LogType: Lacework.AgentManagement - Selectors: - - "IP_ADDR" - - LogType: Lacework.Applications - Selectors: - - "$.PROPS_MACHINE.ip_addr" - - LogType: Lacework.DNSQuery - Selectors: - - "DNS_SERVER_IP" - - "HOST_IP_ADDR" - - LogType: Lacework.Events - Selectors: - # use p_any_ip_addresses because we extract ip addresses but fields are variable - - "p_any_ip_addresses" - - LogType: Lacework.Interfaces - Selectors: - - "IP_ADDR" - - LogType: Lacework.InternalIPA - Selectors: - - "IP_ADDR" - - LogType: Lacework.MachineSummary - Selectors: - - "PRIMARY_IP_ADDR" - - LogType: Lacework.PodSummary - Selectors: - - "PRIMARY_IP_ADDR" - - LogType: Lacework.UserLogin - Selectors: - - "SOURCE_IP_ADDR" - - LogType: Linux.Auditd - Selectors: - - "addr" - - "ip" - - LogType: Microsoft365.Audit.AzureActiveDirectory - Selectors: - - "ActorIpAddress" - - "ClientIP" - - LogType: Microsoft365.Audit.Exchange - Selectors: - - "ClientIP" - - "ClientIPAddress" - - LogType: Microsoft365.Audit.SharePoint - Selectors: - - "ClientIP" - - LogType: Microsoft365.Audit.General - Selectors: - - "ClientIP" - - LogType: Microsoft365.DLP.All - Selectors: - - "ClientIP" - - LogType: MicrosoftGraph.SecurityAlert - Selectors: - # use p_any_ip_addresses because we extract ip addresses but fields are variable - - "p_any_ip_addresses" - - LogType: MongoDB.OrganizationEvent - Selectors: - - "remoteAddress" - - LogType: MongoDB.ProjectEvent - Selectors: - - "remoteAddress" - - LogType: Nginx.Access - Selectors: - - "remoteAddr" - - LogType: Notion.AuditLogs - Selectors: - - "$.event.ip_address" - - LogType: Okta.SystemLog - Selectors: - - "$.client.ipAddress" - - LogType: OneLogin.Events - Selectors: - - "ipaddr" - - LogType: OnePassword.AuditEvent - Selectors: - - "$.session.ip" - - LogType: OnePassword.ItemUsage - Selectors: - - "$.client.ip_address" - - LogType: OnePassword.SignInAttempt - Selectors: - - "$.client.ip_address" - - LogType: OSSEC.EventInfo - Selectors: - - "agentip" - - "dstip" - - "srcip" - - LogType: Panther.Audit - Selectors: - - "sourceIP" - - LogType: Tenable.Vulnerability - Selectors: - - "$.asset.ipv6" - - "$.asset.ipv4" - - LogType: Salesforce.Login - Selectors: - - "CLIENT_IP" - - "SOURCE_IP" - - LogType: Salesforce.LoginAs - Selectors: - - "CLIENT_IP" - - LogType: Salesforce.Logout - Selectors: - - "CLIENT_IP" - - LogType: Salesforce.URI - Selectors: - - "CLIENT_IP" - - LogType: SentinelOne.DeepVisibility - Selectors: - - "$.event.sourceAddress.address" - - "$.event.destinationAddress.address" - - "$.event.local.address" - - LogType: SentinelOne.DeepVisibilityV2 - Selectors: - - "src_ip_address" - - "dst_ip_address" - - "src_endpoint_ip_address" - - LogType: Slack.AccessLogs - Selectors: - - "ip" - - LogType: Slack.AuditLogs - Selectors: - - "$.context.ip_address" - - LogType: Sophos.Central - Selectors: - - "$.source_info.ip" - - LogType: Suricata.Alert - Selectors: - - "$.tls.sni" - - "$.dest_ip" - - "$.src_ip" - - LogType: Suricata.Anomaly - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.DHCP - Selectors: - - "$.dest_ip" - - "$.dhcp.assigned_ip" - - "$.src_ip" - - LogType: Suricata.DNS - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.FileInfo - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.Flow - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.HTTP - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.SSH - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.TLS - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Sysdig.Audit - Selectors: - - "$.content.userOriginIP" - - LogType: Tines.Audit - Selectors: - - "request_ip" - - LogType: Workday.Activity - Selectors: - - "ipAddress" - - LogType: Workday.SignOnAttempt - Selectors: - - "Session_IP_Address" - - LogType: Zeek.Conn - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.DHCP - Selectors: - - "requested_addr" - - LogType: Zeek.DNS - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.DPD - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.HTTP - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.Notice - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.NTP - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.SIP - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.Software - Selectors: - - "host" - - LogType: Zeek.Ssh - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.Ssl - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.Tunnel - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.Weird - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zendesk.Audit - Selectors: - - "ip_address" - - LogType: Zoom.Activity - Selectors: - - "ip_address" diff --git a/lookup_tables/greynoise/basic/riot_basic.yml b/lookup_tables/greynoise/basic/riot_basic.yml deleted file mode 100644 index 557d8c741..000000000 --- a/lookup_tables/greynoise/basic/riot_basic.yml +++ /dev/null @@ -1,492 +0,0 @@ -AnalysisType: lookup_table -LookupName: "greynoise_riot_basic" -Schema: GreyNoise.RIOT -Refresh: - RoleARN: arn:aws:iam::893421435052:role/panther-greynoise-basic-access-role - ObjectPath: s3://panther-greynoise-m5qt4p8qa7nnu5ij6orgsgpd4w58yusw2a-s3alias/luts/data/greynoise/riot_basic.jsonl.gz - PeriodMinutes: 240 -Description: GreyNoise RIOT Basic identifies unpublished or dynamic IPs of common business services that are difficult for security teams to track. This basic version of RIOT is free with Panther. -Reference: https://docs.panther.com/enrichment/greynoise -Enabled: true -LogTypeMap: - PrimaryKey: ip_cidr - AssociatedLogTypes: - - LogType: AlphaSOC.Alert - Selectors: - - "$.event.srcIP" - - LogType: Amazon.EKS.Audit - Selectors: - - "$.sourceIPs" - - "$.spec.clusterIP" - - "$.requestObject.spec.clusterIP" - - LogType: Anomali.Indicator - Selectors: - - "ip" - - LogType: Apache.AccessCombined - Selectors: - - "remote_host_ip_address" - - LogType: Apache.AccessCommon - Selectors: - - "remote_host_ip_address" - - LogType: Atlassian.Audit - Selectors: - - "$.attributes.location.ip" - - LogType: Asana.Audit - Selectors: - - "$.context.client_ip_address" - - LogType: Auth0.Events - Selectors: - - "$.data.ip" - - "$.data.client_ip" - - LogType: AWS.ALB - Selectors: - - "clientIp" - - LogType: AWS.CloudTrail - Selectors: - # add p_any_ip_addresses because we extract ip addresses from polymorphic events - - "sourceIPAddress" - - "p_any_ip_addresses" - - LogType: AWS.GuardDuty - Selectors: - # use p_any_ip_addresses because we extract ip addresses from polymorphic events - - "p_any_ip_addresses" - - LogType: AWS.S3ServerAccess - Selectors: - - "remoteip" - - LogType: AWS.SecurityFindingFormat - Selectors: - - "$.Action.AwsApiCallAction.RemoteIpDetails.IpAddressV4" - - "$.Action.NetworkConnectionAction.RemoteIpDetails.IpAddressV4" - - LogType: AWS.TransitGatewayFlow - Selectors: - - "srcAddr" - - "dstAddr" - - LogType: AWS.VPCDns - Selectors: - # use p_any_ip_addresses because the answers are variable and not always ip addresses - - "p_any_ip_addresses" - - LogType: AWS.VPCFlow - Selectors: - - "dstAddr" - - "srcAddr" - - LogType: AWS.WAFWebACL - Selectors: - - "$.httpRequest.clientIp" - - LogType: Azure.Audit - Selectors: - - "callerIpAddress" - - "$.properties.initiatedBy.user.ipAddress" - - LogType: Azure.MonitorActivity - Selectors: - - "callerIpAddress" - - LogType: Bitwarden.Events - Selectors: - - "ipAddress" - - LogType: Box.Event - Selectors: - - "ip_address" - - LogType: CarbonBlack.AlertV2 - Selectors: - - "device_external_ip" - - "device_internal_ip" - - "netconn_local_ip" - - "netconn_local_ipv4" - - "netconn_local_ipv6" - - "netconn_remote_ip" - - "netconn_remote_ipv4" - - "netconn_remote_ipv6" - - LogType: CarbonBlack.Audit - Selectors: - - "clientIp" - - LogType: CarbonBlack.EndpointEvent - Selectors: - - "device_external_ip" - - "local_ip" - - "remote_ip" - - "netconn_proxy_ip" - - LogType: CarbonBlack.WatchlistHit - Selectors: - - "device_external_ip" - - "device_internal_ip" - - LogType: CiscoUmbrella.CloudFirewall - Selectors: - - "destinationIp" - - "sourceIp" - - LogType: CiscoUmbrella.DNS - Selectors: - - "externalIp" - - "internalIp" - - LogType: CiscoUmbrella.IP - Selectors: - - "destinationIp" - - "sourceIp" - - LogType: CiscoUmbrella.Proxy - Selectors: - - "destinationIp" - - "externalIp" - - "internalIp" - - LogType: Cloudflare.Audit - Selectors: - - "ActorIP" - - LogType: Cloudflare.HttpRequest - Selectors: - - "ClientIP" - - "EdgeServerIP" - - "OriginIP" - - LogType: Cloudflare.Firewall - Selectors: - - "ClientIP" - - LogType: Cloudflare.Spectrum - Selectors: - - "ClientIP" - - "OriginIP" - - LogType: Crowdstrike.CriticalFile - Selectors: - - "aip" - - LogType: Crowdstrike.ActivityAudit - Selectors: - - "UserIp" - - LogType: Crowdstrike.DetectionSummary - Selectors: - - "LocalIP" - - "OriginSourceIpAddress" - - LogType: Crowdstrike.DNSRequest - Selectors: - - "IpAddress" - - LogType: Crowdstrike.GroupIdentity - Selectors: - - "aip" - - LogType: Crowdstrike.AIDMaster - Selectors: - - "aip" - - LogType: Crowdstrike.ManagedAssets - Selectors: - - "GatewayIP" - - LogType: Crowdstrike.NetworkConnect - Selectors: - - "LocalAddressIP4" - - "LocalAddressIP6" - - "RemoteAddressIP4" - - "RemoteAddressIP6" - - LogType: Crowdstrike.NetworkListen - Selectors: - - "LocalAddressIP4" - - "LocalAddressIP6" - - "RemoteAddressIP4" - - "RemoteAddressIP6" - - LogType: Crowdstrike.NotManagedAssets - Selectors: - - "aip" - - "CurrentLocalIP" - - LogType: Crowdstrike.ProcessRollup2 - Selectors: - - "aip" - - LogType: Crowdstrike.ProcessRollup2Stats - Selectors: - - "aip" - - LogType: Crowdstrike.SyntheticProcessRollup2 - Selectors: - - "aip" - - LogType: Crowdstrike.Unknown - Selectors: - - "aip" - - LogType: Crowdstrike.UserIdentity - Selectors: - - "aip" - - LogType: Crowdstrike.UserLogonLogoff - Selectors: - - "aip" - - LogType: Crowdstrike.FDREvent - Selectors: - - "p_any_ip_addresses" - - LogType: Dropbox.TeamEvent - Selectors: - - "$.origin.geo_location.ip_address" - - LogType: Duo.Authentication - Selectors: - - "$.access_device.ip" - - "$.auth_device.ip" - - LogType: GCP.AuditLog - Selectors: - - "$.protoPayload.requestMetadata.callerIP" - - "$.httpRequest.remoteIP" - - "$.httpRequest.serverIP" - - LogType: GCP.HTTPLoadBalancer - Selectors: - - "$.jsonPayload.removeIp" - - "$.httpRequest.remoteIp" - - "$.httpRequest.serverIp" - - LogType: GitHub.Audit - Selectors: - - "actor_ip" - - LogType: GitLab.API - Selectors: - - "remote_ip" - - LogType: GitLab.Audit - Selectors: - - "ip_address" - - LogType: GitLab.Production - Selectors: - - "remote_ip" - - LogType: Gravitational.TeleportAudit - Selectors: - - "dst_addr" - - "src_addr" - - LogType: GSuite.ActivityEvent - Selectors: - - "ipAddress" - - LogType: GSuite.Reports - Selectors: - - "ipAddress" - - LogType: Jamfpro.ComplianceReporter - Selectors: - - "$.process.terminal_id.ip_address" - - "$.socket_inet.ip_address" - - LogType: Jamfpro.Login - Selectors: - - "ipAddress" - - LogType: Juniper.Access - Selectors: - # use p_any_ip_addresses because we extract ip addresses but have no fields - - "p_any_ip_addresses" - - LogType: Juniper.Audit - Selectors: - - "login_ip" - - LogType: Juniper.Firewall - Selectors: - - "SRC" - - "DST" - - LogType: Juniper.Security - Selectors: - - "source_ip" - - LogType: Lacework.AgentManagement - Selectors: - - "IP_ADDR" - - LogType: Lacework.Applications - Selectors: - - "$.PROPS_MACHINE.ip_addr" - - LogType: Lacework.DNSQuery - Selectors: - - "DNS_SERVER_IP" - - "HOST_IP_ADDR" - - LogType: Lacework.Events - Selectors: - # use p_any_ip_addresses because we extract ip addresses but fields are variable - - "p_any_ip_addresses" - - LogType: Lacework.Interfaces - Selectors: - - "IP_ADDR" - - LogType: Lacework.InternalIPA - Selectors: - - "IP_ADDR" - - LogType: Lacework.MachineSummary - Selectors: - - "PRIMARY_IP_ADDR" - - LogType: Lacework.PodSummary - Selectors: - - "PRIMARY_IP_ADDR" - - LogType: Lacework.UserLogin - Selectors: - - "SOURCE_IP_ADDR" - - LogType: Linux.Auditd - Selectors: - - "addr" - - "ip" - - LogType: Microsoft365.Audit.AzureActiveDirectory - Selectors: - - "ActorIpAddress" - - "ClientIP" - - LogType: Microsoft365.Audit.Exchange - Selectors: - - "ClientIP" - - "ClientIPAddress" - - LogType: Microsoft365.Audit.SharePoint - Selectors: - - "ClientIP" - - LogType: Microsoft365.Audit.General - Selectors: - - "ClientIP" - - LogType: Microsoft365.DLP.All - Selectors: - - "ClientIP" - - LogType: MicrosoftGraph.SecurityAlert - Selectors: - # use p_any_ip_addresses because we extract ip addresses but fields are variable - - "p_any_ip_addresses" - - LogType: MongoDB.OrganizationEvent - Selectors: - - "remoteAddress" - - LogType: MongoDB.ProjectEvent - Selectors: - - "remoteAddress" - - LogType: Nginx.Access - Selectors: - - "remoteAddr" - - LogType: Notion.AuditLogs - Selectors: - - "$.event.ip_address" - - LogType: Okta.SystemLog - Selectors: - - "$.client.ipAddress" - - LogType: OneLogin.Events - Selectors: - - "ipaddr" - - LogType: OnePassword.AuditEvent - Selectors: - - "$.session.ip" - - LogType: OnePassword.ItemUsage - Selectors: - - "$.client.ip_address" - - LogType: OnePassword.SignInAttempt - Selectors: - - "$.client.ip_address" - - LogType: OSSEC.EventInfo - Selectors: - - "agentip" - - "dstip" - - "srcip" - - LogType: Panther.Audit - Selectors: - - "sourceIP" - - LogType: Tenable.Vulnerability - Selectors: - - "$.asset.ipv6" - - "$.asset.ipv4" - - LogType: Salesforce.Login - Selectors: - - "CLIENT_IP" - - "SOURCE_IP" - - LogType: Salesforce.LoginAs - Selectors: - - "CLIENT_IP" - - LogType: Salesforce.Logout - Selectors: - - "CLIENT_IP" - - LogType: Salesforce.URI - Selectors: - - "CLIENT_IP" - - LogType: SentinelOne.DeepVisibility - Selectors: - - "$.event.sourceAddress.address" - - "$.event.destinationAddress.address" - - "$.event.local.address" - - LogType: SentinelOne.DeepVisibilityV2 - Selectors: - - "src_ip_address" - - "dst_ip_address" - - "src_endpoint_ip_address" - - LogType: Slack.AccessLogs - Selectors: - - "ip" - - LogType: Slack.AuditLogs - Selectors: - - "$.context.ip_address" - - LogType: Sophos.Central - Selectors: - - "$.source_info.ip" - - LogType: Suricata.Alert - Selectors: - - "$.tls.sni" - - "$.dest_ip" - - "$.src_ip" - - LogType: Suricata.Anomaly - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.DHCP - Selectors: - - "$.dest_ip" - - "$.dhcp.assigned_ip" - - "$.src_ip" - - LogType: Suricata.DNS - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.FileInfo - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.Flow - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.HTTP - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.SSH - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Suricata.TLS - Selectors: - - "dest_ip" - - "src_ip" - - LogType: Sysdig.Audit - Selectors: - - "$.content.userOriginIP" - - LogType: Tines.Audit - Selectors: - - "request_ip" - - LogType: Workday.Activity - Selectors: - - "ipAddress" - - LogType: Workday.SignOnAttempt - Selectors: - - "Session_IP_Address" - - LogType: Zeek.Conn - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.DHCP - Selectors: - - "requested_addr" - - LogType: Zeek.DNS - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.DPD - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.HTTP - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.Notice - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.NTP - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.SIP - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.Software - Selectors: - - "host" - - LogType: Zeek.Ssh - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.Ssl - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.Tunnel - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zeek.Weird - Selectors: - - "$.id.orig_h" - - "$.id.resp_h" - - LogType: Zendesk.Audit - Selectors: - - "ip_address" - - LogType: Zoom.Activity - Selectors: - - "ip_address" From 1f1a05e40c367bd1f747410ac8f02e301fdc27b5 Mon Sep 17 00:00:00 2001 From: ben-githubs <38414634+ben-githubs@users.noreply.github.com> Date: Mon, 24 Jun 2024 09:38:26 -0500 Subject: [PATCH 34/35] added dynamic severity to okta vpn rule, with tests (#1268) --- .../okta_rules/okta_anonymizing_vpn_login.py | 11 +++ .../okta_rules/okta_anonymizing_vpn_login.yml | 79 +++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/rules/okta_rules/okta_anonymizing_vpn_login.py b/rules/okta_rules/okta_anonymizing_vpn_login.py index 8193973ca..51094fd8d 100644 --- a/rules/okta_rules/okta_anonymizing_vpn_login.py +++ b/rules/okta_rules/okta_anonymizing_vpn_login.py @@ -18,3 +18,14 @@ def title(event): def alert_context(event): return okta_alert_context(event) + + +def severity(event): + # If the user is using Apple Private Relay, demote the severity to INFO + if ( + event.deep_get("p_enrichment", "ipinfo_privacy", "client.ipAddress", "service") + == "Apple Private Relay" + ): + return "INFO" + # Return Medium by default + return "MEDIUM" diff --git a/rules/okta_rules/okta_anonymizing_vpn_login.yml b/rules/okta_rules/okta_anonymizing_vpn_login.yml index 688337316..f5d3e4b6f 100644 --- a/rules/okta_rules/okta_anonymizing_vpn_login.yml +++ b/rules/okta_rules/okta_anonymizing_vpn_login.yml @@ -156,3 +156,82 @@ Tests: type: WEB uuid: AbC-123-XyZ version: "0" + - Name: Apple Private Relay Used + ExpectedResult: true + Log: + actor: + alternateId: homer.simpson@duff.com + displayName: Homer Simpson + id: 00abc123 + type: User + authenticationcontext: + authenticationStep: 0 + externalSessionId: 100-abc-9999 + client: + device: Computer + geographicalContext: + city: Springfield + country: United States + geolocation: + lat: 20 + lon: -25 + postalCode: "12345" + state: Ohio + ipAddress: 1.3.2.4 + userAgent: + browser: CHROME + os: Mac OS X + rawUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36 + zone: "null" + debugcontext: + debugData: + requestId: AbCdEf12G + requestUri: /api/v1/users/AbCdEfG/lifecycle/reset_factors + url: /api/v1/users/AbCdEfG/lifecycle/reset_factors? + displaymessage: Authentication of user via MFA + eventtype: user.session.start + legacyeventtype: core.user.factor.attempt_fail + outcome: + reason: FastPass declined phishing attempt + result: FAILURE + p_enrichment: + ipinfo_privacy: + client.ipAddress: + hosting: true + p_match: 1.2.3.4 + proxy: false + relay: true + service: Apple Private Relay + tor: false + vpn: false + published: "2022-06-22 18:18:29.015" + request: + ipChain: + - geographicalContext: + city: Springfield + country: United States + geolocation: + lat: 20 + lon: -25 + postalCode: "12345" + state: Ohio + ip: 1.3.2.4 + version: V4 + securitycontext: + asNumber: 701 + asOrg: verizon + domain: anonymous.org + isProxy: true + isp: verizon + severity: INFO + target: + - alternateId: peter.griffin@company.com + displayName: Peter Griffin + id: 0002222AAAA + type: User + transaction: + detail: {} + id: ABcDeFgG + type: WEB + uuid: AbC-123-XyZ + version: "0" \ No newline at end of file From bc59473cb07f229a1810b50b846051a7bd4157bc Mon Sep 17 00:00:00 2001 From: Evan Gibler <20933572+egibs@users.noreply.github.com> Date: Mon, 24 Jun 2024 11:29:13 -0500 Subject: [PATCH 35/35] Remove unnecessary pipenv step (#1270) Signed-off-by: egibs <20933572+egibs@users.noreply.github.com> --- Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index ea63aff73..b21876f42 100644 --- a/Dockerfile +++ b/Dockerfile @@ -44,7 +44,6 @@ WORKDIR /home/panther-analysis # Install requirements COPY Pipfile . COPY Pipfile.lock . -RUN pipenv uninstall --all RUN pipenv sync --dev # Remove pipfile so it doesn't interfere with local files after install