- PVSM.RU - https://www.pvsm.ru -
Это история о том как я соединил 5 Low-severity багов в один большой баг, с помощью которого можно было читать/писать в приватные репы на Гитхабе (опять [1]).
Несколько дней назад гитхаб запустил баунти программу [2]. За 4 часа я смастерил такой URL после посещения которого я получал доступ к вашему гитхаб аккаунту и репозиториям. Хотите узнать как?
Начал я с проверки Github OAuth [3].
Это просто — можно отослать /path1/../path2 чтобы перезаписать предыдущий путь (path traversal).
Первый баг сам по себе ничего не стоит. В OAuth2 встроена защита, что для каждого выпущеного кода есть соответствующий редирект_ури, и при обмене кода на токен необходимо дать тот же ури что был использован вначале. Попросту говоря если вернулся код на site/callback то и для получения токена надо отослать site/callback.
Как ни странно гитхаб реализовали проверку не правильно. Можно было выпустить код для /path1/../path2 и потом использовать его на /path1. То есть утекший через рефереры код оставался валидным даже для настоящего колбэка. С помощью этих двух багов можно было бы сливать коды через рефереры на сайтах с функцией логина через Гитхаб. Похожий баг был в vk.com.
Я начал смотреть официальные клиенты гитхаба — Education, Pages, Speakerdeck, Gist. Первые два не пользовались OAuth по-сути, третий не входил в bounty программу, а вот гист очень даже подходил. Он был «пре-одобренным» клиентом, то есть по-умолчанию установлен у всех пользователей.
Но нельзя было просто вставить так как Camo-прокси гитхаба заменит это на локальный урл, и реферер не утечет на ваш сервер. Чтобы обойти эту защиту я использовал довольно новый трюк
///host.com парсится как путь всеми серверными библиотеками включая руби, но браузеры же парсят это как хост и загружают host.com [4] вместо github.com///host.com [5]
Наш урл-эксплоит выглядит сейчас так:
https://github.com/login/oauth/authorize?client_id=7e0a3cd836d3e544dbd9&redirect_uri=<b>https%3A%2F%2Fgist.github.com%2Fauth%2Fgithub%2Fcallback/../../../homakov/8820324</b>&response_type=code
Как только юзер загружает это адрес гитхаб автоматически редиректит на мой гист с картинкой на моем сервере:
Location: gist.github.com/auth/github/callback/../../../homakov/8820324?code=CODE [6]
Браузер загружает gist.github.com/homakov/8820324?code=CODE [7]
И тут при запросе на нашу картинку он сливает реферер.
Как только мы получаем CODE жертвы мы можем открыть gist.github.com/auth/github/callback?code=CODE [8] — вуаля. Мы залогинены как жертва на гисте и имеем доступ к его приватным гистам.
Это антипаттерн OAuth, крайне не рекомендуется хранить/показывать токен браузеру, гист же хранит его в рельс сессии. Которая как мы знаем просто base64 закодированная и подписанная кука.
Вот же он — github_token. Теперь мы можем делать запросы напрямую, минуя сайт гиста. Но токен имеет scope = gists и кроме гистов я ничего не могу прочесть. Хотя…
Последний штрих. Так как гист это официальный клиент гитхаба то вы не видите диалога «Одобрить эти скоупы» и гитхаб делает одобрение за вас автоматически. А значит я могу просто послать
https://github.com/login/oauth/authorize?client_id=7e0a3cd836d3e544dbd9&redirect_uri=https%3A%2F%2Fgist.github.com%2Fauth%2Fgithub%2Fcallback/../../../homakov/8820324&response_type=code&<b>scope=repo,gists,user,delete_repo,notifications</b>
Затем использовать слитый КОД для логина в аккаунт жертвы, прочитаю куку, возьму оттуда github_token и тут уже совершать API вызовы совершенно незаметно для пользователя — ведь токен принадлежит Гисту! Стелс-мод эдакий, преступление без следов.
Награда составила $4000.
И вообще я доступен для работы, например.
Автор: Chikey
Источник [9]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/informatsionnaya-bezopasnost/54524
Ссылки в тексте:
[1] опять: http://habrahabr.ru/post/139399/
[2] баунти программу: http://bounty.github.com/
[3] Github OAuth: https://developer.github.com/v3/oauth/
[4] host.com: http://host.com
[5] github.com///host.com: http://github.com///host.com
[6] gist.github.com/auth/github/callback/../../../homakov/8820324?code=CODE: https://gist.github.com/auth/github/callback/../../../homakov/8820324?code=CODE
[7] gist.github.com/homakov/8820324?code=CODE: https://gist.github.com/homakov/8820324?code=CODE
[8] gist.github.com/auth/github/callback?code=CODE: https://gist.github.com/auth/github/callback?code=CODE
[9] Источник: http://habrahabr.ru/post/211845/
Нажмите здесь для печати.