Вскрываем секретный файл с дискеты «Лучшие игры для IBM PC №1» 1994 года
Киоск, где продавались компакт‑диски, аудио‑ и видеокассеты, на Пушкинской площади. 1996 год (Фото: Кавашкин Борис / Фотохроника ТАСС)
Всё завертелось стремительно: попалась ностальгическая заметка о сборниках Classic Fond, и вот я уже скачиваю образы «Лучших игр для IBM PC» с Internet Archive. Раньше других загрузился 25-й диск. Стоило его открыть, как память услужливо вернула всё: школу, подземный переход возле ВДНХ, ряды палаток. Жуёшь беляш, разглядываешь новинки музыкальных альбомов и, разумеется, сборники Classic Fond.
Мне захотелось заглянуть в недра базы данных и выяснить, какие защиты, хитрости и приёмы применяли в те годы.

Однако ещё до того, как дошло до распаковки BASE.EXE, мне попалась любопытная находка. На первых девяти дисках в каталоге CHEAT лежит архив AUTORS.ZIP, защищённый паролем, а в соседнем readme обнаружился такой отрывок:
В: Как стать Вашим дилером и что для этого нужно? Как с вами связаться?
О: Напишите о своих возможностях по адресу, указанному в read.me. Если нас заинтересуют Ваши предложения, мы с Вами свяжемся. К сожалению, по понятным причинам, прямо указать свои координаты на можем. Впрочем, если Вы неумеренно круты, наши координаты находятся в файле \CHEAT\autors.zip Звоните!
Адрес — всего лишь абонентский ящик: «121467 г. Москва, а/я 98, Classic Fond».
Если верить документу, «дилером» здесь называют самого обычного продавца дисков. Зачем предлагать будущему торговцу техническую головоломку со взломом архива, не вполне ясно. Гораздо логичнее выглядит версия, что так в лихие девяностые пытались отыскать продвинутых технических специалистов.
Посмотрим, что скрывается внутри AUTORS.ZIP

Между прочим, из всех ZIP-архивов на диске (а их там 311) пароль установлен лишь на одном — на AUTORS.ZIP. Игры под паролем начали появляться позднее.
Я попробовал найти в поиске, кто и как вскрывал этот архив, но, к своему удивлению, не обнаружил вообще ничего. Судя по дате внутри ZIP, файл был создан 22 августа 1994 года.
Примерно на то же время приходится работа Эли Бихама и Пола Кохера об атаке на шифр PKZIP. Она вошла в сборник FSE 1994, изданный в 1995 году.
“In this paper we describe a known plaintext attack on the PKZIP stream cipher which takes a few hours on a personal computer and requires about 13–40 (compressed) known plaintext bytes, or the first 30–200 uncompressed bytes, when the file is compressed.”
В этой работе описана атака на потоковый шифр PKZIP при известном открытом тексте. На персональном компьютере она занимает несколько часов и требует примерно 13–40 известных байт открытого текста (в сжатом виде) или первых 30–200 байт исходных данных, если файл был сжат.
Вряд ли авторы архива рассчитывали на такой вектор атаки: AUTORS.ZIP с первого диска «Лучшие игры для IBM PC #1» датирован 22 августа 1994 года, а статья Бихама и Кохера увидела свет только в начале 1995-го. Теоретически кто-то мог прочесть работу и написать по ней программу, эксплуатирующую уязвимость (для этого требовалось знать определённый объём открытого текста внутри архива). Мы же попробуем вскрыть документ инструментами той эпохи, не прибегая к уязвимостям PKZIP, — устроим тёплый ламповый реверс в духе 1994 года
Что видно и без пароля

Вывод PKUNZIP -vmt сообщает, что внутри находится файл AUTORS.DOC размером 11 байт с CRC32 B8AB1F5A. Имя, размер и контрольная сумма доступны без пароля. Вспомним фразу из readme: «Наши координаты находятся в файле \CHEAT\autors.zip. Звоните!»
Можно рискнуть и предположить, что внутри записан телефон. Причём уместившийся ровно в 11 байт: скажем, девять символов номера плюс перевод строки CRLF.
Как это могло выглядеть? В DOS-кодировке строка Тел. 777-77-77 занимает 14 байт, а просто 777-77-77 — девять. Зато 777-77-77 или 0957777777 как раз дадут нужные 11.
План несложен: составить шаблоны возможной записи номера и сверить CRC32 каждой получившейся строки. Коллизии вполне допустимы: два разных номера способны дать одинаковую контрольную сумму. Но если мы и вправду в 1994 году, ничто не мешает обзвонить все совпадения со словами: «Я вскрыл ваш архив, давайте знакомиться».
Перебор телефонов
Возьмём популярный в те годы Borland C++ 3.1.
#include
#include
#include
/* Параметры AUTORS.ZIP из вывода PKUNZIP. */
#define TARGET_CRC 0xB8AB1F5AUL
#define FILE_LENGTH 11
#define TOTAL_NUMBERS 10000000UL
char *mask[] = {
"Т.###-##-##", "т.###-##-##",
"T.###-##-##", "t.###-##-##",
"тел.#######", "Тел.#######", "ТЕЛ.#######",
"tel.#######", "Tel.#######", "TEL.#######",
"тел:#######", "Тел:#######", "ТЕЛ:#######",
"tel:#######", "Tel:#######", "TEL:#######",
"тел #######", "Тел #######", "ТЕЛ #######",
"tel #######", "Tel #######", "TEL #######",
"Т.#######\r\n", "т.#######\r\n",
"T.#######\r\n", "t.#######\r\n",
"###-##-##\r\n",
"### ## ##\r\n",
"###.##.##\r\n",
"095-#######",
"095 #######",
NULL
};
Опробуем логичные комбинации, дающие 11 байт. Пространство поиска, конечно, можно заметно сузить — например, проверять лишь реально существовавшие телефонные префиксы. Но пока действуем в лоб: у нас 31 шаблон по 10 миллионов номеров, то есть всего 310 миллионов вариантов. CRC32 считаем по учебнику: таблица, полином 0xEDB88320, XOR с 0xFFFFFFFF.
Строки будем формировать прямо по ходу перебора:
/* Перебор шаблонов телефонных номеров. */
for (t = 0; mask[t] != NULL; t++) {
if (strlen(mask[t]) != FILE_LENGTH)
continue;
/* Перебор номеров от 0000000 до 9999999. */
for (n = 0; n < TOTAL_NUMBERS; n++) {
sprintf(digits, "%07lu", n);
/* Подстановка цифр вместо символов #. */
for (i = 0, j = 0; mask[t][i]; i++)
text[i] = (mask[t][i] == '#')
? digits[j++] : mask[t][i];
text[i] = '\0';
if (crc32(text) == TARGET_CRC) {
printf("Found: %s\n", text);
}
}
}
Я раздобыл настоящий компьютер на базе 286-го процессора и прогнал на нём небольшой бенчмарк: вышло около 6 тысяч проверок в секунду. Для 310 миллионов вариантов это примерно 15 часов в худшем случае — вполне терпимо. Впрочем, если хочется быстрее, можно исключить из списка заведомо невалидные номера.

На дисках 1994–1995 годов присутствовал телефонный справочник SONATA. В нём есть недокументированная возможность: выгрузить в файл по одному номеру на каждую АТС. У меня получилось 555 записей — столько префиксов содержит эта версия справочника. Если ограничиться ими, объём поиска сократится почти вдвое, но пока запустим перебор всех номеров подряд:

Уже через 19 минут обнаружилось первое совпадение: Т.220-34-17

Тем не менее остальные варианты проверить необходимо. Совпадение CRC32 у строки Т.220-34-17 ещё не доказывает, что в архиве лежит именно она. Полный перебор покажет, нет ли других совпадений среди наших шаблонов. Поэтому оставляем компьютер работать. (UPD: в итоге на это ушло 48 часов)
Кому же звонить
Пока машина трудится, изучим сам номер. Префикс АТС 220 в справочнике есть, а номер выглядит московским. SONATA.EXE за 1995 год его не находит, зато поиск в интернете выводит на любопытный документ «ОАОЭиЭ Мосэнерго. Инвестиционный портрет». В разделе «Реквизиты» значится наш телефон:
Наименование: Мосэнерго
Юридическое наименование: Открытое акционерное общество энергетики и электрификации Мосэнерго
Юридический адрес: 113035, г. Москва, Раушская наб., д. 8 Почтовый адрес: 113035, г. Москва, Раушская наб., д. 8
Телефон: (095) 220–35-30, 220–38-84, 220–34-17 Факс: (095) 220–34-70
Судя по содержанию, документ относится к 1999 году. В отчёте за 2000 год встречаются похожие номера, но уже с префиксом 957.

Вероятно, часть номеров АТС 220 перевели на новую нумерацию. (220-35-30 превратился в 957-35-30, а наш загадочный номер — в 957-34-17)
Пока это лишь зацепка. К сожалению, мне не удалось найти ничего, что объяснило бы, кому принадлежал этот номер в 1994 году. Возможно, им владела какая-то другая организация, а к 1999 году он перешёл к «Мосэнерго». Надеюсь, на SE7ENе отыщутся очевидцы тех времён и расскажут всю историю целиком.
Как ни странно, об авторах этих выпусков и о Classic Fond в целом в сети написано очень мало. Мне встретились упоминания лишь двух имён: Олега «Palek» Палько и Дениса Жулитова.
У Олега есть интервью для Литрес, где он прямо говорит об этом сборнике:
Litres: Это я слышу от пирата?
Palek: В 90-х все были пиратами. Я тогда делал сборник «Лучшие игры для IBM PC», все игры посмотрел до 2000-го года. И не считал себя плохим, потому что тогда играми почти никто не торговал.
Олег — писатель, так что не исключено, что именно он отвечал за тексты на дисках и обзоры игр, которые и сегодня читаются с удовольствием.
А если распаковать одну из поздних версий BASE.EXE, внутри обнаружится строка: (С) 1996 -= Classic Fond =-, program by Denis Julitov

Имя Denis Julitov значится и в титрах нашумевшей Big Rigs, а также в нескольких других проектах.

С BASE.EXE я пока только начал разбираться: получил распакованный EXE, определил компилятор (BC 3.1), извлёк пароли от ZIP-архивов с играми и даже выдвинул гипотезы о том, как они генерировались. Внутри нашлась любопытная реализация виртуальной файловой системы (vfs 1.0) и огромное количество ругательств на английском. Если обнаружится что-нибудь ещё интересное, непременно напишу отдельную статью.
А пока вернёмся к нашему архиву.
Проверка на современном компьютере
Пока 286-й перебирает оставшиеся номера, попробуем иным способом убедиться, что строка найдена верно. На этот раз — на современной машине, с помощью bkcrack. Эта утилита реализует атаку по известному открытому тексту, основанную как раз на исследовании Бихама и Кохера, о котором шла речь выше.
AUTORS.DOC хранится без сжатия (Stored). Для атаки bkcrack требуется не менее 12 известных байт: 11 у нас уже есть, а ещё один программа сама берёт из служебных данных ZIP.
Создадим файл с найденной строкой в CP866. (Я упустил из виду, что Windows 3.1 и 3.11 в том году уже были повсюду, поэтому CP1251 и KOI8-R проверил отдельно)
$ printf 'Т.220-34-17' | iconv -f UTF-8 -t CP866 > autors.txt
И запустим bkcrack:
$ ./bkcrack -C AUTORS.ZIP -c AUTORS.DOC -p autors.txt
bkcrack 1.8.1 - 2025-10-25
[14:59:01] Z reduction using 4 bytes of known plaintext
100.0 % (4 / 4)
[14:59:01] Attack on 1234513 Z values at index 6
Keys: 63aa72a7 a18eedca 254c6c2e
9.9 % (121602 / 1234513)
Found a solution. Stopping.
You may resume the attack with the option: --continue-attack 121602
[15:01:42] Keys
63aa72a7 a18eedca 254c6c2e
Всего за пару минут были найдены три 32-битных ключа. Это ещё не пароль, а три внутренних ключа ZipCrypto, которые задают состояние шифра. Но их уже хватает, чтобы создать копию архива без пароля и извлечь AUTORS.DOC:
Источник
Режиссёр Питер Берг рассказал о своём подходе к экранизации Call of Duty, которая не будет бездумным боевиком
Краткий обзор серии или тёмная сага о змеиных наездниках. Часть 1. Heretic / Hexen (1994–1998)
Появились новые подробности сериала Marvel «Зодиак» о противостоянии шпионов и людей со сверхспособностями
Операционный директор Xbox Хелен Чианг уходит из Microsoft, проработав в компании 21 год
Пиксельный боди-хоррор Look Outside появится на консолях
Эксперт по ценообразованию раскритиковала Hollow Knight: Silksong за слишком низкую стоимость
Лидер канадской НДП Ави Льюис раскритиковал закрытие BioWare и предложил помочь сотрудникам выкупить студию у EA
Глава Saber Interactive считает AA-игры вроде Hellraiser: Revival будущим индустрии