...

пятница, 7 февраля 2014 г.

[Перевод] Как я взломал Гитхаб еще раз

Это история о том как я соединил 5 Low-severity багов в один большой баг, с помощью которого можно было читать/писать в приватные репы на Гитхабе (опять).

Несколько дней назад гитхаб запустил баунти программу. За 4 часа я смастерил такой URL после посещения которого я получал доступ к вашему гитхаб аккаунту и репозиториям. Хотите узнать как?


Баг 1. Обход валидации redirect_uri с /../

Это просто, можно отослать /path1/../path2 чтобы перезаписать предыдущий путь (path traversal).
Баг 2. Нет валидации redirect_uri при получении токена.

Первый баг сам по себе ничего не стоит. В OAuth2 встроена защита, что для каждого выпущеного кода есть соответствующий редирект_ури, и при обмене кода на токен необходимо дать тот же ури что был использован вначале. Попросту говоря если вернулся код на site/callback то и для получения токена надо отослать site/callback.

Как ни странно гитхаб реализовали проверку не правильно. Можно было выпустить код для /path1/../path2 и потом использовать его на /path1. То есть утекший через рефереры код оставался валидным даже для настоящего колбэка. С помощью этих двух багов можно было бы сливать коды на сайтах с функцией логина через Гитхаб. Похожий баг был в vk.com.


Баг 3. Картинки на гисте.

image

Я начал смотреть официальные клиенты гитхаба — Education, Pages, Speakerdeck, Gist. Первые два не пользовались OAuth по сути, третий не входил в bounty программу, а вот гист очень даже подходил. Он был «пре одобренным» клиентом, то есть по умолчанию установлен у всех пользователей.

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

///host.com парсится как путь всеми серверными библиотеками включая руби, но браузеры же парсят это как хост и загружают host.com вместо http://ift.tt/1l7g50i


Наш урл-эксплоит выглядит сейчас так:


http://ift.tt/1l7g78A

image

Как только юзер загружает это адрес гитхаб автоматически редиректит на гист:

Location: http://ift.tt/1l7g50q


Браузер загружает http://ift.tt/1l7g50q


И тут при запросе на нашу картинку он сливает реферер.


Как только мы получаем CODE жертвы мы можем открыть http://ift.tt/1l7g50t — вуаля. Мы залогинены как жертва на гисте и имеем доступ к его приватным гистам.


Баг 4. Токен хранится в куках

image

Это антипаттерн OAuth, крайне не рекомендуется хранить/показывать токен браузеру, гист же хранит его в рельс сессии. Которая как мы знаем просто base64 закодированная и подписанная кука.

Но токен имеет scope = gists и кроме гистов я ничего не могу прочесть. Хотя…


Баг 5. Автоматическое одобрение любого scope для официальных клиентов.

Последний штрих. Так как гист это официальный клиент гитхаба то вы не видите диалога «Одобрить эти скоупы» и гитхаб делает одобрение за вас автоматически. А значит я могу просто послать

github.com/login/oauth/authorize?client_id=7e0a3cd836d3e544dbd9&redirect_uri=https%3A%2F%2Fgist.github.com%2Fauth%2Fgithub%2Fcallback/../../../homakov/8820324&response_type=code&scope=repo,gists,user,delete_repo,notifications


Затем использовать слитый КОД для логина в аккаунт жертвы, прочитаю куку, возьму оттуда github_token и могу совершать API вызовы совершенно незаметно для пользователя — ведь токен принадлежит Гисту! Стелс-мод такой.


Награда составила $4000.

image


И вообще я доступен для работы, например.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий