Открываем секретный файл с диска «Лучшие игры для IBM PC #1» 1994 года

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Всё произошло очень быстро: какая‑то ностальгическая статья про сборники Classic Fond — и вот я уже качаю образы «Лучшие игры для IBM PC» с Internet Archive. Первым скачался 25-й диск. Открыл и вспомнил всё: школу, переход рядом с ВДНХ, палатки. Ешь беляш, смотришь, какие альбомы вышли, ну и, конечно, сборники Classic Fond.

 Киоск по продаже компакт-дисков, аудио- и видеокассет на Пушкинской площади. 1996 год (Фото: Кавашкин Борис / Фотохроника ТАСС)
Киоск по продаже компакт‑дисков, аудио‑ и видеокассет на Пушкинской площади. 1996 год (Фото: Кавашкин Борис / Фотохроника ТАСС)

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

BASE.EXE диск 25, 1997 год
BASE.EXE диск 25, 1997 год

Но ещё до распаковки BASE.EXE я наткнулся на интересный артефакт. На первых девяти дисках в папке CHEAT лежит запароленный архив AUTORS.ZIP, а в readme рядом есть такой фрагмент:

В: Как стать Вашим дилером и что для этого нужно? Как с вами связаться?
О: Напишите о своих возможностях по адресу, указанному в read.me. Если нас заинтересуют Ваши предложения, мы с Вами свяжемся. К сожалению, по понятным причинам, прямо указать свои координаты на можем. Впрочем, если Вы неумеренно круты, наши координаты находятся в файле \CHEAT\autors.zip Звоните!

Адрес — это просто абонентский ящик: «121467 г. Москва, а/я 98, Classic Fond».

Судя по документу, под словом «дилер» подразумевается обычный продавец дисков. Непонятно, зачем потенциальному продавцу предлагать технический челлендж со взломом архива. Куда логичнее было бы таким образом искать технически подкованных специалистов в те лихие времена.

Посмотрим, что внутри AUTORS.ZIP

AUTORS.ZIP с комментарием "Как связаться с издателем диска."
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.zip
Вывод pkunzip ‑vmt autors.zip

Из вывода PKUNZIP -vmt можно узнать, что внутри лежит AUTORS.DOC размером 11 байт с CRC32 B8AB1F5A. Имя файла, размер и контрольная сумма видны без пароля. Вспоминаем фразу из readme: «Наши координаты находятся в файле \CHEAT\autors.zip. Звоните!»

Можно сделать смелое предположение, что внутри телефон. Причём записанный ровно в 11 байтах: например, девять символов номера и перевод строки CRLF.

Что это может быть? В DOS‑кодировке строка Тел. 777-77-77 занимает 14 байт, просто 777-77-77 — девять. А вот 777-77-77<CR><LF> или 0957777777<SPC>дадут нужные 11.

План простой: составить шаблоны возможной записи телефонного номера и проверить CRC32 каждой строки. Коллизии вполне возможны: два разных номера могут дать одну и ту же контрольную сумму. Но если мы действительно в 1994 году, никто не мешает позвонить по всем совпадениям со словами: «Я вскрыл ваш архив, давайте знакомиться».

Перебираем телефоны

Воспользуемся популярным в то время Borland C++ 3.1.

#include <stdio.h>
#include <string.h>
#include <dos.h>

/* Параметры 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);
        }
    }
}

A нашел настоящий 286 компьютер, и прогнал на нем небольшой бенчмарк — получилось около 6 к в секунду, что для 310 миллионов вариантов дает около 15 часов в худшем случае, что довольно терпимо, но если хочется быстрей, можно попробовать выкинуть невалидные номера из списка.

Бенчмарк на 286 машине, монохромный EGA монитор
Бенчмарк на 286 машине, монохромный EGA монитор

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

В реальности скорость ниже, чем 6000 проверок в секунду, потому что я не учёл время генерации строки по шаблону.
В реальности скорость ниже, чем 6000 проверок в секунду, потому что я не учёл время генерации строки по шаблону.

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

Реальная скорость: 1 851 проверка в секунду.
Реальная скорость: 1 851 проверка в секунду.

Но всё же надо проверить остальные варианты. То, что строка Т.220-34-17 имеет нужную CRC32, ещё не гарантирует, что именно она лежит в архиве. Полный перебор покажет, есть ли другие совпадения среди наших шаблонов. Так что оставим компьютер работать. (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.

Реквизиты из годового отчета «Мосэнерго», 2000 год
Реквизиты из годового отчета «Мосэнерго», 2000 год

Возможно, часть номеров АТС 220 перенесли на новую нумерацию. (220-35-30 превратился в 957-35-30,а наш таинственный номер в 957-34-17)

Пока это только зацепка. К сожалению, я не нашёл ничего, что объясняло бы, кому принадлежал номер в 1994 году. Он мог принадлежать какой‑то организации, а потом ближе к 1999 году перейти в «Мосэнерго». Надеюсь, на Хабре найдутся свидетели тех времён и расскажут историю целиком.

Удивительно, но в интернете очень мало информации о том, кто делал эти выпуски, да и о Classic Fond вообще. Я смог найти упоминания только двух имен: Олег «Palek» Палько и Денис Жулитов.

У Олега есть интервью Литрес, где он прямо говорит о сборнике:

Litres: Это я слышу от пирата?

Palek: В 90-х все были пиратами. Я тогда делал сборник «Лучшие игры для IBM PC», все игры посмотрел до 2000-го года. И не считал себя плохим, потому что тогда играми почти никто не торговал.

Олег — писатель, так что, возможно, именно он отвечал за тексты на дисках и обзоры игр, которые до сих пор очень приятно читать.

А если распаковать одну из более поздних версий BASE.EXE — внутри находится строка: (С) 1996 -= Classic Fond =-, program by Denis Julitov

BASE.EXE с диска 25,  оригинально запакована WWPACK 3.03
BASE.EXE с диска 25, оригинально запакована WWPACK 3.03

Имя Denis Julitov находится и в титрах нашумевшей Big Rigs, и еще пары проектов.

Big Rigs: Over the Road Racing (2003). Разработчик — Stellar Stone LLC, издатель — GameMill Publishing, США
Big Rigs: Over the Road Racing (2003). Разработчик — Stellar Stone LLC, издатель — GameMill Publishing, США

Я пока только‑только подступился к 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-битных ключа. Это ещё не пароль, а три внутренних 32-битных ключа ZipCrypto, определяющих состояние шифра. Но их уже достаточно, чтобы сделать копию архива без пароля и получить AUTORS.DOC:

$ ./bkcrack -C AUTORS.ZIP -k 63aa72a7 a18eedca 254c6c2e -D AUTORS_CLEAR.ZIP

Распаковываем:

$ unzip AUTORS_CLEAR.ZIP | iconv -f CP866 -t UTF-8
Archive:  AUTORS_CLEAR.ZIP
Как связаться с издателем диска.
 extracting: AUTORS.DOC

$ stat -x AUTORS.DOC | grep Birth
 Birth: Mon Aug 22 18:39:12 1994

$ stat -x AUTORS.ZIP | grep Birth
 Birth: Mon Aug 22 22:40:36 1994

Сдвиг на четыре часа связан с интерпретацией старых DOS‑меток времени в macOS. Cтарые DOS‑метки времени не самый надёжный источник информации, но я прямо представил, как дождливым августовским днём 1994 года кто‑то записал телефон в файл, а минуту спустя запустил PKZIP.

Теперь можно посмотреть содержимое уже расшифрованного файла:

$ iconv -f CP866 -t UTF-8 AUTORS.DOC
Т.220-34-17%      

В распакованном AUTORS.DOC оказалась та самая строка — Т.220-34-17. CRC32 совпала с контрольной суммой из архива, найденные ключи подошли, файл распаковался. Казалось бы, дело закрыто.

Но тут есть подвох: мы сами подсказали bkcrack, какой текст хотим увидеть. Для такого короткого файла можно подобрать другую строку с той же CRC32, восстановить по ней подходящие ключи и успешно расшифровать архив — я проверил это на практике. Поэтому успешная расшифровка ещё не доказывает, что изначально в архиве лежал именно этот телефонный номер.

Задача была бы гораздо проще, если бы в архиве находился ещё один зашифрованный файл с предсказуемым содержимым. Например, EXE‑файл с характерным заголовком MZ или что‑нибудь ещё, что позволило бы независимо проверить правильность найденных ключей.

Перебор по шаблону на 286 завершился за 48 часов и других совпадений не нашел. Я решил расширить поиск — и среди найденных коллизий оказались строки, похожие на телефон:

Строка

Кодировка

CRC32

Т.220-34-17 — исходная

CP866

B8AB1F5A

т75 68 066\x00

CP866

B8AB1F5A

T953-98-01!

ASCII

B8AB1F5A

Т 34 70922

CP866

B8AB1F5A

Т 87.86682!

CP866

B8AB1F5A

t 31.518.38

ASCII

B8AB1F5A

Т.526 51/75

KOI8-R

B8AB1F5A

Т-306 99 13

Windows-1251

B8AB1F5A

t/631-90/60

ASCII

B8AB1F5A

F-844 79-84

ASCII

B8AB1F5A

f.854/67-25

ASCII

B8AB1F5A

Исходная версия Т.220-34-17 выглядит наиболее убедительно, но в 1994 году я бы не поленился позвонить по всем номерам. Прогнал все номера через базу TEL.EXE и SONATA.EXE — совпадений нет.

А пароль?

Можно попробовать восстановить и сам пароль. Сразу скажу: тут долго ничего хорошего не выходило.

Для найденного набора ключей я проверил все возможные значения байтов в паролях длиной до 12 байт включительно — ничего не нашлось. Дальше всё стало медленно. Даже с учётом того, что bkcrack использует обратимость отдельных операций шифра и не перебирает каждый пароль целиком, пространство поиска огромное. Примерно за двое суток нашёлся один эквивалентный пароль — строка, которая приводит шифратор к тем же трём ключам, но не обязательно совпадает с паролем, который набрали авторы архива.

$ bkcrack-1.8.1-cp866 -k 63aa72a7 a18eedca 254c6c2e --charset-file x cp866-ascii.bin -r 0..255 '?x' -j 8 --continue-recovery 25516b93202020
bkcrack 1.8.1 - 2025-10-25
[01:41:19] Recovering password
length 13...
Password: /h.H☉Eu (as bytes: 2f 68 2e a1 a9 48 87 e2 98 89 f8 45 75)
Some characters are not in the expected charset. Continuing.
10.6 % (2759 / 25921)

Если прочитать эти байты в CP866, получится:

/h.бйHЗтШЙ°Eu

Технически такой пароль можно набрать и на клавиатуре — например, через Alt и цифровую клавиатуру (Alt+248) для ввода символа с кодом 0xF8. Но по моим ощущения это лишь эквивалентный пароль. В статье Бихама и Кохера как раз упоминаются такие случаи:

Thus,we expect to remain with only the right key (or an equivalent) in trials of up to
13-byte keys. Note that keys longer than 12 bytes will almost always have equiv‑
alents with up to 12 (or sometimes 13) bytes, since the internal representation
is only 12-bytes long.

Таким образом, мы ожидаем, что при переборе ключей длиной до 13 байт останется только правильный ключ (или его эквивалент). Заметим, что ключи длиннее 12 байт почти всегда имеют эквиваленты длиной не более 12 байт (а иногда — 13 байт), поскольку внутреннее представление ключа занимает всего 12 байт.

Важно уточнить, что пароль я ищу по ключам, полученным для строки Т.220–34-17 как наиболее убедительной версии. Поэтому утверждать, что исходный пароль однозначно длиннее 12 байт, нельзя. Пока я считаю это направление наиболее перспективным.

По примерным оценкам, чтобы добить 13-байтовые пароли, понадобится около недели, 14 байт — уже 4,5 года, а 15 — аж 710 лет. Hashcat на GPU не дает сильного прироста. Учитывая, какие длинные пароли использовались для игровых архивов на дисках Classic Fond, надежды найти исходный пароль мало:

1993 — IMAGINE_WHO_ARE_YOU_A6B9A6DB3Dj2AD7F7D7CEDEN968EC081DD7DB97BCB6708B68B3DB68F
1993TRIS — C9070696199B11F9C2C0200F8C09
3DPINBAL — iu202020iTysi20gic20iidv20ia2020vessir
3DTETRIS — DAMNED_LAMER_7968FF78BDBCEB5960FBF24AND7968ED70F8F96jA24CEDBA62A0F0F
777 — inisiTvi20nhced20asighs20Thuyita20
AB — 20y20rnes20nnssttissiit20tsihiinru
ABC — IMAGINE_WHO_ARE_YOU_0FCCECq796F7F9F9D7B9j0F97DEBC2ADE2A7j1DF71DD73D2AEEB9
ABUSE — aiare20n202020ius20stit20hvssrgi20u2020
ACESW95 — iu202020iTysi20gic20iidv20ia2020vessir
AD3WIZ — FB9BB3EE3BC7HF83B12DB1F24
ADDALOT — VAF3FE3DDgB23BFFBA05DF1CAD
AIRHAVOC — SON_OF_BITCH_8BBFjCCDE3DD78B0F97jD70FF778BDB0FB9jC7qBF2A97N0FC08
AIRPOWER — sni20c20202020sndheiusi20u20rTii20s2020t
AIR_SVGA — uegg20nti20saee20rrtir20uhsv20s20esn
ALUNSER — tniei202020sdi20hst20eTesgggg20ssns20
AMY'S — 20neesgnsd20ni20gyn20hniis20ur20avti
ANATOMIK — iechTi20nii20eisdi20dsnrceaeh20rvi

Подведем итоги:

Мы успешно открыли зашифрованный AUTORS.ZIP с дисков «Лучшие игры для IBM PC» от Classic Fond и получили файл со строкой Т.220-34-17 . Потом повторили и получили другую строку. А затем ещё одну.

Список всех найденных мной вариантов AUTORS.DOC, похожих на телефонные номера, я выложил здесь — github/classic‑fond‑reverse. Интуитивно Т.220-34-17 выглядит наиболее убедительно, плюс этот номер действительно встречается в документах той эпохи, но доказать, что именно его авторы записали в архив в 1994 году, пока не удалось.

После моей предыдущей статьи про реверс «Поля чудес» в комментариях нашлось столько полезной информации, что появилась надежда и на этот раз отыскать кого‑нибудь из непосредственных участников событий. Очень хочется узнать, кто и зачем придумал этот челлендж, удавалось ли кому‑нибудь вскрыть архив в 90-е или позже и звонил ли кто‑нибудь по найденному номеру в 1994–1996 годах. Да и кому вообще принадлежал этот номер в те годы? И почему после 1996 года архив исчез с дисков?

Спасибо, что дочитали до конца.

Источник: https://habr.com/ru/articles/1098090/


Интересные статьи

Интересные статьи

Как мы создали собственный картографический пайплайн для топокарт MapMagic: часть вторая — как наладили автоматическое обновление карт, рендеринг растровых тайлов и их отдачу карт пользователям
При работе с Bitrix24 понадобилось сохранить адрес из Google Maps в стандартное поле Address у лида. Не просто строку, а полноценный адрес: с координатами, разбивкой на части и корректной работой всей...
В шедевральном мультфильме "Падал прошлогодний снег" строгая, но авторитетная жена послала мужика за ёлкой в лес. Главный герой же не особо сконцентрирован на основной цели своей предновогодней прогу...
Эта публикация написана после неоднократных обращений как клиентов, так и (к горести моей) партнеров. Темы обращений были разные, но причиной в итоге оказывался один и тот же сценарий, реализу...
От скорости сайта зависит многое: количество отказов, брошенных корзин. Согласно исследованию Google, большинство посетителей не ждёт загрузки больше 3 секунд и уходит к конкурентам. Бывает, что сайт ...