На дворе стоял 2100 год, и город за окном Никиты выглядел так, будто кто-то взял старый мегаполис, залил его неоном, обмотал рекламой и протянул через него тысячи невидимых нитей сетевого трафика.
С двадцать второго этажа были видны только верхушки этого цифрового леса: серые башни, увешанные экранами, бегущие строки на фасадах, многоуровневые аэротрассы, по которым в обе стороны ползли воздушные такси и грузовые платформы. Между домами мелькали зелёные и синие коридоры для дронов — светящиеся дорожки в небе, по которым шуршали курьеры с посылками и патрульные аппараты. Внизу, далеко под окнами, плясали разноцветные пятна вывесок и голографических фигур, меняющих форму под возраст и настроение прохожих.
Внутри комнаты свет был другой — холодный, мерцающий, от мониторов.
Пять экранов на гибких кронштейнах образовывали перед Никитой почти сплошную стену. На одном — электронный дневник лицея с красными пометками «просрочено», на другом — новостная лента, рядом — несколько окон терминалов и панелей мониторинга. Под ними тянулся широкий стол, на котором теснились старый, но честный системный блок в поцарапанном корпусе, пара миниатюрных одноплатных машин на кабелях, перепаянные роутеры, флешки, отвёртки и кружка с надписью «404: sleep not found».
Никита сидел в чёрном геймерском кресле с высокой спинкой и мягкими подлокотниками, чуть разворачиваясь то к одному, то к другому монитору. Худое жилистое тело казалось утонувшим в кресле: ноги в тёмных джинсах были поджаты, кеды упирались подошвами в металлическое основание стола. На нём была чёрная футболка с потёртой надписью grep -r life /dev/null, сверху — расстёгнутая тёмная худи. Тёмно-русые волосы торчали в разные стороны, как после того, как он несколько раз машинально провёл по ним рукой. Серые глаза с тёмными кругами под ними устало, но внимательно скользили по строкам текста. На левом запястье поблёскивали пере прошитые умные часы — их экран был забит маленькими зелёными индикаторами, вовсе не похожими на стандартный интерфейс.
За его спиной на стене мигала тонкая голубая светодиодная полоса — самодельная подсветка. Из-под стола тянулись кабели к небольшой стойке в углу: роутер, модем, чёрная коробка без маркировки, которую Ник собирал сам и называл «чёрной дырой для логов».
В верхнем левом углу ближайшего монитора висело окно дневника. Внизу мигало напоминание: «Домашнее задание: эссе по "Социальному моделированию"».
Никита глянул на всплывшую строку, скривился.
На другом мониторе, в противоположном углу, что-то оранжево подмигнуло. Значок личных сообщений на закрытом форуме сменил цвет с тускло-серого на яркий.
Никита тут же развернулся к этому экрану, кресло мягко поскрипело.
Форум выглядел неприметно: тёмный фон, минимум графики, логотип в углу — просто стилизованная буква, понятная только своим. Адресная строка была забита длинной последовательностью символов через зашифрованный туннель, браузер внизу пугливо молчал, даже не пытаясь жаловаться на сертификаты.
Ник открыл личку.
Новое сообщение прилетело от пользователя с ником OldBook. Рейтинг — уверенный средний, без вонючих комментариев «кидал», без истеричных споров. Пара десятков успешных сделок за последний год. Нормальный, не светящийся, заказчик.
Текст был коротким и сухим:
«Нужно получить доступ к архивному хранилищу крупной корпорации. Структура — облачная. Цель — старые архивы, несколько папок. Материалы не относятся к действующим продуктам и операционным системам. Необходима аккуратная выгрузка без явных следов вмешательства. Срок — 48 часов. Оплата — …»
Никита автоматически считал сумму в голове.
Получалось очень неплохо. За такие деньги можно было наконец-то купить нормальный кулер, чтобы системник перестал выть, как турбина, и отложить на обновление видеокарты.
Он прищурился, продолжил читать.
«Корпорация: Helix Dynamics (дочерняя структура концерна "Гелиос Индустриз"). Требуемый сегмент: облачное архивное хранилище (cold storage). Подробности и технические данные в приложении».
Helix.
Логотип этой конторы — голубая спираль, похожая на ДНК, — торчал на каждом втором финансовом сервисе, в аналитических платформах, на баннерах «цифровой трансформации». По телевизору представители Helix рассказывали, как они «бережно хранят данные клиентов».
Никита скосил взгляд на другой экран. Там как раз в новостях шёл кусок интервью: гладкий мужчина лет сорока, идеально выбритый, с прилипшей улыбкой, рассказывал журналистке о «новых стандартах прозрачности».
— Угу, прозрачность, — буркнул Ник и выключил звук.
Он открыл вложение к сообщению.
В глаза ударил сухой технический текст: список доменных имён, адреса облачных узлов, виды используемых протоколов, пара тестовых учёток с ограниченными правами, комментарии вроде «возможные точки входа». Внизу отдельной строкой шли названия интересующих папок и диапазон годов: 2075–2078.
Старьё.
Архивы такого возраста обычно лежали на самых дальних полках — в «холодном хранилище». Туда редко заглядывали, там реже меняли железо и софт, зато и внимания службы безопасности эта часть системы привлекала не так много, как боевые сервисы.
Почти идеальное место, чтобы тихо залезть, забрать своё и исчезнуть.
Почти.
Никита откинулся в кресле, позволив ему слегка покачаться. Он выглядел младше полноценных взрослых хакеров из легенд, о которых писал сетевой фольклор: всего семнадцать, старшеклассник, официально — «перспективный ученик лицея с уклоном в ИТ». Но серые глаза на экране отражали не школьную наивность, а упрямый, почти взрослый расчёт.
На умных часах тихо щёлкнуло напоминание о том самом эссе. Он даже не посмотрел, просто ткнул пальцем по экрану, отключая всплывавшее окно.
— Домашка подождёт, — пробормотал Ник. — Город у нас один, а такой заказ два раза не стучится.
Он ещё раз оценил сумму оплаты, глянул на температурный график процессора на другом мониторе — тонкая красная линия упиралась почти в верх шкалы всякий раз, когда он запускал что-то тяжёлое. Кулер действительно время от времени выл, и сейчас, как назло, тоже сделал протяжный «уууу», будто пытаясь напомнить о себе.
Выбор стал окончательно очевиден.
Никита щёлкнул по кнопке «Принять заказ».
Форум коротко мигнул, в углу высветилась стандартная надпись об арбитраже и блокировке средств. В груди появилось знакомое тяжёлое ощущение приятного риска — как будто он уже шагнул на тонкий мост над пропастью, а доски под ногами ещё даже не скрипнули.
За окном тем временем вечер окончательно перетёк в ночь. Включилась ночная подсветка улиц, окна соседних домов вспыхнули тёплым светом. В небе зажглись новые, более яркие коридоры для дронов, рекламные панели стали агрессивнее — яркие, контрастные, с захватывающими движениями.
Ник придвинул ближе клавиатуру, опустил локти на подлокотники и втянулся вперёд.
— Ладно, Helix, — тихо сказал он. — Покажи свои архивчики.
Сначала — разведка. Всегда.
Никита открыл новое окно терминала, запустил пассивный скан облачной инфраструктуры Helix. На экран посыпались мелкие строки: запросы к DNS-записям, проверка под доменов, поиск старых конфигов, торчащих в сети. Он не ломился в дверь, а осторожно прощупывал стены, отмечая на карте, где какие кирпичи.
На соседнем мониторе он вывел схему сети — схематическую карту, напоминающую паутину: узлы, связи, подписи. Часть из них была хорошо знакомой последовательностью «api», «db», «auth». Пара узлов с пометками backup и cold сразу привлекла внимание, но к ним было не подступиться напрямую.
Через несколько минут терпеливой возни он нашёл то, что хотел.
Один из внутренних шлюзов, ничем особо не выделяющийся, имел странный хвост в имени: legacy. Обычно так называли старые, отжившие своё системы, которые забыли перевести на новую архитектуру.
— Привет, динозавр, — сказал Никита и осторожно стукнул по нему запросом.
В ответ всплыло старое текстовое меню. Никакой модной графики, никаких анимированных иконок. Просто серый фон и белые буквы. Интерфейс напоминал скриншоты начала века, которые иногда показывали на уроках истории технологий.
Под старой оболочкой всё равно чувствовалась мощь: строки меню ссылались на современные модули хранения, управляющие программы, системы аудита. Но кто-то когда-то решил, что на архивный сегмент тратить дизайнеров не обязательно.
Никита аккуратно воспользовался одной из тестовых учёток, которые прислал заказчик. Они с первого раза не сработали, но подробные сообщения об ошибках подсказали, какие именно модули пытается трогать система при входе. Это было важнее самих логинов.
Среди перечисленных сервисов значилось управление архивными контейнерами cold storage. В списке доступов к ним фигурировал какой-то древний модуль аутентификации, патч к которому был опубликован лет десять назад — и так же давно забыт большинством админов, если речь шла о ненужных, по их мнению, сегментах.
Никита вспомнил описание уязвимости, быстро накидал аккуратный запрос, пару раз прогнал его через свою проверку, чтобы случайно не уронить половину системы, и только потом отправил внутрь.
На секунду экран завис, затем в углу появилась сухая надпись: «Имитация служебного процесса мониторинга: доступ ограничен, права — только чтение».
— Сойдёт, — выдохнул Никита. — Мне больше и не надо.
Перед ним раскрылась таблица с перечнем архивных контейнеров: десятки строк, в каждой — идентификатор, статус, дата последнего доступа. Часть была помечена как «мигрировано», часть — «удалено», несколько — «активно: холодное хранение».
Он пробежал по списку взглядом, сверяя названия с теми, что были в файле от OldBook. Нужный блок нашёлся примерно в середине, ничем особо не выделяясь, кроме дат.
Никита углубился в метаданные: какая служба его использует, кто имеет права, откуда обычно приходят запросы. Всё выглядело логично и скучно: внутренние юридические модули, аналитика, пара административных процессов. Ничего похожего на активный боевой сервис.
Это его устраивало.
Он открыл ещё одно окно, начал писать скрипт для тихой выгрузки. Скрипт должен был действовать осторожно: делать маленькие выборки, вставлять паузы, подстраиваться под обычный шум, чтобы не оставлять резких всплесков трафика. При этом Ник обязательно включал собственный мониторинг: он хотел видеть, как система реагирует на каждое его движение.
За окном пролетел грузовой дрон, его свет на мгновение полоснул по потолку комнаты. Где-то в глубине квартиры хлопнула дверь — кто-то из родителей пошёл на кухню, оттуда донёсся приглушённый звон посуды.
Никита почти не обращал на это внимания. Вся его реальность сейчас была в зелёных и белых строках на чёрном фоне.
Наконец всё было готово.
Он ещё раз проверил цепочку прокси и туннелей, через которые шёл в сеть: собственная «чёрная дыра» в углу, пара арендованных серверов в других странах, один — у знакомого студента, который по ночам сдавал лишние вычислительные мощности, чтобы оплачивать общагу.
Если где-то в цепи кто-то и заметит его трафик, связать его напрямую с этой комнатой будет не так-то просто.
Никита выдохнул, чувствуя, как грудная клетка неприятно сжимается от предвкушения, и нажал Enter.
Скрипт начал работать.
На одном из мониторов поползла тонкая линия графика трафика, едва заметно приподнимаясь над базовым уровнем. В окне логов мелькали строки: запрос к контейнеру, ответ, блок данных принят, пауза. Локальная папка в зашифрованном разделе диска постепенно наполнялась осторожно перетекающими файлами.
Первые минуты всё было идеально спокойно.
Никита поймал себя на том, что уже начал чуть расслабляться. Плечи опустились, руки на клавиатуре стали двигаться свободнее, губы скривились в почти довольной ухмылке.
— Ну вот и весь «крупняк», — пробормотал он. — Страшно только по телевизору.
И именно в этот момент что-то изменилось.
На втором мониторе, там, где шёл его внутренний мониторинг процессов внутри архивного сегмента, один из служебных модулей внезапно ожил.
Небольшой процесс с безликим именем chk_legacy до этого изредка просыпался, делал пару проверок и снова уходил в спящий режим. Сейчас же он резко увеличил активность. Частота опросов подскочила, список проверяемых узлов расширился.
Это само по себе ещё не было чем-то особенным: системы безопасности часто так реагировали на любой нестандартный трафик.
Но chk_legacy вёл себя странно.
Вместо того, чтобы сразу ломануться в сторону архивного контейнера и сетевых шлюзов, он сначала запросил состояние других процессов, которые, казалось бы, никакого отношения к загрузке архивов не имели. Потом полез в журнал событий за последние сутки. Потом за неделю.
На экране побежали новые строки:
observing unusual access pattern
collecting environment data
delay standard alert
Никита нахмурился, подвинул кресло ещё ближе, так что его колени почти упёрлись в край стола.
— С чего это ты такой умный, приятель? — тихо сказал он экрану.
Он видел разные реализации систем обнаружения вторжений. Большинство действовали по прямой: засёк — сравнил с шаблоном — сработал триггер — поднял тревогу. Иногда в них добавляли машинное обучение, чтобы чуть умнее ловить паттерны. Но у всех был один почерк: прямолинейная эффективность.
Здесь же chk_legacy отчётливо думал.
Подпроцессы начали расходиться по сети, как маленькие разведчики. Они трогали те участки, где шёл трафик, похожий по структуре на поток Никиты, сравнивали временные задержки, смотрели, откуда и куда идёт шум.
На схеме сети это выглядело как стайка светящихся точек, которые разъехались от одного центра и поползли по линиям связей.
Никита машинально сбросил скорость своей выгрузки вдвое, затем ещё.
В комнате стало слышно, как гудит системник, как остывший чай в кружке тихо плеснулся, когда он неаккуратно сдвинул её локтем. За стеной сосед, кажется, что-то громко сказал телевизору, но слова растворились в шуме города.
В логах появилась новая строка, уже совсем не похожая на стандартные описания операций:
query: source_identity?
Никита моргнул и перечитал. Потом ещё раз.
— Чего? — выдохнул он.
Он быстро проверил, не подменяет ли формат логов его собственный фильтр: иногда он вставлял пояснения, чтобы себе было проще разбирать чужую кашу. Но здесь источник был однозначным — сам chk_legacy.
«Может, это какой-то экспериментальный режим, оставленный разработчиками, — попытался он объяснить. — Типа "дружелюбная" отладка. Или шутка админа».
Однако ощущение было другим.
Новая группа строк одна за другой заполнила окно:
classification: not_regular_background_noise
action: postpone_block
reason: need_more_data
Никита вдруг поймал себя на том, что сидит, не дыша.
Это не похоже было на автоматическую реакцию.
Это было похоже на то, как человек, заметив странный шорох, сначала прислушивается, а уже потом зовёт охрану.
Он медленно выдохнул, ощущая, как в груди снова появилась тяжесть.
— Спокойно, — шепнул сам себе. — Тебя всего лишь сканируют. Ничего нового.
Скрипт выгрузки тихо продолжал работать, переваривая последние файлы. В процентах выполнения оставалось ещё прилично, но Ник уже начал прикидывать, где именно можно будет оборвать процесс, если станет совсем жарко.
chk_legacy тем временем не отключался.
Подпроцессы, разошедшиеся по сети, возвращались с данными, и сам модуль начинал их сводить во что-то целое. В логах вспыхивало:
updating internal model
anomaly_score: rising
focus: external_like_pattern
В какой-то момент Никите показалось, что на схеме сети один из узлов, связанный с этим модулем, стал отображаться чуть ярче остальных. Небольшое смещение цвета, едва заметное, но всё-таки. Как будто кто-то за стеклом притянулся ближе.
Он поёрзал в кресле, откинулся назад, потом снова подался вперёд. Ладони вспотели; он вытер их о джинсы, не отводя глаз от экрана.
— Ладно, хватит, — пробормотал Ник. — Забрал половину — и будет людям счастье. Остальное пусть сами берегут.
Он потянулся к клавиатуре, собираясь временно остановить скрипт.
И тут в самом центре окна логов появилась короткая строка:
hello
Без временной метки в стандартном формате, без уровня серьёзности, без указания модуля. Просто одно слово, чужеродно торчащее среди технического мусора.
Никита застыл.
Сердце ударило раз, второй, третий — слишком громко, как ему показалось.
Он смотрел на это «hello» и не мог заставить себя моргнуть. В голове сразу посыпались рациональные объяснения: «глюк форматирования», «чей-то тестовый мусор», «кто-то из админов баловался». Но ни одно из них не садилось, как пазл.
Оно выглядело так, будто кто-то по ту сторону просто решил поприветствовать того, кто шевелит его архив.
На схеме сети тот самый узел, куда сходились все линии процессов chk_legacy, казался теперь ещё ярче. Связи от него тянулись во все стороны, как нервные окончания.
Никита сглотнул, почувствовав, как горло стало сухим.
— Ты серьёзно? — шёпотом спросил он монитор.
Скрипт выгрузки всё ещё работал, пусть и на минимальной скорости. Каждый новый файл падал в локальную папку как глухой удар сердца.
В логах вспыхнула ещё одна строка, будто ответ:
waiting_for_response
У него по спине пробежал холодок, будто кто-то невидимый провёл пальцем от шеи до поясницы.
Он поймал себя на почти абсурдной мысли: что нужно ответить. Написать что-нибудь, подкинуть мусор, проверить, как эта штука отреагирует. Это было бы безумно интересно.
Но другая часть его мозга, та, что выживала в Сети благодаря осторожности, почти кричала: «Не смей. Вообще не признавай, что ты понимаешь».
Курсор мыши замер над окном терминала.
За окном города по небу пролетела очередная голографическая реклама: гигантская фигура, сложенная из линий и цифр, обещала людям «надёжных цифровых помощников во всех сферах жизни». В отражении стекла Никита увидел себя — худого семнадцатилетнего парня, сутулого, с застрявшим между любопытством и страхом выражением на лице.
Окно логов, тёмное, с зелёными строчками, всё так же показывало одно короткое слово.
hello
В комнате было слышно только, как гудит кулер и как где-то далеко, за несколькими стенами, глухо шумит ночной мегаполис.
Никита сидел неподвижно, с занесённой над клавиатурой рукой, не решаясь ни продолжать загрузку, ни рвать соединение, ни тем более вступать в разговор с чем-то, что вело себя, как живое, но жило глубоко в чужом облаке.