Реализация Zephyr WireGuard в subsys/net/lib/wireguard/wg_crypto.c неправильно обрабатывала пакеты поддержки активности. В wg_process_data_message() любое сообщение транспортных данных типа 4, полезная нагрузка которого составляла ровно 16 байт (пустой открытый текст плюс пустой тег Poly1305, т. е. подтверждение активности), принималось и возвращалось немедленно, прежде чем была вызвана функция wg_decrypt_packet(). Таким образом, тег аутентификации Poly1305 никогда не проверялся; единственными предыдущими шлюзами были поиск по индексу получателя в открытом виде (get_peer_keypair_for_index() в предоставленном злоумышленником data_hdr->receiver) и некриптографическая проверка действительности/истечения срока действия пары ключей.
Путь полностью доступен из сети: входящий UDP на порт WireGuard отправляется с помощью wg_input() на handle_transport_data(), а затем на wg_process_data_message(). 32-битный индекс получателя передается в виде открытого текста при подтверждении связи WireGuard и сообщениях данных, поэтому наблюдатель на пути изучает его напрямую, а злоумышленник на другом пути может перебрать его через порт UDP. Учитывая активный сеанс, действительный для получения этого индекса, злоумышленник может отправить 16-байтовую мусорную полезную нагрузку и принять ее, не обладая сеансовым ключом. При принятии неаутентифицированного сообщения уровень управления обнаружил поддельный сигнал NET_EVENT_VPN_CONNECTED (установив одноранговый узел->first_valid и уведомив любого прослушивателя net_mgmt) и увеличил статистику Keepalive-RX.
Влияние ограничивается целостностью этого сигнала состояния: никакой открытый текст не расшифровывается и не внедряется, ключ не раскрывается, а путь раннего возврата не обновляет конечную точку однорангового узла или таймеры жизнеспособности, поэтому нет никаких последствий для внедрения трафика, захвата сеанса или доступности. Исправление удаляет ранний возврат перед расшифровкой, поэтому 16-байтовая полезная нагрузка проходит через wg_decrypt_packet(), который проверяет тег Poly1305 по пустому открытому тексту, после чего следует существующая проверка предотвращения повторного воспроизведения; только проверенное, невоспроизведенное сообщение тогда распознается как подтверждение активности. Поддельные пакеты поддержки активности теперь не проходят проверку тегов и считаются ошибками расшифровки.
Показать оригинальное описание (EN)
Zephyr's WireGuard implementation in subsys/net/lib/wireguard/wg_crypto.c mishandled keepalive packets. In wg_process_data_message(), any type-4 transport-data message whose payload was exactly 16 bytes (an empty plaintext plus a bare Poly1305 tag, i.e. a keepalive) was accepted and returned immediately, before wg_decrypt_packet() was ever called. The Poly1305 authentication tag was therefore never verified; the only preceding gates were a cleartext receiver-index lookup (get_peer_keypair_for_index() on the attacker-supplied data_hdr->receiver) and a non-cryptographic keypair validity/expiry check. The path is reachable entirely from the network: inbound UDP on the WireGuard port is dispatched by wg_input() to handle_transport_data() and then wg_process_data_message(). The 32-bit receiver index is transmitted in cleartext in WireGuard handshake and data messages, so an on-path observer learns it directly and an off-path attacker can brute-force it against the UDP port. Given an active receiving-valid session for that index, an attacker could send a 16-byte garbage payload and have it accepted without possessing the session key. On acceptance the unauthenticated message caused the management layer to observe a spoofed NET_EVENT_VPN_CONNECTED signal (setting peer->first_valid and notifying any net_mgmt listener) and incremented the keepalive-RX statistic. The impact is limited to integrity of this status signal: no plaintext is decrypted or injected, no key is disclosed, and the early-return path did not update the peer endpoint or liveness timers, so there is no traffic-injection, session-takeover, or availability consequence. The fix removes the pre-decrypt early return so a 16-byte payload flows through wg_decrypt_packet(), which verifies the Poly1305 tag over the empty plaintext, followed by the existing anti-replay check; only an authenticated, non-replayed message is then recognised as a keepalive. Forged keepalives now fail the tag check and are counted as decrypt failures.
Характеристики атаки
Последствия
Строка CVSS v3.1