Большинство разработчиков знают и любят github pages. На случай, если вы не встречались с ними — этот сервис даёт возможность создать статический сайт из вашего репозитория, который будет доступен на домене smth.github.io. Это безумно удобно для всякой временной статики, документации, небольших простых сайтов и так далее. Не приходится думать о каком-то дополнительном веб сервере.
Так же там есть возможность привязать к репозиторию свой домен — тогда всё будет совсем красиво. Даже поддержка SSL есть.
После этого небольшого введения перейдём к собственно теме статьи. Совсем недавно (9 ноября) у меня приключилась интересная история. Рекомендую не читать её залпом, а периодически останавливаться и прикидывать, что же означают все полученные на текущий момент вводные. Думаю, из этого выйдет интересная тренировка, хотя сюжет моего детектива оказался и не очень длинным и закрученным.
Решил в очередной профиль добавить адрес своего резюме. Резюме как раз лежит на github pages, потому что почему бы и нет. По привычке кликнул, чтобы проверить, всё ли работает… И внезапно обнаружил там странное:
Очень удивился. Пошёл в настройки репозитория. Увидел, что на текущий момент он не привязан к тому домену, к которому должен быть привязан. Попробовал привязать. Внезапно получил ошибку:
The CNAME whois.jehy.ru
is already taken. Check out https://help.github.com/articles/troubleshooting-custom-domains/#cname-already-taken for more information
Немного напрягся и удивился. После этого пошёл смотреть внимательнее эту внезапную страничку. По прежнему увидел там только некий стандартный шаблон, копирайт от 2013 года и внезапно ссылку на сайтмап. В сайтмапе прописана дата его генерации от текущего числа, а так же статический html-документ с названием и контентом, крайне напоминающим способ валидации google (название googlef3e716e930ae1730
, контент google-site-verification: googlef3e716e930ae1730.html
). Вот тут я уже напрягся сильно, побежал сменил NS запись на свой сервер и начал думать, что же пошло не так.
Поверхностный гуглинг показал следующее:
- Вроде бы угон домена — потенциально известная проблема, и она уже решена — достаточно прописать в CNAME адрес своего репозитория.
- Несмотря на это, во многих инструкции по привязке гитхаба к домену(в том числе из топ 10 поиска) прописываются напрямую айпишники, или просто github.io.
Тут я подумал, что, наверное, у меня была кривая CNAME запись. Так что я сменил её на корректную, с привязкой к своему репозиторию. Теперь запись выглядела так:
dig whois.jehy.ru +nostats +nocomments +nocmd
; <<>> DiG 9.11.3-1ubuntu1.2-Ubuntu <<>> whois.jehy.ru +nostats +nocomments +nocmd
;; global options: +cmd
;whois.jehy.ru. IN A
whois.jehy.ru. 6984 IN CNAME jehy.github.io.
jehy.github.io. 3384 IN A 185.199.108.153
jehy.github.io. 3384 IN A 185.199.110.153
jehy.github.io. 3384 IN A 185.199.109.153
jehy.github.io. 3384 IN A 185.199.111.153
И каково же было моё изумление, когда я опять увидел этот чудесный “Coming Soon” лэндинг!
Для проверки я даже сделал ещё один тест:
1) Завёл новую CNAME запись test.jehy.ru и указал для неё профиль Райана Дала
2) Завёл тестовый репозиторий, указав для него кастомный домен test.jehy.ru. Вроде бы всё правильно, по инструкции, и работать привязка не должна. Но увы, результат налицо.
Далее я связался с техподдержкой гитхаба через странную форму на сайте. Там мне сказали, что могут отвязать от моего домена чужой репозиторий, если я добавлю себе ещё одну NS запись. Я сделал это, отписал обратно — и с пятницы до понедельника ответа уже не получил. Возможно, надо было заново писать в эту форму — но это уже выше было моих сил. Так что я просто оставил мой статический сайт на своём сервере.
На тот момент у меня было три варианта происшедшего:
1) Кто-то совершенно случайно прописал в своём репозитории адрес “whois.jehy.ru” в 2018 году, при этом выкладывая лэндинг с “coming soon” от 2013 года, где зачем-то лежит гугловый html для проверки прав. Ну вряд ли.
2) Случился какой-то безумный баг. Тоже вряд ли. Он повторился на втором тестовом сайте.
3) Фокус с привязкой по CNAME то ли никогда не работал, то ли сломался, и этим пользуются злоумышленники для атаки. Пока что это мне казалось наиболее вероятным вариантом.
Далее я вспомнил, что в случае привязки домена github сам делает файл по имени CNAME в вашем репозитории. И пошёл искать, кто же добавил мой домен. И — бинго!
Злоумышленник найден в поиске:
Вот мой домен:
А вот и кучка других:
Как видите, это была совсем не случайность. Кто-то своровал приличное количество доменов — в том числе второго уровня! И получил полную власть над их содержимым, в том числе подтвердив в гугле права на владение этими доменами!
Кстати, также можно добавить, что иногда хакер не просто заменяет контент сайта, а форкает исходный репозиторий, после чего добавляет туда файлы верификации. И развлекается так уже минимум месяц (нашёл навскидку коммиты с 6 октября). Ну и фолловеры там аналогичные.
Далее мои предположения по тому, как происходит такая атака, и зачем она нужна.
1) Сначала хакер находит сайты, которые резолвятся на github.io. Сделать это довольно несложно.
2) Далее он фильтрует их, оставляя только те, которые возвращают ошибку (кажется, там просто 404). Случаев, когда репозитории оказались не привязаны, может быть множество — кто-то недонастроил репозиторий, кто-то его удалил, у кого-то слетели настройки привязки (кажется, у меня это и случилось, когда я поменял ветку для github pages).
3) Затем хакер просто создаёт новый репозиторий с нужным ему контентом и привязывает его к “свободному” домену. Вуаля!
4) Дальше всё зависит только от фантазии хакера. Дорвеи, размещение ссылок, перехват данных, получение через гугл доступа к управлению Google Apps… Вариантов огромное множество.
Что я сделал дальше, имея на руках все доказательства злонамеренного использования привязки:
- Описал в переписке с support@github.com все подробности;
- Ещё раз заново отписал их в форму контактов;
- Добавил тикет на hackerone.com. Надо сказать, там указано, что в программу вознаграждения не входят githubpages.io, но других вариантов не было. Поэтому пришлось проигнорировать это предупреждение, и даже робота, который мягко советовал мне не оправлять этот репорт в силу тех же причин.
В форму контактов мне так и не ответили и по сей день, зато спустя два дня мне ответили на hackerone. Если вкратце, то ответ состоял в том, что это известная особенность работы сервиса, она не является уязвимостью, и такими вещами занимается команда по работе со спамом. Репорт был закрыт как “информативный”, так что я пишу о всём происшедшем с чистой совестью. Так же мне сообщили, что указанный мной аккаунт был забанен. Я проверил — да, его больше нет. Его фолловеры исчезли спустя несколько дней (непонятно, почему не сразу же).
На этом можно было бы закончить и сказать, что всё в порядке… Но на самом деле я крайне смущён данной ситуацией:
- Почему такие аккаунты не находятся месяцами? Там идентичный контент, там везде файлы валидации google, на одном аккаунте куча таких сайтов… Общих признаков — вагон и маленькая тележка.
- Почему команда по работе со спамом не проверила связанные репозитории?
- Почему в инструкциях по привязке домена тебе показывают иллюзию безопасности, предлагая установить в CNAME имя своего репозитория, если это ни на что не влияет?
- Почему нет механизма предупреждений, который сказал бы о том, что домен, который ранее был привязан к твоему аккаунту, теперь привязан к другому?
- Почему в гитхабе не нельзя отвечать на емейлы от суппорта? Или может я подпал под какой-то фильтр?
Но главный вопрос, который меня смущает — почему гитхаб не проверяет NS записи доменов, которые указаны на github pages, на предмет наличия в них CNAME конкретного репозитория? Это же простейшая операция, которая может выполняться при привязке домена, и не занимает времени… Более того, по инструкциям появляется ощущение, что так оно и задумывалось…. Так почему же эта проверка сломана?
В общем, этот пост я пишу с надеждой, что он в каком-то виде дойдёт до гитхаба, и ребята предпримут меры. Опережая вопрос ”зачем об этом рассказывать, все сейчас полезут так делать” — отвечу, что дырка и так известная и активно эксплуатируется. И так сейчас явно идёт постоянно сканирование “заброшенных” доменов, так что несколько новых участников картину не изменят.
Обычно так не делаю, но будет здорово, если вы похлопаете переводу этой статьи, который я положил на медиум. Да, я знаю, что у хабр теперь многоязычен, но за всё время я видел полтора поста на английском, и не думаю, что кто-то на них может обратить внимание. А на медиуме часто бывают хорошие технические посты. Так что будет здорово, если вы поможете обратить внимание на эту дырку. Если что — денег я за это не получу, карточки США нет, та что интерес чисто альтруистический.
О чём же можно ещё подумать по завершению? Наверное, о том, что стоит всегда помнить, когда вы что-то размещаете на сторонних мощностях. Конечно, в интернете нет вообще ничего личного, и всё является сторонним — “ваши” домены принадлежат регистратору, “ваши” сервера — гуглу, амазону, или ещё кому-то… Нельзя сказать, что гитхаб менее надёжен, чем любой "свой" сервер… Но "свой" сервер как-то ближе к телу и более предсказуем. В общем, всегда нужно помнить о своих ресурсах, о их важности, потенциальных потерях при их перехвате и о том, что в сторонних сервисах может быть весьма внезапная специфика работы.
P.S. Спасибо cavin за картинку и pndpnd за перевод статьи на английский.
Комментарии (13)
zhovner
15.11.2018 18:13Такую же «уязвимость» можно представить и на любом shared-хостинге. Ищем домены направленные на площадки хостеров, но не отдающие сайт. Создаем vhost и «угоняем» сайт.
jehy Автор
15.11.2018 18:46+1Верно подмечено, однако аналогия некорректна в силу толстых нюансов:
1) У большинства хостингов или выделенные IP, или есть некоторый разброс адресов. Придётся искать конкретные хостинги, которые имеют только один IP. Довольно геморройное занятие.
2) Хостинги не бесплатны, в отличие от репозиториев на гитхабе. Поэтому занятие резко становится менее интересным. Да ещё и надо входить в каждую отдельную панель, закачивать файлы сотней разных способов… Совсем неинтересно.
3) Хостинги не заинтересованы в защите доменов, и не имеют возможности связаться с предыдущим владельцем хостинга. Видимо, гитхаб тоже не заинтересован, что печально, однако средство связи (узнать, у кого было привязано это имя ранее) у них есть.
4) Опять же, можно хотя бы проверять факт, был ли ранее привязан куда-то домен, и на основании этого запрашивать проверочную NS запись.
ValdikSS
15.11.2018 18:27CNAME-запись не является средством аутентификации, а служит для удобства идентификации принадлежности привязанного домена к репозиторию, что-то вроде заметки или комментария. Веб-сервер Github Pages, отдающий страницу, не занимается DNS-проверками, он просто отдает страницу того домена, Host которой он знает.
jehy Автор
15.11.2018 18:48+1Формально да. Но в таком случае зачем в руководстве указано ставить именно CNAME своего репозитория? Всё же есть явное ощущение, что в планах было использовать его для аутентификации, благо технически это легко (они и так на этапе привязки проверяют, есть ли CNAME на гитхаб, так что ничего сложнее не станет) — но то ли забыли, то ли сломали.
ValdikSS
15.11.2018 19:32Я не знаю, чем руководствовался Github (возможно, действительно планировалось делать проверку по cname), но мне кажется, что это просто пометка. Представьте, что у вас 100 доменов, привязанных к Github Pages, и из-за уникальных CNAME вы можете понять, к какому репозиторию конкретный домен имеет отношение, просто из DNS-записи. Это визуально удобней, чем если бы у всех доменов был CNAME на github.io.
poloart
15.11.2018 22:00-3Вы, возможно, будете удивлены, но я терпеть не могу git и всё, что с этим связано.
Причина этому — моё прошлое в качестве айти-безопасника, скажем так, попроще.
Да, это удобно. Это очень удобно — проектики ваши, синхронизация, профиль, все дела.
Но вы никогда не думали о том, что в один прекрасный момент кто-то это всё сломает?
Куда потекут ваши «закрытые» данные?
Поэтому, я считаю, всё, что представляет интеллектуальную ценность, просто обязано храниться на ваших же ресурсах. Физически ваших ресурсах. И устраивайте себе на ваших ресурсах всё, что угодно, сейчас возможностей масса.
А плохо и небезопасно всё то, над чем вы лично не имеете контроля. Будь то страничка в vk, профиль в git, облачко… и так далее. Задумайтесь.jehy Автор
15.11.2018 22:10Вы немного перепутали git и github.
К тому же, когда мы говорим про github, то редко подразумеваем закрытые данные — основной смысл эта площадка имеет при совместной работе над open source. А открытый код никуда не утечёт.
NYMEZIDE
15.11.2018 22:15предлагаете каждому купить по серверной стойке? ) дороговато выйдет.
bugdesigner
16.11.2018 08:39Git сервер не обязательно должен занимать целую стойку. Им может быть старый компьютер с Linux или даже одноплатный микро компьютер на ARM размером с пачку сигарет. Ещё вариант — поднять на VPS. Если нужна вэбморда — GitLab есть в репозиториях под многие сборки Linux.
mk2
15.11.2018 22:23Вы, наверное, всё же имеете в виду github. Собственно git к этому сервису никак не привязан.
gecube
Отличная находка! Я думаю, что гитхабу плевать на безопасность пользователей. Тем более, после того, как он продался Microsoft.
Свои проекты перетащил на gitlab. Github остался только для обратной совместимости…
jehy Автор
Думал написать свои мысли по этому поводу в статье, но не стал. Отпишу таки тут.
Не думаю, что тут виноват майрософт. У меня к нему давняя нелюбовь, но в последнее время они очень хорошо маскируются под хороших ребят. Прям хочется верить. Даже дико популярный в последнее время vscode чего стоит.
Скорее причина кроется в том, из-за чего собственно гитхаб отошёл майрософту. У них банально не хватало ресурсов ни на какие нововведения и фиксы. А сейчас они много новых плюшек выкатывают. Хотя странно видеть «реовлюционное нововведение» в виде встроенного в клиент гитхаба способа разрешения конфликтов, который уже есть в любой IDE… Но надо же с чего-то начинать, чтобы догонять.
Да и, хотя я пеняю в этом посте на их безопасность, основные важные вещи у них таки покрыты программой bug bounty. Есть у меня ощущение, что более адекватный человек из поддержки понял бы суть проблемы сломавшегося механизма (я думаю, он был, но сломался) — но мне не повезло. Писать ещё один репорт бесполезно, поэтому решил вынести это наружу.
gecube
Если не хватает ресурсов на «работу над ошибками», то что можно говорить о «новых фичах»?