- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
ТЕХНИКА СЕТЕВЫХ АТАК - Крис Касперский
Шрифт:
Интервал:
Закладка:
Точно так, злоумышленник, не знающий, сколько времени займет подбор пароля той или иной длины, не может назвать его ни длинным, ни коротким. Конечный ответ зависит не длины пароля самой по себе, а от времени, необходимого на его перебор. Ограничение на длину паролей в восемь символов какой-то десяток лет назад не казалась разработчикам UNIX чем-то ненормальным. По вычислительным мощностям того времени такая длина была более чем достаточна и требовала для полного перебора порядка двухсот миллионов лет. Технический прогресс уменьшил этот срок в сотни тысяч раз, и с каждым годом все продолжат уменьшать.
С учетом совершенствования компьютерной техники, становится рискованно давать долгосрочные прогнозы. Но это и не существенно, если речь идет о защите ресурсов, обесценивающихся в течение одного-двух лет.
Другими словами невозможно точно рассчитать стойкость пароля, ее можно лишь приблизительно оценить. Для этого пригодятся формулы, описанные ниже.
Время, необходимое для гарантированного нахождения пароля равно: t = V * n где V количество перебираемых комбинаций в секунду, а n количество существующих паролей. В свою очередь n зависит от максимально возможной длины пароля и количества символов, из которых может быть составлен пароль.
Пусть N обозначает множество символов, потенциально входящих в пароль, тогда, очевидно, чтобы гарантировано найти пароль единичной длины потребуется перебрать N вариантов. А из двух символов можно составить N*N+N комбинаций. Доказать это утверждение можно несколькими способами.
Например, так: поскольку каждый символ пароля можно представить в виде цифры, то и сам пароль можно изобразить в форме числа. Если символы пароля представляют собой ряд натуральных чисел от 1 до N, то, следовательно, каждый пароль численно совпадет со своим индексом, а количество паролей окажется равно значению максимального индекса.
Любое натуральное число можно представить в виде следующей суммы степеней: N1+N2+NL,… где L - количество цифр в числе (т.е. в данном случае длина пароля). Отсюда, если длина пароля равна двум, то всего существует N1+N2 возможных паролей, что и требовалось доказать. Если же учитывать вероятность отсутствия пароля, то к этой формуле придется добавить единицу, таким образом, получится следующий результат:
???? t = V * (N0+N1+N2+NL)
Формула 1. Время, необходимое для гарантированного нахождения заданного пароля. t - время, V - скорость перебора, N - количество символов, из которых может состоять пароль, L длина пароляПо этой формуле можно вычислить время, необходимое для поиска пароля в худшем случае. Однако, вероятность, что искомый пароль окажется самым последним перебираемым вариантом равна вероятности угадать правильный ответ с первой попытки. Поэтому, точно вычислить требуемое время невозможно (это кому как повезет), но принято говорить о времени, необходимом в среднем случае. Оно вычисляется по следующей формуле: tср =tмакс /2.
В некоторых публикациях (например «Моделирование возможности компьютерной атаки нарушителями через систему паролей» Головин Д. В.) затрагивается вопрос, - какой поиск пароля дает наилучший результат - последовательный или хаотичный. На самом деле вопрос нелеп в своей постановке, поскольку не оговаривается, откуда и как возник искомый пароль. Если принять, что он был выбран случайно, то последовательной перебор вариантов будет ничем не хуже (и не лучше) хаотичного поиска, поскольку никаких сведений (ни явных, ни предполагаемых) об искомом паролей нет и одному методу поиска нельзя отдать предпочтение перед другим [337].
Однако выбрать абсолютно случайный пароль прямо-таки затруднительно. Большинство генераторов случайных чисел имеют дефекты, иногда весьма значительные и хотя результат выдаваемый ими результат нельзя предсказать, можно оценить его вероятность.
Если достоверно известно с помощью какого алгоритма был получен исходный пароль то, использовав тот же самый алгоритм в переборщике, можно попытаться несколько сократить требуемое количество попыток. Но при этом возникнет трудность с предотвращением повторных проверок одного и того же пароля. Большинство алгоритмов допускают неоднократное появление один и тех же значений даже в интервале не превышающего периода генерации, поэтому каждый выданный пароль придется где-то сохранять и проверять на уникальность. Все это требует накладных расходов, значительно превышающих выгоды использования дефектов генератора случайных чисел (если только используемый генератор не кривой как бумеранг).
Поэтому, в большинстве случаев используется простой линейный поиск, заключающийся в последовательном переборе возможных паролей один за другим. Один из простейших алгоритмов перебора (получивший название «алгоритм счетчика») приведен ниже (на диске, прилагаемом к книге, он находится в файле “/SRC/gen.pswd.simple.c”):
· #include «stdio.h»·· main()· {· char pswd[10];· int p=0;· pswd[0]='!';· pswd[1]=0;·· while(1)· {· while((++pswd[p])»'z')· {· pswd[p]='!';· p++;· if (!pswd[p])· {· pswd[p]=' ';· pswd[p+1]=0;·}·}· p=0;· printf("%sn", amp;pswd[0]);··}·}
Суть алгоритма заключается в следующем: Первый слева символ пароля увеличиваться до тех пор, пока не превысит максимально допустимое значение. Когда такое произойдет, он «обнуляется» - принимает минимально допустимое значение, а символ, стоящий справа от него инкрементируется на единицу. Происходит, так называемая, «зацепка» - точно так работает механический счетчик на шестеренках. Когда шестеренка совершает полный оборот, она задевает своим удлиненным зубчиком соседнюю, заставляя ее повернуться на одну позицию. В упрощенном виде алгоритм записывается в одной строке на языке Си:
· while ((++pswd[p])»MAX_VAL) pswd[p++]=MIN_VAL;p=0;
Такая конструкция скрывает рекурсию, и тот же алгоритм в рекурсивной форме записи может выглядеть так:
· void GetNextPasswd(char pswd, int p)· {· pswd[p]++;· if (!(pswd[p]»MAX_VAL)) return;· pswd[p]=MIN_VAL;· Count(pswd,++p);·}
Но если MIN_VAL отлично от нуля, то в программу приходится добавлять пару строк, инициализирующих значение очередной ячейки, например, это может выглядеть так:
· if (!pswd[p])· {· pswd[p]=' ';· pswd[p+1]=0;·}
Другое решение заключается в предварительной инициализации всех ячеек значением MIN_VAL-1. Однако потом придется «вручную» вычислять длину пароля и внедрять завершающий строку нуль (если программа написана на языке Си).
Результат работы программы может выглядеть, например, так (все полученные пароли выводятся на экран, на практике же они передаются процедуре наподобие Crypt):
· " # $ % amp; ' () * +, -·. / 0 1 2 3 4 5 6 7 8 9·:; «=»? @ A B C D E· F G H I J K L M N O P Q· R S T U V W X Y Z []· ^ _ ` a b c d e f g h i· j k l m n o p q r s t u· v w x y z!! "! #! $! %! amp;! '!· (!)! *! +!,! -!.! /! 0! 1! 2! 3!· 4! 5! 6! 7! 8! 9!:!;! «! =!»!?!· @! A! B! C! D! E! F! G! H! I! J! K!· L! M! N! O! P! Q! R! S! T! U! V!…
·В данном случае львиная доля процессорного времени тратится на вывод строк на экран, но при реальном подборе пароля, быстродействием переборщика не всегда удается пренебречь, поэтому имеет смысл переписать программу на ассемблер.
Частично оптимизированный вариант [338] (т.е. без учета особенностей исполнения кода процессорами семейства Intel 80x86) может выглядеть так (на диске, прилагаемом к книге, он находится в файле “/SRC/gen.pswd.simple.asm.c”):
· #include «stdio.h»· #include «memory.h»·· main()· {· int p=0;· char pswd[10]; // Буфер для генерации паролей· memset( amp;pswd[0],0,10); // Иницилизация буфера· pswd[0]='!'; // Начальный пароль··· __asm{·; Загрузка в регистр EAX указателя на буфер паролей· LEA EAX,pswd;·; Сохранение регистра EAX в стеке· PUSH EAX· Begin:·}·· // В этом месте должен быть расположен код обработки пароля· // в данном случае очередной пароль выводится на экран· printf("%sn", amp;pswd[0]);·· __asm{· POP EAX; Восстановление регистра EAX· PUSH EAX; И снова - сохранение!· INC [EAX]; ++pswd[p]· CMP Byte ptr [EAX],'z'; if (pswd[p]»'z') go to Check· JBE Begin; Очередной пароль·· // Проверка на перенос (и выполнение переноса)· Check:· MOV Byte ptr [EAX],'!'; pswd[p]='!'· INC EAX; p++· CMP Byte ptr [EAX],0; if (!pswd[p]) go to Ok· JNZ Ok; Это не крайний символ· MOV Byte ptr [EAX],'!'; pswd[p]=0· POP EAX; p=0· PUSH EAX; Восстановление (сохранение) EAX· JMP Begin· Ok:· INC Byte ptr [EAX]; ++pswd[p]· CMP byte ptr [EAX],'z'; if (pswd[p]»'z') go to Check· JA Check· POP EAX; p=0· PUSH EAX; Восстановление (сохранение) EAX· JMP Begin·}··}·
Исходный текст NR.PL
· @ECHO off· perl -x -S "%0"· goto end· #!perl· #line 6· print "TCP SpyServer Version 2.0 Copyright (c) 2000 Kris Kasperskyn";·· #Клиентсерверный шпион· use Socket;·· #Настойки по умолчанию· $local_port = 110;· $remote_port = 110;· $server = 'mail.aport.ru';·· #Попытка взятия настоек из файла· if (open(FH,"tcpspy"))· {· $local_port=«FH»;· $local_port =~ s/n//;· $remote_port=«FH»;· $remote_port =~ s/n//;· $server=«FH»;· $server=~ s/n//;·}·· print "Порт локального сервера t[$local_port]:";· $tmp=«»; $tmp=~ s/n//;if ($tmp»0) {$local_port=$tmp;}·· print "Порт удаленного сервера t[$remote_port]:";· $tmp=«»; $tmp=~ s/n//;if ($tmp»0) {$remote_port=$tmp;}·· print "Адрес сервера (none нет) t[$server]";· $tmp=«»; $tmp=~s/n//;· if (length($tmp)) {$server=$tmp}·· #Сохраняем настойки в файле· if (open(FH,"»tcpspy"))· {· print FH "$local_portn";· print FH "$remote_portn";· print FH "$servern";·}· close (FH);·· # 666 - особый код для Эхо-сервера· if ($server=~/none/) {$server=666;}·· #Создаем сокет для локального сервера· socket(SERVER, PF_INET, SOCK_STREAM, 6);· setsockopt(SERVER, SOL_SOCET, SO_RESEADDR,1);· $my_addr = sockaddr_in($local_port, INADDR_ANY);· bind(SERVER, $my_addr);·· #Слушаем…· listen(SERVER,1);· while(1)· {·· print "Ожидание подключения…tt";· #Определяем адрес клиента· $client_addr=accept(CLIENT, SERVER);· ($clint_port,$client_ip) = sockaddr_in($client_addr);· print "+OK [IP:",inet_ntoa($client_ip),"]n";·· $one=CLIENT;·· $connect=1;·· if ($server!=666)· {# Прокси-схема с удаленным сервером· print "Соединение с узлом $server…t";· socket(RSERVER, PF_INET(), SOCK_STREAM(),6);· connect(RSERVER, sockaddr_in($remote_port,inet_aton($server))) || die;· print "+OKn";· $two=RSERVER;··}· else· {# Эхо-сервер· print "Установка эхосервера…tt+OKn";· $two=CLIENT;·}·· $x='foo';· open(LOG,"»tcpspy.log");· #Обработка текущего подключения· while($connect)· {· $rin='';· vec($rin, fileno($one),1)=1;· $timeout=5;· $nfound=select($rout = $rin, undef, undef, $timeout);· if (vec($rout, fileno($one),1))· {· #Слушаем ответ клиента· recv($one,$x,10000,0);· if (!length($x)) {$connect=0;}· else· {·· if ($x=~/#HALT_OFF/) {send($two,"HANDUP",0);die;}· print "$one$x";· print LOG "$one$x";· #Говорим это серверу· send($two,"$x",0);·}·}· else· {#Меняем сервера с клиентом· ($one,$two) = ($two,$one);·}·}· print "n-ERR:Соединение разорваноn";· close(CLIENT);· close(RSERVER);· close(LOG);·}· __END__·:end
[1]. «UNIX не был создан для того, чтобы мешать кому-то делать глупости, ведь это помешало бы умным людям делать умные вещи» Doug Gwyn

