Утро 26 ноября началось для меня с интересной новости — ребята из Perfect Privacy опубликовали информацию об уязвимости Port Fail, которая позволяет раскрывать IP-адрес клиентов VPN-сервисов с функцией проброса портов. �� немного понегодовал из-за того, что ее назвали уязвимостью, т.к. это никакая не уязвимость, а особенность маршрутизации: трафик до IP-адреса VPN-сервера всегда идет напрямую, в обход VPN. Вполне очевидная вещь, подумал я, о которой должен знать любой сетевой администратор. Заметка вменяемая и технически грамотная, придраться можно только к слову vulnerability (уязвимость). Но потом за дело взялись СМИ, и пошло-поехало…

Критическая уязвимость во всех протоколах VPN на всех операционных системах. У-у-у, как страшно!
В новости, опубликованной на Geektimes, изначально имевшей желтый заголовок, было сказано о награде в $5000 за найденную «уязвимость» от Private Internet Access — одного из крупнейших VPN-сервисов. «$5000 за типичную, совершенно очевидную любому сетевику вещь?» — подумал я — «Невероятно!», и высказал свое негодование по этому поводу в комментариях, попутно расписав еще одну, не менее очевидную, особенность маршрутизации, с которой сталкивался любой настраивавший работу двух и более интернет-провайдеров на одном компьютере: ответ на входящий запрос не обязательно уйдет через этого же провайдера и с этим же IP, чего запросившая сторона совсем не ожидает. Если мы представим, что вместо второго провайдера у нас VPN-соединение, то отправив запрос на IP-адрес нашего провайдера, при определенных условиях может получиться так, что ответ на наш запрос мы получим с IP VPN-сервера.

Приложения, которые слушают порт и принимают на него входящие соединения, в большинстве своем полагаются на операционную систему при формировании ответа на пришедший входящий пакет. Это отлично работает, когда у вас один сетевой интерфейс, но ситуация меняется с несколькими интерфейсами, в зависимости от ОС и протокола:
Windows:
OS X:
Linux:
В Linux существует замечательная настройка Reverse Path Filtering (rp_filter), которая включена по умолчанию в большинстве современных дистрибутивов. Если фильтр включен, то программа, прослушивающая порт, не получит никаких входящих данных, если ОС уверена, что ответ будет направлен через другой интерфейс. Следует отметить, что в некоторых дистрибутивах (как минимум, в Debian) эта опция по умолчанию отключена, хоть и причины этого непонятны.
В Windows и OS X подобной функциональности, к сожалению, нет.
Итак, как могут воспользоваться этой особенностью маршрутизации компании, производящие мониторинг нарушений интеллектуальной собственности:
По моему мнению, эксплуатировать такой подход достаточно проблематично из-за того, что почти все BitTorrent-клиенты выбирают случайный порт при первом запуске, и отправить сообщения на все порты и все IP-адреса в интернете хоть и вполне возможно, но, как минимум, затруднительно делать постоянно. Однако, есть и клиенты, которые используют стандартные порты вроде 8999 или 6881.
Соединиться с таким клиентом не получится со стандартным сетевым стеком, однако можно модифицировать его таким образом, чтобы такие соединения устанавливались.
С Linux все предельно просто — для IPv4 достаточно установить опцию
А для IPv6 необходимо добавить правило iptables:
В Windows существует мощная Windows Filtering Platform, с которой можно писать достаточно гибкие правила межсетевого экрана прямо в user-space, а если и этого не хватает, написать ядерный драйвер.
Как и в случае с утечками DNS в Windows 10, я постарался реализовать подобие Reverse Path Forwarding под Windows в виде плагина для OpenVPN. Он делает следующее:
Хоть это и не полноценный Reverse Path Forwarding, свою работу он делает довольно хорошо: ответы на UDP-запросы могут уйти в VPN-туннель только в том случае, если они пришли из диапазонов немаршрутизируемых адресов, но в таком случае они отбросятся на стороне VPN-сервера, т.к. они, собственно, немаршрутизируемые (работают только в пределах определенной локальной сети); программы, использующие UDP (например, BitTorrent Sync), не перестанут работать в внутри LAN, а соседи по провайдерской подсети все еще смогут с вами корректно связаться.
Скачать плагин можно здесь: github.com/ValdikSS/openvpn-block-incoming-udp-plugin
В OS X все несколько сложнее: PF не позволяет фильтровать только новые UDP-пакеты, поэтому приходится блокировать все входящие UDP, кроме локальных адресов, провайдерской подсети и самого VPN-сервера. Это плохо тем, что вы, например, не сможете использовать DNS провайдера, если захотите, т.к. ответы вам просто не будут доходить, необходимо будет вносить IP DNS-сервера в белый список.
В любом случае, сделать это можно приблизительно так:
Сообщения об этой особенности я отправил 11 VPN-провайдерам, ответ получил только от 5: Private Internet Access, Perfect Privacy и Mullvad выпустили обновленный клиент с возможностью блокировки входящих соединений, Astrill написал, что они не считают эту особенность существенной, и что она не имеет отношения к VPN. Технически, они правы, однако в их клиенте есть защита от других клиентских проблем — утечек IPv6, DNS и WebRTC, и почему не добавить еще одну, остается для меня загадкой. Ребята из Cryptostorm подсказали ключ реестра Windows, который должен включать Reverse Path Forwarding, но он не работает, а TorGuard ничего не написали после ответа на некоторые вопросы с их стороны.
Кстати, вышел OpenVPN 2.3.9 с многочисленными исправлениями Windows-ошибок и долгожданной опцией
Так я и получил свои $5000 от Private Internet Access, $1000 сверху от Perfect Privacy и $1300 от Mullvad за еще одну ерунду, и мне, честно говоря, за это даже несколько неловко. Часть денег уйдет разработчикам OpenVPN и strongSwan.

Критическая уязвимость во всех протоколах VPN на всех операционных системах. У-у-у, как страшно!
В новости, опубликованной на Geektimes, изначально имевшей желтый заголовок, было сказано о награде в $5000 за найденную «уязвимость» от Private Internet Access — одного из крупнейших VPN-сервисов. «$5000 за типичную, совершенно очевидную любому сетевику вещь?» — подумал я — «Невероятно!», и высказал свое негодование по этому поводу в комментариях, попутно расписав еще одну, не менее очевидную, особенность маршрутизации, с которой сталкивался любой настраивавший работу двух и более интернет-провайдеров на одном компьютере: ответ на входящий запрос не обязательно уйдет через этого же провайдера и с этим же IP, чего запросившая сторона совсем не ожидает. Если мы представим, что вместо второго провайдера у нас VPN-соединение, то отправив запрос на IP-адрес нашего провайдера, при определенных условиях может получиться так, что ответ на наш запрос мы получим с IP VPN-сервера.

Как такое может происходить?
Когда вы подключаетесь к VPN, маршрут по умолчанию, который до этого был установлен через вашего провайдера, меняется на маршрут через VPN.Приложения, которые слушают порт и принимают на него входящие соединения, в большинстве своем полагаются на операционную систему при формировании ответа на пришедший входящий пакет. Это отлично работает, когда у вас один сетевой интерфейс, но ситуация меняется с несколькими интерфейсами, в зависимости от ОС и протокола:
Windows:
- OpenVPN (def1) — UDP уходит через VPN-интерфейс, TCP работает корректно
- IPsec IKEv2 — UDP уходит через VPN-интерфейс, TCP отбрасывается
OS X:
- OpenVPN (def1) — UDP уходит через VPN-интерфейс, TCP отбрасывается
- IPsec IKEv2 — UDP уходит через VPN-интерфейс, TCP работает корректно
Linux:
- OpenVPN (def1) — UDP и TCP уходят через VPN-интерфейс при rp_filter=0, отбрасываются при rp_filter=1
В Linux существует замечательная настройка Reverse Path Filtering (rp_filter), которая включена по умолчанию в большинстве современных дистрибутивов. Если фильтр включен, то программа, прослушивающая порт, не получит никаких входящих данных, если ОС уверена, что ответ будет направлен через другой интерфейс. Следует отметить, что в некоторых дистрибутивах (как минимум, в Debian) эта опция по умолчанию отключена, хоть и причины этого непонятны.
В Windows и OS X подобной функциональности, к сожалению, нет.
Чем это может быть чревато?
Как можно видеть, проблему представляют только входящие пакеты к приложениям, прослушивающим UDP-порт. Вряд ли на типичном компьютере пользователя таких приложений найдется много, но несколько, как правило, все же есть.BitTorrent
Как вы можете знать, в некоторых странах, например, в США, Германии, Франции, Австрии, Канаде, Великобритании, существуют специальные организации, которые отслеживают участников интересующих их BitTorrent-раздач по просьбам правообладателей. Они соединяются с BitTorrent-трекерами и DHT-сетью и сохраняют все IP-адреса конкретной раздачи, чтобы потом отправить «письма счастья» — сообщения о том, что такой-то IP-адрес с таким-то портом раздавал такой-то файл в такое-то время, что это все незаконно, и что нужно-бы заплатить за это дело штраф. Жители этих стран используют VPN в других, «менее развитых» странах, чтобы не попасться в сканеры этих злодеев, и компани�� от этого грустят.Итак, как могут воспользоваться этой особенностью маршрутизации компании, производящие мониторинг нарушений интеллектуальной собственности:
- Пользователь, которому провайдер выдает «белый» (маршрутизируемый) IP-адрес, подключается к VPN, запускает BitTorrent-клиент и скачивает некоторые файлы, оставаясь после скачивания на раздаче. BitTorrent-клиент прослушивает порт и открывает его, в случае необходимости, через UPnP.
- Компания, занимающиеся мониторингом, собирает все IP-адреса на этой раздаче, в том числе и IP-адрес и порт VPN-сервера нашего пользователя.
- Компания массово отправляет UDP-пакеты BitTorrent-клиентам на все IP-адреса в интернете, на порты, собранные ранее. Можно уложиться в десятки минут при использовании 10-гигабитного канала.
- BitTorrent-клиент пользователя, получив входящий пакет на сетевой интерфейс провайдера, отправляет ответ через VPN-интерфейс, с IP VPN-сервера.
- Компания обнаруживает настоящий IP клиента, раздающего интересующий их материал.
По моему мнению, эксплуатировать такой подход достаточно проблематично из-за того, что почти все BitTorrent-клиенты выбирают случайный порт при первом запуске, и отправить сообщения на все порты и все IP-адреса в интернете хоть и вполне возможно, но, как минимум, затруднительно делать постоянно. Однако, есть и клиенты, которые используют стандартные порты вроде 8999 или 6881.
Соединиться с таким клиентом не получится со стандартным сетевым стеком, однако можно модифицировать его таким образом, чтобы такие соединения устанавливались.
Skype
Используя ��ту технику, можно узнать настоящий IP интересующих вас пользователей Skype, если они используют VPN. Существует большое количество публичных Skype-резолверов, которые покажут вам IP и порт пользователя по Skype-логину. Далее, вам нужно прибегнуть к такой же технике, которую использовали бы правообладатели — разослать какие-нибудь данные на UDP-порт по всему интернету, и следить за ответами. Примечательно, что отсылать в Skype можно почти любой мусор! Воспользуемся замечательной программой nping из состава nmap:# nping --udp -p 13318 --data-string 'hellothere!' -c 1 serv.valdikss.org.ru
Starting Nping 0.7.00 ( https://nmap.org/nping ) at 2015-12-20 19:54 MSK
SENT (0.0157s) UDP 195.154.127.59:53 > 92.42.31.8:13318 ttl=64 id=10802 iplen=39
RCVD (0.0859s) UDP 185.61.149.121:4272 > 195.154.127.59:53 ttl=54 id=1534 iplen=32
Max rtt: N/A | Min rtt: N/A | Avg rtt: N/A
Raw packets sent: 1 (39B) | Rcvd: 1 (46B) | Lost: 0 (0.00%)
Nping done: 1 IP address pinged in 1.01 secondsКак защититься?
Хоть и я и не считаю эту особенность такой уж большой проблемой, мне все же интересно, как предотвратить утечки такого рода с технической точки зрения.С Linux все предельно просто — для IPv4 достаточно установить опцию
net.ipv4.conf.*.rp_filterв 1, если она еще не установлена. Мой интерфейс VPN называется tun0, а интерфейс с интернетом — wlp3s0, поэтому я делаю следующее:# sysctl net.ipv4.conf.all.rp_filter=1
# sysctl net.ipv4.conf.default.rp_filter=1
# sysctl net.ipv4.conf.tun0.rp_filter=1
# sysctl net.ipv4.conf.wlp3s0.rp_filter=1А для IPv6 необходимо добавить правило iptables:
# ip6tables -t raw -A PREROUTING -m rpfilter --invert -j DROPВ Windows существует мощная Windows Filtering Platform, с которой можно писать достаточно гибкие правила межсетевого экрана прямо в user-space, а если и этого не хватает, написать ядерный драйвер.
Как и в случае с утечками DNS в Windows 10, я постарался реализовать подобие Reverse Path Forwarding под Windows в виде плагина для OpenVPN. Он делает следующее:
- Разрешает любые входящие IPv4 unicast UDP-пакеты с адресов 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 и подсетей активных сетевых адаптеров; любые входящие IPv6 unicast UDP-пакеты с fd00::/8, fe80::/10 и подсетей активных сетевых адаптеров.
- Блокирует все новые unicast UDP-пакеты извне VPN-интерфейса.
Хоть это и не полноценный Reverse Path Forwarding, свою работу он делает довольно хорошо: ответы на UDP-запросы могут уйти в VPN-туннель только в том случае, если они пришли из диапазонов немаршрутизируемых адресов, но в таком случае они отбросятся на стороне VPN-сервера, т.к. они, собственно, немаршрутизируемые (работают только в пределах определенной локальной сети); программы, использующие UDP (например, BitTorrent Sync), не перестанут работать в внутри LAN, а соседи по провайдерской подсети все еще смогут с вами корректно связаться.
Скачать плагин можно здесь: github.com/ValdikSS/openvpn-block-incoming-udp-plugin
В OS X все несколько сложнее: PF не позволяет фильтровать только новые UDP-пакеты, поэтому приходится блокировать все входящие UDP, кроме локальных адресов, провайдерской подсети и самого VPN-сервера. Это плохо тем, что вы, например, не сможете использовать DNS провайдера, если захотите, т.к. ответы вам просто не будут доходить, необходимо будет вносить IP DNS-сервера в белый список.
В любом случае, сделать это можно приблизительно так:
echo 'pass in quick proto udp from 10.0.0.0/8 to any
pass in quick proto udp from 192.168.0.0/16 to any
pass in quick proto udp from 172.16.0.0/12 to any
pass in quick proto udp from 169.254.0.0/16 to any
pass in quick proto udp from 185.61.149.121/32 to any
block in quick on ! utun1 proto udp to any' | sudo pfctl -Ef -Где 185.61.149.121 — IP-адрес VPN-сервера, а utun1 — интерфейс VPN.Послесловие
Если вы весь из себя злодей, и хотите попробовать проэксплуатировать эту особенность, вам поможет логирование пакетов в Linux средствами netfilter. Достаточно добавить следующее правило iptables, и все пакеты с Марса будут как на ладони:iptables -I INPUT -m conntrack -p udp --sport 4455 --ctstate NEW -j LOGГде 4455 — интересующий вас порт.Сообщения об этой особенности я отправил 11 VPN-провайдерам, ответ получил только от 5: Private Internet Access, Perfect Privacy и Mullvad выпустили обновленный клиент с возможностью блокировки входящих соединений, Astrill написал, что они не считают эту особенность существенной, и что она не имеет отношения к VPN. Технически, они правы, однако в их клиенте есть защита от других клиентских проблем — утечек IPv6, DNS и WebRTC, и почему не добавить еще одну, остается для меня загадкой. Ребята из Cryptostorm подсказали ключ реестра Windows, который должен включать Reverse Path Forwarding, но он не работает, а TorGuard ничего не написали после ответа на некоторые вопросы с их стороны.
Кстати, вышел OpenVPN 2.3.9 с многочисленными исправлениями Windows-ошибок и долгожданной опцией
--block-outside-dns, которая исправляет утечки DNS на Windows 8.1 и 10.Так я и получил свои $5000 от Private Internet Access, $1000 сверху от Perfect Privacy и $1300 от Mullvad за еще одну ерунду, и мне, честно говоря, за это даже несколько неловко. Часть денег уйдет разработчикам OpenVPN и strongSwan.
