Техника сетевых атак
Шрифт:
Для разминки воспользуемся командой “type passwd.simple” и на экране незамедлительно появится содержимое файла паролей:
· type passwd.simple
· MyGoodPassword
Разработчики UNIX нашли оригинальное решение, прибегнув к необратимому преобразованию - хешированию. Предположим, существует некая функция f, преобразующая исходную строку к некой последовательности байт таким образом, чтобы обратный процесс был невозможен или требовал огромного объема вычислений, заведомо недоступного злоумышленнику. Математички это можно записать как:
· f(passwd) -» x
Вся изюминка в том, что если строка s1 равна строке s2, то и f(s1) заведомо
Сказанное легче понять, самостоятельно написав простейшую программу, работающую по описанной выше методике. Сначала необходимо выбрать функцию преобразования, отвечающую указанным условиям. К сожалению, это сложная задача, требующая глубоких познаний криптографии и математики, поэтому, просто посчитаем сумму ASCII кодов символов пароля и запомним результат. Пример реализации такого алгоритма приведен ниже (смотри файл “passwd.add.new.user.c”):
· #include «stdio.h»
· #include «string.h»
·
· void main
· {
· char buf[100],c;
· int sum=0xDEAD,i=0;
· FILE *f;
·
· if (!(f=fopen("passwd","w"))) return;
· printf("Enter password:");
· fgets( amp;buf[0],100,stdin);
· while(buf[i])
· {
· c=buf[i++];
· sum+=c;
· }
· _putw(sum,f);
·}
Запустим откомпилированный пример на выполнение и в качестве пароля введем, например, “MyGoodPassword”. Теперь напишем программу, проверяющую вводимый пользователем пароль. Один из возможных вариантов реализации показан ниже (смотри файл “/SRC/passwd.c”):
· #include «stdio.h»
· #include «string.h»
·
· void main
· {
· char buf[100],c;
· int sum=0xDEAD,i=0,_passwd;
· FILE *f;
·
· if (!(f=fopen("passwd","r"))) return;
· printf("Enter password:");
· _passwd=_getw(f);
·
· while(buf[i])
· {
· c=buf[i++];
· sum+=c;
· }
· if (sum-_passwd)
· printf("Wrong password!\n");
· else
· printf("Password ok\n");
·
·}
Обратите внимание на выделенные строки - и в том, и в другом случае использовалась одна и та же функция преобразования. Убедившись в умении программы отличать «свои» пароли от «чужих», заглянем в файл “passwd”, отдав команду “type passwd”:
· type passwd
· Yф
Совсем другое дело! Попробуй-ка, теперь угадай, какой пароль необходимо ввести, что система его пропустила. Строго говоря, в приведенном примере это можно без труда и задача решается едва ли не в уме, но условимся считать выбранную функцию односторонней и необратимой.
Из односторонности функции следует невозможность восстановления оригинального пароля по его хешу, и доступность файла passwd уже не позволит злоумышленнику проникнуть в систему. Расшифровать пароли невозможно, потому что их там нет. Другой вопрос, удастся ли подобрать некую строку, воспринимаемую системой как правильный пароль? К обсуждению этого вопроса мы еще вернемся позже, а для начала рассмотрим устройство механизма аутентификации в UNIX.
Первые версии UNIX в качестве односторонней функции использовали модифицированный вариант известного криптостойкого алгоритма DES. Под криптостойкостью в данном случае понимается гарантированная невозможность вычисления подходящего пароля никаким иными способом, кроме тупого перебора. Впрочем, существовали платы, реализующие такой перебор на аппаратном уровне и вскрывающие систему за разумное время, поэтому пришлось пойти рискованный шаг, внося некоторые изменения в алгоритм, «ослепляющие» существующее «железо». Риск заключался в возможной потере криптостойкости и необратимости функции. К счастью, этого не произошло.
Другая проблема заключалась в совпадении паролей пользователей. В самом деле, если два человека выберут себе одинаковые пароли, то и хеши этих паролей окажутся одинаковыми (а как же иначе?). А вот это никуда не годится, - в многопользовательской системе шансы подобного совпадения не так малы, как это может показаться на первый взгляд, и в результате возможен несанкционированный доступ к чужим ресурсам.
Разработчики нашли элегантное решение, - результат операции хеширования зависит не только от введенного пароля, но и случайной последовательности бит, называемой привязкой (salt). Разумеется, саму привязку после хеширования необходимо сохранять, иначе процесс не удастся обратить. Однако никакого секрета привязка не представляет, (поскольку шифрует не хеш-сумму, а вводимый пользователем пароль).