Full Report
JumpServer is a privileged access management (PAM) system that is open source. Typically, a jump server is a server that can be connected to from the outside world in order to talk to internal and sensitive things in an internal network. So, being able to compromise this software would be an awesome target for attackers. When looking at something for the first time, the authentication system is great to look at. Any mistakes here lead to a compromise of the whole system! Password reset flows are an extremely common item to attack under this, since it's giving users access to their account without their original password. An implementation flaw in this is effectively an authentication bypass. While scrutinizing the password reset flow (which was the standard generate random number, find number in email, click link, reset password), they noticed that it was using the random library from Python. Since this is known to NOT be cryptographically secure, this is a red flag. However, breaking this remotely is feasible in some scenarios but not all. So, now what? Algorithmic random number generators need a starting value, otherwise known as a seed. So, if you know the seed then you can predict what numbers are going to be used going forward, regardless of the randomness of the algorithm. In a crazy turn of events, the author found a way to leak the seed of the randomness. The software uses a captcha in order to prevent brute force attacks. After generating the image for the captcha, it sets a hex id for the image as the seed. Since the id is sent back to the user, we now know the current seed of the randomness. So, how do we actually exploit this? This feels super racey. The author decided to spam these with a bunch of different threads. First, calls the endpoint with the hex captcha key as the parameter to reset the random seed. Now, with a particular seed being set, try triggering the reset code. Finally, submit several codes based upon where we think the randomness would be at. Since the server uses Gunicorn, which employs the pre-fork worker model, all of the processes needed to be poisoned for this to work. In practice, the seed plus 980 bytes needed to be used because of other randomness being used. Overall, this is a crazy vulnerability. I've never seen a way to leak the seed by requesting other information. The post also contains a post-auth RCE but the password reset was my favorite part.
Analysis Summary
# Vulnerability: JumpServer Pre-authentication Exploit Chain (RCE)
## CVE Details
- **CVE ID:** CVE-2023-42820 (Seed Leakage), CVE-2023-42819 (Path Traversal/RCE), CVE-2023-46138 (Default Admin Email)
- **CVSS Score:** 9.8 (Critical)
- **CWE:** CWE-337 (Predictable Seed in PRNG), CWE-22 (Improper Limitation of a Pathname to a Restricted Directory)
## Affected Systems
- **Products:** JumpServer (Open Source Privileged Access Management system)
- **Versions:**
- CVE-2023-42820: < v3.6.4
- CVE-2023-42819: < v3.6.4
- **Configurations:** Systems using `django-simple-captcha` and Gunicorn (pre-fork worker model).
## Vulnerability Description
This exploit chain combines two primary flaws to archive Unauthenticated Remote Code Execution:
1. **CVE-2023-42820 (Account Takeover via PRNG Seed Leak):** JumpServer used Python’s `random` library (Mersenne Twister) for password reset codes, which is not cryptographically secure. The application uses `django-simple-captcha` to prevent brute force. However, requesting a captcha sets a hex ID as the `random.seed`. Since this ID is returned to the user, the attacker knows the seed and can predict the 6-digit verification code for any user's password reset.
2. **CVE-2023-42819 (Authenticated RCE via Path Traversal):** Once an attacker takes over an account (via CVE-2023-42820), they can access the Ansible "Playbook" upload functionality. The `name` parameter in the file creation logic was improperly sanitized, allowing for absolute path traversal and arbitrary file writes (e.g., overwriting Python files) to achieve RCE.
## Exploitation
- **Status:** PoC demonstrated; exploited via a combined chain.
- **Complexity:** High (Requires poisoning Gunicorn worker processes and accounting for approximately 980 bytes of PRNG consumption).
- **Attack Vector:** Network (Remote)
## Impact
- **Confidentiality:** Total (Full access to PAM and internal sensitive assets)
- **Integrity:** Total (Ability to modify system files and reset any user password)
- **Availability:** Total (Ability to overwrite critical system files)
## Remediation
### Patches
- Update JumpServer to **v3.6.4** or later.
- These versions replace the insecure `random` library with the `secrets` module and fix path traversal logic.
### Workarounds
- Disable the "Forget Password" feature if not immediately needed.
- Restrict network access to the JumpServer web interface to trusted IPs only.
- Ensure the default `admin` email (`[email protected]`) is changed to a controlled, internal domain (Mitigates CVE-2023-46138).
## Detection
- **Indicators of Compromise:**
- High volume of requests to `/api/v1/authentication/password/reset-code/` and `/core/auth/password/forget/previewing/` from a single IP.
- Multiple captcha generation requests followed quickly by password reset attempts.
- Unexpected file modifications in JumpServer playbooks or system Python directories.
- **Detection methods:** Monitor web logs for directory traversal sequences (`../`) in the Ansible playbook API endpoints.
## References
- jump-server[.]org
- hxxps://github[.]com/jumpserver/jumpserver
- hxxps://docs[.]python[.]org/3/library/random[.]html
- CVE-2023-42820 Advisory
- CVE-2023-42819 Advisory