В отличие от аналогов, рассматриваемый метод не вызывает срабатывания подсистемы обнаружения нарушителя, так как работает в автономном режиме, на основе данных из перехваченной сессии аутентификации. Приведенное описание технологии атаки на пароль поможет лучше понять сценарий действий злоумышленника и адекватно организовать защиту сети, причем не только на базе Novell NetWare, но и других систем с аналогичной схемой аутентификации, в частности, Windows NT.

На первый взгляд может показаться, что обсуждение каких-либо проблем, связанных с версиями 3.x сегодня совершенно неактуально — давно появились новые версии NetWare, обладающие более широкими возможностями, нежели 3.x. Однако практика показывает, что в небольших сетях, требующих между тем выделенного файлового сервера, можно встретить именно версии 3.x. Кроме того, версии 4.x и 5.x имеют режим обратной совместимости, так называемый bindery emulation (эмуляция базы связок), и аутентификация пользователя в этом режиме, с точки зрения криптографического протокола, ничем не отличается от схемы аутентификации, используемой в NetWare 3.x. Очевидно, что при использовании этого режима, описанные проблемы затрагивают и пользователей версий 4.x и 5.x. На момент разработки криптопротокол был достаточно сильным — просто сейчас изменились возможности оборудования (DES в свое время тоже был очень сильным алгоритмом, но на современных компьютерах ломается за разумное время). Кроме этого, надо учесть, что несмотря на сильную конкуренцию, Novell остается одним из крупнейших производителей сетевых операционных систем и удерживает свои позиции на рынке. По данным IDC, в 1999 на 19% закупаемых серверов была установлена именно ОС Novell NetWare. В России эта ОС заняла свою нишу достаточно давно и пока не намерена терять свой рынок. Такой прогноз основан на том факте, что Novell перестала быть лишь «разработчиком ОС для файловых серверов», а предлагает еще и решения для небольших групп (Novell Small Business Suite), средства обеспечения безопасности (BorderManager) и другие.

Существуют различные способы получения паролей, в частности, в результате доступа к базе связок (bindery), базе Сервиса Каталога (NetWare Directory Services — NDS), проведения атаки типа «ложный сервер» или установки на рабочей станции перехватчика паролей. Большинство из них имеют активную природу, требующую вмешательства в работу системы. Рассматриваемый в данной статье способ не требует такого вмешательства, он основан исключительно на расчетах. Конечно, для получения исходных данных их необходимо «перехватить», но используемая для этого программа прослушивания сети (sniffer) не оказывает влияния на работу сети.

Два подхода к защите паролей

Если рассматривать проблему укрупненно, то можно выделить два основных подхода к хранению паролей, и, соответственно, к используемой схеме аутентификации.

Сначала клиент устанавливает с сервером первичное соединение (attach), характеризуемое состоянием NOT-LOGGED-IN. У пользователя запрашиваются имя и пароль

Первый подход заключается в защищенном хранении паролей на сервере. При этом, в случае хищения базы с паролями, злоумышленник не сможет воспользоваться этими данными непосредственно, ему понадобится произвести некоторое количество преобразований (подчас весьма сложных), так как пароли преобразованы односторонней функцией, и узнать их можно только «прогоняя» различные варианты паролей через эту функцию и сравнивая результат; в данной ситуации, это — единственный способ дешифрования. Очевидно, что при таком подходе пользователь должен предъявлять серверу пароль в открытом виде, чтобы последний, произведя над ним соответствующее преобразование, сравнил полученный результат с записью в базе паролей. Ну, а коль скоро пароль предъявляется в открытом виде, возможен его перехват при передаче по каналам связи. Конечно, если использовать даже самую сложную функцию вида:

y=f(x) (1)

где x — пароль, а y — значение односторонней функции (как правило, в качестве односторонней используется хэш-функция, которая должна обладать, как минимум, следующими характеристиками: ее значение имеет фиксированный размер независимо от размера параметра, а подбор параметра под заданное значение является сложной задачей.), то одинаковым паролям будут соответствовать одинаковые значения функции. Злоумышленнику в этом случае достаточно будет один раз обработать большой словарь и в дальнейшем просто определять пароль по значению функции. Чтобы устранить эти недостатки в процесс вычисления вводят дополнительный элемент — salt, который для каждой генерации пароля выбирается случайным образом, после чего формула (1) приобретает вид:

y=f(salt,x) (2)

а в базе паролей на сервере хранится пара чисел (salt,y). Такой подход к защите паролей применяется в большинстве UNIX-систем. В качестве преобразования (2) используется алгоритм шифрования DES (x выступает в роли ключа шифрования), либо алгоритм хэширования MD5.

Другой подход направлен на невозможность перехвата пароля при его передаче. В этом случае пользователь доказывает серверу, что ему известен правильный пароль, не путем предъявления его в открытом виде, а путем вычисления над предложенным сервером числом некоей функции, зависящей также и от пароля. В простейшем случае это может быть шифрование предложенного сервером числа, используя в качестве ключа пароль. Естественно, что для проверки значения функции, присланного пользователем, серверу необходимо повторить данное преобразование, а для этого, в свою очередь, он должен обладать паролем в открытом виде. Схема похожа на предыдущую, изменяется только место вычисления односторонней функции, а роль salt играет высылаемое сервером число. Очевидно, что при этом способе осуществления аутентификации, необходимо принять меры по недопущению несанкционированного доступа к базе паролей на сервере. Такой подход применяется в семействе ОС Novell NetWare, а также Windows NT.

Как это работает?

Рассмотрим по шагам, как проходит процесс аутентификации в NetWare 3.xx, а также в более старших версиях в режиме обратной совместимости. Сначала клиент устанавливает с сервером первичное соединение (attach), характеризуемое состоянием NOT-LOGGED-IN. У пользователя запрашиваются имя и пароль. После этого клиентское программное обеспечение запрашивает у сервера идентификатор пользователя (UserID), передавая ему имя пользователя и тип объекта (User). UserID представляет собой 4-байтовое целое число, которое используется в процедуре вычисления из введенного пользователем пароля значения хэш-функции размерностью 16 байт. Именно это значение хэш-функции и участвует в процессе аутентификации клиента и хранится на сервере NetWare в виде свойства PASSWORD данного объекта (пользователя). Очевидно, что хотя это значение невозможно подставить в качестве пароля стандартной процедуре регистрации (login.exe), его знания достаточно для осуществления подключения к серверу, и оно представляет такую же ценность, как и собственно пароль. Такое преобразование пароля необходимо для того, чтобы использовать в процессе аутентификации «общий секрет» фиксированного размера, так как пароль, в общем случае, может иметь длину от 0 до 128 символов.

Далее, клиентское программное обеспечение запрашивает у сервера 8-байтовое число и шифрует его, используя в качестве ключа вычисленное на предыдущем шаге 16-байтовое значение хэш-функции пароля. Полученный шифротекст, также имеющий размер 8 байт, отправляется на сервер. Поскольку сервер обладает значениями хэш-функции и 8-байтового числа, которое он отправлял на рабочую станцию, он может повторить указанную операцию шифрования и сравнить результат со значением, полученным от рабочей станции. Если рассчитанное значение совпадает с присланным рабочей станцией, клиент считается аутентифицированным, и ему предоставляется доступ к ресурсам, в соответствии с назначенными правами. В случае несовпадения значений, сервер отказывает в доступе, но перед тем, как вернуть ошибку, делает небольшую задержку — чтобы затруднить организацию быстрого подбора пароля в режиме on-line. Дополнительно, чтобы сделать подбор пароля on-line совсем бессмысленным, в ОС NetWare предусмотрена возможность задания блокировки после нескольких неправильных попыток ввода пароля. Число попыток, время блокировки и интервал, за который набираются попытки, задаются администратором. Для NetWare 4.0 и выше в штатном режиме процесс происходит практически также, но он еще дополнительно шифруется по алгоритму RSA.

Задача злоумышленника

Злоумышленник, вооруженный сниффером и наблюдавший данный процесс, имеет в своем распоряжении имя пользователя (впрочем, скорее всего он знал его заранее), UserID и два 8-байтовых числа: переданное сервером и отправленное обратно рабочей станцией. С точки зрения криптографии, злоумышленник обладает знанием алгоритма шифрования и имеет в своем распоряжении открытый текст и соответствующий ему шифротекст. В его задачу входит узнать ключ шифрования, использованный в данном преобразовании. Современные алгоритмы шифрования разрабатываются с учетом обеспечения стойкости к различным видам атак, в том числе и к атаке на ключ. В данной ситуации также очевидно, что 8-байтовое число не может нести полную информацию о 16-байтовом, поэтому вычислить из него ключ невозможно. Однако злоумышленник может попытаться подобрать ключ — все необходимые для проверки данные у него есть. Он выбирает в качестве пароля некоторую последовательность символов, вычисляет хэш-функцию, производит шифрование первого 8-байтового числа и сравнивает полученное значение со вторым. В случае неудачи — берет следующее значение пароля и так далее.

Стандартная реализация алгоритма

Как уже говорилось, в общем случае длина пароля может находиться в пределах от 0 до 128 символов. Вычисление хэш-функции осуществляется в два этапа. Сначала пароль приводится к длине 32 символа, после чего «сворачивается» до 16. Если длина пароля больше 32 символов, он разбивается на блоки по 32 символа, которые складываются между собой по модулю 2. Естественно, длина последнего блока может оказаться меньше 32 символов, в этом случае он дополняется значениями из специальной таблицы констант. Если длина пароля меньше 32 символов, то он реплицируется до нужной длины со вставкой между копиями констант из той же таблицы. Например, если длина пароля 11 символов, то 32-байтовый массив заполняется следующим образом: в первые 11 байт помещается пароль, в 12-й байт — значение из 12-й ячейки таблицы констант, с 13 по 24 байты — снова пароль, в 25-й байт — значение из 25-ой ячейки таблицы констант, с 26 по 32 байты — начало пароля.

Таким образом, мы получили 32-байтовый буфер. Перед «сворачиванием» до 16-байтового размера данный буфер складывается по модулю 2 с 4-байтовым значением UserID, что вносит дополнительную степень перемешивания битов. Однако, в версиях NetWare 3.x на этом этапе допускается одна досадная оплошность — дело в том, что UserID администратора (supervisor) в этих версиях ОС всегда равен 1 и не может быть изменен штатными средствами системы. Очевидно, что кроме своей известности, такое значение оказывает весьма малое «перемешивающее» воздействие на исходную информацию. Свертка 32-байтового буфера до 16-байтового размера осуществляется процедурой shuffle1(), исходный текст которой на языке Cи можно найти в различных источниках (пакет ncpfs для Linux, комплекс программ Pandora и др.), а также в приведенном далее листинге.

Несмотря на то что человеческий мозг гораздо сложнее любого из существующих суперкомпьютеров, задачу запоминания больших объемов информации он решает не очень хорошо, поэтому большинство людей не применяют в повседневной практике пароли длиннее 32 символов. Более того, рекомендованная минимально безопасная длина пароля в 8 символов является для многих слишком большой, если только они не применяют «парольные фразы» или другие мнемонические приемы. Исходя из этого постулата, можно несколько модифицировать описанную выше хэш-функцию, отбросив ветку алгоритма для паролей длиннее 32 символов. Такое упрощение дает некоторый прирост скорости вычислений. Еще одно упрощение, причина которого совершенно непонятна, заключается в том, что стандартные утилиты NetWare приводят вводимые буквы латинского алфавита к верхнему регистру. Это сильно упрощает задачу злоумышленника — существует всего 65 символов, которые допустимо использовать в качестве пароля в NetWare и для ввода которых не требуется русификатор. В принципе, можно применять и русские буквы, однако, ввиду различия кодировок русских букв в Windows, DOS и UNIX такая практика может привести к невозможности входа в сеть данного пользователя из другой ОС.

Пишем программу

Используя приведенную задачу злоумышленника, попробуем написать программу, которая по имеющимся у потенциального злоумышленника исходным данным сможет подобрать пароль. Мы будем использовать метод «грубой силы», хотя гораздо более эффективным может оказаться метод перебора паролей по словарю. Для упрощения реализации произведем следующие допущения:

  • Подбирается пароль пользователя supervisor (UserID=1).
  • Пароль состоит только из букв латинского алфавита.
  • Максимальная длина пароля — 8 символов. Пароли перебираются последовательно: A, AA, AAA ...ZZZZZZZZ.
  • Необходимые для проверки 8-байтовые числа записаны в бинарном виде в файл, имя которого задается в виде параметра командной строки.

Приведем основные фрагменты программы подбора пароля (полный ее текст доступен в разделе «программы» на сервере http://www.securityelf.net). В реализации использованы модифицированные версии соответствующих процедур из пакета ncpfs.

#include 
#include 
#include 
#include 

#define USERID 1
#define MAXLEN 8
#define BPASS "A"
#define BCHAR `A`
#define ECHAR `Z`

void shuffle1 (buf32 temp,
unsigned char *target)
{short b4;unsigned char b3;
int s, b2, i;
b4 = 0;
for (b2 = 0; b2 <= 1; ++b2){
     for (s = 0; s <= 31; ++s){
          b3 = (temp[s]+b4) ^
 (temp[(s+b4)&31] — encryptkeys[s]);
          b4 = b4 + b3; temp[s] = b3;}}

for (i = 0; i <= 15; ++i) {
     target[i] = encrypttable
[temp[2*i]]
               | (encrypttable[temp[ 2*i
 + 1]] << 4);}};

int main(int argc, char **argv){
unsigned char last, i; unsigned long
 userid=USERID;
unsigned char maxlen=MAXLEN;
time_t time1, time2;
char password[MAXLEN+2];
unsigned char ppack[16]={0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0};
unsigned char ekey[8]={0,0,0,0,0,0,0,0}; 
unsigned char ores[8]={0,0,0,0,0,0,0,0};
unsigned char mres[8]={0,0,0,0,0,0,0,0};
FILE *fd;

fd=fopen(argv[1],"r");
if (fd==NULL){perror("File open error:
 "); return(1); };
fread(ekey,1,8,fd);
 fread(ores,1,8,fd); fclose(fd);

memset(password,0,MAXLEN+2);
 strcat(password,BPASS);
last=strlen(password);
printf("Beginning password: %s,
 len=%d
",password, last);
time(&time1);
while (mutate(password) < maxlen){
      last=strlen(password);
      shuffle((unsigned char *) &userid,
 password, last, ppack);
      prepare_login(ekey,ppack,mres);
      if (memcmp(ores, mres, 8)==0) {
         printf("Password found: %s
",
password); break; }; };
time(&time2); printf("%d seconds.
",
(time2-time1)); return(0);
}

Что в результате?

Теперь у нас есть возможность произвести оценку затрат злоумышленника на подбор пароля с заданными характеристиками. Общее количество паролей k, которые можно составить из алфавита размерности n при длине пароля от 1 до m символов составляет:

(3)

Максимальное время T, необходимое для подбора пароля с указанными характеристиками, будет равно, таким образом:

T=k/v (4)

Скорость перебора v определим экспериментально с использованием описанной программы. Для этого в качестве посылки сервера возьмем число 0001020304050607 и зашифруем его на пароле ZZZZZZ. Программа «подобрала» пароль за 1 час 4 минуты 35 секунд. По формуле (3), определяем, что для 26-символьного алфавита можно составить 321272406 6-символьных комбинаций. Решая уравнение (4) относительно v получаем скорость: 82909 паролей в секунду.

Следует упомянуть об использованной аппаратуре и программном обеспечении. В качестве аппаратной платформы был выбран ПК с процессором Pentium II/ 400 МГц с 64 Мбайт памяти, функционирующий под управление ОС Linux (Debian 2.1, версия ядра 2.2.14). Компиляция осуществлена компилятором gcc версии 2.7.2.3 (с опцией -O6). Такая конфигурация аппаратной части является достаточно распространенной, и в то же время производительной. Итак, мы имеем все исходные данные для ответа на вопрос: «Пароль какой длины сможет подобрать злоумышленник методом грубого перебора, если у него есть предположения об использованных в пароле символах?». Результаты расчета для различных размерностей алфавита сведены в приведенные таблицы.

Выводы

Несмотря на защищенный алгоритм, исключающий передачу пароля в открытом виде, процесс аутентификации NetWare 3.x может оказаться уязвимым к подбору пароля методом грубой силы при неправильном подходе к его выбору. В связи с этим не рекомендуется использовать без насущной необходимости режим эмуляции базы связок (bindery emulation) в старших версиях, а в версиях 3.x предпринять дополнительные меры защиты.

К сожалению, штатными средствами Novell NetWare невозможно задать ограничения на качественные характеристики пароля. Установки минимальной длины, периодичности смены пароля и требования его уникальности, конечно, приносят некоторые плоды, но не позволяют избежать ситуации, когда пользователь все же использует тривиальные пароли типа «11111111», «22222222» и т.п. Эту проблему можно решить двумя способами: организационным и техническим.

  • Организационный способ предполагает обязательное помещение копии пароля в запечатанный конверт. По истечении срока его действия ответственный за информационную безопасность имеет возможность проверить, соблюдает ли пользователь требования по выбору пароля.
  • Технический способ заключается в установке на серверах специальной программы, разработки третьих фирм, которая бы занималась проверкой качества паролей на сервере (например, в ночное время) и в случае обнаружения тривиального пароля выставляла бы ему признак «устарел, требуется смена». В совокупности с введенным ограничением на число попыток входа со старым паролем, этот способ позволит автоматически поддерживать качество паролей на должном уровне.

Наконец, можно организовать сеть таким образом, чтобы исключить возможность прослушивания процесса аутентификации — путем замены концентраторов на коммутаторы.

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

Данная статья не претендует на полноту в части освещения всех особенностей парольной защиты в операционных системах Novell. В частности, остался за кадром вопрос с NDS-аутентификацией, где дополнительно применяется шифрование по алгоритму RSA. Как уже говорилось, здесь рассмотрен только один из возможных способов получения пароля.

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

Во-вторых, он может попытаться подобрать под имеющееся значение хэш-функции символьный пароль, что сопряжено с гораздо меньшими вычислительными затратами. Обе эти задачи решаются при помощи комплекса программ Pandora (http://www.nmrc.org/pandora/download.html). Большое количество информации по обеспечению безопасности Novell NetWare и других сетевых операционных систем можно найти по адресам http://security.tsu.ru и http://www.nmrc.org.

Владислав Мяснянкин, независимый эксперт. С ним можно связаться по адресу hugevlad@yahoo.com.


Как долго ваша система будет неприступна

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

Алфавит 10 символов (цифры)
Длина пароляВремя подбора
13 символов1613 суток
12 символов161 сутки
11 символов16 суток
10 символов1 сутки 15 часов
9 символов3 часа 52 минуты
8 символов23 минуты 14 секунд
7 символов2 минуты 19 секунд
6 символов14 секунд
Алфавит 26 символов (латинские буквы)
9 символов820 суток
8 символов31 сутки, 13 часов
7 символов1 сутки 5 часов
6 символов1 час 7 минут
5 символов2 минуты 35 секунд
4 символа6 секунд
Алфавит 36 символов (латинские буквы и цифры)
9 символов15166 суток
8 символов421 сутки
7 символов11 суток 17 часов
6 символов7 часов 48 минут
5 символов13 минут
4 символа22 секунды
Алфавит 65 символов (все допустимые символы)
8 символов46985 суток
7 символов723 дня
6 символов11 суток 3 часа
5 символов4 часа 6 минут
4 символа3 минуты 47 секунд
3 символа3 секунды