R0 CREW

Наномиты и техника «Debug Blocker» в приложениях Linux

Наномиты и техника «Debug Blocker» в приложениях Linux

Автор: Apriorit.inc
Перевод: keyst0rke

Введение

Продолжая исследование антиотладки, в этой статье мы исследуем один из современных методов борьбы с отладкой и дампингом, который основан на наномитах.

Этот приём впервые был введён в протекторе Armadillo для защиты приложений ОС Windows. В этой статье мы рассмотрим возможно применение этой техники в решении задач под ОС Linux.

Протектор Armadillo

Armadillo (также известен как SoftwarePassport) является коммерческим протектором с богатой историей развития. Первый выпуск состоялся 15 января 1999 года. Разработчиком протектора являлась фирма Silicon Realms, в качестве ведущего разработчика выступал Чарльз Нельсон.

Один из методов, используемых Armadillo являются наномиты.

Механизм работы наномитов в Armadillo

«Debug Blocker»

Armadillo использует защиту родительским процессом. В ОС Windows, процесс может отлаживаться только одним отладчиком пользовательского уровня. Это использовано в Armadillo. Сначла создаётся процесс, который в свою очередь порождает дочерний процесс и начинает его отлаживать. В результате, отлаживать можно только процесс-отладчик. Эта техника полчила назание «Debug Blocker».

«Armadillo Nanomites»

Программист, использующий Armadillo на стадии написания кода отмечает участки кода в исходном коде программы. Компилятор оставляет эти маркеры нетронутыми после компиляции. Это позволяет протектору найти код требующий защиты. После нахождения кода он вырезает его и программы и упаковывает. При распаковке программы, вырезанные участки кода записываются в выделенную память и на них осуществляются прыжки, это называется «jmp-вермишель».

Затем обрабатываются условные и безусловные переходы в защищаемой области. Вместо переходов (Jxx) устанавливаются отладочные прерывания INT3 (0xCC), также они могут устанавливаться произвольно, являясь мусорными прерываниями. Для обработки прерывания создаётся таблица, содержащая флаги, размер и смещение прыжка.

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

Этот метод — самое мощное оружие этого протектора, поскольку нет 100% надёжного средства борьбы с наномитами.

Борьба с наномитами

Существует три основных способа борьбы с наномитами. Первый из них - повторное навешивание отладочного процесса, либо включение VEH с последующим включением в код отладчика таблиц наномитов. По сути отладчик защиты заменяется отладчиком крэкера. Исследовать такую программу - не самое приятное занятие, отсутствие переходов и мусорные байты ломают работу почти всех анализаторов. Второй способ - запуск программы под анпакером или встроенным в распакованную программу отладчиком. Во время работы программы следует постараться воспользоваться как можно большим числом возможностей программы, попробовать разные комбинации возможных настроек. Так постепенно можно собрать информацию о “настоящих” наномитах и восстановить их. Поскольку все наномиты таким способом вряд ли можно восстановить, способ кобминируют с первым. Третий способ самый сложный в реализации - анализатор. Анализатор должен “выполнить” код и пройтись по всем его ветвлениям, а напарываясь на наномиты восстанавливать их по таблице. Сложность здесь возникает в обработке switch-таблиц, табличных вызовов (вызовы методов классов и конструкторов высокоуровневых языков выглядят на низком уровне, например
[COLOR=navy]call ds:[edx+410h][/COLOR]), а также API функций с параметрами-CALLBACK’ами.

Трудности реверсинга приложений, защищённых наномитами

  1. Debug blocker требует специального подхода. Мы не можем присоединиться с отладчиком к процессу, который уже отлаживается в третьем кольце. Единственная опция - нулевое кольцо, и это не очень удобно. Отсоединение родительского процесса возможно только после восстановления всей таблицы наномитов. Результат попытки присоединения отладчика к процессу, защищенному наномитами:

  1. Из-за отсутствия переходов в коде, приложение выглядит как сплошной кусок кода в дизассемблерах (например, IDA Pro), и это затрудняет любой анализ. Код выглядить следующим образом:

Недостатки использования наномитов

  1. Главный недостаток - производительность. Каждый раз, когда выполнение сталкивается с наномитом, контекст переключается, управление передаётся родительскому процессу. Эта процедура очень медлительна, поэтому лучше использовать наномиты в не критических по скорости участках кода.
  2. Этот механизм может конфликтовать с другими антиотладочными методами.

Исправления make-файлов защищенного проекта требуются для реализации этого механизма, и это не всегда удобно.

Описание проекта в Linux

Проект проектирован под 32-разрядные приложения Linux. Но принципы могут легко быть реализованы для других операционных систем, таким образом, запланировано и дальнейшее развитие.

Во-первых, мы будем смотреть на создание пользовательского отладчика для Linux. После этого мы будем двигаться к реализации наномитов. Binutils и Perl используются для компиляции проекта.

Мы применим комбинацию двух методов: Наномиты и Debug Blocker.

Основная идея

Библиотека Linux Code Protection включает 2 основных компонента:

  • Nanomites: статическая библиотека, которая содержит отладчик, обрабатывает логику.
  • Debugger Nanomites: исполняемый файл отладчика, собран с библиотекой Nanomites.

Есть также набор скриптов для добавления наномитов к приложению и для создания таблицы наномитов.

Пошаговое создание защищённого приложения

Приложение с ключом –S для создания ассемблерного листинга создано;

Ассемблерный листинг проанализирован Perl скриптом. Все переходы и вызовы (например, jmp, jz, jne, call, и т.д.) обработаны и заменены instructionOffsetLabel (N): int 3;

После этого пользовательское приложение, которое состоит из измененных ассемблерных вставок, собрано. С помощью сценария Perl проанализировано собранное приложение, и таблица наномитов создана.

Описание библиотеки отладчика

Наш отладчик основывается на ptrace (трассировка процесса), который существует в некоторых подобных Unix системах (включая Linux, FreeBSD, Mac OS X). Он позволяет отлаживать выбранный процесс. Можно сказать, что ptrace обеспечивает полный контроль над процессом: мы можем изменить поток выполнения приложения, дисплей и изменить значения в состояниях реестра или памяти. Нужно упомянуть, что нам не предоставляется никаких дополнительных прав: возможные действия ограничены полномочиями запущенного процесса. Кроме того, когда программа с setuid трассируется, бит привелегий не работает, поскольку права не передаются.

После того, как демо приложение обработано скриптами, это весьма зависимо, и если это запущено без отладчика, «отказ сегментации» появляется сразу. Отладчик запускает демонстрационное приложение с этого времени. С этой целью дочерний процесс создается в отладчике, и затем родительский процесс присоединяется к нему. Все события отладки от дочернего процесса обработаны в цикле. Это включает все события перехода; родительский процесс анализирует nanomite таблицу и таблицу флагов, чтобы выполнить корректное действие.

Преимущество решения по сравнению с Armadillo

В Armadillo изменен бинарный код. Поэтому когда 2/5-байтовый прыжок заменён более короткой 1-байтовой инструкцией INT 3 (0xCC), остается свободное место. Соответственно, мы можем и должны записать исходную команду перехода вместо INT 3, чтобы восстановить наномит.

В нашем решении мы изменяем код на уровне исходного кода. Поэтому размер наномита будет равен 1 байту. Соответственно, восстановить наномит, просто переписав его на исходный прыжок не возможно. И мы не можем расширить размер, выделенный под наномит, поскольку все относительные переходы были бы повреждены. Но есть способ восстановить наш наномит, например ниже.

Восстановление наномитов в Linux

Хакер может создать дополнительный раздел в исполняемом файле, затем найти наномит и получить его команду перехода и соответственно адрес перехода.

Тогда восстановление произойдёт следующим образом:

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

Оффициальный сайт проекта - apriorit.com

Конечно технология вызывает академический интерес, но практическое применение имеет слишком много минусов. Что косается обхода различных реализаций наномитов мне кажется очень круто было бы заюзать DBI инструментарий для этого.

А и еще, если я не ошибаюсь то эта статья уже была на русском на сайте codingskills.biz или то была похожая

По-моему, наномиты это отличное решение, которые относительно других, слабо влияет на быстродействие, зато обеспечивает, по крайней мере, геморрой исследователю.
Статья от 23 июля 2013 года, так что врятли он уже была переведена. Хотя не исключено.

Вот нашел где я видел часть этой статьи https://www.youtube.com/watch?v=_DMbMUu1urU

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

Как аналог похожей схемы можно попробывать замутить такое в контексте своего процесса используя SEH(если речь про win). Например используя маркеры пометить нужный участок, вынуть этот код, мутировать и разбавить мусором чтобы увеличить в размере и добавить доп. ветвления, накинуть наномиты с обработчиком в SEH. Да тут потеряется антиотладка, но зато шустрее будет работать и реверсить\дампить будет не в кайф.

Этот чувачёк скомуниздил часть статьи из вики крэклаба (http://www.cracklab.ru/faq/Armadillo), про борьбу. Только заметил.
Я сейчас в свободное время занимаюсь переводом статей из CodeProject, так вот в какой-то из них, не нашёл в какой именно, говорилось, что использование наномитов это лучшее решение в купе “Качество защиты - скорость исполнения”.
P.S. а почему бы не сделать вики R0Crew? Было бы не лишним :slight_smile:

А кто туда будет писать? У кряклаба комунити побольше, но всё равно вики никто не заполняет.

У нас проектов и идей куча, нет человеческих ресурсов на поддержку. Например, есть та же вики для реверсеров:

http://ru.und3rgr0und.org/RCE

Недавно поступила идея, которая заключается в задействовании студентов в развитии наших вики-проектов. Правда, для этого нам нужно будет их как-то материально за мотивировать. Предлагается вариант с выплатой денежной суммы равной размеру стипендии. Пока это всё только планы и в этом году реализовываться не будет. Но, возможно, уже в следующем году, мы что-то придумаем по этому поводу… Всё упирается в финансы, которые идут исключительно из кармана администраторов форума (ximera, root), которые как бы далеко не миллионеры. Плюс, до конца года, запланирована поддержка двух “бета-конференций форума”, с довольно таки приличным уставным фондом.

Абсолютно поддерживаю вышеизложеное, самому хотелось бы сделать как можно больше, но к сожалению человеческих ресурсов очень мало, в основном люди приходят познают и уходят дальше. Мы делаем все что в наших силах для достижения светлого будущего!