187 064 инструкции мусора: как мы взломали HTB Callfuscated с помощью самодельного эмулятора
Статический анализатор crackme с платформы Hack The Box (HTB) уровня Insane по имени Callfuscated выплёвывает 187 064 инструкции мусорного кода. Разобрать такую порцию вручную — безумие. Автор статьи на Хабре пошёл другим путём: написал собственный ptrace-трассировщик, затем создал валидируемый x86-

Статический анализатор crackme с платформы Hack The Box (HTB) уровня Insane по имени Callfuscated выплёвывает 187 064 инструкции мусорного кода. Разобрать такую порцию вручную — безумие. Автор статьи на Хабре пошёл другим путём: написал собственный ptrace-трассировщик, затем создал валидируемый x86-64 эмулятор на Python, снял дампы памяти и свёл сложную VM-обфускацию к арифметике первого курса. Результат — флаг HTB, полученный без брутфорса и без ручного разбора тонн ассемблера.
Как работает VM-обфускация в Callfuscated
Callfuscated — это crackme, в котором настоящая логика спрятана за виртуальной машиной (VM). Вместо того чтобы выполнять код напрямую, программа интерпретирует байт-код, раздувая количество инструкций в сотни тысяч раз. Каждая операция превращается в десятки переходов, вызовов и проверок. Статический анализ бесполезен: дизассемблер показывает 187 064 инструкции, но 99% из них — мусор, который никогда не влияет на результат.
Автор решил не разбирать мусор, а перехватить выполнение на уровне системных вызовов. Он написал трассировщик на основе ptrace — стандартного механизма Linux для отладки. Трассировщик записывал все инструкции, которые действительно выполнялись, игнорируя мёртвый код. Это сразу сократило объём в десятки раз: осталось около 10 000 реально исполненных инструкций.
Но и этого было много. Тогда автор пошёл дальше: написал эмулятор x86-64 на Python, который не просто исполнял код, а верифицировал каждый шаг. Эмулятор мог воспроизводить выполнение байт-кета VM, записывать состояния регистров и памяти, а затем сравнивать с эталоном. Это позволило выявить, какие именно инструкции VM отвечают за проверку флага.
Чем самодельный эмулятор отличается от готовых решений
Готовые эмуляторы вроде Unicorn или QEMU — мощные, но для такого таска они слишком тяжёлые и не дают гибкости. Автор написал свой эмулятор на чистом Python, реализовав только нужные инструкции: mov, add, sub, cmp, jmp и несколько других. Эмулятор был валидируемым — то есть каждую инструкцию можно было проверить на корректность, сравнив результат с реальным процессором.
Ключевая фишка: эмулятор умел делать дампы памяти в ключевых точках. Вместо того чтобы трассировать каждую инструкцию, автор ставил точки останова на определённые адреса VM и снимал снимки состояния. Это позволило выделить участки кода, которые обрабатывают введённый пользователем флаг.
После анализа дампов выяснилось, что VM выполняет простую арифметику: складывает, вычитает и сравнивает байты флага с заранее заданными константами. Никакой криптографии, никаких сложных алгоритмов — только запутанный поток управления. Автор восстановил алгоритм проверки флага, написав скрипт, который эмулировал VM в обратном направлении и восстанавливал входные данные.
Как написать эмулятор для обфусцированного кода
Создание собственного эмулятора может показаться сложным, но на самом деле это посильная задача для любого разработчика, знакомого с ассемблером x86-64. Первым шагом автор определил минимальный набор инструкций, которые реально используются в VM. Затем он реализовал их на Python, используя словари для регистров и байтовые массивы для памяти. Валидация проводилась путём сравнения состояния эмулятора с состоянием реального процессора после каждого шага — для этого использовался ptrace. Такой подход гарантирует, что эмулятор не вносит ошибок и точно повторяет поведение оригинального кода.
Кого затронет и как
Разбор Callfuscated — не просто развлечение для хакеров. Он демонстрирует, что даже самые запутанные VM-обфускации можно взломать динамическим анализом. Разработчики защитного ПО (крипторы, упаковщики, античит-системы) часто используют подобные техники, чтобы затруднить реверс-инжиниринг. Статья показывает, что ptrace-трассировка в сочетании с кастомным эмулятором — эффективный способ борьбы с VM-обфускацией.
Для русскоязычного сообщества это особенно ценно: автор подробно описал код на Python, который можно адаптировать под свои задачи. Если вы занимаетесь реверс-инжинирингом малвари или защитой своего софта, этот подход поможет вам быстрее анализировать образцы с VM-обфускацией.
Что будет дальше
Автор планирует выложить код эмулятора и трассировщика в открытый доступ, чтобы любой желающий мог повторить эксперимент. Вероятно, вскоре появятся и другие решения для HTB Callfuscated, но это — одно из самых элегантных. В долгосрочной перспективе такие методы могут лечь в основу автоматизированных инструментов для деобфускации, которые будут использоваться в CTF и при анализе вредоносного ПО.
Итог
187 064 инструкции мусора — не приговор. Используя ptrace-трассировщик и самодельный эмулятор на Python, автор свёл сложную VM-обфускацию к простой арифметике и получил флаг HTB. Этот разбор — отличный пример того, как динамический анализ побеждает статический, и полезный кейс для всех, кто занимается реверс-инжинирингом.