Русский
Русский
English
Статистика
Реклама

Mitm

L2TP amp IPsec with pre shared key vs MITM

31.05.2021 12:16:05 | Автор: admin

В статье рассмотрены основные vpn протоколы, которые на текущий момент применимы в бизнес процессах, а также углубленно освещен вопрос использования L2TP в связке с IPsec в режиме pre shared key. На практике разобраны подходы к организации виртуальных сетей на оборудовании MikroTik и выполнен практический аудит безопасности передачи данных с позиции анализа третьими лицами исходящего трафика при возможности MITM атаки.

Vpn технологии прочно вошли не только в корпоративную среду, но и в повседневную жизнь многих IT и других специалистов в реализации рабочих и личных проектов. Если перед вторыми вопрос безопасности может вставать исключительно с исследовательским интересом, то для бизнеса важно понимать риски, связанные с эксплуатацией различных информационных процессов в задействованной инфраструктуре, слабые и сильные места, а также экономическое обоснование применяемых решений. Безопасность стоит денег, но не всегда стоит подходить к этому вопросу, как к неприступной крепости, при условии правильной оценки складывающейся ситуации.

Для начала разберем, в каких случаях бизнесу нужен vpn:
при подключении удаленных сотрудников к сетевым ресурсам компании (site-to-client vpn) и
при объединении территориально разнесенных сетевых элементов (site-to-site vpn). Самих протоколов vpn сейчас много: GRE , PPTP, SSTP, OVPN, L2TP, Wireguard и т.д.

Здесь важно не путать протоколы с сервисами vpn, которых еще больше: ExpressVPN, CyberGhost, NordVPN и т.д. Вторые по сути являются провайдерами услуг, обеспечивая доступ клиентов к собственным ресурсам с целью обхода блокировок со стороны ISP, а также анонимности серфинга в интернете. Про них сейчас речь не идет.

С вариацией протоколов определились, какой же выбрать?
Во-первых, в зависимости от того, что строим site-to-client или site-to-site, потому что GRE для первого случая не подойдет.

Во-вторых, Wireguard хоть молодой, простой и очень перспективный, но на офисном маршрутизаторе Cisco или MikroTik его не поднять, вендоры даже не планируют внедрять. PPTP очень легок в настройке, однако будет либо не шифрованным, либо шифрованным протоколом MPPE, который не имеет аппаратной разгрузки, в следствие чего, многопользовательскую сеть замедлит в работе. SSTP отличный протокол, работает по TLS в UDP на 443 порту, пролезет через любой Firewall, а может даже и IDS. У некоторых вендоров, например, MikroTik, может работать по pre shared key вместо сертификата, запускается на Windows клиентах из коробки.
Из минусов: определенные танцы с бубном при настройке Linux клиентов (протокол все-таки от Microsoft) и отсутствие поддержки со стороны вендоров в аппаратной разгрузке. OpenVPN всем хорош, особенно высокой гибкостью. Можно туннелировать на L2, можно на L3, всего не перечислить. Не даром он open soft. Роутер MikroTik скоро научится работать с ним по UDP (ожидается в следующем поколении RouterOS), так как смысла в TCP нет, ведь соединение все равно проверяется во вложенном туннеле. Однако, скорее всего ваша офисная Cisco не умеет с ним работать, поэтому vpn сервер из нее не организовать.

Фактически, стандартом де-факто в корпоративной среде является протокол L2TP. Он работает на UDP, порт по умолчанию 1701. С шифрованием все хорошо, особенно наличие возможности аппаратной разгрузки IPsec. Есть вероятность, что ваш корпоративный MikroTik (несмотря на то, что он софтовый маршрутизатор) умеет шифровать IPsec на железе (смотри таблицу Hardware acceleration на сайте производителя ). У Cisco в этом вопросе дела обстоят еще лучше. Даже если ваш офисный роутер не умеет шифровать железом, никто кроме вас это знать не должен не будет.

Итак, подведем промежуточный итог: vpn технологии бизнесу нужны, использовать лучше всего L2TP. Закончив с затянувшейся вводной частью, перейдем непосредственно к теме статьи. Рассмотрим на примере оборудования MikroTik безопасность передачи данных в туннеле при возможности MITM атаки со стороны третьих лиц. Этот вопрос возникает в следствие того, что почти всегда в корпоративной среде используют L2TP в связке с IPsec в туннельном режиме и общим ключем для всей сети, вместо создания PKI и задействования сертификатов. Это удобно, сеть быстро разворачивается и легко обслуживается. Безопасно ли это в условиях компрометации pre shared key? Разберем на практике.

Начнем с того, что L2TP может быть не шифрованным:

/ppp profile name=test use-encryption=no


с интегрированным в протокол шифрованием MPPE:

/ppp profile name=test use-encryption=yes (или require, при этом IPsec отключен)



с качественным внешним шифрованием от IPsec, вроде AES:

/ppp profile name=test use-encryption=yes (или require, при этом IPsec включен)



Настройка L2TP сервера осуществляется достаточно просто, активируем его и указываем тип аутентификации:

/interface l2tp-server server set authentication=mschap2 default-profile=test enabled=yes


Здесь же появляется возможность сразу активировать IPsec и настроить pre shared key. Если это сделать, то общий ключ будет закреплен за всей vpn сетью и передан всем ее участникам в качестве настроечной информации. Один и тот же на всех. На самом деле, если активировать IPsec таким образом, то RouterOS автоматически создает необходимые настройки в соответствующем разделе /ip ipsec сразу после установления L2TP соединения.

Конкретно речь идет:

  • IPsec Policy с указанными протоколом UDP и портом подключения 1701;
  • IPsec Peer c IP адресами сервера и клиента;
  • IPsec Identity с указанным ранее pre shared key.

Автоматически созданные настройки IPsec

Очень удобно. Особенно, когда IP адреса динамические и вообще натированные. Клиентам не нужно выполнять лишние процедуры по отслеживанию их текущих значений. В RouterOS в разделе L2TP есть дополнительная настройка, определяющая общий секрет при конфигурировании в сетях Virtual Private DialUp Network протяженных соединений точка-точка между удаленным сервером PPPOE и L2TP сетью, но это к теме статьи не относиться, поэтому просто ее упомянем всуе:

/ppp l2tp-secret add address=0.0.0.0/0 secret=

Допустим, мы не хотим простого счастья и дополнительно желаем, чтобы у каждого клиента был индивидуальный сертификат вместо общего ключа (возможно, для этого в компании уже все готово). Звучит очень круто и безопасно. Нет технически не преодолимых проблем, кроме танцев с бубнами: создаем все вышеперечисленное в ручном режиме, не забываем про корректно заданные IP адреса, как со стороны сервера, так и со стороны клиентов.

/ip ipsec peer add address=IP local-address=IP name=peer1/ip ipsec identity add peer=peer1 auth-method=digital-signature certificate=u01.crt_0/ip ipsec policy add dst-address=IP dst-port=1701 peer=peer1 protocol=udp src-address=IP src-port=1701

Здесь нас поджидает кропотливая работа, ведь, скорее всего, адреса у клиентов меняются (и достаточно часто), кроме этого клиенты сидят за провайдорским NAT. Все это можно накрутить кастомными скриптами на RouterOS, и все будет отлично работать. Нужно ли это? Cмоделируем ситуацию, когда общий для всех pre shared key стал известен злоумышленнику, который целенаправленно хочет нам навредить. Или клиент vpn нам больше не клиент. Сразу баним его учетную запись, и теперь аутентификацию mschap2 (или какая у вас там выбрана) он не пройдет и доступ не получит:

/ppp secret disable bad_user

Если каким-то чудом у него есть возможность MITM, то есть пропускать трафик через себя, то толку в этом ровно никакого нет. Весь трафик зашифрован. Выдать себя за vpn сервер другим участникам корпоративной сети тоже не удастся. В подобном нереальном сценарии аутентификацию mschap2 клиенты не пройдут, ведь их секрет известен только им и вам, разумеется:

/ppp secret add name=good_user password=12345 service=l2tp

Шифрованный трафик L2TP туннеля

Исследовательский интерес нас ведет дальше. Может все-таки что-то можно сделать с трафиком? И в результате извлечь передаваемую информацию? Попробуем дешифровать трафик в лабораторных условиях. MikroTik позволяет нам выполнить debug соединения и увидеть подробную информацию об установленной IPsec сессии:

/ip ipsec installed-sa print

Как видно, сессия установилась на 30 минут, имеются разные ключи аутентификации и шифрования. Применим их в Wireshark, после приведения шестнадцатеричных значений к корректному формату: SPI 0x0ada181b, вместо MikroTik-овского 0xADA181B, ключи начинаются со значения 0x. Если все сделано правильно, тогда трафик откроется.

Ввод данных сессии для дешифрования IPsec

Дешифрованный IPsec

Подведем результаты

Насколько безопасно использовать L2TP c общим секретом? Абсолютно безоапасно. По сути IPsec с помощью pre shared key выполняет функцию аутентификации, но в нашем случае процедура аутентификации выполняется ранее при установлении L2TP соединения. Нет практической необходимости выполнять аутентификацию повторно. По сути MikroTik, введя возможность настройки IPsec в разделе создания L2TP сервера, автоматизирует рутинные задачи по настройке шифрованного туннеля в ручном режиме (история про танцы с бубном). Это еще один плюс в сторону использования не дорогостоящего, но качественного оборудования MikroTik. Конечно, в ручном режиме гораздо больше вариаций на тему шифрования, но по умолчанию задаются, по авторскому мнению, идеальные значения: aes256 и sha1.


Как рекомендации для бизнеса, смело можно использовать L2TP с IPsec pre shared key. При планировании политик информационной безопасности, нет необходимости в задании сложных значений для pre shared key. Важно выставить не угадываемые и не словарно подбираемые значения для аутентификации L2TP (/ppp secret). Удобно, безопасно и качественно, админ доволен, клиенты не замучены.


Подробнее..

MITM на уровне провайдера европейский вариант

20.07.2020 18:22:00 | Автор: admin
Говорим о новом законопроекте в Германии и более ранних инициативах с аналогичным уклоном.


/ Unsplash / Fbio Lucas

Как это может выглядеть


В начале месяца власти Германии внесли на рассмотрение законопроект, который позволит правоохранительным органам пользоваться инфраструктурой интернет-провайдеров для установки систем слежки на устройства граждан. Как сообщает издание Privacy News Online, принадлежащее VPN-провайдеру Private Internet Access и специализирующееся на новостях ИБ, для реализации MITM предположительно задействуют программное обеспечение FinFly ISP от компании FinFisher. Подробнее о нем уже говорили на Хабре в рамках аналогичной новости.

О чем еще мы пишем на Хабре:


В брошюре, предоставленной WikiLeaks, сказано, что софт FinFly ISP предназначен для работы в сетях интернет-провайдеров, совместим со всеми стандартными протоколами и может быть установлен на целевой компьютер вместе с обновлением программного обеспечения. Один из резидентов Hacker News в тематическом треде предположил, что систему можно будет использовать для реализации атаки QUANTUMINSERT. Как отмечают в Wired, её использовали в NSA еще в 2005 году. Она позволяет прочитать идентификаторы DNS-запросов и перенаправить пользователя на поддельный ресурс.

Очень старая практика


Еще в 2011 году эксперты из Chaos Computer Club (CCC) немецкого общества хакеров рассказали о программном обеспечении, используемом правоохранителями в Германии. Это троян, способный устанавливать бэкдоры и удаленно запускать программы. Также он умел делать скриншоты, включать камеру и микрофон компьютера. Уже тогда систему подвергли жесткой критике.

В 2015 году эту тему вновь вынесли на обсуждение. Встал вопрос конституционности подобной формы наблюдения. Как писала немецкая международная телерадиокомпания DW, представители политической организации Зеленая партия выступили против этой системы. Они отметили, что цели правоохранительных органов не оправдывают средства.


/ Unsplash / Thomas Bjornstad

История с MITM на уровне интернет-провайдера начала широко обсуждаться в треде на Hacker News. Несколько резидентов подняли вопрос о ситуации с приватностью персональных данных в целом.

Речь зашла и об обязательствах хранить данные на стороне интернет-провайдеров, а кто-то даже вспомнил кейс Crypto_AG. Это мировой производитель криптографического оборудования, которым тайно владело Центральное разведывательное управление США. Организация участвовала в разработке алгоритмов и давала указания по встраиванию бэкдоров. Довольно подробно эту историю также освещали на Хабре.

Что дальше


Окончательное решение по новому законопроекту еще не принято и его предстоит увидеть. Но уже сейчас понятно, что проблема подмены сайтов может стать еще более острой. Но кто уж точно сумет извлечь пользу из ситуации это VPN-провайдеры. Они уже упоминаются практически в каждой ветке или хабрапосте с подобной тематикой.

Что почитать в нашем корпоративном блоге:

Подробнее..

Новое применение Captive Portal для проведения MiTM атак

03.09.2020 22:12:42 | Автор: admin

Тема проведения Man in the Middle атаки в контексте Captive Portal стара как мир.
Как правило ведется речь о поднятии фейковой беспроводной точки доступа с собственным Captive порталом. Сегодня я покажу совершенно другой вектор атаки, выходящий за грани WiFi и применимый в том числе и в проводных Ethernet сетях.


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

Являясь непосредственным регулятором доступа в интернет, данный сетевой сервис обладает возможностями блокировать или пропускать соединения клиента. Попав в изолированную порталом сеть клиент должен каким-то образом понять, что для доступа в интернет требуется предварительная авторизация. Со стороны Captive Portal'а могут применяться следующие шаги:

1. Слать HTTP редиректы на все открытые веб запросы клиента.
2. Отвечать IP адресом портала на все DNS запросы.
3. Грубо редиректить весь веб траффик на страницу портала.

На стороне клиента так же имеются вспомогательные механизмы для детектирования наличия портала ловушки. Они разнятся у операционных систем и браузеров, но алгоритм, в целом, схож резольв определенного домена и проверка доступности какого-либо файла.

Для Windows Vista\7\8 это проверка www.msftncsi.com/ncsi.txt
Для Windows 10 www.msftconnecttest.com/connecttest.txt
Для iOS www.apple.com/library/test/success.html
Android и Chrome делают запрос /generate_204 на один из своих доменов.

Ключевым моментом здесь является использование голого HTTP. Это сделано для того, чтобы Captive Portal имел возможность послать редирект клиенту на страницу авторизации.

Теперь я опишу как можно создать Captive Portal используя один лишь Intercepter-NG и провести MiTM атаку.

Будем применять ARP Spoofing против выбранной для тестов цели, пусть это будет Windows 10. Затем нам нужно изолировать цель от интернета, как это делает настоящий портал-ловушка. В данном случае достаточно будет включить SSL MiTM и интернет в виде браузера и всех служб, использующих HTTPS в своей работе, перестанет функционировать, т.к. возникнут проблемы доверия к SSL сертификату.

Столкнувшись с недоступностью HTTPS у цели будут запущены описанные ранее механизмы проверки соединения. Специально для реализации Captive Portal'а в Intercepter был добавлен обработчик таких проверок, в итоге он отправит цели редирект на свой же IP адрес. В режиме FATE интерцептера используется простенький web сервер и там же можно выбрать шаблон со страницей портала. В итоге цель попадёт на созданный нами портал.

Вот несколько интересных моментов:

1. У Windows в фоне осуществляется множество различных процессов, использующих сеть. Если при их выполнении произойдет неудачное подключение, то может запуститься механизм определения состояния сети. Находясь под атакой Windows поймает редирект Intercepter'а и откроет браузер с нашим порталом. Представьте ситуацию: заблокирована пользовательская сессия, пользователь возвращается на рабочее место, авторизуется и тут же на экране всплывает веб страница атакующего.

2. Происходит атака, цель открывает Chrome и пытается зайти в Google. Выявляется ошибка SSL, т.к. включен MiTM, затем Chrome посылает запрос /generate_204 Intercepter отвечает ему редиректом и Chrome открывает в новой вкладке страницу портала.

Эта техника работает и в беспроводных и в проводных сетях, в любой момент времени, а не только после подключения к сети. Проведено несколько тестов на Android смартфонах полёт нормальный. С Apple пока непонятно, на iOS версий 12 и 13 при блокировке HTTPS не обнаружены никакие диагностические HTTP запросы, возможно удастся решить этот вопрос в будущем.

Область применения данного MiTM портала ограничена только фантазией. Чуть больше деталей и полноценная демонстрация представлена в следующем видео ролике. В нем показан перехват вводимых пользователем данных, авторизации Twitter с помощь SSL Strip и HSTS Spoofing, а так же перехват SSL авторизации Vkontakte.



Обновленную сборку можно скачать на Github

Информация дана для ознакомления, используйте для добрых дел. Доступен чат в телеграмме t.me/cepter_chat
Подробнее..

Перевод Как я угнал национальный домен Демократической Республики Конго

25.02.2021 16:13:17 | Автор: admin
Примечание: проблема решена. Сейчас национальный домен .cd уже не делегирует полномочия скомпрометированному нейм-серверу

TL;DR Представьте, что может произойти, если национальный домен верхнего уровня (ccTLD) суверенного государства попадет в чужие руки. Однако я (@Almroot) купил доменное имя, которое указано для делегирования NS в национальном домене Демократической Республики Конго (.cd), и временно принял более 50% всего DNS-трафика для этой TLD. На моём месте мог оказаться злоумышленник, который использовал бы эту возможность для MITM или других злоупотреблений.



Вступление


За неделю до Рождества я решил провести анализ всех записей NS для всех TLD в мире. И моё внимание привлекло одно обстоятельство. У домена scpt-network.com был указан код статуса EPP redemptionPeriod. Это означает, что владелец не перечислил деньги за продление домена. Если владелец продолжит игнорировать оплату, то у него отберут собственность и домен поступит в свободную продажу.

Довольно проблематичная ситуация, поскольку он входит в список NS-серверов, управляющих зоной .cd:

almroot@x:~$ dig NS +trace cd | grep "cd."cd.172800INNSns-root-5.scpt-network.com.cd.172800INNSigubu.saix.net.cd.172800INNSsangoma.saix.net.cd.172800INNSns-root-2.scpt-network.com.cd.172800INNSsabela.saix.net.cd.172800INNSns-root-1.scpt-network.com.

Я решил на всякий случай написать bash-скрипт, который уведомит меня при любом изменении EPP-статуса.

К моему удивлению, примерно через неделю пришло уведомление, что домен перешёл в статус pendingDelete.

Я осознавал всю серьёзность ситуации. Доменное имя вскоре выставят на продажу для всех желающих, то есть любой человек может элементарно завладеть нейм-сервером .cd.

Я изменил скрипт и начал поминутно пинговать регистратора на предмет дальнейших изменений статуса.

Вечером 30 декабря пришло уведомление. Я открыл ноутбук и купил доменное имя, чтобы оно не попало в чужие руки.



Поскольку оставались ещё три записи делегирования на SAIX (South African Internet eXchange, Южноафриканская точка обмена трафиком), национальный домен сохранил работоспособность (хотя скорость резолвинга любых доменов немного уменьшилась).

Завладев scpt-network.com, я мог настроить любой поддомен на своё усмотрение. Например, если создать новый поддомен ns-root-1 с A-записью, которая указывает на IP-адрес 1.3.3.7, то на этот адрес 1.3.3.7 пойдут DNS-запросы для зоны .cd. Любой DNS-ответ на эти запросы будет принят как легитимный.



Если не ответить на запрос, то абонент словит таймаут с кодом состояния SERVFAIL. Это хорошо, потому что при получении такого кода он попытается связаться с любым другим сервером имён (NS record) для этой зоны. Так он в конечном итоге попадёт в одну из нормальных записей SAIX и будет соответствующим образом перенаправлен в нужное место назначения.

Потенциальное влияние


Захват национального домена верхнего уровня суверенного государства имеет серьёзные негативные последствия, особенно если этот домен попадёт в руки киберпреступников или иностранного противника. Демократическая Республика Конго (ДРК) немаленькая страна. Это примерно 90 миллионов человек, не говоря о многочисленных международных компаниях и организациях, работающих в этой доменной зоне.

Угон DNS-записи TLD целой страны явление редкое, но не новое. Например, десять лет назад киберпреступники захватили домен бывшего Советского Союза (.su), а в 2015 году вьетнамские сайты Lenovo и Google (.vn) также стали жертвами угона DNS. Перенаправление DNS-трафика с легальных сайтов .cd на фишинговый сайт одна из очевидных возможностей для злоупотреблений, но есть и другие:

  • Пассивный перехват DNS-трафика
    для слежки или эксфильтрации данных
  • Создание новых доменных имён из воздуха
    представьте себе возможности для быстрой генерации новых доменных имён с переключением ботнета на новые командные серверы каждые несколько минут, так что их никто не успевает заблокировать (техника fast flux)
  • Атаки с удалённым выполнением кода (RCE) в локальных сетях
    жертвами станут компании, которые используют протокол WPAD (протокол автоматической настройки прокси)
  • Поддельные DNS-ответы на законные DNS-запросы
    полный захват корневых доменов в зоне .cd или проведение DDoS-атаки.

Например, я мог написать эксплоит для захвата конкретного домена в зоне .cd. Представьте, что для любых NS-запросов к google.cd я всегда возвращаю ответы ns-root-1.scpt-network.com (вместо этих четырёх: [ns1,ns2,n3,ns4].google.com). Абонент получит такой ответ, и отправит любые последующие DNS-запросы к ns-root-1.scpt-network.com.

Это также заставило меня задуматься: а что, если отвечать на все NS-запросы ссылкой на себя. Тогда для любого запроса, на который ответит 1.3.3.7, все поиски домена в конечном итоге пойдут по этой ссылке. И весь последующий сетевой трафик будет перенаправлен на 1.3.3.7, что может привести к DDoS-атаке.

На самом деле это также повлияет на доступность всей TLD, ведь 50% DNS-ответов станут неправильными. Силу (обеих) DoS-атак можно увеличить путём установки высокого TTL в ответах DNS.

Сделаем ещё один шаг вперёд. Скажем, я конкретно подделываю TXT-записи для сервера google.cd. С помощью поддельных текстовых файлов я обманываю
систему проверки DNS-01 у регистратора Lets Encrypt и получаю действительный сертификат для google.cd, после чего эффективно взламываю зашифрованный канал SSL/TLS.

Поскольку я могу контролировать делегирование NS-серверов для любого домена .cd и получить валидные сертификаты, то могу провести MITM-атаку даже если жертва использует SSL/TLS.

Примечание переводчика. Некоторые описанные методы доступны государственным службам, которые контролируют национальные домены в своих странах.

В то время как Google применяет различные контрмеры против таких злоупотреблений, можно с уверенностью сказать, что это не относится ко всем корневым доменам в зоне .cd. Дополнительную информацию о том, как удостоверяющие центры проверяют право собственности на домены, см. в BR 1.7.3.

И последнее, но не менее важное: имея привилегированный доступ на вышестоящий хост с контролем DNS, я могу проникнуть в локальные сети компаний (пример на скриншоте ниже), которые отправляют DNS-запросы для WPAD можно отслеживать их запросы, подделать ответы и перенаправить жертву для загрузки и выполнения вредоносной конфигурации прокси-сервера на JS. У протокола WPAD своя куча проблем, включая уязвимости RCE, как рассказывали хакеры из команды Project Zero в Google.



Исправление проблемы


7 января 2021 года я связался с административными и техническими контактами, указанными для зоны .cd на странице IANA. Первоначально я хотел передать домен оператору .cd.

Хотя один из контактов ответил и направил меня к коллеге, на момент написания этой статьи я не получил письменного подтверждения, что они устранили проблему. Но вскоре DNS-трафик перенаправили на scpt-network.net.

8 января я также отправил отчёт по программе Internet Bug Bounty в HackerOne, которая предлагает вознаграждение за ответственный взлом инфраструктуры интернета.

Заключение


Угон DNS-сервера несёт крайне негативные последствия, особенно если у злоумышленника плохие намерения. Эта уязвимость затрагивает не только один сайт, поддомен или один корневой домен. Жертвой фишинга, MITM или DDoS может стать абсолютно любой сайт .cd, включая сайты крупных международных компаний, финансовых учреждений и других организаций. А это вторая по численности страна Африки и популярная доменная зона.

На момент написания этой статьи я всё ещё владею доменным именем scpt-network.com хотя делегирование NS-запросов из зоны .cd прекратились примерно 8 января 2021 года после того, как я с ними связался. Эту операцию я провёл для того, чтобы предотвратить захват злоумышленниками доменной зоны Демократической Республики Конго, когда любой желающий мог угнать доменное имя одного из серверов, управляющих ccTLD. К счастью, в этом случае всё обошлось.
Подробнее..

Сим-сим откройся как я научил дверь своего подъезда узнавать меня в лицо

07.06.2021 18:08:54 | Автор: admin

Пятничный рабочий день на удалёнке уже подходил к концу, как в дверь постучали, чтобы сообщить об установке нового домофона. Узнав, что новый домофон имеет мобильное приложение, позволяющее отвечать на звонки не находясь дома, я заинтересовался и сразу же загрузил его на свой телефон. Залогинившись, я обнаружил интересную особенность этого приложения даже без активного вызова в мою квартиру я мог смотреть в камеру домофона и открывать дверь в произвольный момент времени. "Да это же онлайн АРI к двери подъезда!" щёлкнуло в голове. Судьба предстоящих выходных была предрешена.

Видеодемонстрация в конце статьи.

Кадр из фильма Пятый ЭлементКадр из фильма Пятый Элемент

Дисклеймер

Используемая технология аутентификации на основании распознавания лиц не учитывает множества сценариев атак и недостаточна для обеспечения безопасности. Описанная система анализа кадров была активна только в моменты, когда кому-то из моей семьи было необходимо попасть в подъезд она не совершала автоматическую обработку лиц других людей и не могла привести к допуску в подъезд третьих лиц.

Получение API

Чтобы автоматизировать управление дверью, необходимо понять, куда и в каком формате отправляет запросы само приложение. Реверс-инжиниринг дело неоднозначное, поэтому я попытался обойтись без него и вместо этого просто перехватить свой собственный трафик. Для этой задачи я взял НТТР Тооlkit комплекс программ, который позволяет наладить прослушивание http(s) запросов собственного Android устройства.

Первая попытка оказывается провальной после установки на телефон Android-части инструментария и сгенерированного Certificate authority оказалось, что мобильное приложение домофона не доверяет пользовательским СА. Согласно документации, начиная с Android 7 манифест приложения должен явно изъявлять такое желание.

Так как мой телефон не поддерживает root доступ для модификации списка системных СА, я воспользовался официальным эмулятором Android, идущим в комплекте с Android Studio. После запуска эмулятора и перехвата с помощью ADB меня встретило радостное сообщение о том, что трафик от всех приложений без Certificate pinning будет успешно расшифрован.

Успешное соединение с HTTP ToolkitУспешное соединение с HTTP Toolkit

К счастью, приложение оказалось как раз из таких немного побродив по приложению и открыв дверь, можно переходить к анализу логов.

Запрос открытия двериЗапрос открытия двери

Всего интересными показалось три запроса:

  1. Запрос на открытие двери подъезда: POST по адресу /rest/v1/places/{place_id}/accesscontrols/{control_id}/actions с JSON-телом {"name": "accessControlOpen"}

  2. Получение снимка (превью) с камеры: GET по адресу /rest/v1/places/{place_id}/accesscontrols/{control_id}/videosnapshots

  3. Получение ссылки на видеопоток с аудио: GET по адресу /rest/v1/forpost/cameras/{camera_id}/video?LightStream=0

HTTP заголовки всех трёх запросов содержат ключ Authorization судя по всему, именно по нему происходит авторизация при выполнении запросов. Сделав пару запросов руками через Advanced REST Client, чтобы убедиться, что заголовка Authorization достаточно и в самостоятельной работе с API не осталось подводных камней, я понял, что можно откладывать эмулятор и переходить к написанию кода.

Вооружившись Python и requests, я написал необходимые для следующих этапов функции исполнения каждого из трёх действий:

HEADERS = {"Authorization": "Bearer ###"}ACTION_URL = "https://###.ru/rest/v1/places/###/accesscontrols/###/"VIDEO_URL = "https://###.ru/rest/v1/forpost/cameras/###/video?LightStream=0"def get_image():    result = requests.get(f'{ACTION_URL}/videosnapshots', headers=HEADERS)    if result.status_code != 200:        logging.error(f"Failed to get an image with status code {result.status_code}")        return None    logging.warning(f"Image received successfully in {result.elapsed.total_seconds()}sec")    return result.contentdef open_door():    result = requests.post(        f'{ACTION_URL}/actions', headers=HEADERS, json={"name": "accessControlOpen"})    if result.status_code != 200:        logging.error(f"Failed to open the door with status code {result.status_code}")        return False    logging.warning(f"Door opened successfully in {result.elapsed.total_seconds()}sec")    return Truedef get_videostream_link():    result = requests.get(VIDEO_URL, headers=HEADERS)    if result.status_code != 200:        logging.error(f"Failed to get stream link with status code {result.status_code}")        return False    logging.warning(f"Stream link received successfully in {result.elapsed.total_seconds()}sec")    return result.json()['data']['URL']

Поиск знакомых лиц в кадре

Прежде чем начать этот раздел, нужно рассказать пару слов об уже имеющихся на тот момент у меня в распоряжении серверных мощностях это недорогая виртуальная машина с доступом ко всего одному потоку Intel(R) Xeon(R) CPU E5-2650L v3 @ 1.80GHz, 1GB оперативной памяти и 0 GPU. Тратиться на более дорогую конфигурацию не хотелось, а значит, нужно было попробовать выжать максимум из имеющихся ресурсов.

На данном этапе проектом заинтересовалась моя жена, хорошо разбирающаяся в машинном обучении и в итоге взявшая на себя эту задачу. Для этой работы был выбран OpenVINO Toolkit инструментарий от Intel, в том числе заточенный как раз на запуск моделей машинного обучения на CPU.

Непродолжительный поиск существующих решений привёл на страницу Interactive Face Recognition Demo официального демо, показывающего ровно необходимый функционал сравнения видимых в кадре лиц с базой заранее сохранённых. Единственная проблема состояла в том, что данный пример по каким-то причинам исчез после релиза 2020.3, а удобная установка пакета через pip у проекта появилась только с 2021.1. Было решено установить последнюю версию OpenVINO и адаптировать код под неё.

К счастью, гит помнит всё и получить из репозитория проекта код демо и нужные модели не составило труда. После удаления всей работы с командной строкой (взяв для всего значения по умолчанию), визуализацией и видеопотоком вебкамеры, был получен класс, способный распознавать лица в конкретном кадре:

class ImageProcessor:    def __init__(self):        self.frame_processor = FrameProcessor()    def process(self, image):        detections = self.frame_processor.process(image)        labels = []        for roi, landmarks, identity in zip(*detections):            label = self.frame_processor.face_identifier.get_identity_label(                identity.id)            labels.append(label)        return labels

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

100 runs on an image with known face:Total time: 7.356sTime per frame: 0.007sFPS: 135.944100 runs on an image without faces:Total time: 2.985sTime per frame: 0.003sFPS: 334.962

Очевидно, что показанная производительность с запасом покрывает нужды детектирования лиц в реальном времени.

1 FPS: Работа со снимками с камеры

Итак, на этом этапе у меня уже был класс для поиска заданных лиц в кадре, а также функции получения снимка с камеры и ссылки на видеопоток. С видео на тот момент я никогда не работал, потому для MVP решил переложить работу по выделению кадров на сервер и снова воспользоваться get_image().

class ImageProcessor:# <...>    def process_single_image(self, image):        nparr = np.fromstring(image, np.uint8)        img_np = cv2.imdecode(nparr, cv2.IMREAD_COLOR)        labels = self.process(img_np)        return labelsdef snapshot_based_intercom_id():    processor = ImageProcessor()    last_open_door_time = time.time()    while True:        start_time = time.time()        image = get_image()        result = processor.process_single_image(image)        logging.info(f'{result} in {time.time() - start_time}s')        # Successfull detections are "face{N}"        if any(['face' in res for res in result]):            if start_time - last_open_door_time > 5:                open_door()                with open(f'images/{start_time}_OK.jfif', 'wb') as f:                    f.write(image)                last_open_door_time = start_time

Цикл получает картинки от домофона, ищет на них знакомые лица, открывает дверь в случае успешной детекции и сохраняет фото на память. Важно было не забыть ограничить частоту отправки команды открытия двери, т.к. лицо обычно распознаётся ещё на подходах к двери.

Момент успешного распознавания, версия с обработкой отдельных снимковМомент успешного распознавания, версия с обработкой отдельных снимков

Заработало! Полностью довольный первым запуском, я вернулся в квартиру. Единственное, что портило впечатление от системы распознавания время реакции на появление лица в кадре, т.к. время отклика API оставляло желать лучшего. Низкая частота поступления данных, 0.7с на получение картинки и 0.6с на открытие двери, давали видимый невооружённым взглядом лаг.

До 30 FPS: Обработка видеопотока

Получить кадры из видео оказалось на удивление просто:

vcap = cv2.VideoCapture(link)success, frame = vcap.read()

Замеры показали, что камера домофона способна выдавать стабильные 30 FPS. Проблемой оказалось поддержание меньшей частоты кадров: метод read() возвращает последний необработанный кадр из внутренней очереди кадров. Если эта очередь наполняется видеопотоком быстрее, чем вычитывается, то обрабатываемые кадры начинают отставать от реального времени, что приводит к нежелательной задержке. Дополнительно, с практической точки зрения, распознавать лица 30 раз в секунду пустая трата вычислительных ресурсов, так как обычно люди подходят к двери подъезда с небольшой скоростью.

Первым потенциальным решением было установить размер внутренней очереди: vcap.set(CV_CAP_PROP_BUFFERSIZE, 0);. Согласно найденной информации, такой трюк должен был хорошо работать с любой конфигурацией системы для версий OpenCV выше 3.4, но по какой-то причине, так и не оказал никакого влияния в моём случае. Единственной рабочей альтернативой стал подход, описанный в этом ответе со StackOverflow завести отдельный поток, читающий кадры из камеры на максимально возможной скорости и сохраняющий последний в поле класса для дальнейшего доступа (впоследствии оказалось, что именно этот цикл ответственен за большую часть потребления процессора).

Получилась модификация ImageProcessor для обработки видеопотока с частотой 3 кадра в секунду:

class CameraBufferCleanerThread(threading.Thread):    def __init__(self, camera, name='camera-buffer-cleaner-thread'):        self.camera = camera        self.last_frame = None        self.finished = False        super(CameraBufferCleanerThread, self).__init__(name=name)        self.start()    def run(self):        while not self.finished:            ret, self.last_frame = self.camera.read()    def __enter__(self): return self    def __exit__(self, type, value, traceback):        self.finished = True        self.join()class ImageProcessor:# <...>    def process_stream(self, link):        vcap = cv2.VideoCapture(link)        interval = 0.3 # ~3 FPS        with CameraBufferCleanerThread(vcap) as cam_cleaner:            while True:                frame = cam_cleaner.last_frame                if frame is not None:                    yield (self.process(frame), frame)                else:                    yield (None, None)                time.sleep(interval)

И соответствующая модификация snapshot_based_intercom_id:

def stream_based_intercom_id():    processor = ImageProcessor()    link = get_videostream_link()    # To notify about delays    last_time = time.time()    last_open_door_time = time.time()    for result, np_image in processor.process_stream(link):        current_time = time.time()        delta_time = current_time - last_time        if delta_time < 1:            logging.info(f'{result} in {delta_time}')        else:            logging.warning(f'{result} in {delta_time}')        last_time = current_time        if result is None:            continue        if any(['face' in res for res in result]):            if current_time - last_open_door_time > 5:                logging.warning(                  f'Hey, I know you - {result[0]}! Opening the door...')                last_open_door_time = current_time                open_door()                cv2.imwrite(f'images/{current_time}_OK.jpg', np_image)

Тест в реальных условиях показал ощутимое падение времени отклика при хорошем освещении подъездная дверь оказывалась открытой ещё до того, как я успевал подойти к ней вплотную.

Момент успешного распознавания, версия с обработкой видеопотокаМомент успешного распознавания, версия с обработкой видеопотока

Управление с помощью Telegram бота

Сама система доказала свою работоспособность и теперь хотелось создать для неё удобный интерфейс для включения/выключения. Телеграм бот показался отличным вариантом решения для этой задачи.

С помощью пакета python-telegram-bot была написана простая оболочка, принимающая в себя callback включения/выключения системы и список доверенных никнеймов.

class TelegramInterface:    def __init__(self, login_whitelist, state_callback):        self.state_callback = state_callback        self.login_whitelist = login_whitelist        self.updater = Updater(            token = "###", use_context = True)        self.run()    def run(self):        dispatcher = self.updater.dispatcher        dispatcher.add_handler(CommandHandler("start", self.start))        dispatcher.add_handler(CommandHandler("run", self.run_intercom))        dispatcher.add_handler(CommandHandler("stop", self.stop_intercom))        self.updater.start_polling()    def run_intercom(self, update: Update, context: CallbackContext):        user = update.message.from_user        update.message.reply_text(            self.state_callback(True) if user.username in self.login_whitelist else 'not allowed',            reply_to_message_id=update.message.message_id)    def stop_intercom(self, update: Update, context: CallbackContext):        user = update.message.from_user        update.message.reply_text(            self.state_callback(False) if user.username in self.login_whitelist else 'not allowed',            reply_to_message_id=update.message.message_id)    def start(self, update: Update, context: CallbackContext) -> None:        update.message.reply_text('Hi!')                class TelegramBotThreadWrapper(threading.Thread):    def __init__(self, state_callback, name='telegram-bot-wrapper'):        self.whitelist = ["###", "###"]        self.state_callback = state_callback        super(TelegramBotThreadWrapper, self).__init__(name=name)        self.start()    def run(self):        self.bot = TelegramInterface(self.whitelist, self.state_callback)

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

def stream_based_intercom_id_with_telegram():    processor = ImageProcessor()    loop_state_lock = threading.Lock()    loop_should_run = False    loop_should_change_state_cv = threading.Condition(loop_state_lock)    is_loop_finished = True    loop_changed_state_cv = threading.Condition(loop_state_lock)    def stream_processing_loop():        nonlocal loop_should_run        nonlocal loop_should_change_state_cv        nonlocal is_loop_finished        nonlocal loop_changed_state_cv        while True:            with loop_should_change_state_cv:                loop_should_change_state_cv.wait_for(lambda: loop_should_run)                is_loop_finished = False                loop_changed_state_cv.notify_all()                logging.warning(f'Loop is started')            link = get_videostream_link()            last_time = time.time()            last_open_door_time = time.time()            for result, np_image in processor.process_stream(link):                with loop_should_change_state_cv:                    if not loop_should_run:                        is_loop_finished = True                        loop_changed_state_cv.notify_all()                        logging.warning(f'Loop is stopped')                        break                current_time = time.time()                delta_time = current_time - last_time                if delta_time < 1:                    logging.info(f'{result} in {delta_time}')                else:                    logging.warning(f'{result} in {delta_time}')                last_time = current_time                if result is None:                    continue                if any(['face' in res for res in result]):                    if current_time - last_open_door_time > 5:                        logging.warning(f'Hey, I know you - {result[0]}! Opening the door...')                        last_open_door_time = current_time                        open_door()                        cv2.imwrite(f'images/{current_time}_OK.jpg', np_image)    def state_callback(is_running):        nonlocal loop_should_run        nonlocal loop_should_change_state_cv        nonlocal is_loop_finished        nonlocal loop_changed_state_cv        with loop_should_change_state_cv:            if is_running == loop_should_run:                return "Intercom service state is not changed"            loop_should_run = is_running            if loop_should_run:                loop_should_change_state_cv.notify_all()                loop_changed_state_cv.wait_for(lambda: not is_loop_finished)                return "Intercom service is up"            else:                loop_changed_state_cv.wait_for(lambda: is_loop_finished)                return "Intercom service is down"    telegram_bot = TelegramBotThreadWrapper(state_callback)    logging.warning("Bot is ready")    stream_processing_loop()

Результат

Видео:

Послесловие

Несмотря на возможности, которые технология умных домофонов несёт жильцам, объединённые в единую сеть сотни (тысячи?) подъездных дверей с камерами и микрофонами (да, в произвольно получаемом видеопотоке есть и аудио!), ведущими непрерывную запись как по мне, скорее пугающее явление, открывающее новые возможности для нарушения приватности.

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

Подробнее..

Что может предложить экспериментальная система коммуникаций для защиты от MITM-атак

24.01.2021 02:22:11 | Автор: admin

Специалист Техасского университета в Остине и Нью-Йоркского университета вместе с экспертом исследовательского подразделения MSR предложили оригинальный подход к разработке систем связи. Обсуждаем особенности и ограничения пробного протокола.

Unsplash / Jon TysonUnsplash / Jon Tyson

Как она может работать

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

Он поддерживает большее число пользователей по сравнению с аналогами и не боится компрометации систем, обслуживающих проект. В случае экспериментального Pung-кластера это четыре севера с пропускной способностью в 135 тыс. сообщений пользователей в минуту.

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

В этом случае система автоматически генерирует послания так, чтобы по своим базовым характеристикам они не выделялись из общего числа сообщений пользователя. Это решение стало ключевой особенностью и потенциальным недостатком протокола.

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

Unsplash / Daria NepriakhinaUnsplash / Daria Nepriakhina

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


Дополнительное чтение у нас на Хабре:


Стоит заметить, что разработку опубликовали давно, но в этом году, кажется обновили репозиторий. Так или иначе, на момент выхода статьи авторы говорили о проблеме холодных сообщений, когда пользователь определяется с получателем. Для Pung не придумали чего-то кроме массовой рассылки приглашений всех участников, что является не самым элегантным решением. Еще система может быть подвержена блокировке на стороне провайдера и этот момент разработчики указали в списке потенциальных ограничений для научного проекта.

Зачем все это нужно

Ранее мы рассказывали о MITM-атаках на стороне некоторых европейских провайдеров, когда службы правопорядка загружали в их сеть программное обеспечение, позволяющее подменять обновления ПО. Подобные практики отмечали и в WikiLeaks. Еще мы говорили о том, как провайдеры торгуют метаданными клиентов, и попытках Фонда электронных рубежей (EFF) урегулировать подобные практики. Внедрение оптимизированной версии Pung или его альтернативы могло бы защитить пользовательские данные на уровне протокола.

Unsplash / Jaroslav DeviaUnsplash / Jaroslav Devia

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


Что еще почитать у нас в блоге:


Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru