
Rogue RMI Registry — эксплуатация небезопасной десериализации Java через методы list/lookup/bind. Генерирует и доставляет гаджеты Ysoserial для запуска удаленного выполнения кода на уязвимых клиентах.
Ermir — это злонамеренный/подставной RMI-реестр, который эксплуатирует небезопасную десериализацию в любом Java-коде, вызывающем стандартные методы RMI (list()/lookup()/bind()/rebind()/unbind()).
Установите Ermir из rubygems.org:
$ gem install ermir
или клонируйте репозиторий и соберите gem:
$ git clone https://github.com/hakivvi/ermir.git
$ rake install
Ermir — это cli gem, который поставляется с двумя cli-файлами: ermir и gadgetmarshal. ermir — это сам gem, а второй — просто удобный интерфейс к файлу GadgetMarshaller.java, который переписывает гаджеты из Ysoserial для соответствия требованиям MarshalInputStream. Затем вывод должен быть направлен через конвейер в ermir или в файл. В случае пользовательских гаджетов используйте MarshalOutputStream вместо ObjectOutputStream для записи вашего сериализованного объекта в выходной поток.
ermir использование:
➜ ~ ermir
Ermir by @hakivvi * https://github.com/hakivvi/ermir.
Info:
Ermir is a Rogue/Evil RMI Registry which exploits unsecure Java deserialization on any Java code calling standard RMI methods on it.
Usage: ermir [options]
-l, --listen bind the RMI Registry to this ip and port (default: 0.0.0.0:1099).
-f, --file path to file containing the gadget to be deserialized.
-p, --pipe read the serialized gadget from the standard input stream.
-v, --version print Ermir version.
-h, --help print options help.
Example:
$ gadgetmarshal /path/to/ysoserial.jar Groovy1 calc.exe | ermir --listen 127.0.0.1:1099 --pipe
gadgetmarshal использование:
➜ ~ gadgetmarshal
Usage: gadgetmarshal /path/to/ysoserial.jar Gadget1 cmd (optional)/path/to/output/file
java.rmi.registry.Registry предоставляет 5 методов: list(), lookup(), bind(), rebind(), unbind():
public Remote lookup(String name): метод lookup() ищет привязанный объект в реестре по его имени, реестр возвращает объект Remote, который ссылается на удаленный объект, который был найден. Возвращенный объект читается с помощью MarshalInputStream.readObject(), который является еще одним слоем поверх ObjectInputStream. В основном он ожидает после каждого дескриптора класса/прокси (TC_CLASSDESC/TC_PROXYCLASSDESC) URL-адрес, который будет использоваться для загрузки этого класса или класса-прокси. Это та же самая дикая ошибка, которая была исправлена в jdk7u21. (Ermir не указывает этот URL-адрес, так как уязвимы только старые версии Java; вместо этого он просто записывает null). Поскольку гаджеты Ysoserial сериализуются с помощью ObjectOutputStream, Ermir использует gadgetmarshal — обертку вокруг GadgetMarshaller.java — для сериализации указанного гаджета в соответствии с требованиями .

Сообщения об ошибках и запросы на слияние приветствуются на GitHub по адресу https://github.com/hakivvi/ermir. Этот проект предназначен для безопасного и гостеприимного пространства для сотрудничества, и от участников ожидается соблюдение кодекса поведения.
Gem доступен в качестве открытого исходного кода на условиях лицензии MIT.
Все, кто взаимодействует в кодовой базе, трекерах проблем, чатах и списках рассылки проекта Ermir, должны следовать кодексу поведения.
MarshalInputStream
public String[] list(): метод list() запрашивает у реестра имена всех привязанных объектов. Тип String не может быть заменен вредоносным гаджетом, так как он не является обычным объектом и читается не через readObject(), а через readUTF(). Однако, поскольку list() возвращает String[], который является реальным объектом и читается с помощью readObject(), Ermir отправляет гаджет вместо этого типа String[].

public void bind(java.lang.String $param_String_1, java.rmi.Remote $param_Remote_2): bind() привязывает объект к имени в реестре. В случае bind() возвращаемый тип — void, и ничего не возвращается. Однако, если реестр указывает в пакете возвращаемых данных RMI, что это возврат является исключительным, клиент/сервер вызовет readObject(), несмотря на то, что возвращаемый тип — void. Так реестр отправляет исключения своему клиенту (обычно java.lang.ClassNotFoundException). И снова Ermir доставит сериализованный гаджет вместо легитимного объекта исключения.

public void rebind(java.lang.String $param_String_1, java.rmi.Remote $param_Remote_2): rebind() заменяет привязку переданного имени на указанную удаленную ссылку, также возвращает void. Ermir возвращает исключение, как и в случае с bind().
public void unbind(java.lang.String $param_String_1): unbind() отвязывает удаленный объект по имени в RMI-реестре, этот метод также возвращает void.