Пешком по Firebase. Находим открытые базы данных, которые прячет Google
Life-Hack [Жизнь-Взлом]/ХакингОблачная база данных — штука удобная: считай, вся работа по деплою и настройке сервера за тебя уже сделана, осталось только пользоваться! Админов это расслабляет настолько, что такие базы часто остаются незащищенными и ищутся с помощью поисковиков. Один нюанс — этим поисковиком не может быть Google!
WARNING
Вся информация предоставлена исключительно в ознакомительных целях. Автор и редакция не несут ответственности за любой возможный вред, причиненный с использованием сведений из этой статьи.
Firebase — это облачная платформа, которую разработала компания Envolve в 2011 году. Изначально это была база данных для приложений‑чатов, но позже ее полюбили разработчики многопользовательских онлайновых игр. Это подвигло основателей разделить Firebase на две части: модуль чата и модуль игрового фреймворка.
Два года спустя, в 2014 году, Google приобрела Firebase и продолжила развивать. Программные интерфейсы для этой базы данных есть для множества платформ и языков программирования.
INFO
С технической точки зрения Firebase — крутая и удобная штука. Кажется, что ничего докручивать и допиливать здесь не нужно. Но безопасная настройка облачной базе таки нужна, и многие владельцы об этом забывают, чересчур расслабившись. Настолько, что забывают о простейшей вещи — аутентификации.
ИЩЕМ ОТКРЫТЫЕ БАЗЫ ДАННЫХ
Получается, что в интернете масса не закрытых паролем баз данных, а это легкая добыча для злоумышленников. Только вот взять и нагуглить их не получится, потому что в Google решили, что эту проблему можно решить, просто исключив эти базы из поисковой выдачи. Ловко! Но крайне ненадежно.
Ничто не мешает нам воспользоваться другим поисковиком — например, Bing или DuckDuckGo. Они выдают уже намного больше полезной информации.
Что можно сделать дальше, после того как найдены домены с уязвимыми базами? Открываем любую ссылку — например, https://hacker-news.firebaseio.com/v0/topstories.json
. Информация о ней бесполезна, но если убрать из ссылки название таблицы topstories
и оставить только .json
, то можно проверить, защищена база или нет. В этом случае результат выглядит вот так:
{ "error" : "Permission denied" }
Все верно, лично я бы знатно удивился, если бы владельцы этого сайта допустили настолько вопиющую оплошность. Но некоторые ее таки допускают. Минут десять перебора ссылок, и поиск увенчается успехом.
Я нашел что‑то более интересное — учетки с хешами паролей. Выбрать их из файла несложно простым скриптом на Python или утилитой jq.
При помощи HashID определяем тип хешей (это был MD5) и загоняем в hashcat. Если нет достаточно мощного железа, можно воспользоваться онлайновым сервисом — тулза FindMyHash автоматически их подбирает. Все эти утилиты предустановлены в Kali Linux.
Ждем десять минут, и перед нами логины и пароли в открытом виде.
АВТОМАТИЗАЦИЯ
Сидеть, менять поисковики и перебирать все URL вручную очень нудно. Слишком часто видишь «error : Permission denied». Значит, пора автоматизировать! Программировать, правда, не потребуется, потому что это уже сделали до нас. Возьмем, к примеру, скрипт за авторством Францеска Эрреры.
Скрипт сам подбирает URL и ищет уязвимые базы данных.
Качаем его и устанавливаем зависимости:
git clone https://github.com/Turr0n/firebase.git cd firebase pip install -r requirements.txt
И запускаем:
python3 firebase.py -p 4 -c 150 –dnsdumpster
Ключи:
p
— указывает количество потоков (по умолчанию 1, максимум 4);dnsdumpster
— генерирует URL самостоятельно;с
— какое количество доменов генерировать.
Да, скрипт умеет генерировать ссылки самостоятельно. Точнее, делает это не сам, а обращается за помощью к утилите DNSdumpster.
По результату видно, что из найденных баз:
- 37 урлов «битые» или больше не существуют;
- 171 база имеет аутентификацию при обращении к данным и защищена;
- одна база с подозрением на уязвимость;
- 25 баз не защищены или уязвимы.
Можно скормить скрипту и свой список. В нем должны быть только поддомены третьего уровня. Например, ты делаешь вот такой входной список:
xxx yyy zzz
Тогда скрипт проверит вот эти URL:
https://xxx.firebaseio.com https://yyy.firebaseio.com https://zzz.firebaseio.com
В поисках поддоменов
Чтобы получить наиболее эффективный список, можно воспользоваться скриптом sublist3r, который использует разные техники поиска и OSINT, чтобы подобрать наиболее правдоподобные варианты.
Запускаем:
python3 sublist3r.py -d firebaseio.com
И на выходе получаем около 650 доменов. Работает очень быстро.
Еще одна утилита для генерации доменов — subbrute. Она выдала мне в районе 100 поддоменов, но работала 30–40 минут.
Censys-subdomain-finder, на который я возлагал большие надежды, выдал всего семь доменов. К слову, и сам сервис выдал немного — 25 урлов.
Все перечисленные утилиты не входят в состав дистрибутива Kali Linux, их пришлось качать отдельно.
Из онлайновых сервисов можно воспользоваться nmmapper, DNSdumpster, Pentest-Tools.
Если все еще мало, можно задействовать знания о том, что настройки интеграции происходят в файле google-services.json
, и поискать в гите запросом site:github.com google-services.json
. Этот вариант идет вразрез со словом «автоматизация», зато можно докопаться до уникальных баз.
Ковыряем и дописываем скрипт
Теперь мы вооружены добротным набором урлов и знаем, что какие‑то из них могут быть уязвимы. Даже можем запустить скрипт и проверить количество неверно настроенных баз из нашего списка. Но цель в таких случаях — не собрать статистику, а получить уязвимые цели. Поэтому откроем код скрипта и слегка поправим.
Посмотри вот на этот кусок кода:
urls = set() with open(args_.list, 'r') as f: [urls.add('https://{}.firebaseio.com/.json'.format(line.rstrip())) for line in f]
Из него понятно, как формируется полный адрес. А в конце формируется отчет:
print('404 DBs: {}'.format(l['-2'])) print('Secure DBs: {}'.format(l['-1'])) print('Possible vulnerable DBs: {}'.format(l['0'])) print('Vulnerable DBs: {}'.format(l['1']))
Кусок кода с проверкой я приводить не буду. Там нет ничего любопытного, мне нужно было найти само присвоение. И вот оно:
with open(args_.fn, 'w') as f: json.dump(loot, f) l = {'1':0, '0':0, '-1':0, '-2':0} for result in loot: l[str(result['status'])] += 1
Вот в этом месте я создаю свой массив по статусу 1. Так как я еще не понимаю, чем его заполнять, записываю все подряд. Получилось примерно следующее:
l = {'1':0, '0':0, '-1':0, '-2':0} Vulnerable = [] for result in loot: l[str(result['status'])] += 1 if str(result['status']) == '1': Vulnerable.append(result)
И в конце добавляю вывод результата в консоль:
print('404 DBs: {}'.format(l['-2'])) print('Secure DBs: {}'.format(l['-1'])) print('Possible vulnerable DBs: {}'.format(l['0'])) print('Vulnerable DBs: {}'.format(l['1'])) print(Vulnerable)
После запуска вижу такую картину.
Мне высыпалось все, что хранилось в базах. Зато теперь я знаю, что записывать в Vulnerable. Правим код, как надо:
l = {'1':0, '0':0, '-1':0, '-2':0} Vulnerable = [] for result in loot: l[str(result['status'])] += 1 if str(result['status']) == '1': Vulnerable.append(result['url']) ... print('404 DBs: {}'.format(l['-2'])) print('Secure DBs: {}'.format(l['-1'])) print('Possible vulnerable DBs: {}'.format(l['0'])) print('Vulnerable DBs: {}'.format(l['1'])) print(Vulnerable)
На этот раз при запуске видим то, что было нужно, — список уязвимых баз.
Особенно меня заинтересовала вот эта ссылка: https://covid-19-tracker-e76ca.firebaseio.com/.json
. В Малайзии так спешили отслеживать перемещения больных ковидом, что не поставили пароль на базу данных с их координатами...
КАК НЕ ДОПУСТИТЬ УТЕЧКУ
Назвать эту проблему уязвимостью — некоторое преувеличение. Все сводится к тому, что Google позволяет открыть доступ к содержимому базы всем неавторизованным пользователям, и некоторые разработчики так и поступают.
Поэтому, чтобы защититься, достаточно прописать политики безопасности Firebase. Google предлагает придерживаться следующих правил.
Даже во время разработки (на тесте и на stage) не стоит открывать доступ ко всем данным в Firebase неавторизованным пользователям, но есть возможность открыть их при авторизации:
service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if request.auth != null; } } }
Это правило необходимо, когда нескольким пользователям нужно работать с одним контентом.
Следующее правило дает доступ к данным только владельцам этих данных. Остальные пользователи не смогут их видеть или обрабатывать:
service cloud.firestore { match /databases/{database}/documents { // Allow only authenticated content owners access match /some_collection/{userId}/{documents=**} { allow read, write: if request.auth != null && request.auth.uid == userId } } }
И третье правило устанавливает доступ на чтение некоторых данных некоторым пользователям, но редактирование — только его владельцу:
service cloud.firestore { match /databases/{database}/documents { // For attribute-based access control, Check a boolean `admin` attribute allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true; allow read: true; // Alterntatively, for role-based access, assign specific roles to users match /some_collection/{document} { allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader" allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Writer" } } }
ЗАКЛЮЧЕНИЕ
Итак, мы рассмотрели, как происходит утечка данных, разобрались с поиском уязвимых URL, научились автоматизировать процесс и узнали, как избежать этой проблемы.
В документации по безопасности Firebase приведены и сами правила, и разные способы защитить данные. Не стоит ими пренебрегать, перекладывая ответственность на какие‑нибудь гейты или прокси‑серверы. Адрес базы может быть обнаружен.
Источник