Fuck 2fa! обходим двухфакторную аутентификацию с помощью modlishka

В начале 2019 года польский исследователь Пётр Душиньский (Piotr Duszyński) выложил в открытом доступе реверс-прокси Modlishka. По его словам, этот инструмент может обойти двухфакторную аутентификацию, что мы сейчас и проверим.

Если сравнить его с тем же SEToolkit (он встроен практически во все популярные дистрибутивы для пентеста), то разница вот в чем: SET клонирует и размещает на локальном сервере страницу авторизации. Там все основано на работе скриптов, которые перехватывают вводимые учетные данные жертвы. Можно, конечно, настроить редирект на оригинальный сайт, но трафик от жертвы до твоего сервера будет незашифрованным. По сути, такого рода программы выступают в роли web-серверов с поддельным (фишинговым) сайтом.

Modlishka действует иначе. Генерируется свой сертификат, которым шифруется соединение от жертвы до нашего сервера (чтобы не палиться). Затем эта машина выступает в роли обратного прокси.

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

Поднимаем стенд
Давай поднимем сервер с Modlishka внутри локальной машины. Я сделаю это на примере Kali Linux, но принципиальной разницы для других дистрибутивов не будет — разве что слегка изменится путь к исходникам Go.

Вначале ставим Go — на этом языке написан реверс-прокси, и без Go он не скомпилируется.

Код:

$ apt-get install golang

Следом указываем путь к директории исходников:

Код:

$ export GOPATH='/root/go'

Проверить все можно командой

Код:

$ go env

В выводе должен быть указан GOPATH.

Затем клонируем ветку с инструментом.

Код:

$ go get -u github.com/drk1wi/Modlishka
$ cd /root/go/src/github.com/drk1wi/Modlishka/

Создаем сертификат:

Код:

$ openssl genrsa -out secret.key 2048
$ openssl req -x509 -new -nodes -key secret.key -sha256 -days 1024 -out cert.pem

Теперь необходимо перенести содержимое ключа и сертификата в файл plugin/autocert.go и заменить значение двух переменных: const CA_CERT — значение сертификата (файл pem); const CA_CERT_KEY — значение ключа (файл key).

Теперь собираем все это дело:

Код:

$ make

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

Сам запускаемый файл находится в директории dist/ под названием proxy. Для проверки можно запустить с ключом -h — вывод справки.

Код:

$ ./dist/proxy -h

Ловим учетные данные и сессию жертвы

Как я писал выше, чтобы создать прозрачный для жертвы шифрованный канал до нашего реверс-прокси, необходимо сперва экспортировать в браузер сертификат. Дальнейшие действия разбираются на примере Mozilla Firefox x64 v. 67.0.

Перед запуском взглянем внимательно на содержимое еще одного файла в директории templates. Нам интересен google.com_gsuite.json. Подробное описание каждого пункта можно найти в гайде по этому конфигу.

Код:

$ ./dist/proxy -target https://google.com -phishingDomain loopback.modlishka.io -listeningPort 443 -tls

Запуск с использованием конфигурационного файла:

Код:

$ ./dist/proxy -config /templates/google.com_gsuite.json

Запустим из конфига и перейдем в браузере по адресу loopback.modlishka.io. Нам откроется страница google.com. Входим в аккаунт и видим, как в выводе терминала появляются учетные данные жертвы.

Если перейти по адресу loopback.modlishka.io/SayHello2Modlishka (очень символично), то получим консоль управления перехваченной сессией (в данный момент это бета-функция). На данном этапе мы перехватили логин и пароль жертвы безо всяких ошибок с шифрованием и в «защищенном» соединении. Насколько мне известно, другие инструменты аналогичного назначения такого не умеют.

Что же теперь делать с двухфакторной аутентификацией? А вот что: в панели управления есть незаполненное поле UUID, и эта цифра — ключ ко всему.

Если сразу нажать на кнопку Impersonate user (beta), то откроется пустая вкладка, и в консоли Modlishka нам подскажет, что нет UID пользователя. Его необходимо задать, а задается он в самом начале — указывается в ссылке на наш злой URL. Для этого вернемся к конфигурационному файлу.

Нам интересна строка «trackingParam»: «ident». В ней необходимо задать значение ident, чтобы наш URL выглядел следующим образом:

Код:

https://loopback.modlishka.io/?ident=1

Именно на такой (или дополнительно обфусцированный) URL необходимо направить жертву.

На этот раз, после перехода и авторизации по такой ссылке, в панели управления (loopback.modlishka.io/SayHello2Modlishka) будет доступна сессия с заполненным UUID. Как именно это выглядит, я покажу чуть позже на реальном примере. Теперь при нажатии на большую желтую кнопку мы увидим красивую синюю анимацию и через пять-десять секунд попадем в авторизованную сессию жертвы, невзирая на трудности двухфакторной авторизации. Жертва, как обычно, получит и введет подтверждающий код, видя зашифрованное соединение и настоящую панель авторизации Google, но не замечая вклинившегося посередине реверс-прокси Modlishka. Хоть я и привел Wiki по всем параметрам конфигурационного файла, есть еще один момент. После того как жертва ввела учетные данные, желательно предотвратить выход из аккаунта и сохранить авторизованную сессию. Это делает параметр terminateTriggers. Если в этом параметре указать URL, на который попадет пользователь после успешной авторизации, то при появлении такого адреса весь трафик начнет перенаправляться на оригинальный URL, а авторизованная сессия не будет тронута даже после выхода из аккаунта.

Готовый комплект за NAT

Атаковать внутри одной машины или ЛВС оказалось не так сложно, а вот с подготовкой в качестве PoC «боевого» стенда в WWW у меня поначалу вышла заминка. Для него понадобится либо перенаправление на белый (внешний) IP-адрес, либо выделенный сервер с таким адресом. Арендовать сервер можно от 300 рублей в месяц.

Когда я поднимал этот сервер на Kali Linux, проблем не было. На VDS стояла Ubuntu Server 16.4, и при установке Golang оказалось, что в указанных по умолчанию репозиториях лежит очень старая версия Go, которая при компиляции выдавала массу ошибок. В таком случае необходимо добавить актуальные репозитории Go и установить свежую версию.

Первая проблема заключается в доменном имени. Если перейти с компьютера жертвы на URL loopback.modlishka.io, то ничего не выйдет, так как внешние и неподконтрольные нам DNS не знают такого адреса. Если же перенаправить на IP-адрес машины с Modlishka, то жертва попадет прямиком на страницу Google, минуя прокси-сервер, а в выводе терминала увидим две строки:

Код:

Host 192.168.1.15 does not contain the phishing domain
Redirecting client to google.com

Если жертва в той же локальной сети, то можно задать соответствие IP — URL в местном DNS или в ее файле hosts. В моем случае это было так:

Код:

192.168.1.15 loopback.modlishka.io

В интернете я сначала попробовал зарегистрировать бесплатный домен 3-го уровня. Предполагал, что этого хватит, но не тут-то было! При переходе оказывалась лишь страница, что сайт недоступен, а при вводе IP-адреса через HTTPS редиректило на Google. По простому HTTP и вовсе открывалась приветственная страница Apache. Как обычно, дьявол кроется в деталях. При переходе по URL в глобальной сети автоматом добавляется префикс www, а программа ждала чистого обращения к домену. Добавление www в конфиг не помогло, и пришлось добывать в свои владения полный пул поддоменов. Другими словами, если домен выглядит как loopback.modlishka.io, то иметь необходимо *.loopback.modlishka.io. Следующая загвоздка касается сертификатов. Необходимо на зарегистрированный домен сделать сертификат и ключ. В идеале необходимо подписывать сертификат в удостоверяющем центре, но для теста можно использовать и самоподписанный. Идем на любой генератор сертификатов, делаем и скачиваем два файла. Их содержимое надо подставить в конфигурационный файл Modlishka соответственно полям «cert»: «» и «certKey»: «». Небольшая ремарка: сертификат и ключ должны указываться в одну строку, а перенос строки, как обычно, задается последовательностью \n. Выглядеть должно примерно так:

Код:

"cert": "-----BEGIN CERTIFICATE-----MIIDJTCCAg2gAwIBAgIESjdT0DANBgkqhkiG9w0BAQsFADApMScwJQYDVQQDDB5SZWdlcnkgU2Vs...".

Также в конфигурационном файле нам необходимо изменить пару других параметров: «phishingDomain»: «loopback.modlishka.io» — тут вместо loopback.modlishka.io подставляем свой домен; «listeningAddress»: «127.0.0.1» — нужно заменить на 0.0.0.0, иначе прослушивается лишь lo-интерфейс, а работать все будет только внутри локальной машины. Modlishka каждый раз разворачивается для конкретных доменных имен. Поэтому лучше изначально регистрировать доменное имя, затем получать сертификат и только потом разворачивать техническую часть. В таком случае можно импортировать содержимое сертификатов в autocert.go, и прописывать ключ с сертификатом в файл конфигурации уже не потребуется.

Взломать хакера

Этот стенд я тестировал с редактором журнала «Хакер» Андреем Васильковым, который выступал в роли очень наивной жертвы. На google.com адрес моего домена ничуть не похож, но мы решили пропустить обфускацию. Об этом уже была отдельная статья, и не одна.

Результаты совместного эксперимента можно увидеть на скриншотах. Андрей находился в другом городе и поэтому ничего не мог мне сделать подключался через другого провайдера, заходя на мой фишинговый сайт через десктопный Firefox v. 67.0.

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

В адресной строке творится безобразие, но мало кто в нее смотрит (на мобильных браузерах она вообще скрывается для экономии места на экране). Зеленый замочек «защищенного» соединения вселяет уверенность, а панель авторизации Google вообще загружается оригинальная.

Первый этап прошел успешно — Андрей ввел свой логин и пароль, после чего Google отправил ему одноразовый код подтверждения в SMS.

Меньше чем через минуту Андрей вводит его в стандартное поле верификации. Он вошел в свой аккаунт… и я тоже!

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

Самое главное — удалось перехватить активную сессию.

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

Выводы

Сессия в панели управления Modlishka очень живучая. Она не умирает до тех пор, пока из нее самой не выйдет пользователь (либо хакер). То есть, если жертва закроет вкладку, авторизованная сессия останется активной. Если заново авторизоваться напрямую на google.com, а потом выйти из аккаунта, то сессия все равно останется живой. Даже если остановить сервер Modlishka и запустить его заново — сессия все равно остается. Есть только одна гарантированная возможность деавторизации — выйти в тот момент, когда только «редиректишься» на прокси.

Хоть в статье и были описаны технические детали, обход 2FA не сработает без социальной инженерии. Нужно замаскировать сайт и как-то установить сертификат на компьютер жертвы. Впрочем, это может оказаться не так уж сложно. Большинство пользователей охотно выполняют инструкции, начинающиеся со слов «отключите антивирус и файрвол», а уж в установке сертификата мало кто из обывателей увидит потенциальную опасность.

Источник