Привет, Хабр! Меня зовут Илья Буймистров, я занимаюсь исследованиями в области информационной безопасности в команде CICADA8 центра инноваций МТС.
Чтобы защищать пользователей, надо понимать, где слабые места в их ИТ-системах. Сегодня я расскажу, как можно обойти ввод пароля в достаточно известной программе Shadow Defender. Если вы росли в 2000-х, наверняка сталкивались с ней в компьютерных клубах и других местах, где ПК доступен большому количеству людей. Иногда её называют антивирусом, но не совсем точное определение. Обо всём по порядку.
![](https://habrastorage.org/getpro/habr/upload_files/4a3/11b/e05/4a311be05d6759ab36ddbc209a9845b5.jpg)
Почему Shadow Defender?
Моё первое знакомство с Shadow Defender произошло около десяти лет назад. Помню лето на даче, когда я каждый день устанавливал Quake III с внешнего жёсткого диска на ноутбук. И каждый раз при выключении компа Shadow Defender безжалостно стирал все изменения. Уверен, что не у меня одного остались «тёплые» воспоминания о встрече с этим ПО, зато я хорошо его запомнил.
Основное преимущество Shadow Defender — свобода экспериментов с компьютером. Вы можете скачивать и запускать все, что не запретит (или не заметит) тезка от Microsoft — Windows Defender, включая вирусы и майнеры.
Фокус в том, что все внесенные пользователем изменения удаляются после перезагрузки компьютера. Это правда может спасти, так как антивирусы иногда пропускают вредоносный софт. Он добавляется в автозагрузку и закрепляется в операционной системе. Понятное дело, Shadow Defender не защитит от утечки чувствительной информации и злонамеренного использования ПК в текущей сессии, но помешает вирусу закрепиться.
Shadow Defender появился в 2007 году и часто применялся в компьютерных клубах и общественных местах – в библиотеках, школах и государственных учреждениях. Везде, где важно, чтобы любой желающий мог сесть за компьютер и использовать его по своему усмотрению. Конечно, есть и другая целевая аудитория этого ПО — любители экспериментов, для которых важно вернуть работоспособность личной машины при любом поведении исследуемого ПО.
![Прекрасные времена Прекрасные времена](https://habrastorage.org/getpro/habr/upload_files/4de/857/bce/4de857bcee16dd6cb9ddee5e16312d6e.jpg)
С 2007 года вышло 45 версий, и в 2020 году на сайте разработчика появился последний релиз — 1.5.0.762. С тех пор ПО не обновляется и даже требует костылей для запуска под Windows 11. Но оно по-прежнему удобнее многих более современных аналогов вроде Deep Freeze и ToolWiz Time Freeze. Например, Shadow Defender позволяет выбрать, какие папки «замораживаются» и изменения в них не будут обнуляться после перезагрузки.
![](https://habrastorage.org/getpro/habr/upload_files/de7/f54/f2a/de7f54f2a5747d20133a8c0f8d74a687.jpg)
В результате до сих пор можно найти множество обсуждений, посвященных последствиям установки Shadow Defender. Кто-то обрел новые эмоции, безвозвратно потеряв дипломную работу или фотографии. Другие — как и я — заскриптовали установку необходимых приложений после включения компьютера. Самая частая проблема у пользователей заключается в том, что они не знают или забывают пароль от Shadow Defender. В результате не могут управлять конфигурацией программы и теряют свои данные.</spoiler>
Объект исследования
При очередной встрече с Shadow Defender на одном из проектов, я убедился, что приложение всё ещё подходит для своих задач. А реальная проблема на проекте стала основным направлением исследования — обход ввода пароля Shadow Defender при удаленном подключении к компьютеру.
С одной стороны, забытые пароли — это актуальная беда для многих пользователей. С другой — приложение давно не обновлялось, сертификат на сайте разработчика устарел и мне не удалось найти новостей о планируемых релизах. А значит, если обход пароля возможен, то удалённо подключившийся злоумышленник (никто не застрахован от бэкдора) легко изменит настройки Shadow Defender и повредит данные пользователя.
Лицензии на приложение всё ещё продаются и стоят около 35 долларов. Но для эксперимента хватило 30-дневной пробной версии. Исследование проходило на компьютере под управлением Windows 10.
![Сайт приложения жив, но его SSL-сертификат уже истёк Сайт приложения жив, но его SSL-сертификат уже истёк](https://habrastorage.org/getpro/habr/upload_files/ff5/1cf/248/ff51cf2482314be8481d599f4feb0f0d.png)
Официальный сайт Shadow Defender и форумы сходятся в том, что главная фишка ПО — виртуализация. Дополнительной информации мало, поэтому изучим приложение практическим путём, начнём с основных файлов.
Конфигуратором Defender.exe с графическим интерфейсом пользуется большинство пользователей. Программа позволяет настроить защиту одного или нескольких дисковых разделов, создать исключения для директорий и файлов, которые могут быть изменены во время пользовательского сеанса. Также конфигуратор позволяет защитить значения из реестра Windows. Интерфейс понятный, настройки просты. Будет несложно найти и активировать самый интересный для нас режим — Shadow Mode.
CmdTool.exe имеет близкую к Defender.exe функциональность, но управление идёт из консоли.
Также важный файл — драйвер diskpt.sys.
Все изменения записываются в конфигурационный файл user.dat
Вышеупомянутый Shadow Mode — это режим защиты компьютера. В нём операции чтения и записи перенаправляются в выделенное пространство на накопителе. Там и происходят изменения, которые пользователь делает во время сессии вплоть до ее завершения. Среди них — создание и редактирование папок, файлов и значений в реестре.
ПО позволяет задать исключения для объектов, результаты редактирования которых надо сохранить после перезагрузки — они останутся в «эталонном» (так назвал его разработчик) дисковом пространстве. Для этой информации всё будет как обычно, ваши работа, диплом или фото не исчезнут после выключения.
Когда пользовательская сессия закончена, выделенная область памяти стирается, и после перезагрузки компьютер возвращается в эталонное (исходное) состояние. Работу режима Shadow Mode обеспечивает драйвер diskpt. Он и обслуживает выделенную под временные изменения область памяти. Драйвером управляет приложение-конфигуратор — Defender.exe или CmdTool.exe.
Наглядно на схеме ниже приведён процесс чтение файлов в режиме Shadow Mode на примере конфигурационного файла user.dat. Он содержит настройки приложения в текстовом формате и hash (о котором мы поговорим ниже).
![Чтение файла в режиме Shadow Mode Чтение файла в режиме Shadow Mode](https://habrastorage.org/getpro/habr/upload_files/b55/4e9/a1c/b554e9a1cc4348f68d89af615c56b18a.png)
Файл может быть:
Прочитан с диска C (эталонного дискового раздела), если в него еще не вносились изменения.
Прочитан с диска C (эталонного дискового раздела), когда файл находится в исключениях.
Прочитан из выделенного под изменения пространства памяти если файл был создан или изменен после включения режима Shadow Mode.
Запись файлов в режиме Shadow Mode на примере конфигурационного файла user.dat выглядит так:
![Запись файла в режиме Shadow Mode Запись файла в режиме Shadow Mode](https://habrastorage.org/getpro/habr/upload_files/67d/e81/ea4/67de81ea4728e739ef4040dc16b81493.png)
Файл может быть:
Записан на диск C (эталонный дисковый раздел), когда файл находится в исключениях.
Записан на выделенном под изменения пространстве памяти, если файл не попадает под исключения.
Давайте попробуем обойти ввод пароля, понимая эту схему работы Shadow Defender и используя имеющуюся в интернете информацию.
Первая попытка — методы из Сети
В интернете много решений с сомнительной функциональностью – неизвестно, работают ли они и что делают. Например, варианты доступа к файлу конфигурации без предъявления пароля включают удаление Shadow Defender из оперативной памяти путем перезагрузки Windows в безопасный режим. Этот подход нам не подходит, так как нас интересует удалённая работа с компьютером. А при работе в безопасном режиме изменения (например, софт, добавленный в автозагрузку) не сохранятся. Нужно более деликатное решение.
Продолжая поиски, я наткнулся на YouTube-инструкцию по обходу пароля Shadow Defender. В описании под ним сразу же была ссылка на патч для обхода пароля в версии 1.4.0.648. Эта версия ПО выпущена в августе 2016 года. Но, если предложенное в видео решение действительно работает, то, может, с его помощью удастся разработать методику обхода пароля и в последней версии — 1.5.0.762?
Я нечасто устанавливаю неподписанные исполняемые файлы из описания к видео на YouTube. Но отчет VirusTotal, гласящий всего о 45 обнаруженных угрозах из 60, меня «успокоил». Безусловно с таким файлом можно работать только в виртуальной машине — такой подход я счёл вполне безопасным. Проверка файла из Интернета на Shadow Defender версии 1.4.0.648 привела к успешному обходу ввода пароля конфигурации.
![](https://habrastorage.org/getpro/habr/upload_files/19a/53f/1d7/19a53f1d71e59dd6317a083eeddf1eee.jpg)
При вводе пароля, отличающегося от установленного в приложении, окно конфигурации успешно открывается. Есть важный нюанс: попытка ввести правильный пароль вызывает ошибку доступа, что наводит на мысль об изменении логики приложения после патчинга.
Для статического и динамического анализа приложений применим IDA Pro 7.7.
Декомпилируем полученный из описания к YouTube-ролику исполняемый файл и смотрим на его строки. Быстрый анализ дает понять, что в исполняемом файле спрятана статическая библиотека dup2patcher.dll и именно она используется для воздействия на приложение Shadow Defender.
![](https://habrastorage.org/getpro/habr/upload_files/40a/8ab/dd3/40a8abdd312ee29267e27f1ae9f8af30.jpg)
Перед анализом библиотеки ее нужно достать из исполняемого файла. Самый удобный способ — сделать это через IDA Pro, с помощью которой можно сохранить файл статической библиотеки во время отладки исполняемого файла. Декомпиляция и поиск строк dup2patcher.dll в интернете без труда позволяют найти проект diablo2oo2's Universal Patcher (dUP2). Он используется как конструктор для сборки исполняемых файлов — патчеров под различное программное обеспечение.
Одна из особенностей dUP2 — информация о вносимых в приложение изменениях сохраняется в исполняемый файл. Такой подход даёт защиту от зорких глаз исследователей. Но теперь становится окончательно ясно, что патчер вносит изменения в байты приложения Shadow Defender, а конкретнее — в исполняемое приложение «C:\Program Files\Shadow Defender\Defender.exe».
Как сильно приложение было изменено патчем? Учитывая поведение пропатченной программы, возникло предположение, что в нём может быть изменён всего один байт. Проверить это довольно легко, возьмем исполняемый файл Defender.exe до применения патча и после. На картинке для удобства исполняемые файлы расположены в папках v1 и v2 соответственно.
![Сравнение исходного и пропатченного приложения Shadow Defender Сравнение исходного и пропатченного приложения Shadow Defender](https://habrastorage.org/getpro/habr/upload_files/e04/d47/8d3/e04d478d396b86bae239cff361840b27.jpg)
Сравнение исполняемых файлов с использованием стандартной утилиты Windows fc.exe доказывает, что в результате применения патча был затронут один байт по адресу 0x00018F7B. Его значение изменилось с 0x75 на 0x74, что предварительно соответствует изменению кода операций на ассемблере.
Операция с кодом 0x75 —это JNZ, переход при условии отличного от нуля содержимого регистра памяти по адресу 0x00018F7B. Новое значение по указанному адресу — 0x74 или команда JZ соответствует переходу при равенстве нулю содержимого регистра. Прекрасно, изменяемый байт найден, остается рассмотреть контекст, в котором он располагается.
Снова используем IDA Pro и декомпилируем приложение Shadow Defender в состоянии до применения патча. Ожидаемо, изменение логики применяется к участку проверки соответствия введенного пользователем пароля и того, что задан в приложении. Обратим внимание на инструкции: в регистр RDX помещается указатель на значение, сформированное с использованием введенного пользователем пароля (ниже поясню подробнее).
В регистр RCX помещается указатель на значение, которое было сформировано на основе изначально установленного пароля. Функция sub_14005A75C принимает на вход указатели на строки регистров RDX и RCX, а потом проводит посимвольное сравнение. В случае эквивалентности строк в регистре EAX возвращается нулевое значение.
Расположенная по адресу 0x00140019B7B (адрес из вывода fc.exe со смещением) инструкция JNZ запускает функции по выводу ошибки и повторному запросу пароля. Как мы выяснили выше, байт 0x75 данной инструкции изменяется на байт 0x74, что приводит к изменению логики проверки пароля. Теперь Shadow Defender запускается при несовпадении вводимого пользователем и заданного в приложении паролей.
![](https://habrastorage.org/getpro/habr/upload_files/c9b/597/1f0/c9b5971f0c04b4e708edefe8b6ace5e3.png)
Изменяемый участок распознан, попробуем распознать его содержимое. Функция sub_14005A75C, отвечающая за сравнение строк, принимает на вход два аргумента, очень похожих на хэш MD5. Берём хэш MD5 от вводимого нами пароля и сравниваем его с тем, что приходит в функцию, но нет… Хэш не совпадает. Проделываем ту же операцию с изначальным паролем приложения — результат тот же, отрицательный. Поглядим, откуда берется значение, передаваемое на сравнение.
Проследим путь введенного пользователем пароля с помощью IDA Pro. Для формирования хэша используется значение «HKLM\SYSTEM\CurrentControlSet\Services\diskpt\GUID» из реестра Windows, которое конкатенируется с введенным паролем, от полученной строки берется хэш MD5. Пример хэшируемого значения: «{04ad3b3e-1688-4bc3-923c-3207d58a0762}password». Прекрасно, формат мы распознали, а значит можно попробовать подменить хэш изначального пароля приложения на другой, сформированный с использованием вводимого нами пароля.
Дело за малым, пишем скрипт на Python, который получит значение из реестра, совместит его с новым паролем, возьмёт хэш MD5 и заменит его в конфигурационном файле Shadow Defender.
import hashlib
import winreg
import sys
# Получение значения из реестра
reg_type = winreg.HKEY_LOCAL_MACHINE
reg_dir = winreg.OpenKeyEx(reg_type, r"SYSTEM\\CurrentControlSet\\Services\\diskpt\\")
guid = winreg.QueryValueEx(reg_dir, 'GUID')[0]
winreg.CloseKey(reg_dir)
# Формирование значения
password = sys.argv[1]
data = "{}{}".format(guid, password)
# Получение хэша
hash_store = b''
for byte in data:
hash_store += byte.encode() + b'\x00'
hash = hashlib.md5(hash_store).hexdigest()
line = "hash={}\n".format(hash)
# Чтение из файла конфигурации
with open(r"C:\\Program Files\\Shadow Defender\\user.dat", 'r') as file:
data = file.readlines()
for ptr in range(len(data)):
if "hash=" in data[ptr]:
del data[ptr]
data.append(line)
# Запись в файл конфигурации
with open(r"C:\\Program Files\\Shadow Defender\\user.dat", 'w') as file:
data = file.writelines(data)
![](https://habrastorage.org/getpro/habr/upload_files/d1b/bfc/d3e/d1bbfcd3e199203f2588e02f398e63de.jpg)
Проверяем. Подмена пароля конфигурации работает только в случае, когда приложение Shadow Defender не находится в режиме Shadow Mode. Это происходит из-за того, что при обращении к файлу C:\Program Files\Shadow Defender\user.dat с включенным режимом Shadow Mode, конфигурационное приложение как исключение получает доступ к эталонному файлу конфигурации. Но в последнем содержится значение хэша от пароля, хранящегося в конфигурации. Согласно цели исследования мы его не знаем (забыли). А значит, внесенные скриптом изменения остаются в песочнице.
То есть мы научились обходить парольную защиту Shadow Defender, только если ПО работает не в режиме Shadow Mode. Но именно в нём нам и надо получить доступ. Миссия не выполнена.
![](https://habrastorage.org/getpro/habr/upload_files/540/4ff/d7d/5404ffd7de998fdb0845bd64e9ad7808.jpg)
Второй заход — используем полученный опыт
Несмотря на неудачный подход, найденный патчер познакомил нас с тем, как приложение проверяет пароль. А ещё он обнадёжил, что соответствующий участок кода не сильно меняется от версии к версии.
Проверим, это не слишком сложно: декомпилируем приложение Shadow Defender версии 1.5.0.762 и… Схожий по логике участок декомпилированного кода действительно присутствует. Хотя он претерпел незначительные изменения по сравнению с версией 1.4.0.648, но логика сравнения хэшей от паролей осталась идентичной.
![Знакомые инструкции Знакомые инструкции](https://habrastorage.org/getpro/habr/upload_files/62c/51a/0fa/62c51a0faff8b5486ce9744a6e1f96f8.png)
На изображении заметно, что функцию посимвольного сравнения заменила библиотечная функция wcsmp со схожей логикой работы. Расположенная по адресу 0x7FF7538CA5A9 инструкция JNZ совершает переход к функциям вывода ошибки и повторного ввода пароля. Как нам известно, байт 0x75 данной инструкции заменяется на байт 0x74, что приводит к извращению логики проверки пароля: переход к запуску конфигурации происходит в случае несовпадения паролей.
Напишем патч на Python под версию Shadow Defender 1.5.0.762, который заменит инструкцию JNZ на JZ по уникальному для этого бинарного файла набору байт.
defender_path = "C:\\Program files\Shadow Defender\Defender.exe"
with open(defender_path, "rb") as reader:
defender_data = reader.read()
defender_data = defender_data.replace(b"\x0F\x85\x82\x00\x00\x00\xE8\x18\x6E\xFE\xFF", b"\x0F\x84\x82\x00\x00\x00\xE8\x18\x6E\xFE\xFF")
with open(defender_path, "wb") as writer:
writer.write(defender_data)
Проверяем…Бинго! Обход пароля доступа к конфигурации на актуальной версии работает.
![](https://habrastorage.org/getpro/habr/upload_files/19b/707/e77/19b707e77d3bbd81a2fdb3ac46829452.jpg)
Дополнительно, для более удобного портирования обхода пароля доступа к конфигурации можно использовать патч для CmdTool.exe. Такой подход удобнее использовать для смены пароля конфигурации. Пропатченное приложение имеет небольшой размер и совместимо с любой версией Shadow Defender. Достаточно доставить на защищенный режимом Shadow Mode компьютер исполняемый файл и запустить его с параметрами /xpwd:password, где password — новый пароль.
Повторяем вышеприведённые операции по исследованию кода CmdTool.exe. Оказывается, изменяемый участок кода, как ни странно, тоже касается сравнения установленного в приложения и введённого пользователем паролей. При этом логика сравнения отличается от приложения Defender.exe, все решает один байт. В качестве кандидата на изменение выступает возвращаемый байт со значением 0, который свидетельствует о несовпадении паролей и запускает операции по выводу сообщения о невалидном пароле. Следовательно, решением будет изменение значения байта с 0x00 на 0x01.
![](https://habrastorage.org/getpro/habr/upload_files/31f/3c8/319/31f3c83192856840897492b2e4f5d40f.png)
Напишем патч на Python под версию Shadow Defender 1.4.0.648, который заменит байт 0x00 на 0x01 по уникальному для этого бинарного файла набору байт.
defender_path = "C:\\Program files\Shadow Defender\CmdTool.exe"
with open(defender_path, "rb") as reader:
defender_data = reader.read()
defender_data = defender_data.replace(b"\xC7\x84\x24\x6C\x04\x00\x00\x00\x00\x00\x00", b"\xC7\x84\x24\x6C\x04\x00\x00\x01\x00\x00\x00")
with open(defender_path, "wb") as writer:
writer.write(defender_data)
Проверяем. Работает!
![](https://habrastorage.org/getpro/habr/upload_files/a9e/663/713/a9e66371356a198cdbf3026f1799f237.jpg)
Надеюсь, вам понравилось это интеллектуальное упражнение. К тому же оно имеет практический выхлоп — позволит восстановить доступ к приложению с забытым паролем. Что касается Shadow Defender, мы сообщили об уязвимости.
Есть гипотетическая вероятность, что появится исправленная версия. Тем, кто уже использует это ПО стоит помнить, что описанным в статье способом можете воспользоваться не только вы. Как всегда, стоит учитывать риски работе с приложениями, разработка которых остановлена.