Содержание статьи
Наши призеры
Вот она, золотая пятерка чемпионов!
Главный победитель, Егор Василенко, получил обещанную стипендию на сумму в 100 тысяч и написал офигенное решение задач для нашего журнала, проиллюстрировав его двадцатью девятью листингами. Это просто пир духа, огромное удовольствие для всех, кто интересуется взломом и форензикой!
Сертификаты на меньшие суммы получили:
- Евгений Александрович Акулов
- eakj@protonmail.ch (неплохое ФИО, сразу видно настоящего анонима, респект)
- Ацамаз Маратович Гацоев (между прочим, семнадцать лет парню, а даст прикурить некоторым дяденькам от хакинга ;))
- Олег Евгеньевич Климов
Решение от победителя: задание 1
Условие
На рабочем компьютере секретного агента была найдена подозрительная программа, которая крадет данные. Агент не растерялся и снял дамп программы непосредственно перед отправкой зашифрованных данных.
Требуется: найти флаг.
Решение
Проведем статический анализ дампа с помощью дизассемблера IDA.
Обрати внимание, что файл был собран с отладочной информацией. Название pdb-файла уже в некотором смысле служит подсказкой.

Формат EntryPoint’а свидетельствует о том, что исполняемый файл написан на языке C++.

Аналогичный вывод можно сделать при обнаружении функции WinMain
, с которой и следует начинать анализ. Функция WinMain
выглядит следующим образом.

В самом начале своей работы исследуемый процесс создает и отображает окно приложения. Параметры окна являются аргументами функции CreateWindowExW
.

Более подробно о сообщениях и очередях сообщений можно узнать здесь. Важнее всего то, что функция обратного вызова TimerFunc
срабатывает каждый раз при вызове функции DispatchMessageW
. Таким образом, анализ дампа сводится к анализу функции TimerFunc
.
Переходим в функцию TimerFunc
. Она описывается следующим псевдокодом.

Вот что здесь происходит:
- процесс получает путь к файлу из директории
%TEMP%
; - получает параметры экрана: ширину и высоту;
- последовательно выполняет функции, которые я назвал
Get_Screen
,Encrypt_Screen
иSend_Screen
(функцииGdiplusStartup
иGdiplusShutdown
используются для инициализации Windows GDI+ и окончания работы с Windows GDI+ соответственно).
Get_Screen
В функции Get_Screen исследуемый процесс делает скриншот экрана и сохраняет его в файл fIsdWlasd.bin
, который должен располагаться в директории %TEMP%
.

Encrypt_Screen
После незначительных правок функция Encrypt_Screen
выглядит так.

Чтобы понять, что здесь осуществляется шифрование, зайдем в Encrypt_sub_3B1F50
. В ней трудно не заметить вызовы таких функций, как EVP_CIPHER_CTX_new
, EVP_EncryptInit_ex
, и других функций из EVP, которые обеспечивают интерфейс высокого уровня для функций из библиотеки OpenSSL.
Для того чтобы понять, какой алгоритм используется при шифровании, идем сюда.

В функции Set_Cipher_Parameters_sub_CE1260
видим выбор параметров блочного шифра.



А вызывается данная функция следующим образом.

Если сопоставить передаваемые аргументы со значениями внутри Set_Cipher_Parameters_sub_CE1260
, получится структура, где Name = 0 ("AES-")
, Mode = 1 ("CBC")
и KeyLength = 1 ("128-")
.

Делаем вывод, что скриншот экрана шифруется алгоритмом AES-128-CBC с помощью OpenSSL. Ключ шифрования берется из ресурсов.

Его можно без труда получить с помощью программы Resource Hacker или любого hex-редактора.

Теперь мы знаем, что скриншот шифруется алгоритмом AES-128-CBC по известному нам ключу, но этого недостаточно. Для полноты анализа необходимо узнать инициализирующий вектор, который используется в CBC-режиме.
В EVP ключ шифрования и инициализирующий вектор передаются в функцию EVP_EncryptInit_ex
.

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

К слову, так делать нельзя.
Send_Screen
В функции Send_Screen
выполняется отправка данных на сервер злоумышленника.

Причем отправляется тот самый зашифрованный файл fIsdWlasd.bin
. Содержимое зашифрованного файла, полученное с помощью функции ReadFile
, находится в переменной buf
.

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

Помимо этого, злоумышленник оставил нам подсказку в виде размера зашифрованного скриншота.

Сохранить зашифрованный скриншот в файл можно прямо из IDA.

Флаг
Зная все параметры алгоритма шифрования, мы можем без труда восстановить исходный скриншот из дампа, это и будет наш флаг.
Python-скрипт, с помощью которого можно получить исходный скриншот, я положил сюда. Помимо этого, расшифровать скриншот можно в OpenSSL:
> openssl enc -aes-128-cbc -d -in enc_screen -out dec_screen.jpeg -K 2682377FB2C7898E5EB781D941C09C5A -iv 2682377FB2C7898E5EB781D941C09C5A
А вот и флаг!

Решение от победителя: задание 2
Условие
В вашем распоряжении оказалась зашифрованная информация в файле flag.enc
. Данный файл зашифрован алгоритмом AES-256-ECB. К счастью, у вас есть ключ от зашифрованного файла key.enc
. Проблема в том, что он зашифрован алгоритмом RSA публичным ключом key.pub
.
Требуется: расшифровать файл flag.enc
и достать флаг.
Решение
Посмотрим, что собой представляет публичный ключ RSA.

Видим, что длина модуля составляет 256 бит. C таким модулем ни о какой стойкости криптосистемы говорить не приходится. Первое, что пришло на ум, — факторизовать модуль с помощью YAFU.

Нам удалось получить разложение модуля на простые множители. Этого вполне достаточно, чтобы сгенерировать секретный ключ RSA-256 и расшифровать им key.enc
. В OpenSSL есть возможность генерации секретного ключа RSA с помощью команды asn1parse
. Для этого необходимо знать следующие параметры ключа:
-
modulus
: модуль, в нашем случаеmodulus = 71521286555472299312252291246589709247849481750774732993492805730954699131789
-
pubExp
: открытая экспонента, в нашем случаеpubExp = 65537
-
privExp
: секретная экспонента, элемент, обратный кpubExp
по модулю?(modulus) = (p - 1) ? (q - 1)
-
p
: первый множительmodulus
, в нашем случаеp = 261857794043121448213410325750790838383
-
q
: второй множительmodulus
, в нашем случаеq = 273130256889334854338089243490350662083
-
e1
: элемент, обратный кpubExp
по модулю(p - 1)
; -
e2
: элемент, обратный кpubExp
по модулю(q - 1)
; -
coeff
: элемент, обратный кq
по модулюp
.
Как правило, для нахождения обратного элемента по модулю используют расширенный алгоритм Евклида. Таким образом, все недостающие параметры можно получить с помощью следующего Python-скрипта. Ниже — результат работы скрипта.

Для того чтобы сгенерировать секретный ключ RSA, необходимо создать конфигурационный файл.

И выполнить набор команд в OpenSSL.

Здесь мы сгенерировали приватный ключ RSA-256 в формате DER по параметрам, указанным в asn1_struct
, перевели его в формат PEM и записали в файл key.priv
. Теперь ничто не мешает нам расшифровать ключ AES и достать флаг.

Можно заметить, что после расшифровки ключ AES имеет длину не 256, а 128 бит. Поэтому реальный ключ выглядит так:
197b706e1595cf81c533136a2990249700000000000000000000000000000000
В OpenSSL это не имеет значения, но при расшифровке вручную может сыграть определенную роль.
Флаг: Stvgn6CFHKYd3BDE
Правильные ответы на тест
Честно говоря, я думал, что эти вопросы слишком простые, легко гуглятся и публиковать их смысла нет. По результатам оказалось, что нашлись такие невнимательные участники, которые накосячили даже в них. 🙂 Так что — публикуем правильные ответы (выделены жирным).
- При каком варианте спама злоумышленники вынуждены указывать настоящий обратный адрес?
- Фишинговые письма
- Нигерийские письма
- Малотиражная целевая спам-рассылка с вредоносным вложением
- Возможна ли утечка данных пользователя, если он их вводит с виртуальной клавиатуры?
- Нет
- Нет, если на компьютере заклеена видеокамера
- Да
- Выберите все из нижеперечисленных проблем, которые удается решить с помощью технологии соления паролей
- Выбор слишком короткого пароля
- Неинформативность пароля
- Совпадение паролей у разных пользователей
- Какая из перечисленных вредоносных программ предназначена для атак на онлайн-банкинг?
- Chameleon
- Virus.Win9x.CIH
- Carberp
- Какой вид атак на онлайн-банкинг технически наиболее сложен и требует внедрения на атакуемом информационном ресурсе эксплоита?
- Phishing
- Man-in-the-Middle
- Man-in-the-Endpoint
- В чем слабое место протокола Диффи — Хеллмана?
- Математическая основа этого протокола ненадежна
- Уязвим по отношению к атакам Man-in-the-Middle
- Стал уязвим по отношению к brute-force attack с учетом выросших вычислительных возможностей компьютеров
- Какой метод DDOS-атаки позволяет добиться многократного усиления трафика?
- UDP flood
- Http slow post
- Dns amplification атака
- Какой хеш-алгоритм работает быстрее?
- CRC32
- MD5
- SHA-2
- Какие криптографические методы используются в технологии блокчейн?
- Потоковое шифрование
- Хеширование
- Цифровая подпись
- Выберите все правильные варианты ответа
- Формат HTTPS разработан специально для нужд онлайн-банкинга
- HTTPS является отдельным по сравнению с HTTP протоколом
- HTTPS — это расширение протокола HTTP, в котором добавлено шифрование передаваемых по транспортным механизмам протокола HTTP данных
IT-компании, шлите нам свои задачки!
Миссия этой мини-рубрики — образовательная, поэтому мы бесплатно публикуем качественные задачки, которые различные компании предлагают соискателям. Вы шлете задачки на lozovsky@glc.ru — мы их публикуем. Никаких актов, договоров, экспертиз и отчетностей. Читателям — задачки, решателям — подарки, вам — респект от нашей многосоттысячной аудитории, пиарщикам — строчки отчетности по публикациям в топовом компьютерном журнале.