Совсем недавно системы распределенных вычислений
стали очень популярными. Не мудрено, это что-то вроде новой технологии. С помощью них уже успешно расшифровывают
с виду необратимые коды, а также ищут всяких инопланетных существ и лекарства от рака. Принять участие в такой системе может любой желающий. За каждый отосланный пакетик с расшифровкой он получит определенные бонусы. Я не буду расписывать тебе как работает система... а просто предложу рабочий вариант своей реализации.

Я уверен, что далеко не каждый замахнется на такую идею, как система распределенных вычислений. Во первых, нужно придумать, что будет делать такой проект. Во вторых, надо как-то реализовать эту идею. И, наконец, привлечь пользователей (для этого существуют отдельные методы).

Итак, поехали. Что же будет делать наша система? Нет, она не будет изучать инопланетные импульсы, ибо мы не владеем такой информацией. Она не будет искать лекарство от неизлечимых заболеваний, потому как мы не работаем в НИИ. Она не будет расшифровывать PGP-коды - алгоритмов расшифровки мы не имеем... Хотя, это уже близко к моей задумке. Наша система будет взламывать DES и OpenBSD BlowFish хэши.

Я остановился на этой идее по нескольким причинам. Для хакеров очень важно расшифровать подобный пароль. Нередко за этим же обратится и админ, забывший пассворд. Поэтому клиентов будет предостаточно. Реализация проста и быстра одновременно. Заставим джоника работать за нас. То есть John The Ripper будет пытаться расшифровать пароль, а затем отправит его в систему. Но я забегаю вперед.

Что мы имеем? У нас есть несколько паролей, которые мы распределим между участниками проекта. Типов паролей, как я уже сказал, два. Поэтому необходимо учитывать переменную $type, которая заведует видом хэша. Также будет существовать некоторая переменная $cid (client id) - она отвечает за идентификатор клиента.

Конф - всему голова

У каждого проекта должен существовать свой конф, чтобы админ смог пластично его настроить под себя. Мы тоже создадим свой конф. Обзовем его main.inc и закинем в главную директорию системы.

## Main.inc - main configuration file.

# Files and directories
$etcdir='etc'; ##
Директория, где будут хранится файлы с паролями
$logdir='log'; ##
Директория, где хранятся логи

$saltfiledes="$etcdir/des.fs"; ## Так называется файл с DES-хэшами
$saltfileob="$etcdir/ob.fs"; ##
OpenBSD BlowFISH
$mainlog="$logdir/mainlog.fs"; ##
Главный лог системы
$userdir='users'; ##
Директория с пользовательскими файлами

# System variables

$countcrack=3; ## Переменная, отвечающая за то, сколько должно быть реквестов на один пароль, после которых он будет временно удален из базы.

Принимаем запросы - getpass.cgi

Настало время написать один из главных модулей системы - файл getpass.cgi. Этот скрипт будет выдавать клиенту пароль по его id и типу. В моей первой версии модуля там нет идентификации клиента, скрипт принимает всех за "своих" и выглядит следующим образом:

#!/usr/bin/perl

## Simply CGI script, which puts your Fsystem client data with the pwd salt.

require "main.inc"; ## Заюзаем файл с переменными (конф мы описывали чуть выше)
use CGI qw(:standard); ##
А также модуль CGI.pm

$cid=param('id');
$stype=param('type'); ## Might be 1 (DES) or 2 (OpenBSD Blowfish); ##
Выделим два параметра из запроса - type и
id.

$salt=printpass(); ##
Передадим салт клиенту
$oid=checkcount("$salt"); ##
И проверим - удалить ли из базы пароль?
putlog($oid); ##
Запишем в логи результат

sub printpass { ## Процедура, которая выкинет пароль на экран юзеру
my($salt,@salts); ##
Задаем локальные переменные
openquery(""); ##
Откроем файл с паролями (в нашем случае на чтение)
while(<PWD>) {
push(@salts,$_) ##
Загрузим салт как элемент массива
unless(/^\#/|/^\^/|/^$/); ##
Если салт не заремлен
}
$salt=$salts[int(rand(scalar(@salts)))]; ##
Выберем совершенно случайный элемент из списка
close(PWD); ##
Закроем файл
print "Content-type: text/html\n\n$salt";
return $salt; ##
Выпишем клиенту инфу, и вернем результат
}

sub openquery {
my($access)=shift;
$stype == 1 ? open("PWD","$access$saltfiledes") : open("PWD","$access$saltfileob"); ##
Тут все просто. Открываем файл заданного типа по заданному доступу.
}

sub checkcount { ## Процедура подсчета обращений к паролю
my $salt = shift;
my (@salts,$count,$user,$pwd,$oid); ##
Выделим локальные переменные
openquery(""); ##
Откроем базу паролей для чтения
while(<PWD>) {
push(@salts,$_); ##
Опять грузим все салты
}
close(PWD);
openquery(">"); ##
И открываем уже для записи.
foreach (@salts) {
if ($_ ne $salt) { ##
Если салт не соответствует нужному
print PWD "$_" ##
Пишем его назад в файл
} else {
($user,$pwd,$oid,$count)=split(':',$_); ##
Иначе сплитуем по важным переменным (формат файла: юзер:пароль:владелец пароля:число_запросов)
$count++; ##
Увеличим число запросов на 1
if ($count < $countcrack) {
print PWD "$user:$pwd:$oid:$count\n"; 
} else {
print PWD "\#$user:$pwd:$oid:$count\n";
} ##
Если оно превысило
норму (она оговорена в конфе) - ремить салт, иначе оставить как есть

}
}
close(PWD);
return($oid); ##
Вернуть результат
}

sub putlog {
my $oid=shift;
open(LOG,">>$mainlog");
print LOG "$cid:$oid:".time()."\n";
close(LOG);
} ##
Тут все просто - записать в лог инфу о запросе.

Этот довольно простой модуль принимает запрос от клиента и выдает ему рандомный пароль. После этого клиент системы должен его перебрать.

Расшифровал? Пришли результат!

Второй модуль системы называется putpass.cgi, который, в свою очередь принимает уже подобранный пароль, проверяет его на вшивость и записывает в логи результат о том, что он был взломан. Все довольно просто.

#!/usr/bin/perl

## Putpass.cgi script, which recv salt from client

require "main.inc";
use CGI qw(:standard); ##
Заголовок аналогичен первому модулю

$salt=param('salt');
$pwd=param('pwd');
$id=param('id');

## Три переменных - id клиента, расшифрованный пароль и салт.

$res=checksalt(); ## Проверка на вшивость
print "Content-type: text/html\n\n$res"; ##
И вывод результата проверки для клиента.

writelog
if ($res eq 1); ##
Если все ок - запишем лог
exit; ##
Иначе просто выйдем.

sub checksalt {
(undef,$salt)=split(':',$salt);
return 0 ## Вернем 0 ...
if (crypt($pwd, $salt) ne $salt); ##
Если декриптованный пароль не
совпадает...

return 1 ##
Иначе все ок 🙂
}

sub writelog {
open(UF,">>$userdir/$id");
print UF "$oid:".time()."\n";
close(UF);
} ##
Оформляем лог (понадобится для детальной статистики).

Вот, собственно и вся система. Точнее ее каркас. Эти два модуля могут вполне хорошо обеспечить выдачу и прием запросов от клиента. Остается написать этот самый клиент и проверить систему в действии. Этим мы займемся в следующей части статьи ;). А пока переваривай материал и жди продолжения.

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии