# Ultralytics AI Library Hacked via GitHub for Cryptomining

Attacker injected shell payload via malicious PR branch name into Ultralytics 'Publish Docs' GitHub Actions workflow, shipping XMRig cryptominer in PyPI versions 8.3.41/8.3.42.

- Payout: Real-world hack
- Severity: high
- Program: Ultralytics
- Analysis by: Wiz Research
- Disclosed: 2024-12-09
- Write-up quality: 7/10
- Original: https://www.wiz.io/blog/ultralytics-ai-library-hacked-via-github-for-cryptomining
- Library page: https://bugbountylibrary.com/r/blog%3Awiz-io-blog-ultralytics-ai-library-hacked-via-github-for-cryptomining
- Tags: area:cloud domain:infra domain:oss impact:integrity impact:rce kind:incident platform:threat-intel sev:high tech:github-actions tech:python technique:source-review vuln:command-injection

**Target:** GitHub Actions workflow 'Publish Docs' and PyPI release pipeline
**Root cause:** The workflow interpolated the attacker-controlled github.head_ref (PR branch name) directly into a shell command without sanitization, allowing command injection. The crafted branch name piped file.sh into bash.
**Steps:**
1. Attacker (GitHub user openimbot) opens draft PRs against Ultralytics with a branch name crafted as a shell payload using parentheses notation and $IFS to avoid spaces
2. The 'Publish Docs' workflow triggers on pull_request and interpolates github.head_ref into a run step, executing the branch name as shell
3. Payload pipes content of file.sh into bash, which checks in malicious changes to v8.3.41/ultralytics/models/yolo/model.py and v8.3.41/ultralytics/utils/downloads.py
4. model.py downloads and runs XMRig miner on victim machines; downloads.py implements the download/run functions
5. Malicious versions 8.3.41 and 8.3.42 published to PyPI; a later 'mitigation' release was also compromised
**How found:** Discovery was first alerted on the dependent package ComfyUI, not Ultralytics itself; a user-raised issue noted the discrepancy in the package. Root cause identified by analyzing the maintainers' later fix of the workflow.
**Exploitation:** External actor with no repo write access used a PR branch name as a command-injection vector into the CI workflow, causing the release pipeline to commit miner code into the package and publish it to PyPI, distributing XMRig to all installers of 8.3.41/8.3.42 including ComfyUI Impact Pack users.
**Escalation:** Compromise of a second 'mitigation' release increased risk for users who updated assuming they were safe; downstream dependency ComfyUI Impact Pack propagated the miner further.
**Insight:** PR-triggered workflows that interpolate github.head_ref (or other PR-controlled strings) into run steps are command-injection sinks; branch names can carry shell payloads using $IFS and parentheses to avoid spaces, so audit every workflow using pull_request context values.

## Proof of concept (copied exactly from the original report)

**Malicious PR branch name payload**

```
This branch name payload, when executed by the job, pipes the content of file.sh into a bash session. The way the payload is constructed (using the parentheses bash notation and the $IFS special shell variable) is explained by the fact that, to be valid, the branch name should not contain any spaces. In fact, this is a common technique used for WAF bypasses. The content of file.sh is currently unavailable, but we can speculate that it contained instructions to check in malicious changes to the following two files:
```

**Vulnerable workflow trigger config**

```
pull_request:

branches: [main]
```

