"Алекс Федченко. Описание механизма функционирования парольных кэшей Windows v4.xx" - читать интересную книгу автора


typedef struct { /* version depended W95 PWL partition */
byte UserName[20]; /* Padded owner name */
word ResOffsets[0xF]; /* Resources offsets. */
} W95_pwl_data;

typedef struct { /* PWL file header itself */
dword Sign; /* .PWL file signature */
dword UnknownC; /* ?? Strange counter */
byte ResLink[0x100]; /* Resource link index */
byte ResKey[0x100]; /* Resource key entry */
union {
W95_pwl_data W95_Data; /* W95 format PWL data */
OSR_pwl_data OSR_Data; /* OSR format PWL data */
} HdrV;
} pwl_hdr;

Итак, файл содержит в самом начале сигнатуру W95_PwlSign, заголовок имеет
размер W95_PwlBase, собственно, с этого смещения располагаются (обычно)
зашифрованные ресурсы. Поле UnknownC увеличивается с течением времени при
модификации файла и является скорее всего версией парольного кэша (вернее не
столько версией, сколько возрастом).
Теперь ключевой момент, доступ к ресурсам. Он осуществляется по 16-ти
точкам входа (соответствующая индексация осуществляется по телу ресурса), это
позволяет значительно ускорить доступ к ресурсной информации и не
расшифровывать лишний раз "критические" данные (впрочем, их все равно потом в
памяти _не_ затирают). Лирическое отступление: я часто замечал вольную работу
со стеком и регистрами библиотечных функций Windows (здесь и далее версия не
ниже 4.0). Имеется ненулевая вероятность получения интересной информации после
отработки многих системных вызовов. (Скажем, многие функции осуществляют поиск
файла по системному маршруту: текущий каталог, затем %WINDIR%, затем PATH и
т.п. Достаточно часто после выхода из такой функции в EDx содержится указатель
на полный путь найденного файла, это лишь пример... Только пример для
думающего человека...) Собственно, файл кэша может содержать максимально 255
ресурсов. Поля массива ResLink[] содержат номера ресурсов (в случае, если
необходим итеративный, а не ассоциативный доступ), эти поля индексируют поля
ResKey[], содержащие номера точек входа (другими словами - номера каналов
ресурсов) в ресурсном файле. Почему именно такая двухуровневая система?
Возможно по соображениям простоты вставки-удаления элементов (ну лень им было
возиться со списками и проч., файлы, кстати, вычитываются по кусочкам, т.е. по
2-4-...-256 байта, как раз полями).
Открытие парольного кэша осуществляется следующим образом: сворачивается
пароль в 4-х байтовый хеш, затем по хешу строится таблица RC4 и осуществляется
расшифровка полей UserName и ResOffsets, поле UserName должно содержать имя
пользователя. Ресурсы в каждом канале зашифрованы независимо друг от друга, но
одним и тем же ключевым значением. Вспомним о том, что RC4 потоковый алгоритм.
Практически всегда зная имя пользователя (которое выровнено 0-ми на 20-ти
байтовую границу) мы получаем начало гаммы, затем предполагая определенные
значения смещений ресурсов (на основе полей ResKey и ResLink, а так же знания
константы W95_PwlBase) мы можем получить еще несколько (до 15*2) байтов гаммы,