
Забавные вещи против злоупотребления недавней уязвимостью CVE-2021-44228 (Log4Shell) с использованием обычных веб-серверов.
Забавные вещи против злоупотребления недавней уязвимостью CVE-2021-44228 (Log4Shell) с использованием обычных веб-серверов.
Основано на посте @shipilev (https://gist.github.com/shipilev/92e709a868f3d328b6636e1bfc21cf09). Я портировал его пример на Apache2. Мой коллега сделал это для Lighttpd. Я решил сделать наши примеры общедоступными для удобства.
Есть лишь несколько причин помещать строку "jndi:" в заголовки запросов, User Agents или куда-либо ещё. В настоящее время я знаю только одну причину это делать: эксплуатация CVE-2021-44228. Пока мир, надеюсь, занят исправлением всех реализаций уязвимых версий Log4j, было бы разумно максимально замедлить атакующих. Так почему бы не отдавать им гигабайты бессмыслицы, пока они пытаются эксплуатировать ваши сервисы?
Следующие фрагменты кода не защищают ваши устройства и сервисы от 0-Day уязвимости Log4Shell! Пожалуйста, обновите уязвимое программное обеспечение, используйте log4j2.formatMsgNoLookups=true для отключения jndi-поисков или отключите его от сети, пока не появится патч! Используйте это только на серверах без сервисов, использующих Log4j! Дополнительная информация о том, как смягчить CVE-2021-44228: https://research.hisolutions.com/log4shell
Это также не будет охватывать обфусцированные вызовы, такие как ${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://${hostName}.} или всё остальное, что пытается скрыть часть "jndi:". Поскольку простого решения для этого нет, я пока не буду рассматривать более продвинутые методы обнаружения. Я всё ещё верю, что большинство атак не будут использовать такие методы, поэтому мы всё ещё можем досадить большинству скрипт-кидди. :)
В Linux создайте файл с каким-нибудь случайным HTML-сообщением. Пожалуйста, не используйте LOL из примера ниже, так как это облегчает атакующему реализацию общего фильтра для обхода нас. Мы используем утилиту pv для отображения прогресса создания файла; возможно, вам придётся установить её через ваш любимый менеджер пакетов или просто опустить эту часть.
$ awk 'BEGIN { for(c=0;c<10000000;c++) printf "<p>LOL</p>" }' > 100M.html
$ (for I in `seq 1 100`; do cat 100M.html; done) | pv | gzip -9 > 10G.boomgz
$ rm 100M.html
Предполагая, что ваш веб-сервер работает от имени www-data, создадим каталог, принадлежащий www-data, чтобы не загружать копию в каждый корень веб-сервера, который он, возможно, обслуживает:
mkdir /bombs
mv 10G.boomgz /bombs
chown -R www-data:www-data /bombs
Теперь самое интересное...
См. https://gist.github.com/shipilev/92e709a868f3d328b6636e1bfc21cf09
Все заслуги принадлежат @shipilev
Включите необходимые модули
a2enmod rewrite headers ratelimit
Перейдите в /etc/apache2/sites-enabled. Откройте каждый файл конфигурации хоста вашим любимым редактором и вставьте следующий фрагмент кода прямо над каждой строкой, содержащей (их может быть больше одной):
RewriteEngine On
RewriteCond %{THE_REQUEST} "^.*(\${jndi|\${\${).*$" [OR]
RewriteCond %{QUERY_STRING} "^.*(\${jndi|\${\${).*$" [OR]
RewriteCond %{REQUEST_URI} "^.*(\${jndi|\${\${).*$" [OR]
RewriteCond %{HTTP_COOKIE} "^.*(\${jndi|\${\${).*$" [OR]
RewriteCond %{HTTP_HOST} "^.*(\${jndi|\${\${).*$" [OR]
RewriteCond %{REMOTE_HOST} "^.*(\${jndi|\${\${).*$" [OR]
RewriteCond %{REMOTE_USER} "^.*(\${jndi|\${\${).*$" [OR]
RewriteCond %{HTTP_USER_AGENT} "^.*(\${jndi|\${\${).*$" [OR]
RewriteCond %{HTTP_REFERER} "^.*(\${jndi|\${\${).*$"
RewriteRule . /bombs/10G_lol.boomgz [L]
<Files ~ "\.boomgz$">
Header Set Expires "Sat, 1 Jan 2000 00:00:00 GMT"
Header Set Content-Encoding "gzip"
Header Set Content-Type "text/html"
SetOutputFilter RATE_LIMIT
SetEnv rate-limit 100
</Files>
<Directory /bombs>
allow from allow
Require all granted
</Directory>
Возможно, вы задаётесь вопросом, почему здесь так много переменных по сравнению с исходным примером от @shipilev. Я решил попытаться перехватить как можно больше мест. В очень редких случаях это может нарушить работу сервисов, поэтому если вы хотите использовать исходный набор проверок, просто закомментируйте или удалите первые 7 строк после оператора RewriteEngine On и уберите части |\${\${ в оставшихся строках.
Вы также можете поместить код в новый файл, например /etc/apache2/conf-available/anti-jndi.conf и подключить его так:
Include /etc/apache2/conf-available/anti-jndi.conf
Теперь сохраните файл(ы) и перезагрузите конфигурацию Apache2:
systemctl reload apache2
Если всё прошло хорошо, вы не должны получить сообщение об ошибке.
Скоро будет
Вы можете проверить, всё ли получилось, подключившись к вашему изменённому сайту через curl (не забудьте заменить your-hostname на реальное имя хоста одного из сервисов, которые вы только что отредактировали):
curl -s -L your-hostname -A "\${jndi:testing}" | pv > /dev/null
Вы должны увидеть индикатор прогресса, показывающий скорость загрузки около 100 КБ/с. Если вы не отмените его, он должен завершиться через несколько минут, в зависимости от того, какую строку вы использовали в исходном HTML-файле. У меня это заняло около 5 минут. Теперь проверьте, что происходит на стороне клиента:
curl -s --compressed -L your-hostname -A "\${jndi:testing}" | pv > /dev/null
Видите, что скорость уже не 100 КБ/с? Сжатие творит чудеса, на стороне клиента это гигабайты. Таким образом, после загрузки кучи бессмыслицы в течение нескольких минут у атакующего будет лежать несколько гигабайт (если данные сохраняются для анализа). Кто знает? :)