forked from chainguard-dev/malcontent
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve detection for Python setuptools backdoors (chainguard-dev#164)
* Improve reliability of py_setuptools rules * Fix GoReleaser (chainguard-dev#162) * Fix GoReleaser * Add project_name * Remove problematic MS repository from Checks * Repository has been fixed * Import rule URLs, add them to markdown & JSON output (chainguard-dev#165) * Add URLs to markdown output * run prettier against output * Disable or modify GitHub actions to work better with third_party code (chainguard-dev#152) * Bump actions/checkout from 4.1.3 to 4.1.4 in the all group (chainguard-dev#171) Bumps the all group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.3 to 4.1.4 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](actions/checkout@1d96c77...0ad4b8f) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Add ThreatHunting-Keywords-yara-rules (chainguard-dev#160) * Add ThreatHunting-Keywords-yara-rules * Update README * Remove superfluous mkdir command * Fix tests * Fix tests * Remove merge artifacts * Pin rules to a known commit; add check for updates * Re-add -s * Avoid using jq for portability * Add new commit to output * Fix test * Bump golangci/golangci-lint-action from 4.0.0 to 5.0.0 (chainguard-dev#172) Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 4.0.0 to 5.0.0. - [Release notes](https://github.com/golangci/golangci-lint-action/releases) - [Commits](golangci/golangci-lint-action@3cfe3a4...82d40c2) --- updated-dependencies: - dependency-name: golangci/golangci-lint-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Thomas Strömberg <[email protected]> Co-authored-by: Ville Aikas <[email protected]> * Improve how we approach Python code * Add 2021.DiscordSafety sample * Make pythonSetup private again * Add aiohttp sample --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: Evan Gibler <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Ville Aikas <[email protected]>
- Loading branch information
1 parent
bdcd078
commit 5a95dc0
Showing
14 changed files
with
398 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,78 +1,69 @@ | ||
import "math" | ||
|
||
rule setuptools_cmd_exec : high { | ||
private rule pythonSetup { | ||
strings: | ||
$i_distutils = "from distutils.core import setup" | ||
$i_setuptools = "setuptools" | ||
$setup = "setup(" | ||
condition: | ||
filesize < 2097152 and $setup and any of ($i*) | ||
} | ||
|
||
rule setuptools_cmd_exec : suspicious { | ||
meta: | ||
description = "Python library installer that executes external commands" | ||
hash_2022_laysound_4_5_2_setup = "4465bbf91efedb996c80c773494295ae3bff27c0fff139c6aefdb9efbdf7d078" | ||
hash_2022_2022_requests_3_0_0_setup = "15507092967fbd28ccb833d98c2ee49da09e7c79fd41759cd6f783672fe1c5cc" | ||
hash_2023_grandmask_3_13_setup = "8835778f9e75e6493693fc6163477ec94aba723c091393a30d7e7b9eed4f5a54" | ||
strings: | ||
$setup = "setup(" fullword | ||
$setuptools = "setuptools" | ||
$distutils = "distutils" | ||
$s_sys_val = /os.system\([\"\'\w\ \-\)\/]{0,64}/ | ||
$s_subprocess_val = /subprocess.\w{0,32}\([\"\'\/\w\ \-\)]{0,64}/ | ||
$s_import = "import subprocess" | ||
$os_system = /os.system\([\"\'\w\ \-\)\/]{0,64}/ | ||
$os_popen = /os.spopen\([\"\'\w\ \-\)\/]{0,64}/ | ||
$subprocess = /subprocess.\w{0,32}\([\"\'\/\w\ \-\)]{0,64}/ | ||
condition: | ||
$setup and ($setuptools or $distutils) and any of ($s_*) | ||
pythonSetup and any of them | ||
} | ||
|
||
rule setuptools_eval : critical { | ||
meta: | ||
description = "Python library installer that evaluates arbitrary code" | ||
hash_2022_2022_requests_3_0_0_setup = "15507092967fbd28ccb833d98c2ee49da09e7c79fd41759cd6f783672fe1c5cc" | ||
hash_2023_requet_2_28_1_setup = "9438107245ebfba792dfa95f7d551392831c20adbcac7d3176797f0f00683ab0" | ||
hash_2023_zproxy_1_0_setup = "f3d7eec1ae2eba61715fd0652fa333acc2e4c0d517579392043880aa2f158b62" | ||
strings: | ||
$setup = "setup(" fullword | ||
$setuptools = "setuptools" | ||
$distutils = "distutils" | ||
$s_sys_val = /eval\([\"\'\w\ \-\)\/]{0,64}/ fullword | ||
$s_subprocess_val = /exec\([\"\'\/\w\ \-\)]{0,64}/ fullword | ||
$f_sys_val = /eval\([\"\'\w\ \-\)\/]{0,64}/ fullword | ||
$f_subprocess_val = /exec\([\"\'\/\w\ \-\)]{0,64}/ fullword | ||
condition: | ||
pythonSetup and any of ($f*) | ||
} | ||
|
||
rule setuptools_b64decode : suspicious { | ||
meta: | ||
description = "Python library installer that does base64 decoding" | ||
strings: | ||
$base64 = "b64decode" | ||
condition: | ||
$setup and ($setuptools or $distutils) and any of ($s_*) | ||
pythonSetup and any of them | ||
} | ||
|
||
rule setuptools_url_access : high { | ||
rule setuptools_exec_powershell : critical { | ||
meta: | ||
description = "Python library installer that accesses external URLs" | ||
hash_2022_laysound_4_5_2_setup = "4465bbf91efedb996c80c773494295ae3bff27c0fff139c6aefdb9efbdf7d078" | ||
hash_2022_2022_requests_3_0_0_setup = "15507092967fbd28ccb833d98c2ee49da09e7c79fd41759cd6f783672fe1c5cc" | ||
hash_2022_selenuim_4_4_2_setup = "5c5e1d934dbcbb635f84b443bc885c9ba347babc851cd225d2e18eadc111ecf0" | ||
description = "Python library installer that runs powershell" | ||
strings: | ||
$setup = "setup(" fullword | ||
$setuptools = "setuptools" | ||
$distutils = "distutils" | ||
$s_requests = /requests.get\([\"\'\w\ \-\)\/]{0,64}/ | ||
$s_urlopen = /urlopen\([\"\'\w\ \-\)\/]{0,64}/ | ||
$powershell = "powershell" fullword | ||
$encoded = "-EncodedCommand" fullword | ||
$window = "WindowStyle Hidden" fullword | ||
condition: | ||
$setup and ($setuptools or $distutils) and any of ($s_*) | ||
setuptools_cmd_exec and any of them | ||
} | ||
|
||
rule setuptools_random : critical { | ||
rule setuptools_os_path_exists : notable { | ||
meta: | ||
description = "Python library installer that exhibits random behavior" | ||
hash_2023_yfinancce_0_1_setup = "3bde1e9207dd331806bf58926d842e2d0f6a82424abd38a8b708e9f4e3e12049" | ||
hash_2023_yvper_0_1_setup = "b765244c1f8a11ee73d1e74927b8ad61718a65949e0b8d8cbc04e5d84dccaf96" | ||
description = "Python library installer that checks for file existence" | ||
strings: | ||
$setup = "setup(" fullword | ||
$setuptools = "setuptools" | ||
$distutils = "distutils" | ||
$s_sys_val = "import random" fullword | ||
$ref = /[\w\.]{0,8}path.exists\([\"\'\w\ \-\)\/]{0,32}/ | ||
condition: | ||
$setup and ($setuptools or $distutils) and any of ($s_*) | ||
pythonSetup and $ref | ||
} | ||
|
||
rule setuptools_builtins : medium { | ||
rule setuptools_excessive_bitwise_math : critical { | ||
meta: | ||
description = "Python library installer that directly references builtins" | ||
hash_2023_yfinancce_0_1_setup = "3bde1e9207dd331806bf58926d842e2d0f6a82424abd38a8b708e9f4e3e12049" | ||
hash_2023_yvper_0_1_setup = "b765244c1f8a11ee73d1e74927b8ad61718a65949e0b8d8cbc04e5d84dccaf96" | ||
description = "Python library installer that makes heavy use of bitwise math" | ||
strings: | ||
$setup = "setup(" fullword | ||
$setuptools = "setuptools" | ||
$distutils = "distutils" | ||
$s_sys_val = "__builtins__" fullword | ||
$x = /\-{0,1}\d{1,8} \<\< \-{0,1}\d{1,8}/ | ||
condition: | ||
$setup and ($setuptools or $distutils) and any of ($s_*) | ||
pythonSetup and #x > 20 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,62 @@ | ||
private rule py_fetcher { | ||
meta: | ||
description = "fetches content" | ||
strings: | ||
$http_requests = "requests.get" fullword | ||
$http_requests_post = "requests.post" fullword | ||
$http_urrlib = "urllib.request" fullword | ||
$http_urlopen = "urlopen" fullword | ||
condition: | ||
any of ($http*) | ||
} | ||
|
||
private rule py_runner { | ||
meta: | ||
description = "runs programs" | ||
strings: | ||
$os_system = /os.system\([\"\'\w\ \-\)\/]{0,64}/ | ||
$os_popen = /os.spopen\([\"\'\w\ \-\)\/]{0,64}/ | ||
$subprocess = /subprocess.\w{0,32}\([\"\'\/\w\ \-\)]{0,64}/ | ||
condition: | ||
any of them | ||
} | ||
|
||
rule http_open_write_system : high { | ||
rule py_dropper : suspicious { | ||
meta: | ||
description = "fetch and execute programs" | ||
hash_2022_laysound_4_5_2_setup = "4465bbf91efedb996c80c773494295ae3bff27c0fff139c6aefdb9efbdf7d078" | ||
hash_2023_JokerSpy_shared = "5fe1790667ee5085e73b054566d548eb4473c20cf962368dd53ba776e9642272" | ||
hash_2023_JokerSpy_shared = "39bbc16028fd46bf4ddad49c21439504d3f6f42cccbd30945a2d2fdb4ce393a4" | ||
description = "fetch, stores, and execute programs" | ||
strings: | ||
$http_requests_get = "requests.get" fullword | ||
$http_requests_post = "requests.post" fullword | ||
$http_urllib = "urllib.request" fullword | ||
$http_urlopen = "urlopen" fullword | ||
$open = "open(" | ||
$write = "write(" | ||
$system = "os.system" fullword | ||
$sys_popen = "os.popen" fullword | ||
$sys_sub = "subprocess" fullword | ||
$open = "open(" | ||
$write = "write(" | ||
condition: | ||
filesize < 16384 and any of ($h*) and $open and $write and any of ($sys*) | ||
filesize < 16384 and $open and $write and py_fetcher and py_runner | ||
} | ||
|
||
private rule pythonSetup { | ||
strings: | ||
$i_distutils = "from distutils.core import setup" | ||
$i_setuptools = "setuptools" | ||
$setup = "setup(" | ||
condition: | ||
filesize < 2MB and $setup and any of ($i*) | ||
} | ||
|
||
rule setuptools_fetcher : suspicious { | ||
meta: | ||
description = "setuptools script that fetches content" | ||
condition: | ||
pythonSetup and py_fetcher | ||
} | ||
|
||
rule setuptools_fetch_run : critical { | ||
meta: | ||
description = "setuptools script that fetches and executes" | ||
condition: | ||
setuptools_fetcher and py_runner | ||
} | ||
|
||
rule setuptools_dropper : critical { | ||
meta: | ||
description = "setuptools script that fetches and executes" | ||
hash_2022_laysound_4_5_2_setup = "4465bbf91efedb996c80c773494295ae3bff27c0fff139c6aefdb9efbdf7d078" | ||
hash_2022_2022_requests_3_0_0_setup = "15507092967fbd28ccb833d98c2ee49da09e7c79fd41759cd6f783672fe1c5cc" | ||
hash_2022_selenuim_4_4_2_setup = "5c5e1d934dbcbb635f84b443bc885c9ba347babc851cd225d2e18eadc111ecf0" | ||
strings: | ||
$setup = "setup(" | ||
$setuptools = "setuptools" fullword | ||
$http_requests = "requests.get" fullword | ||
$http_requests_post = "requests.post" fullword | ||
$http_urrlib = "urllib.request" fullword | ||
$http_urlopen = "urlopen" fullword | ||
$system = "os.system" fullword | ||
$sys_popen = "os.popen" fullword | ||
$sys_sub = "subprocess" fullword | ||
condition: | ||
all of ($setup*) and any of ($http*) and any of ($sys*) | ||
meta: | ||
description = "setuptools script that fetches, stores, and executes" | ||
condition: | ||
pythonSetup and py_dropper | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,24 @@ | ||
|
||
rule excessive_bitwise_math : medium { | ||
rule large_bitwise_math : medium { | ||
meta: | ||
description = "excessive use of bitwise math" | ||
description = "large amounts of bitwise math" | ||
hash_2023_yfinancce_0_1_setup = "3bde1e9207dd331806bf58926d842e2d0f6a82424abd38a8b708e9f4e3e12049" | ||
hash_2023_yvper_0_1_setup = "b765244c1f8a11ee73d1e74927b8ad61718a65949e0b8d8cbc04e5d84dccaf96" | ||
hash_2023_aiohttpp_0_1_setup = "cfa4137756f7e8243e7c7edc7cb0b431a2f4c9fa401f2570f1b960dbc86ca7c6" | ||
strings: | ||
$x = /\-{0,1}\d{1,8} \<\< \-{0,1}\d{1,8}/ | ||
condition: | ||
filesize < 128000 and #x > 10 | ||
} | ||
|
||
rule excessive_bitwise_math : high { | ||
meta: | ||
description = "excessive use of bitwise math" | ||
hash_2023_yfinancce_0_1_setup = "3bde1e9207dd331806bf58926d842e2d0f6a82424abd38a8b708e9f4e3e12049" | ||
hash_2023_yvper_0_1_setup = "b765244c1f8a11ee73d1e74927b8ad61718a65949e0b8d8cbc04e5d84dccaf96" | ||
hash_2023_aiohttpp_0_1_setup = "cfa4137756f7e8243e7c7edc7cb0b431a2f4c9fa401f2570f1b960dbc86ca7c6" | ||
strings: | ||
$x = /\-{0,1}\d{1,8} \<\< \-{0,1}\d{1,8}/ | ||
condition: | ||
filesize < 128000 and #x > 20 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,30 @@ | ||
import "math" | ||
|
||
rule setuptools_no_fail : high { | ||
private rule pythonSetup { | ||
strings: | ||
$i_distutils = "from distutils.core import setup" | ||
$i_setuptools = "setuptools" | ||
$setup = "setup(" | ||
condition: | ||
filesize < 2097152 and $setup and any of ($i*) | ||
} | ||
|
||
rule py_no_fail : notable { | ||
meta: | ||
description = "Python library installer that hides exceptions" | ||
description = "Python code that hides exceptions" | ||
hash_2023_grandmask_3_13_setup = "8835778f9e75e6493693fc6163477ec94aba723c091393a30d7e7b9eed4f5a54" | ||
hash_2023_libgrandrandomintel_3_58_setup = "cd211e0f8d84100b1b4c1655e913f40a76beaacc482e751e3a7c7ed126fe1a90" | ||
hash_2023_py_guigrand_4_67_setup = "4cb4b9fcce78237f0ef025d1ffda8ca8bc79bf8d4c199e4bfc6eff84ce9ce554" | ||
hash_2023_py_killtoolad_3_65_setup = "64ec7b05442356293e903afe028637d821bad4444c4e1e11b73a4ff540fe480b" | ||
strings: | ||
$setup = "setup(" fullword | ||
$setuptools = "setuptools" | ||
$distutils = "distutils" | ||
$e_val = /except:.{0,4}pass/ fullword | ||
$e_short = /except:.{0,4}pass/ fullword | ||
$e_long = /except Exception as.{0,8}pass/ fullword | ||
condition: | ||
$setup and ($setuptools or $distutils) and $e_val | ||
any of them | ||
} | ||
|
||
rule setuptools_no_fail2 : high { | ||
rule setuptools_no_fail : suspicious { | ||
meta: | ||
description = "Python library installer that hides exceptions" | ||
strings: | ||
$setup = "setup(" fullword | ||
$setuptools = "setuptools" | ||
$distutils = "distutils" | ||
$e_val = /except Exception as.{0,8}pass/ fullword | ||
condition: | ||
$setup and ($setuptools or $distutils) and $e_val | ||
pythonSetup and py_no_fail | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,37 @@ | ||
|
||
rule indirect_python_builtins : high { | ||
rule py_builtins { | ||
meta: | ||
description = "references Python builtins" | ||
strings: | ||
$ref = "__builtins__" fullword | ||
condition: | ||
$ref | ||
} | ||
|
||
rule py_indirect_builtins : suspicious { | ||
meta: | ||
description = "Indirectly refers to Python builtins" | ||
hash_2023_yfinancce_0_1_setup = "3bde1e9207dd331806bf58926d842e2d0f6a82424abd38a8b708e9f4e3e12049" | ||
hash_2023_yvper_0_1_setup = "b765244c1f8a11ee73d1e74927b8ad61718a65949e0b8d8cbc04e5d84dccaf96" | ||
hash_2023_aiohttpp_0_1_setup = "cfa4137756f7e8243e7c7edc7cb0b431a2f4c9fa401f2570f1b960dbc86ca7c6" | ||
strings: | ||
$val = /getattr\(__builtins__,[ \w\.\)\)]{0,64}/ | ||
condition: | ||
any of them | ||
} | ||
|
||
private rule pythonSetup { | ||
strings: | ||
$i_distutils = "from distutils.core import setup" | ||
$i_setuptools = "setuptools" | ||
$setup = "setup(" | ||
condition: | ||
filesize < 2097152 and $setup and any of ($i*) | ||
} | ||
|
||
rule setuptools_builtins : notable { | ||
meta: | ||
description = "Python library installer that references builtins" | ||
condition: | ||
pythonSetup and py_builtins | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import "math" | ||
|
||
private rule pythonSetup { | ||
strings: | ||
$i_distutils = "from distutils.core import setup" | ||
$i_setuptools = "setuptools" | ||
$setup = "setup(" | ||
condition: | ||
filesize < 2MB and $setup and any of ($i*) | ||
} | ||
|
||
rule setuptools_random : critical { | ||
meta: | ||
description = "Python library installer that exhibits random behavior" | ||
strings: | ||
$ref = "import random" | ||
condition: | ||
pythonSetup and $ref | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.