Поиск открытых баз данных с помощью поисковиков

Поиск открытых баз данных с помощью поисковиков

Об­лачная база дан­ных — удоб­ная вещь: вся работа по деп­лою и нас­трой­ке сервера за вас уже сде­лана, оста­ется толь­ко поль­зовать­ся! Системных администраторв это рас­слаб­ляет нас­толь­ко, что такие открытые находяться с помощью поис­ковых систем.

Еще по теме: Как проверить сайт на уязвимости

В статье я покажу, как автоматизировать поиск незащищенных баз данных с помощью поисковиков.

Поиск открытых баз данных с помощью поисковиков

Си­деть, менять поисковые системы и переби­рать все URL вруч­ную не очень увлекательно. Слиш­ком час­то видим «error : Permission denied». Зна­чит, пора переходить к автоматизации!

Вся информация предоставлена исключительно в ознакомительных целях. Ни автор, ни редакция сайта spy-soft.net не несут ответственности за любой возможный вред, причиненный материалами данной статьи.

Прог­рамми­ровать, прав­да, не придется, потому что некоторые такие как Францеска Эрера — это уже сде­лали до нас. Возь­мем, к при­меру интересный скрипт, который сам под­бира­ет 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 при­веде­ны и сами пра­вила, и раз­ные спо­собы защитить дан­ные. Не сто­ит ими пре­неб­регать, перек­ладывая ответс­твен­ность на какие‑нибудь гей­ты или прок­си‑сер­веры. Адрес базы может быть обна­ружен.

Еще по теме: Что такое Google Dorks?

ВКонтакте
OK
Telegram
WhatsApp
Viber

Один комментарий

  1. Avatar
    Андрей

    Скажите сколько будет стоить что бы создать свой сайт интернет магазина?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *