
MD5-Monomorphic Shellcode Packer - все полезные нагрузки имеют одинаковый MD5-хеш
════════════════════════════════════╦═══
╔═╦═╗ ╔═╗ ╔═╗ ╔═╗ ╔═╦═╗ ╔═╗ ╔══╔═╗ ╠═╗
═╩ ╩ ╩═╚═╝═╩ ╩═╚═╝═╩ ╩ ╩═╚═╝═╩ ╠═╝═╩ ╩═
════════════════════════════════╩═══════
От Retr0id
═══ MD5-Мономорфный упаковщик шеллкода ═══
ИСПОЛЬЗОВАНИЕ: python3 monomorph.py input_file output_file [payload_file]
## Что он делает?
Он упаковывает до 4 КБ сжатого шеллкода в исполняемый бинарный файл почти мгновенно. Выходной файл *всегда* будет иметь один и тот же MD5-хеш: `3cebbe60d91ce760409bbe513593e401`
В настоящее время поддерживается только Linux x86-64. Перенос этой техники на другие платформы тривиален, хотя каждая версия будет иметь разный MD5. Также возможно использование мультиплатформенного полиглот-файла, такого как [APE](https://justine.lol/ape.html).
Пример использования:
$ python3 monomorph.py bin/monomorph.linux.x86-64.benign bin/monomorph.linux.x86-64.meterpreter sample_payloads/bin/linux.x64.meterpreter.bind_tcp.bin
## Зачем?
Люди [ранее](https://www.mscs.dal.ca/~selinger/md5collision/) использовали одиночные коллизии для переключения бинарного файла между «хорошим» и «злым» режимами. Мономорф выводит эту концепцию на новый уровень.
Некоторые люди до сих пор настаивают на использовании MD5 для ссылок на образцы файлов по разным причинам, которые мне не понятны. Если кто-то из них в итоге будет исследовать код, упакованный с помощью Monomorph, они сильно запутаются.
## Как это работает?
Для каждого бита, который мы хотим закодировать, был предварительно рассчитан коллизионный MD5-блок с помощью [FastColl](https://github.com/cr-marcstevens/hashclash/tree/master/src/md5fastcoll). Как резюмировано [здесь](https://github.com/corkami/collisions/tree/master/hashquines#read-an-encoded-value), каждая коллизия даёт нам пару блоков, которые можно заменять без изменения общего MD5-хеша. Загрузчик проверяет, какой блок был выбран во время выполнения, чтобы декодировать бит.
Чтобы закодировать 4 КБ данных, нам нужно сгенерировать 4\*1024\*8 коллизий (на это уходит несколько часов), что занимает 4 МБ места в конечном файле.
Для ускорения я внёс небольшие изменения в FastColl, чтобы сделать его ещё быстрее на практике, что позволяет запускать его параллельно. Я уверен, что есть более умные способы распараллеливания, но мой наивный подход заключается в одновременном запуске N экземпляров и ожидании завершения первого, после чего убиваются все остальные.
Поскольку я уже выполнил предварительные вычисления, перенастройка полезной нагрузки может быть выполнена почти мгновенно. Переключение состояния предварительно вычисленных блоков выполняется с помощью [техники](https://github.com/corkami/collisions/blob/master/hashquines/scripts/collisions.py), реализованной Анже Альбертини.
## Это обнаруживаемо?
Да. Это совсем не скрытно, да и не ставит целью быть таковым. Вы можете обнаружить коллизионные блоки с помощью [detectcoll](https://github.com/cr-marcstevens/hashclash/tree/collisiondetection/src/collisiondetection).