PHP

Zabezpieczenia formularzy - metoda z hasłem na obrazku.

piechnat

Artykuł ten jest właściwie bardziej gotowcem ale takiego działu
nie ma w sekcji PHP więc musiał zostać artykułem :-))

Problem:

Mamy super skrypt i chcemy żeby wykonywany był tylko i wyłącznie
przez formularz znajdujący się na naszej stronie.

Rozwiązanie w teorii:

Najlepiej jest przy pomocy formularza oprócz konkretnych danych
przesłać hasło. Powinno ono za każdym razem być inne. Można
to uzyskać na wiele sposobów. Najprościej jest generować
hasło na podstawie aktualnego czasu. Sprawny 'hacker' formularzy
jest w stanie bez problemu wyciągnąć hasło z kodu źródłowego
strony dlatego właśnie pojawił się pomysł z wyświetleniem go
w postaci obrazka co uniemożliwia programowe pobranie hasła.
Jedyną wadą jest to, że użytkownik musi przepisywać je z obrazka
do pola tekstowego ręcznie. Nasz super skrypt powinien
przed wykonaniem swoich właściwych działań pobrać czas, rozkodować
czas z hasła i sprawdzić czy oba czasy są sobie równe. W przypadku
gdy tak się nie stanie powinien przerwać swoje działanie.
Musimy oczywiście dać internaucie czas na wypełnienie formularza.
Ja przyjąłem tolerancję do dwóch godzin.

Rozwiązanie w praktyce:

Strona z formularzem - index.php:

<form action="skrypt.php" method="post"> image.php

Aby wysłać formularz wpisz hasło z obrazka

<input type="text" name="pass" size="8"> <input type="submit" value="Wyślij"> </form>

Plik generujący obrazek z hasłem - image.php:

```php
<? 
    function passgen() {
       $nr = floor(time() / 3600);
       srand(array_sum(explode(" ", microtime())) * 100000);
       $a = rand(0, min(getrandmax(), $nr)); 
       $b = $nr - $a;
       $a = base_convert($a, 10, 36); 
       $b = base_convert($b, 10, 36);
       $a = strrev(str_pad($a, max(strlen($a), strlen($b)), 0, STR_PAD_LEFT));
       $b = str_pad($b, max(strlen($a), strlen($b)), 0, STR_PAD_LEFT);
       for($i = 0; $i < strlen($a); $i++) $pass .= $a[$i].$b[$i];
       return $pass;
    }
    header("Content-type: image/jpeg");
    $img = imagecreate(110, 30); 
    $background = imagecolorallocate($img, 206, 207, 099);
    $textcolor = imagecolorallocate($img, 0, 0, 0);
    imagestring($img, 5, 10, 7, passgen(), $textcolor);  
    imagejpeg($img); 
    imagedestroy($img); 
?> 

Nasz super skrypt - skrypt.php:

<?  
   function passcheck($pass) {
       $nr = floor(time() / 3600);
       for($i = 0; $i &lt; strlen($pass); $i++)
         if($i % 2 == 0) $a .= $pass[$i]; else $b .= $pass[$i];
       $a = base_convert(strrev($a), 36, 10);
       $b = base_convert($b, 36, 10);
       if($a + $b &lt;= $nr && $a + $b &gt;= $nr - 2) return true; 
       return false;
   }

   if(!passcheck($pass)) die("Hasło nie poprawne !!!");

   //reszta super skryptu
?>

To by było na tyle :-)

pozdrawiam...
piechnat

PHP

15 komentarzy

Ciekawy skrypt, często się z takimi spotykam, a w szczególności np dla autoryzacji kodów otrzymanych sms-em na wielu portalach

Heh... Bramka SMS Idei ...

np na stronie idola przy autoryzacji kody dostepu, bramka tesh, ale cos sie im wali, bo niepoprawnie odczytuje wpisany text

dzięki za ten skrypt :)

Takie rozwiązanie sprawia, że przy każdym kolejnym wygenerowaniu kodu działa jeszcze ten sprzed godziny więc praktycznie takie rozwiązanie mija się z celem zabezpieczenia.
Po za tym na większości już serwerów register globals jest wyłączone więc na początku skrypt.php powinno być:
$pass = $_POST['pass'];

a nie lepiej (?) : wygenerowac haslo, zapisac w sesji i po wyslaniu formy sprawdzic czy sie zgadzaja

a nie lepiej (?) : wygenerowac haslo, zapisac w sesji i po wyslaniu formy sprawdzic czy sie zgadzaja

Nie wiem, czy zabezpieczenie obrazkiem jest takie pewne http://sam.zoy.org/pwntcha/.
Najlepsze wtedy wydaje się wyświetlanie grafiki w częściach, co raczej nie jest trudne do zrobienia

Cóż... Mi ten skrypt nie działa..... mam je na http://www.elektrobed.yoyo.pl/zaasdbez/ . Prosze o kontakt. [email protected]

Ale przecież wszystkie take skrypty są bez sensu w porównaniu ze http://sblam.com !!!

Poprawiony znak specjalny html < na < , co czyniło z skryptu błędny

Dlaczego u mnie zawsze pokazuje że podano niepoprawne hasło
http://www.kruchy.eu/test/kod/index.php
skopiowałem dosłownie ten skrypt, poprawiłem znaki <> i nic. Proszę o info

Coś a'la bramka na stronie idei możecie znaleźć tutaj: http://ztmnews.kernel.pl/token/ -- bardzo proste do wykonania to było, ale wykorzystuje mysql'a