habrahabr

IPv6 под прицелом

  • суббота, 29 ноября 2014 г. в 02:11:31
http://habrahabr.ru/company/xakep/blog/244383/



Казалось бы, зачем сейчас вообще вспоминать про IPv6? Ведь несмотря на то, что последние блоки IPv4-адресов были розданы региональным регистраторам, интернет работает без каких-либо изменений. Дело в том, что IPv6 впервые появился в 1995 году, а полностью его заголовок описали в RFC в 1998 году. Почему это важно? Да по той причине, что разрабатывался он без учета угроз, с той же доверительной схемой, что и IPv4. И в процессе разработки стояли задачи сделать более быстрый протокол и с большим количеством адресов, а не более безопасный и защищенный.


Кратко про темпы роста


Если изучить графики, которые предоставляет региональный регистратор IP-адресов и автономных систем, то можно обнаружить, что по состоянию на первое сентября 2014 года количество зарегистрированных IPv6 автономных систем уже перевалило за 20%. На первый взгляд, это серьезная цифра. Но если брать во внимание только реальное количество IPv6-трафика в мире, то сейчас это около 6% от всего мирового интернет-трафика, хотя буквально три года назад было всего 0,5%.


Рис. 1. Реальные объемы IPv6-трафика

По самым скромным оценкам ожидается, что к концу 2015 года доля IPv6-трафика дойдет как минимум до 10%. И рост будет продолжаться. Кроме того, недавно вступил в силу специальный протокол для региональных регистраторов. Теперь новый блок IPv4-адресов будет выдан только в том случае, если компания докажет, что уже внедрила у себя IPv6. Поэтому если кому-то потребуется подсеть белых IPv4-адресов — придется внедрять IPv6. Этот факт также послужит дальнейшему росту IPv6-систем и увеличению трафика. Что же касается рядовых пользователей, то уже по всему миру начали проявляться провайдеры, которые предоставляют конечным абонентам честные IPv6-адреса. Поэтому IPv6 будет встречаться все чаще и чаще, и мы не можем оставить это без внимания.

Что нового в IPv6?


Первое, что бросается в глаза, — это адреса. Они стали длиннее, записываются в шестнадцатеричном виде и сложно запоминаются. Хотя, поработав некоторое время с IPv6, обнаруживаешь, что адреса в целом запоминаемые, особенно если используются сокращенные формы записи. Напомню, что IPv4 использует 32-битные адреса, ограничивающие адресное пространство 4 294 967 296 (2^32) возможными уникальными адресами. В случае же IPv6 под адрес уже выделено 128 бит. Соответственно, адресов доступно 2^128. Это примерно по 100 адресов каждому атому на поверхности Земли. То есть адресов должно хватить на достаточно длительное время.

Адреса записываются в виде восьми групп шестнадцатеричных значений. Например, IPv6-адрес может выглядеть как 2001:DB8:11::1. Важно отметить, что IPv6-адресов на одном интерфейсе может быть несколько, причем это стандартная ситуация. Например, на интерфейсе может быть частный адрес, белый адрес и еще по DHCPv6 приедет дополнительный адрес. И все будет штатно работать, для каждой задачи будет использоваться свой адрес. Если нужно выйти в мир, то будет использоваться белый адрес. Надо до соседнего сервера? Пойдет через частный адрес. Все это будет решаться обычным анализом поля destination.

Все IPv6-адреса делятся на две группы: линк-локал и глобал юникаст. По названию очевидно, что Link local — это адрес, который используется только в пределах одного линка. Такие адреса в дальнейшем применяются для работы целого ряда механизмов вроде автоматической настройки адреса, обнаружения соседей, при отсутствии маршрутизатора и тому подобное. Для выхода в мир такие адреса использовать не допускается.

Link local адрес назначается автоматически, как только хост выходит онлайн, чем-то отдаленно такие адреса похожи на механизм APIPA в ОС Windows. Такой адрес всегда начинается с FE80, ну а последние 64 бита — это мак-адрес с FFFE, вставленными посередине, плюс один бит инвертируется. Механизм формирования такого адреса еще называется EUI-64. В итоге адрес будет уникальный, так как мак-адреса обычно отличаются у всех хостов. Но некоторые ОС используют рандомный идентификатор вместо механизма EUI-64.

Что еще нового


Только адресами изменения, естественно, не заканчиваются. Еще был значительно упрощен заголовок (см. рис. 2).


Рис. 2. Сравнение заголовков IPv6 и IPv4

Теперь все, что не является обязательным для маршрутизации пакета из точки в А в точку Б, стало опциональным. А раз опциональное — значит, переезжает в extension header, который лежит между IPv6-заголовком и TCP/UDP-данными. В этом самом extension-заголовке уже и проживают фрагментирование, IPsec, source routing и множество другого функционала.

Резко упростили задачу маршрутизаторам, ведь уже не надо пересчитывать контрольные суммы, и в итоге IPv6 обрабатывается быстрее, чем IPv4. Контрольные суммы убрали вовсе. Во-первых, у фрейма на уровне L2 есть CRC, во-вторых, вышележащие протоколы (TCP) тоже будут обеспечивать целостность доставки. В итоге из заголовка выбросили лишние поля, стало проще, быстрее и надежнее.

Aвтоконфигурирование и служебные протоколы


Существует два основных варианта назначения IPv6-адресов: stateless autoconfiguration — это когда роутер отправляет клиентам адрес сети, шлюза по умолчанию и прочую необходимую информацию и statefull autoconfiguration — когда используется DHCPv6-сервер. Поэтому если раньше DHCP был единственным вариантом раздачи информации, то в IPv6 он стал дополнительным.

ICMP 6-й версии тоже не остался без внимания, в него было добавлено множество фич. Например, механизм Router discovery — клиенты могут слушать, что сообщает им роутер (сообщения ICMPv6 тип 134 router advertisement, которые приходят в рамках процесса stateless autoconfiguration), и при включении могут сразу звать роутер на помощь, мол, помоги сконфигуриться (сообщения ICMPv6 тип 133 router solicitation).

Еще добавили механизм Neighbor discovery — можно сказать, что это своеобразная замена ARP, которая помогает находить мак-адреса соседей, маршрутизаторы и даже обнаруживать дублирующиеся адреса в сегменте (duplicate address detection DaD), работает исключительно по мультикасту. Чистого бродкаста в IPv6 уже нет, но не нужно забывать, что глупые копеечные свичи весь мультикаст рассылают широковещательно, в итоге часть новых механизмов сводится на нет.

Инструментарий пентестера IPv6


Перед тем как перейти к уязвимостям и атакам, неплохо бы рассмотреть, какие есть инструменты в арсенале пентестера. До недавнего времени существовал только один набор утилит для проведения атак на протоколы IPv6 и ICMPv6. Это был THC-IPV6 от небезызвестного Марка ван Хаузера, того самого автора брутфорсера THC-hydra и массы других незаменимых инструментов. Именно он в 2005 году серьезно заинтересовался этой темой и вплотную занялся ресерчем протокола IPv6. И до недавнего времени оставался первопроходцем.

Но в последний год ситуация начала меняться. Все больше исследователей обращают свое внимание на IPv6, и, соответственно, стали появляться новые утилиты и новые сканеры. Но на сегодня THC-IPV6 по-прежнему остается лучшим набором утилит для пентестера. В его комплект входит уже более 60 инструментов, разделенных на различные категории — от сканирования и митмов до флудинга и фаззинга. Но не будем забывать и тру инструмент scapy — утилиту, которая позволяет вручную создавать любые пакеты, с любыми заголовками, даже если такие вариации не предусмотрены ни в одном RFC.

Разведка в IPv6-сетях


Перед тем как атаковать цель, нужно ее как-то обнаружить, поэтому стандартный пентест обычно начинается с поиска живых хостов. Но здесь появляется проблема: мы не можем просканировать весь диапазон. Сканирование всего одной подсети затянется на годы, даже если отправлять миллион пакетов в секунду. Причина в том, что всего лишь подсеть /64 (или их еще называют префиксами) больше, чем весь интернет сегодня, причем значительно больше. Поэтому самая серьезная проблема с IPv6 — это обнаружение целей.

К счастью, выход есть. Вначале нужно будет найти AS (автономную систему), которая принадлежит цели (объекту пентеста). Сервисов, позволяющих искать по AS их владельцев, вполне достаточно, можно это делать прямо на сайтах региональных регистраторов (европейский регистратор — это RIPE NCC). Затем, зная номер AS, принадлежащей конкретной компании, можно уже искать выделенные ей IPv6-подсети.

Самый удобный такой поисковый сервис предоставляет Hurricane Electric (bgp.he.net). В итоге можно найти несколько огромных подсетей, которые, как мы уже убедились, нереально просканировать на предмет живых хостов. Поэтому нужно составлять список часто используемых адресов и проводить сканирование уже точечно по ним.

Каким образом можно собрать такой словарь? Если проанализировать, как в компаниях, которые уже внедрили IPv6, назначаются адреса клиентам, то можно выделить три основные группы: автоконфигурация, ручное назначение адресов и DHCPv6.

Автоконфигурация может осуществляться тремя способами: на основе мак-адреса, с использованием privacy option (то есть рандомно и, например, меняться раз в неделю) и fixed random (полностью случайным образом). В данной ситуации возможно сканировать только те адреса, что строятся на основе мака. В результате могут выйти подсети, сравнимые по размеру с IPv4 класса А, процесс работы с такими сетями не очень быстрый, но все равно это уже вполне реально. Например, зная, что в целевой компании массово используются ноутбуки определенного вендора, можно строить сканирование, основываясь на знаниях о том, как будет формироваться адрес.

Если адреса задаются вручную, то они могут назначаться либо случайным образом, либо по некому шаблону. Второе, естественно, в жизни встречается гораздо чаще. А паттерн может быть ::1,::2,::3 или ::1001,::1002,::1003. Также иногда в качества адреса используются порты сервисов, в зависимости от сервера: например, веб-сервер может иметь адрес ::2:80.

Если же брать DHCPv6, то в этом случае обычно адреса раздаются последовательно из пула (точно такое же поведение можно наблюдать и с обычным DHCPv4-сервером). Зачастую в DHCPv6 можно встретить пул вроде ::1000-2000 или ::100-200. Поэтому в итоге берем утилиту alive6 (она включена в комплект THC-IPV6 и, как и все рассматриваемые сегодня инструменты, по дефолту входит в Kali Linux) и запускаем:

# alive6 -p eth0 2001:67c:238::0-ffff::0-2
  Alive: 2001:db8:238:1::2 [ICMP echo-reply]
  Alive: 2001:db8:238:3::1 [ICMP echo-reply]
  Alive: 2001:db8:238:3::2 [ICMP echo-reply]
  Alive: 2001:db8:238:300::1 [ICMP echo-reply]
  Scanned 65536 systems in 29 seconds and found 4 
  systems alive


При таком обнаружении живых машин будет меняться только часть, отвечающая за адрес хоста. Используя такой подход, можно достаточно эффективно и в разумные временные рамки находить живые хосты в обнаруженных ранее подсетях.

Но это еще не все — естественно, можно использовать и DNS. С приходом IPv6 никуда не делись трансферы DNS-зоны и брутфорсы DNS по словарю. Применив все эти техники вместе, можно обнаруживать до 80% всех включенных хостов в заданной IPv6-подсети, что очень неплохо. В случае же компрометации одного лишь хоста обнаружить всех его соседей не составит никакого труда при помощи мультикаста. Достаточно будет запустить ту же утилиту alive6, только уже с ключом -l.

Из свежих фич THC-IPV6, и в частности утилиты alive6, можно отметить возможность искать живые хосты, передавая в качестве паттерна для перебора целую IPv4-подсеть:

# alive6 -4 192.168.0/24


Если же брать классическое сканирование, то здесь практически ничего не изменилось. Тот же Nmap, те же варианты сканирования портов, единственное отличие в том, что теперь сканировать можно только один хост за раз, но это вполне очевидное решение.

Пожалуй, единственная дополнительная техника при сканировании портов — это сканирование IPv4 вначале, а затем получение IPv6-информации по этим хостам. То есть некое расширение поверхности атаки. Для этого можно использовать как вспомогательный модуль метасплойта ipv6_neighbor, так и отдельные скрипты ipv6_surface_analyzer. Работают они по схожему принципу — принимают на входе IPv4-подсеть, сканируют ее, находят живые хосты, проверяют порты на открытость, а затем, определив MAC-адрес, высчитывают по нему IPv6-адрес и уже пробуют работать по нему. Иногда это действительно помогает, но в некоторых случаях (privacy option) IPv6-адреса обнаружить не удается, даже несмотря на то, что они есть.

INFO


При использовании протокола IPv4 и ARP достаточно полезно было иногда смотреть ARP-кеш; что на линуксе, что на Windows-платформе это можно было сделать, используя команду arp -a.
Теперь же, в случае IPv6, в линуксе, чтобы посмотреть соседей, используется команда ip -6 neighbor show, а в Windows среде это можно сделать командой netsh interface ipv6 show neighbors.


Угрозы периметра IPv6



Если рассмотреть внешний периметр, то можно обнаружить, что многие компании, которые уже начали внедрять IPv6, не спешат закрывать свои административные порты (SSH, RDP, Telnet, VNC и так далее). И если IPv4 уже почти все стараются как-то фильтровать, то про IPv6 или забывают, или не знают, что их нужно защищать так же, как и в случае с IPv4. И если можно отчасти понять используемый IPv4 телнет — например, ограниченная память или CPU не позволяют в полной мере использовать SSH, — то каждое устройство, которое поддерживает сегодня IPv6, просто гарантированно будет поддерживать и протокол SSH. Бывают даже случаи, когда ISP выставляют в мир административные порты IPv6 на своих роутерах. Выходит, что даже провайдеры более уязвимы к IPv6-атакам. Происходит это по различным причинам. Во-первых, хороших IPv6-файрволов еще не так много, во-вторых, их еще нужно купить и настроить. Ну и самая главная причина — многие даже и не подозревают об угрозах IPv6. Также бытует мнение, что пока нет IPv6-хакеров, малвари и IPv6-атак, то и защищаться вроде как не от чего.

Угрозы, поджидающие внутри LAN


Если вспомнить IPv4, то там обнаружится три атаки, которые эффективны и по сей день в локальных сетях, — это ARP spoofing, DHCP spoofing, а также ICMP-редиректы (подробно этот класс атак освещался во время моего выступления на PHDays, так что можешь поискать соответствующее видео в Сети).

В случае же протокола IPv6, когда атакующий находится в одном локальном сегменте с жертвой, ситуация, как ни странно, остается примерно такой же. Вместо ARP появился NDP, на смену DHCP пришла автоконфигурация, а ICMP просто обновился до ICMPv6. Важно то, что концепция атак осталась практически без изменений. Но кроме того, добавились новые механизмы вроде DAD, и, соответственно, сразу же появились новые векторы и новые атаки.

Протокол обнаружения соседей (Neighbor Discovery Protocol, NDP) — это протокол, с помощью которого IPv6-хосты могут обнаружить друг друга, определить адрес канального уровня другого хоста (вместо ARP, который использовался в IPv4), обнаружить маршрутизаторы и так далее. Чтобы этот механизм работал, а работает он с использованием мультикаста, каждый раз, когда назначается линк-локал или глобал IPv6-адрес на интерфейс, хост присоединяется к мультикаст-группе. Собственно, используется всего два типа сообщений в процессе neighbor discovery: запрос информации, или NS (neighbor solicitation), и предоставление информации — NA (neighbor advertisement).
Взаимодействие в таком режиме можно увидеть на рис. 3.


Рис. 3. Штатная работа ND

В результате атакующему нужно всего лишь запустить утилиту parasite6, которая будет отвечать на все NS, пролетающие в отдельно взятом сегменте (см. рис. 4). Перед этим нужно не забыть включить форвардинг (echo 1 > /proc/sys/net/ipv6/conf/all/forwarding), в противном случае произойдет не MITM-атака, а DoS.


Рис. 4. Работа утилиты parasite6

Минусами такой атаки является то, что атакующий будет пытаться отравить ND-кеш всех хостов, что, во-первых, шумно, во-вторых, затруднительно в случае больших объемов трафика. Поэтому можно взять scapy и провести эту атаку вручную и прицельно. Сначала необходимо заполнить все необходимые переменные.

>>> ether=Ether(src="00:00:77:77:77:77",
dst="00:0c:29:0e:af:c7")
Вначале идут адреса канального уровня, в качестве адреса отправителя выступает мак-адрес атакующего, в качестве адреса получателя — мак-адрес жертвы.
>>> ipv6=IPv6(src="fe80::20d:edff:fe00:1",
dst="fe80::fdc7:6725:5b28:e293")
Далее задаются адреса сетевого уровня, адрес отправителя спуфится (на самом деле это адрес роутера), адрес получателя — это IPv6-адрес жертвы.
>>> na=ICMPv6ND_NA(tgt="fe80::20d:edff:
fe00:1", R=0, S=0, O=1)


Третьей переменной нужно указать правильно собранный пакет NA, где ICMPv6ND_NA — это ICMPv6 Neighbor Discovery — Neighbor Advertisement, а tgt — это собственно адрес роутера, который анонсируется как адрес атакующего. Важно правильно установить все флаги: R=1 означает, что отправитель является роутером, S=1 скажет о том, что анонс отправляется в ответ на NS-сообщение, ну а O=1 — это так называемый override-флаг.

>>> lla=ICMPv6NDOptDstLLAddr
(lladdr="00:00:77:77:77:77")
Следующая переменная — это Link local адрес ICMPv6NDOptDstLLAddr (ICMPv6 Neighbor Discovery Option — Destination Link-Layer). Это мак-адрес атакующего.
>>> packet=ether/ipv6/na/lla
Осталось собрать пакет в единое целое, и можно отправлять такой пакет в сеть.
>>> sendp(packet,loop=1,inter=3)


Значение loop=1 говорит о том, что отправлять нужно бесконечно, через каждые три секунды.
В итоге через некоторое время жертва обновит свой кеш соседей и будет отправлять весь трафик, который предназначается маршрутизатору, прямо в руки атакующему. Нужно отметить, что для того, чтобы создать полноценный MITM, потребуется запустить еще один экземпляр scapy, где адреса будут инвертированы для отравления роутера. Как видишь, ничего сложного.

Также стоит отметить, что в IPv6 не существует понятия gratuitous NA, как это было во времена ARP (gratuitous ARP — это ARP-ответ, присланный без запроса). Но вместе с тем кеш ND живет недолго и быстро устаревает. Это было разработано, чтобы избегать отправки пакетов на несуществующие MAC-адреса. Поэтому в сети IPv6 обмен сообщениями NS — NA происходит очень часто, что сильно играет на руку атакующему.

Угрозы конечных хостов


И раз уж заговорили про RA, то плавно перейдем к угрозам конечных хостов, и в частности к тем хостам, работа которых с IPv6 не планировалась. То есть рассмотрим атаку на хосты, работающие в дефолтной конфигурации IPv6, в обычной IPv4-сети. Что произойдет, если любая современная ОС получит пакет RA? Так как любая система сейчас поддерживает IPv6 и ожидает такие пакеты, то она сразу превратится в так называемый дуал стек. Это ситуация, когда в пределах одной ОС используется и IPv4, и IPv6 одновременно. При этом сразу же откроется целый ряд ранее недоступных векторов. Например, можно будет сканировать цель, ведь IPv4 обычно фильтруется, а про IPv6, как уже знаем, зачастую вообще не думают.

Кроме того, в большинстве ОС IPv6 имеет приоритет над IPv4. Если, например, придет запрос DNS, то большая вероятность, что IPv6 сработает раньше. Это открывает огромный простор для различных MITM-атак. Для проведения одной из самых эффективных потребуется разместить свой зловредный IPv6-маршрутизатор. Каждый маршрутизатор IPv6 должен присоединиться к специальной мультикаст-группе. Это FF02::2. Как только роутер присоединится к такой мультикаст-группе, он сразу же начинает рассылать сообщения — RA. Сisco-роутеры рассылают их каждые 200 с по дефолту. Еще один нюанс состоит в том, что клиентам не нужно ждать 200 с, они отправляют RS-сообщение — Router Solicitation — на этот мультикаст-адрес и таким образом незамедлительно требуют всю информацию. Весь этот механизм называется SLAAC — Stateless Address Autoconfiguration. И соответственно была разработана атака на него с очевидным названием SLAAC attack.

Атака заключается в том, что нужно установить свой роутер (не стоит понимать буквально, в роли роутера может выступать любой линукс или даже виртуальная машина), который будет рассылать сообщения RA, но это только полдела. Также атакующему потребуется запустить DHCPv6-сервер, DNSv6 и NAT64-транслятор. В качестве сервиса, способного рассылать сообщения RA, можно использовать Router Advertisement Daemon (radvd), это опенсорсная реализация IPv6-роутера. В итоге после правильной конфигурации всех демонов жертва получит RA и превратится в дуал стек и весь трафик жертвы будет абсолютно незаметно идти через IPv6.

На маршрутизаторе атакующего этот трафик будет перебиваться натом в обычный IPv4 и затем уже уходить на настоящий роутер. DNSv6-запросы также будут иметь приоритет и также будут обрабатываться на стороне атакующего.

Таким образом, атакующий успешно становится посередине и может наблюдать весь трафик жертвы. А жертва при этом ничего не будет подозревать. Такая атака несет максимальную угрозу, работает даже при использовании IPv4-файрволов и статических ARP-записей, когда, казалось бы, воздействовать на жертву нет никакой возможности.

Как же защищать IPv6


Если говорить про защиту от обозначенных выше атак, то сперва очевидно, что на периметре необходимо внимательно фильтровать весь трафик и отключать неиспользуемые сервисы, также отдельное внимание нужно уделять административным сервисам. Для того чтобы сократить воздействие локальных атак, направленных на служебный протокол ICMPv6, можно ограничивать поверхность таких атак, разбивая большие сети на подсети (что еще называется микросегментацией). Одна и та же сетевая инфраструктура может быть разделена на несколько вланов, с отдельным IPv6-префиксом для каждого такого влана. В таком случае атакующий сможет атаковать хосты, только находящиеся с ним в одном влане, что уже сильно ограничит возможный урон от атак.


Рис. 5. Схема SLAAC attack


Рис. 6. Результат SLAAC attack

Отдельно существует защита от ложных RA-сообщений, которые, как известно, должны приходить только от маршрутизаторов. Компания Cisco реализовала фичу под названием Router Advertisement Guard, которая предотвращает инжект недоверенных RA-сообщений, отдельно помечая потенциально небезопасные порты. То есть пакеты RA просто не будут приниматься с пользовательских портов. Работает эта фича по аналогии с DHCP-снупингом. Единственный минус в том, что доступна такая фича только на определенном классе железок — на каталистах серий 2960S, 3560 и 3750. Кроме того, в 2012 году появились DHCPv6 Guard и NDP Snooping, опять же это аналоги DHCP Snooping и Dynamic ARP Inspection из мира IPv4. Доступны эти защитные механизмы на каталистах 4500/4948 и на роутерах серии 7600.

Если рассматривать защиту конечных хостов, то все последние версии Windows позволяют полностью отключить обработку RA-сообщений. В случае если все IPv6-параметры конфигурируются вручную, это может быть неплохим вариантом, хотя и несколько ломает канонические механизмы IPv6. Выключается достаточно легко, прямо на интерфейсе командой

netsh int ipv6 set int X routerdiscovery=disabled


где X — это индекс интерфейса (просмотреть индексы IPv6-интерфейсов можно командой netsh int ipv6 show int). Проверяется результат командой netsh int ipv6 show int X.

Если же рассмотреть ситуацию с обнаружением атак IPv6, то в целом там все хорошо. Детектить IPv6-атаки достаточно легко, но пока их сложно превентить.

Завершаем рассказ


Что же имеем в сухом остатке? Как оказалось, сам по себе протокол IPv6 не безопаснее, но при этом и не дырявее, чем IPv4. Проблема лежит в недостаточных знаниях и опыте работы с этим протоколом. Нужно фильтровать IPv6 на периметре и выключать его, если он не используется на конечных устройствах. Многие люди считают, что IPv6 значительно безопаснее, чем IPv4, потому, что IPv6 требует использования IPsec. Но это миф. Да, IPsec может сразу работать в среде IPv6, но ни разу не является обязательным. IPv6 делает некоторые вещи лучше, другие — хуже, но большинство вещей просто отличаются от того, к чему все успели привыкнуть. Другими словами, протокол IPv6 не более или менее безопасен, чем IPv4, протокол IPv6 просто уникален и несет свои собственные соображения на счет безопасности.

Автор: Александр Дмитриенко, PentestIT



Впервые опубликовано в журнале «Хакер» от 11/2014.

Подпишись на «Хакер»