[#] Atak typu "SQL Injection"

( Ostatnio zmieniony czw., 12/06/2008 - 13:32 )
 

SQL injection – „Zastrzyk SQL“

Atak typu SQL injection – manipulacji aplikacją komunikującą się z bazą danych, tak aby umożliwiła ona atakującemu uzyskanie dostępu lub modyfikację danych, do których nie posiada on uprawnień.
W praktyce polega to na wykorzystaniu interfejsu użytkownika (adresu URL, formularza HTML/XML, okna dialogowego itp.) do wprowadzenia do aplikacji spreparowanego ciągu znaków, który, dzięki naiwności programisty, bez odpowiedniego uprzedniego przetworzenia, stanie się częścią kodu wykonanywanego w bazie danych. W zależności od architektury aplikacji, może to być gotowe wyrażenie SQL, ale nie tylko. Zagrożenie atakami typu SQL injection dotyczy głównie aplikacji internetowych, jednak technikę tę można z powodzeniem zastosować do atakowania aplikacji typu klient, serwer.

Ważne:

  1. ataki typu SQL injection to ataki wysokiego poziomu
  2. zabezpieczenia działające na poziomie sieci IP np. firewall nie widzą takich ataków
  3. bezsilne są nawet systemy wykrywania włamań
  4. skanery antywirusowe oraz filtry treści wykorzystujące bazy sygnatur – nic nie pomogą

Metody ataków:

apostrof

Sprawdzenie czy aplikacja jest podatna na SQL Injection polega na wprowadzeniu ' w polu formularza. Jeśli wyświetli się błąd, możemy podejrzewać, że aplikacja nie jest odporna na SQL Injection. Wyświetlane błędy są ogólnie dobrym źródłem informacji.
Jeśli otrzymaliśmy komunikat błędu po wprowadzeniu apostrofu w polu e-mail, na stronie z opcją – „Wyślij mi moje hasło“ podejrzewamy, że wyrażenie wywołane w bazie wygląda tak:

SELECT fieldlist FROM table WHERE field = '$EMAIL';

$EMAIL to wpisany adres, już wiemy, że jest częścią dynamicznie wykonywanego kodu. Wprowadzając xxx@mimuw.edu.pl' otrzymujemy:

SELECT fieldlist FROM table WHERE field = 'xxx@mimuw.edu.pl'';

i syntax error.

Możemy wprowadzić również, coś takiego: ‚anything‘ OR ‚x‘='x

SELECT fieldlist FROM table WHERE field = 'anything' OR 'x'='x';

Zdradliwe znaki specjalne

'
zakończenie pojedynczego cudzysłowu, w który są ujmowane dane wprowadzane z wewnątrz;
;
Zakończenie zapytania i rozpoczęcie nowego;
Początek komentarza – w ten sposób usuwa się dalszą część kodu, która nie jest intruzowi potrzebna, a może wywołać błąd składniowy i uniemożliwić wykonanie ataku.

Przykłady:

"SELECT id FROM users WHERE username = '" . $username . "' AND password = '" . $password ."'";

Operatorem konkatenacji w języku PHP jest znak kropki. Cudzysłowy ograniczają poszczególne ciągi znaków (string), a znaki apostrofu (') otaczają fragmenty danych wprowadzane przez użytkownika.

Na czym polega atak? Jeżeli użytkownik do formularza LoginPage.php wprowadzi następujące dane:

Użytkownik:

'; delete from users-- Hasło

To kluczowy fragment kodu PHP, po wstawieniu wprowadzonych danych będzie wyglądał następująco:

"SELECT id FROM users WHERE username = '" . '; delete from users" . "' AND password = '" . . "'";

inne przykłady

SELECT email, passwd, login_id, full_name FROM table WHERE email = 'x' AND 1=(SELECT COUNT(*) FROM tabname); --';
SELECT email, passwd, login_id, full_name FROM members WHERE email = 'x' OR full_name LIKE '%Bob%';

Jak unikać SQL Injection

1. Analizowanie wejścia Wszystkie dane pochodzące z zewnątrz aplikacji powinny być filtrowane. Procedury powinny przepuszczać tylko te znaki/ciągi, które są dopuszczalne w danym kontekście. Szczególnie ważne jest wyszukiwanie słów kluczowych, takich jak SELECT. Znaków takich jak cudzysłów, apostrof czy podwójny myślnik.
Oczyszczanie wczytanego ciągu znaków nie zawsze jest jednak rzeczą prostą, a przynajmniej czasami, może być uciążliwe (SQL jest językiem rozbudowanym, istotny jest również kontekst, w którym znaki zostają wczytane).

2. Zarządzanie komunikatami o błędach
Zwykły użytkownik nie powinien otrzymywać komunikatów, mogacych zdradzać szczegóły budowy bazy danych.

3. Ograniczanie uprawnień użytkowników
Przy nadawaniu uprawnień należy stosować zasadę najmniejszych przywilejów. W fazie projektowania należy zdefiniować najmniejszy zestaw informacji niezbędny do wykonania danego zadania. Szczególną uwagę należy zwrócić na prawa dostępu do wewnętrznych struktur bazy danych. Oddzielenie danych od kodu

4. Unikanie dynamicznie generowanego kodu SQL jest najlepszym rozwiazaniem.
Większość interfejsów baz danych zapewnia taką możliwosć (parametry wiązane – PHP, parametry nazwane JDBC). Wyrażenie powinno najpierw zostać „przygotowane“ i czekać w bazie na wyliczenie z podanym parametrem, który już nie może zostać pomylony z kodem.

Przykład w perl'u

$sth = $dbh->prepare("SELECT email, userid FROM members WHERE email = ?;"); $sth->execute($email);
5
Twoja ocena: Brak Średnio: 5 (3 głosy)