
A Smart Log4Shell/Log4j/CVE-2021-44228 Scanner
Хотя было выпущено несколько отличных инструментов, помогающих организациям сканировать свои среды на предмет приложений, уязвимых к критической уязвимости Log4J / CVE-2021-44228, я посчитал, что:
Так родился Log4Shell Sentinel. Log4Shell Sentinel — это файловый сканер с некоторыми уникальными возможностями. Он не предназначен для замены всех остальных доступных инструментов, но может их дополнять.
Log4Shell Sentinel — это файловый сканер. Он ищет Java-приложения, сканируя целевую систему на наличие артефактов следующих форматов файлов:
| Тип файла | Описание |
|---|---|
| Простой jar | Случай, когда файл log4j-core не встроен. |
| Fat / Uber jar | Uber jar — это jar, который содержит как ваши классы/пакет, так и все зависимости вашего приложения (библиотеки, ресурсы и метаданные) в одном файле jar. Это наиболее часто используемый вариант развёртывания. |
| WAR | Файл war (Web Application Archive) содержит ваш код JSP, HTML и JavaScript, а также библиотеки и другие ресурсы. Этот формат используется реже. |
| EAR | EAR (Enterprise Application Archive) — ещё один формат, который чаще использовался с Jakarta EE для развёртывания. |
и ищет экземпляры уязвимых jar-файлов log4j-core. Затем он:
вычисляет MD5-хэш артефакта. Это позволяет аналитику идентифицировать одно и то же приложение, работающее на разных машинах/контейнерах, и рассматривать их как одну находку.
для файлов, определённых как принадлежащие контейнеру, например: /var/lib/docker/overlay2/192768f471818601094bf4edd96d14bfc0e2b178a04a2efd00b2231ad4e46b33/merged/app/spring-boot-application.jar, выполняет сложную работу по сопоставлению файла с соответствующим образом. Например, он преобразует вышеуказанное в следующий образ: ghcr.io/christophetd/log4shell-vulnerable-app:latest. Поскольку различные среды выполнения контейнеров хранят это сопоставление по-разному, это может сэкономить аналитику часы разочарований. Это также позволяет аналитику рассматривать несколько контейнеров, запускающих одно приложение, как одну находку.
удаляет бесполезные совпадения, такие как совпадения, соответствующие контейнерам, которые в данный момент не запущены, включая кэшированные образы. Это позволяет аналитику сосредоточиться на важном и снова экономит часы ненужной работы.
позволяет аналитику игнорировать совпадения на основе:
Это позволяет аналитику удалить приложения, которые, как известно, не являются уязвимыми, или которые соответствуют приложениям командной строки, не представляющим угрозы. Например, если обнаружен экземпляр Logstash, аналитик может решить игнорировать его, если они не используют этот инструмент или запускают его только время от времени из командной строки.
оптимизирован для работы с вашими инструментами управления конфигурацией, такими как Ansible, что позволяет быстро сканировать вашу среду за считанные минуты.
Подробнее об обогащении метаданными, добавленном Log4Shell Sentinel, читайте в моём блог посте.
Самый простой способ — просто скачать предварительно скомпилированный бинарный файл.
Опять же, это просто. Однако, скорее всего, вы захотите собрать статически скомпилированную версию, чтобы обойти любые различия, связанные с GLIBC в вашей среде. Инструмент использует следующие модули, которые по умолчанию используют CGO:
os/usernetЧтобы собрать статически скомпилированную версию, использующую Go-версии этих библиотек, просто клонируйте репозиторий, а затем выполните:
$ CGO_ENABLED=0 go build -ldflags="-s -w"
$ ldd log4shell_sentinel
not a dynamic executable
$ ./log4shell_sentinel -h
NAME:
Log4Shell Sentinel - by Osama Elnaggar
USAGE:
log4shell_sentinel [global options] command [command options] [arguments...]
VERSION:
v1.0.0
COMMANDS:
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--path value, -p value Path to search (default: ".")
--no-banner, --nb Suppress banner (default: false)
--no-messages, --nm Suppress messages except for CSV output (default: false)
--no-header, --nh Suppress header in CSV output (default: false)
--imd5 value, --im value Ignore MD5 hashes. Refer to the GitHub page for expected format
--ipath value, --ip value Ignore file path matches. Refer to the GitHub page for expected format
--icimage value, --ic value Ignore container image matches. Refer to the GitHub page for expected format
--print-headers, --ph Print CSV Headers only (default: false)
--help, -h show help (default: false)
--version, -v print the version (default: false)
Из коробки сканирование просто сканирует текущую директорию. Например:
$ ./log4shell_sentinel
░█░░░█▀█░█▀▀░█░█░█▀▀░█░█░█▀▀░█░░░█░░░░░█▀▀░█▀▀░█▀█░▀█▀░▀█▀░█▀█░█▀▀░█░░
░█░░░█░█░█░█░░▀█░▀▀█░█▀█░█▀▀░█░░░█░░░░░▀▀█░█▀▀░█░█░░█░░░█░░█░█░█▀▀░█░░
░▀▀▀░▀▀▀░▀▀▀░░░▀░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░░░▀▀▀░▀▀▀░▀░▀░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀
- A CVE-2021-44228/CVE-2021-45046/CVE-2021-45105 Scanner
- v1.0.0
- by Osama Elnaggar
[*] WARNING: Running as non-root user.
Non-readable files / dirs will be skipped
Container mapping will fail
[*] Starting shallow scan ............ [DONE]
[*] Starting deep scan ............... [DONE]
[*] Calculating MD5 hashes ........... [DONE]
[*] Performing container image lookups [DONE]
[*] Processing ignore list(s) ........ [DONE]
[*] Generating output ................ [DONE]
IP,Hostname,AppName,Team,Ignore (Y/N),Comments,MD5Hash,Timestamp,Container,ContainerImage,FullPath,Version
192.168.121.121,server3,,,,,4e615cd580758b70c49ade1f79103328,2021-12-21T07:38:09Z,true,ghcr.io/christophetd/log4shell-vulnerable-app:latest,/run/containerd/io.containerd.runtime.v2.task/k8s.io/dc2c9c214809f506283c917244cd126a9b056ac7274322d12b59c9196d95dd9b/rootfs/app/spring-boot-application.jar,log4j-core-2.14.1.jar
Вы сразу получите ПРЕДУПРЕЖДЕНИЕ, если запустите его от имени непривилегированного пользователя, так как для работы требуются права root:
Он будет работать и без прав root, но может не дать наилучших результатов.
Пример находки выглядит так:
IP,Hostname,AppName,Team,Ignore (Y/N),Comments,MD5Hash,Timestamp,Container,ContainerImage,FullPath,Version
192.168.121.121,server3,,,,,4e615cd580758b70c49ade1f79103328,2021-12-21T07:38:09Z,true,ghcr.io/christophetd/log4shell-vulnerable-app:latest,/run/containerd/io.containerd.runtime.v2.task/k8s.io/dc2c9c214809f506283c917244cd126a9b056ac7274322d12b59c9196d95dd9b/rootfs/app/spring-boot-application.jar,log4j-core-2.14.1.jar
Некоторые поля намеренно оставлены пустыми и предназначены для заполнения аналитиком в Excel и т.д. Краткое описание каждого поля приведено ниже:
Инструмент имеет следующие параметры:
Одна из уникальных особенностей Log4Shell Sentinel, не встречающаяся ни в одном другом инструменте, — это возможность переводить jar-файлы, найденные при сканировании файловой системы, такие как:
/var/lib/docker/overlay2/192768f471818601094bf4edd96d14bfc0e2b178a04a2efd00b2231ad4e46b33/merged/app/spring-boot-application.jar
в соответствующий образ контейнера (вышеуказанное, например, преобразуется в ghcr.io/christophetd/log4shell-vulnerable-app:latest). Поскольку различные среды выполнения контейнеров хранят это сопоставление по-разному, это может сэкономить аналитику часы разочарований. Это также позволяет аналитику рассматривать несколько контейнеров, запускающих одно приложение, как одну находку. Решение в настоящее время поддерживает следующие поиски:
Количество выявленных приложений может сначала оказаться ошеломляющим, или вы можете захотовать сосредоточиться на определённом подмножестве выявленных приложений, например, на тех, которые доступны внешним пользователям. Или вы можете захотеть сосредоточиться на определенной области соответствия. Для поддержки этого приложение поддерживает указание списка. Log4Shell в настоящее время поддерживает 3 списка игнорирования:
Вместо простых списков он ожидает ввод в виде CSV-файла. Это побуждает аналитика документировать, почему они игнорируют конкретную находку. По мере того как аналитик обрабатывает находки и выявляет неуязвимые приложения с помощью ручного или автоматизированного анализа исходного кода, инструментов DAST и т.д.
Список представляет собой простой CSV-файл в следующем формате:
MD5Sum,AppName,Reason
Столбцы AppName и Reason могут быть пустыми, но они предназначены для того, чтобы вы могли отслеживать, почему вы включаете или исключаете конкретные приложения.
ПРИМЕЧАНИЕ: Поскольку эта функция использует MD5-хэш, вычисленный для приложения, она будет работать только для приложений, которые являются fat / uber jar, EAR или WAR.
Например, если у нас есть следующая находка:
IP,Hostname,AppName,Team,Ignore (Y/N),Comments,MD5Hash,Timestamp,Container,ContainerImage,FullPath,Version
192.168.121.121,server3,,,,,4e615cd580758b70c49ade1f79103328,2021-12-21T07:38:09Z,true,ghcr.io/christophetd/log4shell-vulnerable-app:latest,/run/containerd/io.containerd.runtime.v2.task/k8s.io/dc2c9c214809f506283c917244cd126a9b056ac7274322d12b59c9196d95dd9b/rootfs/app/spring-boot-application.jar,log4j-core-2.14.1.jar
и мы определили, что приложение не уязвимо, мы можем просто сохранить следующее в hashes.csv:
4e615cd580758b70c49ade1f79103328,Demo App,Not vulnerable
а затем перезапустить:
# ./log4shell_sentinel --im hashes.csv --path /
вышеуказанная находка будет подавлена.
Список представляет собой простой CSV-файл в следующем формате:
Container Image,AppName,Reason
Основываясь на предыдущем примере, мы можем указать игнорировать любую находку, где образом контейнера является: ghcr.io/christophetd/log4shell-vulnerable-app:latest, создав файл images.csv следующего содержания:
ghcr.io/christophetd/log4shell-vulnerable-app:latest,,
а затем запустив его:
# ./log4shell_sentinel --ic images.csv -p /
Опять же, наша предыдущая находка будет подавлена.
Опять же, это простой CSV-файл в следующем формате:
Path,AppName,Reason
Используя приведённый выше пример, если мы создадим следующий файл paths.csv:
/run/containerd/io.containerd.runtime.v2.task/k8s.io/dc2c9c214809f506283c917244cd126a9b056ac7274322d12b59c9196d95dd9b/rootfs/app/spring-boot-application.jar,Demo App,Not vulnerable
предыдущая находка будет подавлена.
ПРЕДУПРЕЖДЕНИЕ: По возможности лучше использовать MD5-хэш или имя образа контейнера для подавления, так как путь может быть не уникальным.
Хотя запуск Log4Shell Sentinel на одном сервере вполне нормально, он действительно раскрывается в сочетании с вашим любимым инструментом управления конфигурацией (Ansible, Chef, Puppet, Salt, AWS SSM и т.д.) или даже простыми параллельными SSH-инструментами, такими как parellel-ssh.
Это даёт многочисленные преимущества, включая:
Полный пример этого в действии смотрите в моём блог посте
Смотрите раздел Массовое сканирование вашей среды.
root (требуется доступ к местам, где могут быть установлены ваши приложения), либо с тем, что вы указали правильный path. Рекомендуется запускать его от пользователя root и установить --path /.Начиная с версии v1.0.0, инструмент в настоящее время поддерживает сопоставление для следующих:
Если вы используете что-то другое, сопоставление работать не будет. Если вы используете один из вышеперечисленных, возможно, вы запускаете инструмент не от пользователя root, или используемые сокеты/файлы находятся в нестандартном расположении.
Разработано: Osama Elnaggar
| Поле | Пример | Описание |
|---|
| IP | 192.168.121.121 | Если у экземпляра несколько IP-адресов, добавляется основной IP |
| Hostname | server3 | Имя хоста |
| AppName | Оставляется пользователю для заполнения после завершения сканирования | |
| Team | Оставляется пользователю для заполнения после завершения сканирования | |
| Ignore (Y/N) | Оставляется пользователю для заполнения после завершения сканирования | |
| Comment | Оставляется пользователю для заполнения после завершения сканирования | |
| MD5Hash | 4e615cd580758b70c49ade1f79103328 | Уникальный отпечаток приложения |
| Timestamp | 2021-12-21T07:38:09Z | Временная метка выполнения сканирования. Полезна при агрегации нескольких сканирований одного хоста |
| Container | true | True = это контейнер |
| ContainerImage | ghcr.io/christophetd/log4shell-vulnerable-app:latest | Если обнаружен контейнер, это соответствующий образ |
| FullPath | /run/containerd/io.containerd. runtime.v2.task/k8s.io/.../spring-boot-application.jar | Полный путь к находке. В этом примере уязвимый JAR-файл является частью fat / uber jar |
| Version | log4j-core-2.14.1.jar | Обнаруженная версия log4j-core |
| Параметр | Описание |
|---|
--path value, -p value | Указывает, какие пути сканировать. По умолчанию сканирует текущую директорию. ВАЖНО: рекомендуется установить значение / для покрытия всей файловой системы |
--no-banner, --nb | Подавляет баннер |
--no-messages, --nm | Подавляет сообщения, такие как сообщения о прогрессе |
--no-header, --nh | Подавляет заголовок вывода CSV. Рекомендуется при запуске на нескольких серверах |
--imd5 value, --im value | Игнорировать MD5-хэши. Подробнее об этом в разделе Списки игнорирования |
--ipath value, --ip value | Игнорировать совпадения по пути к файлу. Подробнее об этом в разделе Списки игнорирования |
--icimage value, --ic value | Игнорировать совпадения по образу контейнера. Подробнее об этом в разделе Списки игнорирования |
--print-headers, --ph | Печатать только заголовки CSV. При запуске Log4Shell Sentinel на нескольких серверах и агрегации результатов обычно отключают вывод заголовков. Эта команда выводит только заголовок, чтобы вы могли добавить его в лист Excel |