Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #59, НОЯБРЬ 2003 г.

Дадим отпор грубой силе!

Докучаев Дмитрий aka Forb

Xakep, номер #059, стр. 059-062-3


Все, теперь нам осталось только вывести картинку на экран. Для этого переводим поток STDOUT в бинарный режим (ведь наша картинка бинарная) при помощи команды binmode. Далее сообщаем браузеру, что у нас идет тип данных "image/jpeg", и выводим саму картинку методом jpeg:

binmode STDOUT;

print "Content-type: image/jpeg\n\n";

print $image->jpeg;

Сохраняй полученный результат и бегом открывай браузер, чтобы посмотреть на результат. На экране у тебя появится черный квадрат с числом 1000. Поздравляю, ты только что научился выводить динамические картинки! :)

Защита своего проекта

С теорией закончили. Теперь поговорим об организации защиты. Во-первых, каждый раз нам необходимо выводить рандомные значения, а не статическое 1000. Для этого воспользуемся функцией rand. Но rand выдает число с плавающей запятой, поэтому мы его округлим до целого значения функцией int. Вот что у нас получится:

$number = int rand 31337;

Этой командой мы будем генерить целое рандомное значение от 0 до 31337 (не включительно).

Теперь нам надо связать картинку с HTML-формой. Главное - не вздумай делать hidden поле с номером на картинке. Хакер не дурак и быстренько напишет парсер, вытаскивающий этой значение из формы. Разумнее будет создавать для каждой сессии свой MD5-код и помещать его в hidden. И чтобы скрипт понимал передаваемый ему код, надо записать этот самый код в файл и уже затем производить его сравнение с введенной цифрой.

Конечно, сгенерировать MD5 можно и консольной командой "md5 -s строка", но разумнее будет использовать модуль Perl под названием Digest::MD5. Вот как выглядит простенький скрипт, генерящий хеш по строке "time().$$" (текущее время в raw-формате, а также процесс скрипта). После создания уникального номера записываем его файл.

Таблица: Создание хеша сессии

#!/usr/bin/perl

use Digest::MD5;

# Каталог, который не будет виден через web

$chrootdir="/home/user/nonwebbrowseabledir/";

# Новый метод для MD5

$salt=Digest::MD5->new;

# Уникальная строка, по которой ведется шифрование

$string=time().$$;

# Формируем хеш

$hash = $salt->add($string);

# Шифруем методом ASCII-HEX

$id=$hash->hexdigest;

# Открываем файл для записи

open(FILE,">$chrootdir$id") ||

die "Can't open file for write: $!\n";

# Выводим заранее сгенерированный номер

print FILE $number;

close(FILE);

# Выводим контент документа

print "Content-type: text/html\n\n";

# Произвольные данные для формы

print "<HTML><FORM>.....\n";

# Заносим id в форму для последующей проверки

print "<input type=hidden name=hash value=$id>";

После того как юзер передаст все данные скрипту, тебе необходимо будет проверить логин с паролем, а также чекнуть верность введенного номера на картинке. Я сделал это так: открыл файл "$chrootdir$id" ($id пришло сценарию в качестве параметра), извлек из документа номер и сравнил его со вторым параметром формы.

После решения о допуске клиента в систему надо удалить наш вспомогательный файл, иначе у тебя в каталоге будет куча ненужного мусора.

Назад на стр. 059-062-2  Содержание  Вперед на стр. 059-062-4
<<< НАЗАД ||| ГЛАВНАЯ