Настало время подвести итоги мартовских задач на собеседованиях и прославить тех парней, которые их с блеском решили. Спасибо победителю — его решение оказалось настолько подробным, что потянет на целую статью по крякингу. 🙂
 

Наши призеры

Вот она, золотая пятерка чемпионов!

Главный победитель, Егор Василенко, получил обещанную стипендию на сумму в 100 тысяч и написал офигенное решение задач для нашего журнала, проиллюстрировав его двадцатью девятью листингами. Это просто пир духа, огромное удовольствие для всех, кто интересуется взломом и форензикой!

Сертификаты на меньшие суммы получили:

  1. Евгений Александрович Акулов
  2. eakj@protonmail.ch (неплохое ФИО, сразу видно настоящего анонима, респект)
  3. Ацамаз Маратович Гацоев (между прочим, семнадцать лет парню, а даст прикурить некоторым дяденькам от хакинга ;))
  4. Олег Евгеньевич Климов
 

Решение от победителя: задание 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

 

Правильные ответы на тест

Честно говоря, я думал, что эти вопросы слишком простые, легко гуглятся и публиковать их смысла нет. По результатам оказалось, что нашлись такие невнимательные участники, которые накосячили даже в них. 🙂 Так что — публикуем правильные ответы (выделены жирным).

  1. При каком варианте спама злоумышленники вынуждены указывать настоящий обратный адрес?
    1. Фишинговые письма
    2. Нигерийские письма
    3. Малотиражная целевая спам-рассылка с вредоносным вложением
  2. Возможна ли утечка данных пользователя, если он их вводит с виртуальной клавиатуры?
    1. Нет
    2. Нет, если на компьютере заклеена видеокамера
    3. Да
  3. Выберите все из нижеперечисленных проблем, которые удается решить с помощью технологии соления паролей
    1. Выбор слишком короткого пароля
    2. Неинформативность пароля
    3. Совпадение паролей у разных пользователей
  4. Какая из перечисленных вредоносных программ предназначена для атак на онлайн-банкинг?
    1. Chameleon
    2. Virus.Win9x.CIH
    3. Carberp
  5. Какой вид атак на онлайн-банкинг технически наиболее сложен и требует внедрения на атакуемом информационном ресурсе эксплоита?
    1. Phishing
    2. Man-in-the-Middle
    3. Man-in-the-Endpoint
  6. В чем слабое место протокола Диффи — Хеллмана?
    1. Математическая основа этого протокола ненадежна
    2. Уязвим по отношению к атакам Man-in-the-Middle
    3. Стал уязвим по отношению к brute-force attack с учетом выросших вычислительных возможностей компьютеров
  7. Какой метод DDOS-атаки позволяет добиться многократного усиления трафика?
    1. UDP flood
    2. Http slow post
    3. Dns amplification атака
  8. Какой хеш-алгоритм работает быстрее?
    1. CRC32
    2. MD5
    3. SHA-2
  9. Какие криптографические методы используются в технологии блокчейн?
    1. Потоковое шифрование
    2. Хеширование
    3. Цифровая подпись
  10. Выберите все правильные варианты ответа
    1. Формат HTTPS разработан специально для нужд онлайн-банкинга
    2. HTTPS является отдельным по сравнению с HTTP протоколом
    3. HTTPS — это расширение протокола HTTP, в котором добавлено шифрование передаваемых по транспортным механизмам протокола HTTP данных

 

IT-компании, шлите нам свои задачки!

Миссия этой мини-рубрики — образовательная, поэтому мы бесплатно публикуем качественные задачки, которые различные компании предлагают соискателям. Вы шлете задачки на lozovsky@glc.ru — мы их публикуем. Никаких актов, договоров, экспертиз и отчетностей. Читателям — задачки, решателям — подарки, вам — респект от нашей многосоттысячной аудитории, пиарщикам — строчки отчетности по публикациям в топовом компьютерном журнале.

8 комментариев

  1. JK_MIB

    27.04.2018 at 12:30

    А я инициализирующий вектор в первом задании не нашел (не искал)…
    Но флаг добыл)

    • Егор Василенко

      29.04.2018 at 23:04

      Ничего удивительного в этом нет, первые 16 байт должны удовлетворять формату JPEG-файла, их не обязательно расшифровывать. Но ведь это частный случай)

  2. kn-vasilenko

    28.04.2018 at 23:04

    Ребята, спасибо за вашу мини-рубрику. Нужное для всех дело делаете. В выигрыше все.

  3. benkow_

    30.04.2018 at 08:21

    маленькая исторя о Ацамаз Маратович Гацоев, наслаждаемся)
    https://benkowlab.blogspot.ru/2018/04/sorry-not-sorry-1ms0rry-atsamaz-gatsoev.html

  4. Asylum

    30.04.2018 at 18:13

    *между прочим, семнадцать лет парню
    Так самый возраст, позднее начинают обрастать семьей, работой, бытовыми проблемами …

    • 0Nly Sterile Aleecce

      01.05.2018 at 14:10

      Логика ясна, но можно не заводить семью, на работе читать википедию и так далее, и игнорировать обычные проблемы. Это единственный вариант. Нужно просто поставить задачу и оптимизироваться. 🙂 Чем больше десятков лет возраста, тем больше проблем с физической памятью. То сектор повредился, то шпиндель не крутится.

  5. 0Nly Sterile Aleecce

    01.05.2018 at 14:17

    Мега-полезная рубрика! Спасибо! Решать основные задания то времени нет, то мозгов не хватает, то всё вместе. Правильно, что публикуете инструкцию по выполнению. 🙂

Оставить мнение

Check Also

10 научно-фантастических комиксов для тех, кто не читает комиксы и не любит супергероев

В то время как фильмы по комиксам бьют все возможные рекорды кассовых сборов, сами комиксы…