18.6 C
Warszawa
czwartek 25 lipca • 2024
Strona głównaTECHNIKACYBERBEZPIECZEŃSTWOPOZNAJ CZYM JEST ATAK SQL INJECTION

POZNAJ CZYM JEST ATAK SQL INJECTION

SQL Injection, czyli wstrzyknięcie kodu SQL (Structured Qurey Language), to jeden z najgroźniejszych ataków na aplikacje webowe korzystające z baz danych, jak i na same bazy danych, o czym świadczy zajęcie trzeciej pozycji w raporcie OWASP Top Ten 2021.

SQL Injection, czyli wstrzyknięcie kodu SQL (Structured Qurey Language), to jeden z najgroźniejszych ataków na aplikacje webowe korzystające z baz danych, jak i na same bazy danych, o czym świadczy zajęcie trzeciej pozycji w raporcie OWASP Top Ten 2021.

Jego skuteczne przeprowadzenie prowadzi do wycieku poufnych i często tajnych informacji z zaatakowanej bazy danych. Informacjami tymi mogą być loginy, hasła, dane klientów, wyniki finansowe, czy inne tajemnice handlowe lub tajemnice przedsiębiorstwa. Stąd też niezwykle ważne jest wiedzieć jak bronić się przed tym atakiem i jak mu zapobiegać.

Na czym polega atak SQL Injection?

Atak SQL Injection (w skrócie SQLi) polega na wykorzystaniu przez hakera luki w zabezpieczeniach aplikacji webowej (internetowej) dotyczącej odpowiedniej walidacji zapytania kierowanego przez jej użytkownika do bazy danych i dotyczy systemów generujących dynamiczne zapytania do bazy danych. Warto dodać, że szczególnie podatne na wstrzyknięcie kodu SQL są języki, interfejsy i narzędzia, takie jak: ASP, JSP, XML, XSL, XSQL, CGI, Perl, JavaScript, VB, narzędzia przedsiębiorstw odpowiedzialnych za wytwarzanie baz danych, same bazy danych oraz języki wyższego rzędu, jak np. C czy COBOL.

W przypadku, gdy każde zapytanie jest uznawane przez aplikację webową za kod SQL, haker może dopisać (wstrzyknąć) swój własny kod, który aplikacja wykona, przez co umożliwi atakującemu nieautoryzowany dostęp do bazy danych zarówno w trybie odczytu, jak i zapisu, ale także pozwala na ominięcie mechanizmów uwierzytelniania, wykonanie kodu, stworzenie lub odczytanie plików w systemie operacyjnym, na którym działa zaatakowana baza danych.

Jak już wspomniałem powyżej atak ten prowadzi do odczytania danych zapisanych w bazie, ale także haker może dopisywać do bazy dane, modyfikować je lub usuwać, łącznie z usunięciem całej bazy danych, co spowoduje niedostępność aplikacji korzystającej z takiej bazy danych. Ponadto atak ten może być wykorzystany do wstrzyknięcia złośliwego oprogramowania odpowiadającego np. za tworzenie spamu, zmiany linków czy ustawienie przekierowań na niepożądane strony. Jest to o tyle niebezpieczne dla właściciela strony, że zasypanie jej spamerskimi treściami może spowodować, że Google doda ją na czarną listę, wobec czego przestanie być wyświetlana w wynikach wyszukiwania. Ponadto uzyskanie dostępu przez hakera do kont użytkowników może prowadzić do kradzieży tożsamości, niezgodnego z wolą użytkowników wykorzystania ich kont, do naruszającej prawo działalności w Internecie, ale także do zmiany ich uprawnień i przyznania atakującemu uprawnień administracyjnych, co wiąże się z przejęciem przez hakera bazy danych i posiadaniem pełnej kontroli nad samą bazą oraz zapisanymi w niej danymi.

Struktura zapytania SQL

SQL to specjalnie stworzony język zapytań do komunikacji z bazami danych, czyli uporządkowanymi zbiorami informacji niezbędnych do prawidłowego funkcjonowania danej aplikacji webowej. W bazach danych przechowywane są różne informacje, od loginów i haseł, adresów, numerów PESEL, poprzez produkty (dotyczy to sklepów), informacje o klientach i kontrahentach poprzez dane finansowe.

Natomiast zapytaniem SQL jest instrukcja, którą przekazuje się do bazy danych, aby otrzymać potrzebne informacje lub zmodyfikować dane przechowywane w tej bazie. Najprostsze zapytanie w języku SQL może wyglądać następująco:

SELECT login, hasło FROM Użytkownicy WHERE Konto=’aktywne’;

Zapytanie to zwraca odpowiednie wartości z kolumn „Login” i „Hasło” z tabeli „Użytkownicy” tylko dla wierszy, które w kolumnie „Konto” są oznaczone jako „Aktywne”. Oznacza to, że tak sformułowane zapytanie zwróciłoby loginy i hasła wszystkich użytkowników danej aplikacji, których konta są aktywne.

Jak przeprowadzany jest atak SQL Injection?

Atak SQL Injection polega na wykorzystaniu przez atakującego błędów w samym kodzie aplikacji (błędów projektowych) popełnionych przez programistów i osoby odpowiedzialne za bezpieczeństwo danej aplikacji internetowej. W tym przypadku haker nie musi przełamywać zabezpieczeń, jedynie wykorzystuje swego rodzaju furtkę wynikającą z niewłaściwie napisanego kodu.

Najczęściej odbywa się to poprzez wykorzystanie wbudowanych formularzy witryny i dodanie własnego zapytania SQL do używanego przez aplikację w komunikacji z bazą danych. Dobrym przykładem jest tu wykorzystanie przez atakującego formularza logowania do konkretnej usługi lub samej aplikacji, gdzie haker oprócz danych logowania (np. hasła) dopisze zredagowane przez siebie zapytanie SQL. Jeśli aplikacja jest podatna na taki atak, wówczas użyje tego zapytania zamiast hasła i przekaże je do bazy danych. Taki błąd w aplikacji może umożliwić hakerowi zalogowanie się do aplikacji z uprawnieniami administracyjnymi i tym samym uzyskanie dostępu do loginów i haseł lub innych danych przechowywanych w bazie. Ponadto atakujący może mieć możliwość dowolnej modyfikacji danych oraz ich usunięcia, jak i usunięcia całej bazy danych. Jak wspomniałem powyżej ataki SQL Injection są przeprowadzane przez formularze wbudowane w aplikację, czyli np.:

  • pola logowania,
  • wewnętrzne wyszukiwarki produktów,
  • formularze kontaktowe,
  • formularze rejestracyjne, np. do newsletterów.

W związku z tym atak ten jest typowym atakiem na część serwerową aplikacji, czyli jest skierowany na serwer i szkodzi głównie twórcy aplikacji. Odwrotnością tego ataku jest atak XSS, którego celem jest klient (a nie aplikacja), a w szczególności jego dane, jak np. loginy, hasła, czy pliki cookie.

Samo przeprowadzenie ataku jest niezwykle proste i skuteczne w przypadku aplikacji webowych posiadających błędy projektowe w kodzie umożliwiające przeprowadzanie ataków SQL Injection. Dla przykładu w polu logowania, zamiast podawać swoje dane, haker może umieścić frazę, która zawsze zwróci wynik TRUE: ” or ””=”

W takim przypadku zapytanie wysłane przez aplikację do bazy danych będzie wyglądało następująco:

SELECT * FROM Użytkownicy WHERE Login =”” or „”=”” AND Hasło =”” or „”=””

Atak polega na wykorzystaniu faktu, że w języku SQL fraza OR „”=”” zawsze zwraca wartość TRUE, w związku z czym wykonując takie zapytanie, baza danych zwróci wszystkie przechowywane loginy i hasła.

W niektórych przypadkach możliwe jest nawet zalogowanie się do aplikacji bez podawania loginu i hasła. Załóżmy, że najprostszy formularz logowania przekazuje do bazy danych takie zapytanie:

SELECT * FROM Uzytkownicy WHERE Login=’$uzytkownik’ AND Haslo=‘$haslo’

Na podstawie tego zapytania baza danych zwraca użytkownika, którego login i hasło są zgodne z przekazanymi w zapytaniu, czyli wartość zapytania dla jego skutecznego wykonania zawsze musi zwracać TRUE.

Jeżeli jednak haker zmanipuluje zapytanie tak, by zwracał wartość TRUE bez podawania danych uwierzytelniających, wówczas będzie mógł poprawnie się zalogować. Aby jednak to było możliwe, wystarczy zamiast loginu podać frazę ‘OR 1=1’;/*, a zamiast hasła: */-.

Dokując analizy wprowadzonych poleceń łatwo możemy zauważyć, że podany w loginie argument „1=1” jest zawsze prawdziwy, a gwiazdki i ukośniki oznaczają w języku SQL otwarcie i zamknięcie komentarza, w związku z czym wszystko co jest zawarte między nimi nie jest brane pod uwagę podczas przetwarzania zapytania. Stąd taka konstrukcja zapytania powoduje zignorowanie hasła, a całe zapytanie sprowadza do sprawdzenia, czy argument „1=1” jest prawdziwy, a że tak jest i zapytanie zwróci wartość TRUE, to dojdzie do uwierzytelnienia użytkownika.

Warto zaznaczyć, że często hakerzy nie wpisują ręcznie poszczególnych wstrzykiwanych zapytań, ale generują je automatycznie przy wykorzystaniu dedykowanych w tym celu narzędzi, przez co nawet osoba bez głębszej znajomości strukturalnego języka zapytań może stać za takim atakiem.

Rodzaje ataków SQL Injection

Ataki SQL Injection możemy podzielić na kilka rodzajów (typów), które różnią się od siebie sposobem, w jaki atakujący wchodzi w interakcję z bazą danych za pomocą zapytań SQL przesyłanych przez aplikację:

  1. In-band SQLi, czyli klasyczny atak SQL Injection, który jednocześnie jest najprostszy do przeprowadzenia i najpowszechniejszy. W tym przypadku haker wykorzystuje tylko jeden kanał (np. zwykłą przeglądarkę internetową) do przeprowadzenia ataku i uzyskania jego wyników. Ten typ ataku dzieli się na dwa podtypy:
  • Error-based SQLi, polegający na celowym wywoływaniu błędów w bazie danych, które mogą dostarczyć cennych informacji, takich jak, np. typ i wersja bazy danych, jej struktura, co jest niezwykle pomocne w celu ustalenia dalszej strategii działania. Dla przykładu znajomość struktury bazy danych i aplikacji umożliwia konstruowanie kolejnych metod i zapytań SQL w celu lepszej penetracji bazy danych i realizacji określonych celów.
  • Union-based SQLi, polegający na wykorzystaniu polecenia UNION w języku SQL w celu połączenia wyników kilku zapytań w jeden. Ten atak jest uznawany za jeden z najbardziej niebezpiecznych, ponieważ przy braku odpowiednich zabezpieczeń umożliwia wydobycie z bazy danych praktycznie wszystkich informacji, które są w niej przechowywane.
  1. Inferential SQLi (Blind SQLi), czyli „ślepy” atak SQL, gdyż haker nie widzi bezpośrednio wyników wstrzykiwanych zapytań. Może jednak obserwować zachowanie bazy danych i na tej podstawie odtworzyć jej strukturę. Pomimo, że ten typ ataku SQL Injection wymaga poświęcenia znacznie większej ilości czasu niż klasyczny atak SQLi, to jest równie groźny i podobnie jak In-band SQLi dzieli się na dwa podtypy:
  • Boolean-based (Content-based) Blind SQLi, polegający na wstrzykiwaniu zapytań SQL w celu zmuszenia aplikacji do zwracania różnych wyników w zależności od tego, czy odpowiedź jest prawdziwa (TRUE), czy fałszywa (FALSE). Jest on najczęściej wykorzystywany przez hakerów do wstępnego badania, czy dana aplikacja jest podatna na ataki SQL Injection.
  • Time-based Blind SQLi, polegający na „zmuszeniu” bazy danych do „odczekania” pewnego okresu czasu (zazwyczaj kilku sekund) przed wysłaniem odpowiedzi. W tym przypadku czas odpowiedzi sugeruje atakującemu, czy zapytanie zwróciło wynik fałsz (FALSE), czy prawda (TRUE), co np. pozwala odgadnąć nazwę tablicy litera po literze, co jest jednak bardzo czasochłonne.
  1. Out-of-band SQLi – w tym ataku haker nie korzysta z jednego kanału do przeprowadzenia ataku i uzyskania jego wyników, jak to było zaprezentowane w przypadku klasycznego ataku SQL Injection, ale zamiast tego zmusza aplikację do przesyłania odpowiedzi do innego punktu końcowego będącego pod jego kontrolą.
  2. Compounded SQL Injestion, polegający na łącznym wykorzystaniu ataku SQL Injection z innym rodzajem ataku w celu przeprowadzenia bardziej zaawansowanego i wyrafinowanego ataku hakerskiego.

Jak zabezpieczyć się przez atakiem SQL Injection?

Oczywiście możliwe jest zabezpieczenie się przed atakiem SQL Injection, a stosowanie się do poniższych zaleceń uniemożliwi lub znacząco utrudni przeprowadzenie tego typu ataku.

Chcąc ochronić swoją bazę oraz zapisane w niej dane przed atakiem SQL Injection, w pierwszej kolejności należy dokonać dokładnej weryfikacji kodu aplikacji, a podczas jego tworzenia (pisania) powinno stosować się do dobrych praktyk i zasad bezpieczeństwa.

Ponadto zasadnym jest stosowanie segregacji danych, czyli przechowywanie ich w różnych bazach danych, np. informacje o klientach w jednej bazie, a informacje o produktach w kolejnej. Jednocześnie należy usuwać zbędne informacje i pliki, tak aby, np. nie pozostała w bazie danych zapisana wersja pliku przed jej edycją, która może zawierać swoistą furtkę dla hakera umożliwiając mu przeprowadzanie ataku SQL Injection.

Jednocześnie należy wprowadzić ścisła kontrolę dostępu do wewnętrznych struktur bazy danych oraz dokładną weryfikację uprawnień użytkowników korzystających z takiej bazy.

Następnie powinno się wprowadzić mechanizm rzutowania danych, czyli ich konwersję (przekształcenie na odpowiedni format), aby zapobiec niektórym atakom SQL Injection, gdyż użytkownicy nie powinni mieć możliwości wpisania w formularzu czego tylko zechcą. Rozszerzeniem tego mechanizmu może być sanityzacja, czyli wykorzystanie wyszukiwania słów kluczy, co uniemożliwia umieszczenie kolejno po sobie znaków specjalnych, takich jak np. podwójny myślnik, apostrof, itp. W związku z tym aplikacja powinna przechowywać listę fraz i znaków, które wolno jej zaakceptować podczas przetwarzania formularza (tzw. white lista). Jeśli użytkownik spróbuje wpisać coś, co nie znajduje się na liście (np. komendę w języku SQL), powinno to być automatycznie odrzucone przez system sprawdzania danych wejściowych. Oczywiście mechanizm sanityzacji można połączyć z listą znaków i fraz, których użytkownikowi wpisać nie wolno (tzw. black lista), i które będą automatycznie odrzucone przez aplikację.

Dodatkowo warto korzystać z gotowych zapytań (prepared statements), co polega na tym, że aplikacja nie generuje sama zapytań, lecz buduje je z odpowiednio przygotowanych części, czyli wcześniej zaprojektowanych instrukcji w języku SQL, które służą do komunikacji z bazą danych. Chodzi o to, by nie tworzyć całej instrukcji na raz, lecz rozdzielić ją na polecenie oraz argumenty, które zostaną do niej dodane później. Zmienne w instrukcji są w tym wypadku zastępowane znakami zapytania.

Stosując ten mechanizm ochronny, zmienne wprowadzane przez użytkowników (np. loginy, hasła, frazy wyszukiwania, itp.) są dodawane w odpowiednie miejsca na późniejszym etapie tworzenia zapytania, a sam szkielet instrukcji pozostaje niezmienny. Nie ma więc możliwości zmodyfikowania go z poziomu formularza w danej aplikacji webowej. Metoda ta jest szczególnie zalecana, gdyż chroni przed większością ataków SQLi. Jedynym jej minusem jest możliwość negatywnego wpływu na wydajność aplikacji.

Przykłady udanych ataków SQL Injection

Poniżej przedstawiam kilka głośnych ataków przeprowadzonych za pomocą wstrzyknięcia kodu SQL:

  1. Tesla podatna na atak SQL Injection: w 2014 roku grupa etycznych hakerów odkryła, że przy wykorzystaniu ataku SQL Injection można wykraść dane klientów Tesla Motors, jednak zamiast kradzieży danych, firma została poinformowana o problemie;
  2. Atak na bank w Katarze: w 2016 roku turecka grupa hakerska wykradła 2GB dokumentów i informacji o klientach Narodowego Banku Kataru;
  3. SQL Injection w Fortnite: w 2019 roku naukowcy z Checkpoint Research odkryli podatność, między innymi na ataki SQLi w grze Fortnite, a twórcy gry zostali poinformowani o znalezionych podatnościach.

Podsumowanie

Reasumując, atak SQL Injection jest niesłychanie groźny, ponieważ jego wykrycie jest wyjątkowo trudne, a czasem niemożliwe. Najczęściej o ataku można się dowiedzieć jedynie po wycieku danych z zaatakowanej bazy. W związku z tym jest niezwykle istotne, aby jak najlepiej zabezpieczyć aplikację webową i wykorzystywaną przez nią bazę danych przed atakiem SQLi. Dzięki temu nasza aplikacja będzie odporna na wstrzykiwanie kodu SQL, a tym samym dane przechowywane w bazie będą odpowiednio zabezpieczone przed ich kradzieżą przy wykorzystaniu wstrzykniętych zapytań SQL.

Autor: Michał Mamica

Zobacz również

SKOMENTUJ

Proszę wpisać swój komentarz!
Proszę podać swoje imię tutaj

Artykuły

Komentarze