Обзор
Роутеры Java I2P и i2pd старше API 0.9.58 (выпущенного в марте 2023) уязвимы перед атакой повторной передачи пакетa SYN. Это проблема в проектировании протокола, а не ошибка реализации.
Пакеты SYN подписываются, но подпись начального пакета SYN, отправленного от Алисы Бобу, не привязана к идентичности Боба, поэтому Боб может сохранить и повторно передать этот пакет, отправив его жертве Чарли. Чарли подумает, что пакет пришел от Алисы и ответит ей. В большинстве случаев это безвредно, но пакет SYN может содержать начальные данные (такие как GET или POST), которые Чарли обработает немедленно.
Проектирование
Решение заключается в том, чтобы Алиса включала хеш назначения Боба в подписанные данные SYN. Боб проверяет при приеме, что этот хеш совпадает с его хешем.
Любая потенциальная жертва атаки Чарли проверяет эти данные и отвергает SYN, если он не совпадает с его хешем.
Используя поле опций NACK в SYN для хранения хеша, изменение обратно-совместимо, поскольку NACK не ожидаются в пакете SYN и в настоящее время игнорируются.
Все опции покрыты подписью, как обычно, поэтому Боб не может перезаписать хеш.
Если Алиса и Чарли используют API 0.9.58 или новее, любая попытка повторной передачи Бобом будет отвергнута.
Спецификация
Обновить спецификацию Streaming для добавления следующего раздела:
Предотвращение повторной передачи
Чтобы предотвратить возможность Боба использовать атаку повторной передачи, сохранив действительный подписанный пакет SYNCHRONIZE, полученный от Алисы, и затем отправив его жертве Чарли, Алиса должна включить хеш назначения Боба в пакет SYNCHRONIZE следующим образом:
.. raw:: html
{% highlight lang=‘dataspec’ %} Установить поле количества NACK в 8 Установить поле NACKs на 32-байтовый хеш назначения Боба
{% endhighlight %}
При получении SYNCHRONIZE, если поле количества NACK равно 8, Боб должен интерпретировать поле NACKs как 32-байтовый хеш назначения и должен проверить соответствие его хешу назначения. Он также должен проверить подпись пакета как обычно, так как она покрывает весь пакет, включая поля количества NACK и NACKs. Если количество NACK равно 8 и поле NACKs не совпадает, Боб должен отбросить пакет.
Это требуется для версий 0.9.58 и выше. Это обратно-совместимо с более старыми версиями, поскольку NACKs не ожидаются в пакете SYNCHRONIZE. Назначения не могут и не должны знать, какая версия запущена на другой стороне.
Не требуется изменений для пакета SYNCHRONIZE ACK, отправляемого от Боба Алисе; не включайте NACKs в этот пакет.
Анализ безопасности
Эта проблема присутствует в потоковом протоколе с момента его создания в 2004 году. Она была обнаружена внутри разработчиками I2P. У нас нет доказательств, что эта проблема когда-либо была использована. Фактическая вероятность успеха эксплуатации может значительно варьироваться в зависимости от протокола уровня приложения и сервиса. Вероятно, приложения peer-to-peer более склонны к воздействию, чем клиент/серверные приложения.
Совместимость
Проблем нет. Все известные реализации в настоящее время игнорируют поле NACKs в пакете SYN. И даже если бы они не игнорировали его и пытались интерпретировать его как NACKs для 8 различных сообщений, эти сообщения не были бы ожидаемыми во время SYNCHRONIZE рукопожатия и NACKs не имели бы смысла.
Миграция
Реализации могут добавлять поддержку в любое время, координация не требуется. Роутеры Java I2P и i2pd реализовали это в API 0.9.58 (выпуск март 2023).