Массовый взлом телеграм аккаунтов.

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

Помимо официального клиентов активно используется домен telegram.me. Он служит как ссылка на контакт, инвайт-ссылка для добавления в группу или канал, через него также можно добавить стикеры. Если пользователь аутентифицирован в веб-клиенте, то там присутствует кука stel_web_auth, которая отвечает, на какой домен перенаправлять пользователя.

Вот примеры запроса к telegram.me с кукой:

GET /i_bo0om HTTP/1.1 Host: telegram.me Cookie: stel_web_auth=localhost

И ответ:

HTTP/1.1 302 Found Server: nginx/1.6.2 Date: Thu, 19 May 2016 22:02:23 GMT Content-Type: text/html; charset=windows-1251 Content-Length: 0 Connection: keep-alive Set-Cookie: stel_ssid=823678114; path=/ Pragma: no-cache Cache-control: no-store Location: localhost#/im?tgaddr=tg%3A%2F%2Fresolve%3Fdomain%3Di_bo0om Strict-Transport-Security: max-age=15768000

Стоит заметить, что в куке присутствует возможность вставить \r\n символы, что позволяет подделать заголовки ответов от сервера, или, например, целый HTTP-пакет. А это ведет как минимум к XSS (привет Internet Explorer).

Обычно, в случае CRLF для демонстрации уязвимости ставят заголовок Set-cookie, который устанавливает куку. Но у меня CRLF инъекция уже через куку, поэтому обойдусь :))

Вот пример подделки заголовков:

GET /i_bo0om HTTP/1.1 Host: telegram.me Cookie: stel_web_auth=localhost%0d%0a%20Header1%3a%20ok%0d%0a%20Header2%3a%20ok%0d%0a%20other:%20

Ответ:

HTTP/1.1 302 Found Server: nginx/1.6.2 Date: Thu, 19 May 2016 22:23:31 GMT Content-Type: text/html; charset=windows-1251 Content-Length: 0 Connection: keep-alive Set-Cookie: stel_ssid=1297301663; path=/ Pragma: no-cache Cache-control: no-store Location: localhost Header1: ok Header2: ok other: #/im?tgaddr=tg%3A%2F%2Fresolve%3Fdomain%3Di_bo0om Strict-Transport-Security: max-age=15768000

Заметь, что присутствует заголовок Strict-Transport-Security, что не позволяет добраться до заветной печеньки, если пытаешься использовать MiTM-атаку (человек посередине), несмотря на то, что у куки нет флага Secure. Значит куку можно поставить с помощью XSS (нет флага HttpOnly), но я её так сходу не нашёл.

И тут я вспомнил про одну особенность современных веб-приложений. Поддомен (blabla.telegram.me) может поставить cookie на главный домен (telegram.me). Получится, конечно, не open redirect, а хитрое перенаправление на чужой домен, при использовании домена telegram.me

Для этого, мне нужно:

  1. Раздать свою Wi-Fi точку.
  2. Перенаправлять пользователей на несуществующий поддомен, который ставит куку.
  3. Заставить пользователя зайти на мой поддомен. С учетом первого шага — легко.

Когда пользователю кинут ссылку на приглашение, например, в группу — его перенаправит на фейковое приложение. Пробуем? Поехали!

Готовим фейк.

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

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

Вот полный конфиг «фейка» главного сайта telegram:

server { listen 80; # слушаем 80 порт server_name telergam.org; #на какой домен откликаемся location / { proxy_pass https://telegram.org; #проксируем сайт телеграма }

А ещё используя модуль sub_filter можно заменять содержимое строки на произвольную. По образу и подобию было настроено проксирование на web.telegram, с некоторыми поправками — клиент отправлял на мой сервер текущий идентификатор сессии (и прочие данные из localStorage), номер телефона, браузер.

Что еще нужно для хорошей жизни? SSL! Ну продвинутые пользователи сразу заподозрят неладное, а присутствие «зеленого замочка» прибавляет к харизме фейку.

Поэтому регистрируем бесплатный аккаунт на cloudflare и получаем возможность закрыть от чужих глаз ip адрес сервера и заветный замочек 🙂

Теперь попробуй найти 10 отличий:

Но если посмотреть исходник, то там будет лишний js, который и отправляет данные жертвы на подконтрольный сервер.

Positive Hack Days

Не так давно, на конференции ZeroNights я уже игрался с MiTM’ом, раздавая «бесплатный Wi-Fi», подрезая SSL и собирая трафик. На этот раз дамп трафика мне был уже неинтересен, поэтому основной целью была раздача волшебных печенек в браузеры пользователей.

Шаг 1. Wi-Fi

У нас было 2 wi-fi pineapple, 4500 потенциальных жертв, 3 альфы, несколько 8 dbi антенн и целое множество Wi-Fi карточек всех сортов и расцветок, а также MITMf, DNSspoof, Mana Toolkit, strip-n-inject и проксирующий сервак с фейковым dns-сервером. Не то что бы это был необходимый запас для поездки. Но если начал собирать оборудование для MITM’а, становится трудно остановиться. Единственное что вызывало у меня опасение — это BeEF. Нет ничего более беспомощного, безответственного и испорченного, чем XSS зомби. Я знал, что рано или поздно мы перейдем и на эту дрянь.

На помощь приходят «ананасы», это специальные устройства для атак с помощью поддельной Wi-Fi точки. На конференции было два этажа, а хотелось покрыть максимальное количество людей. К тому же раздавался официальный Wi-Fi с SSID «PHD», поэтому оставалось только запитать устройство. Отлично подошла розетка и место под столом на первом этаже.

Ананасу помощнее, на втором этаже, повезло больше — ему достался ethernet-кабель, поэтому раздавался быстрый и стабильный интернет. «Альфа» с ноутбуком (эту же пару я использовал на ZeroNights) кочевала со мной. Вдобавок, я хотел приспособить mr3040 с OpenWRT, но из-за количества людей и малой мощности я оставил эту идею.

Ещё из Питера привезли мощный роутер Xiaomi, но из-за нехватки времени на прошивку/настройку он так и остался лежать в коробке. Тем более покрытие было уже достаточным для успешной атаки.

Шаг второй. DNS

Задача — записать куку на telegram.me, поэтому на сервере я создал поддомен i.telegram.me и отвечал на любой запрос установкой куки (без контента). Думаю, отдавать DNS с помощью DHCP смысла не много, но на всякий случай поставил unbound и открыл его миру (чтобы подключались). Сразу после PHDays пришла абуза, кто-то успел засканить dns и DDoS’ил им .gov сайты.

Еще были использованы утилиты DNSMasqSpoof и DNSspoof. Первый вариант почему-то глючно работал, поэтому остался последний.

Шаг третий. Инъекция

На этот раз использовать sslstrip/sslsplit/hsts bypass не нужно. Да и зачем палиться? Чуть что, браузер начнет кричать на невалидность сертификата, а надо, чтоб он пользовался интернетом. При сёрфинге жертва скорее всего перейдет на http ресурс, а я тут как тут. Поэтому вконец документа вставлялся тег
<img src="http://i.telegram.me/" onerror=remove()>

Все просто — отправляется GET-запрос на несуществующий домен, но фейковый DNS отвечает нужным мне IP-адресом, в ответ от фейкового домена приходит заголовок с установкой cookie. Так как тег — изображение, срабатывает событие onerror и тег удаляется.
Ребята из Hardware Village преложили делать инъекцию BeEf’а, чтобы полностью контролировать браузер жертвы, потом выводить на телике кто попался (да-да, как на конференции BlackHat). Не было времени, но в следующий раз надо заняться.

В результате, если пользователь зайдет на любой HTTP сайт используя мой WiFi, его браузер будет «заражённым», и когда он будет переходить по ссылкам telegram.me — его будет перенаправлять на фейковую страницу аутентификации.

https://bo0om.ru/wp-content/uploads/2016/05/fake.gif

Результаты

А вот результаты я ожидал получше…
В первый день активной атаки (когда на конференции находится максимум народа) — никого. Никто не зашел. В середине конференции несколько внимательных зашли на страницы сниффера, полазили по фейкограму. Ближе к ночи был один вход. Ну хоть так…

Ещё один вход был пол второго ночи, его можно так же засчитать за первый день.

На второй день я пошел перепроверять оборудование, все ли работает как надо? Я пробовал сам запускать браузер — всё круто, кука ставится, telegram.me редиректит, лог входа пишется. Пару часов сидел и перепроверял, в чем же может быть проблема. Народ цеплялся. Большинство было с мобильных устройств, но и ноутбуки охотно подключались. На Hardware Village к инъекции был запущен mitmf (с respoder’ом), на всякий случай. Опять два входа и опять ночью.

Выводы

Плюсы:

  • Помните, когда сломали telegram журналистов? Там было очень явное палево — IP адреса взломщика, ведь telegram сообщает, с какого IP происходит вход. В этом случае IP адрес будет совпадать с адресом жертвы. А так как мы контролируем сам клиент, мы имеем доступ к переписке и возможность выполнять любые действия от имени жертвы.
  • Даже если стоит двухфакторная аутентификация — не поможет.
  • Кнопку выхода можем заменить на уничтожении сессионного идентификатора только на стороне жертвы, тем самым наблюдать за перепиской всё время, пока жертва не уничтожит активные сессии в настройках.
  • Способ можно модифицировать и улучшить

Минусы:

  • Пользователь вовсе может не зайти. Из 4500 человек на хакерской конференции пробив был менее 1%.
  • Естественно, доступ к секретным чатам мы не получим.
  • На невнимательных пользователей. Но лично я — не заметил бы.
  • Если пользователь аутентифицируется в официальном веб-клиенте, кука перезапишется.

Статья была позаимствована с блога bo0om.ru