Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
log4j-jndi-be-gone — Исправление на основе Java-агента Byte Buddy для CVE-2021-44228, уязвимости log4j 2.x «JNDI LDAP». | Kitploit
Инструменты/GitHubGitHub/nccgroup/log4j-jndi-be-gone
Оборонительные ИнструментыАнализ уязвимостейАнализ КодаЭксплуатацияБезопасность Цепочки Поставок
GitHubnccgroup/log4j-jndi-be-gone

log4j-jndi-be-gone

Исправление на основе Java-агента Byte Buddy для CVE-2021-44228, уязвимости log4j 2.x «JNDI LDAP».

Репозиторий
7216294 лет назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Сайт
Поделиться

log4j-jndi-be-gone

Исправление на основе Java-агента Byte Buddy для CVE-2021-44228, уязвимости log4j 2.x «JNDI LDAP».

Оно делает три вещи:

  • Отключает внутренний обработчик методов для строк формата jndi: («lookups»).
  • Записывает сообщение в System.err (т.е. stderr), указывающее, что была предпринята попытка log4j JNDI (включая строку формата, с санитизацией всех символов ${} для предотвращения транзитивных инъекций).
  • Разрешает строку формата в "(log4j jndi disabled)" в сообщении журнала (для предотвращения транзитивных инъекций).

Использование

Добавьте -javaagent:path/to/log4j-jndi-be-gone-1.0.0-standalone.jar в ваши команды java.

Примечание: Если у вас уже есть Byte Buddy в classpath, попробуйте использовать log4j-jndi-be-gone-1.0.0.jar.

$ java -javaagent:path/to/log4j-jndi-be-gone-1.0.0-standalone.jar -jar path/to/some.jar

Начиная с версии 1.1.0, log4j-jndi-be-gone по умолчанию пытается обрабатывать переупакованные (так называемые «shaded») версии log4j, которые могут быть встроены в JAR под альтернативным именем пакета, чтобы предотвратить конфликты между версией зависимости в приложении и версией той же зависимости в другой зависимости. Однако следует отметить, что log4j, похоже, нелегко переупаковывается под альтернативными именами/префиксами пакетов из-за использования рефлексии со статическими именами классов и/или именами классов из встроенных файлов конфигурации.

Это поведение можно отключить, указав =structureMatch=0 после пути к JAR-файлу агента в аргументе -javaagent:, например:

-javaagent:path/to/log4j-jndi-be-gone-1.0.0-standalone.jar=structureMatch=0

что приведёт к тому же поведению сопоставления, что и в 1.0.0 — простому точному сравнению строк с именем класса.

Получение log4j-jndi-be-gone

Вы можете собрать JAR с помощью ./gradlew (build/libs/log4j-jndi-be-gone-1.0.0(-standalone).jar) или скачать его со страницы релизов.

Совместимость

JAR-файл агента log4j-jndi-be-gone поддерживает Java 6-17+.

Сопоставление классов

Реализация начинает с сопоставления классов, чьи суффиксы совпадают с самыми внутренними подпакетами и именем класса org.apache.logging.log4j.core.lookup.JndiLookup, lookup.JndiLookup, поскольку можно обоснованно ожидать, что org.apache.logging.log4j.core был изменён правилами переупаковки, которые не стремились сохранить имена пакетов. Кроме того, вместо простого выполнения аналогичных проверок для всех остальных ожидаемых типов log4j, она гарантирует, что они также находятся в том же базовом пакете.

Затем реализация проходит по структуре всех идентифицированных потенциальных классов log4j lookup.JndiLookup, пытаясь проверить их на соответствие:

  • модификаторам самого класса
  • родительскому классу и/или реализованным интерфейсам (они различаются между версиями log4j)
  • аннотации org.apache.logging.log4j.core.config.plugins.Plugin, ожидаемой во всех версиях 2.x, включая параметры аннотации и их значения
  • методу lookup(), сопоставляя его модификаторы и сигнатуру типа (и игнорируя версию с 1 аргументом из 2.0)
  • методу convertJndiName(), сопоставляя его модификаторы и сигнатуру типа
  • полю CONTAINER_JNDI_RESOURCE_PATH_PREFIX, сопоставляя его модификаторы

Предостережения

  • log4j-jndi-be-gone не будет работать, если библиотека log4j была обфусцирована или если её пакеты/имена классов были изменены иначе, чем базовая переупаковка (т.е. «shading»).

    • К слову, log4j 2.x довольно негибкий в отношении переупаковки, так что неясно, насколько распространены такие практики.
  • log4j-jndi-be-gone-1.0.0-standalone.jar включает в себя Byte Buddy. Если вы уже используете Byte Buddy, у вас могут возникнуть с ним проблемы. Вместо этого попробуйте log4j-jndi-be-gone-1.0.0.jar, хотя учтите, что log4j-jndi-be-gone ожидает Byte Buddy 1.12.x. Начиная с версии 1.1.0, автономный JAR log4j-jndi-be-gone включает переупакованный Byte Buddy под собственным префиксом пакета. Это должно предотвратить любые конфликты.

  • Если вы заменили свои классы JndiLookup реализациями, которые пытаются создавать ловушки (honeypotting) или логировать вызовы lookup(), log4j-jndi-be-gone потенциально отключит их метод lookup, не давая им работать.

Пример

В каталоге tests/jnditest есть простой тестовый пример, где вызов логирования log4j передаёт строку формата JNDI LDAP. Он также настраивает собственный прослушиватель порта, чтобы определить, была ли предпринята попытка подключения со стороны log4j, и завершает тест ошибкой, если подключение было получено.

$ ./tests/jnditest/test-uninstrumented.sh

BUILD SUCCESSFUL in 1s
6 actionable tasks: 5 executed, 1 up-to-date

BUILD SUCCESSFUL in 1s
3 actionable tasks: 3 up-to-date
JUnit version 4.12
.16:08:49.547 [main] ERROR trust.nccgroup.jnditest.test.JndiTest - Hello, _${jndi:ldap://127.0.0.1:8899/evil}_!
E
Time: 0.929
There was 1 failure:
1) logging(trust.nccgroup.jnditest.test.JndiTest)
java.lang.AssertionError: jndi ldap connection received
	at org.junit.Assert.fail(Assert.java:88)
	at trust.nccgroup.jnditest.test.JndiTest.logging(JndiTest.java:55)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runners.Suite.runChild(Suite.java:128)
	at org.junit.runners.Suite.runChild(Suite.java:27)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runners.Suite.runChild(Suite.java:128)
	at org.junit.runners.Suite.runChild(Suite.java:27)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
	at org.junit.runner.JUnitCore.runMain(JUnitCore.java:77)
	at org.junit.runner.JUnitCore.main(JUnitCore.java:36)
	at trust.nccgroup.jnditest.Main.main(Main.java:24)

FAILURES!!!
Tests run: 1,  Failures: 1

$ ./tests/jnditest/test-instrumented.sh

BUILD SUCCESSFUL in 1s
6 actionable tasks: 5 executed, 1 up-to-date
Скачать инструмент