47
Удар по MongoDB Фирстов Михаил

Attacking MongoDB

  • Upload
    -

  • View
    3.423

  • Download
    4

Embed Size (px)

DESCRIPTION

My presentation about mongoDB vulns from ZeroNights'12 My E-mail: [email protected] Programs: https://github.com/cyberpunkych/attacking_mongodb

Citation preview

Page 1: Attacking MongoDB

Удар по MongoDB

Фирстов Михаил

Page 2: Attacking MongoDB

Что это вообще такое?

MongoDB — документо-ориентированная СУБД с открытым исходным кодом, не требующая описания схемы таблиц. (wiki)

Особенности:

1. Документо-ориентированное хранилище.

2. Достаточно гибкий язык для формирования запросов

3. Динамические запросы

4. Полная поддержка индексов

5. Профилирование запросов

6. Поддержка отказоустойчивости и масштабируемости

Page 3: Attacking MongoDB

А на чем он?

CC++JavaJavascript.NET (C# F#, PowerShell,

etc)Node.js PerlPHPPythonRubyScala

У Mongodb существуют официальные драйвера для основных ЯП:

./mongo – офф. клиент, написанный на C++ и JS

./mongod — это серверная часть, написанная на C++

Page 4: Attacking MongoDB

Где используются

Краткий список компаний использующих MongoDB:

1. SAP (Крупный производитель программного обеспечения)

2. SourceForge (Хостинг открытого исходного кода)

3. The New York Times

4. GitHub (Проект социального хостинга)

5. Foursquare (Достаточно крупный и известный стартап)

6. Yandex (некоторые сервисы)

Page 5: Attacking MongoDB

Веб-службы RESTful в MongoDB используют интерфейс API для связи с базами данных, просмотра логов и исполнения других ф-ций администрирования.

Что такое RESTful?

Page 6: Attacking MongoDB

А как я узнаю его?

Он по дефолту запускается на порту «28017».

Он может быть запущен без параметра –rest, тогда будет вот эта ошибка:

Page 7: Attacking MongoDB

А как я узнаю его?

Page 8: Attacking MongoDB

Какие там уязвимости?

Во время исследования были найдены следующие уязвимости:

Исполнение произвольного серверного JS кода

Хранимая XSS в логах обращения к БД

Хранимая XSS в журнале запросов

CSRF в удаленном обращении к БД

Our SSJS code

Page 9: Attacking MongoDB

Проведение атаки

MongoDBMongoDB

--REST--REST

HackerHacker

Site with Site with mongoDB mongoDB driver supportdriver support

Admin’s browserAdmin’s browser

1) Посылаем запрос с тегом script, и адресом нашего скрипта.

Hacker’s Hacker’s ServerServer

Page 10: Attacking MongoDB

Проведение атаки

MongoDBMongoDB

--REST--REST

HackerHacker

Site with Site with mongoDB mongoDB driver supportdriver support

Admin’s browserAdmin’s browser

1) Посылаем запрос с тегом script, и адресом нашего скрипта.

Hacker’s Hacker’s ServerServer

2) В результате нашего запроса, в REST интерфейсе будет подгружаться наш скрипт

Page 11: Attacking MongoDB

Проведение атаки

MongoDBMongoDB

--REST--REST

HackerHacker

Site with Site with mongoDB mongoDB driver supportdriver support

Admin’s browserAdmin’s browser

1) Посылаем запрос с тегом script, и адресом нашего скрипта.

Hacker’s Hacker’s ServerServer

2) В результате нашего запроса, в REST интерфейсе будет подгружаться наш скрипт

3) Через XSS в браузере подгружается наш скрипт

Page 12: Attacking MongoDB

Проведение атаки

MongoDBMongoDB

--REST--REST

HackerHacker

Site with Site with mongoDB mongoDB driver supportdriver support

Admin’s browserAdmin’s browser

1) Посылаем запрос с тегом script, и адресом нашего скрипта.

Hacker’s Hacker’s ServerServer

4) Посылаем команду, браузеру жертвы

2) В результате нашего запроса, в REST интерфейсе будет подгружаться наш скрипт

3) Через XSS в браузере подгружается наш скрипт

Page 13: Attacking MongoDB

Проведение атаки

MongoDBMongoDB

--REST--REST

HackerHacker

Site with Site with mongoDB mongoDB driver supportdriver support

Admin’s browserAdmin’s browser

1) Посылаем запрос с тегом script, и адресом нашего скрипта.

Hacker’s Hacker’s ServerServer

4) Посылаем команду, браузеру жертвы

5) Ждем, пока скрипт не запросит команду (JSONP) ( скрипт запрашивает новую команду каждые 30 секунд)

2) В результате нашего запроса, в REST интерфейсе будет подгружаться наш скрипт

3) Через XSS в браузере подгружается наш скрипт

Page 14: Attacking MongoDB

Проведение атаки

MongoDBMongoDB

--REST--REST

HackerHacker

Site with Site with mongoDB mongoDB driver supportdriver support

Admin’s browserAdmin’s browser

1) Посылаем запрос с тегом script, и адресом нашего скрипта.

Hacker’s Hacker’s ServerServer

4) Посылаем команду, браузеру жертвы

5) Ждем, пока скрипт не запросит команду (JSONP) ( скрипт запрашивает новую команду каждые 30 секунд)

2) В результате нашего запроса, в REST интерфейсе будет подгружаться наш скрипт

3) Через XSS в браузере подгружается наш скрипт

6) Выполняем полученную команду, через недокументированное исполнение SSJS, и получаем ответ

Page 15: Attacking MongoDB

Проведение атаки

MongoDBMongoDB

--REST--REST

HackerHacker

Site with Site with mongoDB mongoDB driver supportdriver support

Admin’s browserAdmin’s browser

1) Посылаем запрос с тегом script, и адресом нашего скрипта.

Hacker’s Hacker’s ServerServer

4) Посылаем команду, браузеру жертвы

5) Ждем, пока скрипт не запросит команду (JSONP) ( скрипт запрашивает новую команду каждые 30 секунд)

7) Отправляем результат исполнения команды на запись в БД

2) В результате нашего запроса, в REST интерфейсе будет подгружаться наш скрипт

3) Через XSS в браузере подгружается наш скрипт

6) Выполняем полученную команду, через недокументированное исполнение SSJS, и получаем ответ

Page 16: Attacking MongoDB

Проведение атаки

MongoDBMongoDB

--REST--REST

HackerHacker

Site with Site with mongoDB mongoDB driver supportdriver support

Admin’s browserAdmin’s browser

1) Посылаем запрос с тегом script, и адресом нашего скрипта.

Hacker’s Hacker’s ServerServer

4) Посылаем команду, браузеру жертвы

8) Получаем результат исполнения команды

5) Ждем, пока скрипт не запросит команду (JSONP) ( скрипт запрашивает новую команду каждые 30 секунд)

7) Отправляем результат исполнения команды на запись в БД

2) В результате нашего запроса, в REST интерфейсе будет подгружаться наш скрипт

3) Через XSS в браузере подгружается наш скрипт

6) Выполняем полученную команду, через недокументированное исполнение SSJS, и получаем ответ

Page 17: Attacking MongoDB

Видео

Page 18: Attacking MongoDB

Разве такое можно встретить?

Page 19: Attacking MongoDB

Стабильный CRASH

MongoDB очень часто падает если вызвать ф-цию с нестандартными параметрами. На скриншотах можно увидеть результат:

Page 20: Attacking MongoDB

Интересные фичи

Ф-ции ls, cat, (остальные - help admin) работают только из самой консоли Mongo.

Скорее всего существуют и другие варианты NoSQL-инъекций, с другими языками программирования.

Очень интересна ф-ция nativeHelper, которая как раз и отвечает за работу с ФС из консоли mongo.

Чаще всего путь к файлам бд – «/data/db» или «/var/lib/mongodb». Структура каталога простая: (dbname).(num). Чтобы извлечь информацию достаточно сделать $ strings users.*

Page 21: Attacking MongoDB

Сетевое взаимодействие

Добавление пользователя:

Исходный код:

Расшифровываем соль:

Page 22: Attacking MongoDB

Сетевое взаимодействие

Перехваченные пакеты авторизации:

Нужные нам данные передаются в открытом виде:

Page 23: Attacking MongoDB

Сетевое взаимодействие

Логика работы скрипта, для перехвата и перебора паролей:

Перехватываем Перехватываем n n пакетов, связанных пакетов, связанных с с mongodbmongodb

Проверяем Проверяем их на их на наличие наличие пакетов пакетов авторизацииавторизации

ВыходВыходНе нашли

Получаем из данных Получаем из данных key, nonce, loginkey, nonce, login

Нашли

key2 = md5(nonce + user + key2 = md5(nonce + user + md5(user + ":mongo:" + passw)), md5(user + ":mongo:" + passw)), где где passw passw это строка из словаряэто строка из словаря

Получаем Получаем следующую следующую строку из строку из словарясловаря

key key ==== key2 key2

false

Выводим Выводим user:passwduser:passwd

true

Page 24: Attacking MongoDB

Сетевое взаимодействие

Page 25: Attacking MongoDB

Сетевое взаимодействие. MiTM атака

adminadmin

mongoDBmongoDB

HackerHacker

1. Запрос авторизации

Page 26: Attacking MongoDB

Сетевое взаимодействие. MiTM атака

adminadmin

mongoDBmongoDB

HackerHacker

1. Запрос авторизации

2. Отдаем nonce, под который сгенерированы rainbow tables

Page 27: Attacking MongoDB

Сетевое взаимодействие. MiTM атака

adminadmin

mongoDBmongoDB

HackerHacker

1. Запрос авторизации

2. Отдаем nonce, под который сгенерированы rainbow tables

3. Клиент отдает нам login и получившийся key

Page 28: Attacking MongoDB

Сетевое взаимодействие. MiTM атака

adminadmin

mongoDBmongoDB

HackerHacker

1. Запрос авторизации

2. Отдаем nonce, под который сгенерированы rainbow tables

3. Клиент отдает нам login и получившийся key

4. Подбираем 4. Подбираем пароль по заранее пароль по заранее сгенерированным сгенерированным к этомук этому nonce nonce радужным радужным таблицамтаблицам

Page 29: Attacking MongoDB

Сетевое взаимодействие. MiTM атака

adminadmin

mongoDBmongoDB

HackerHacker

1. Запрос авторизации

2. Отдаем nonce, под который сгенерированы rainbow tables

3. Клиент отдает нам login и получившийся key

4. Подбираем 4. Подбираем пароль по заранее пароль по заранее сгенерированным сгенерированным к этомук этому nonce nonce радужным радужным таблицамтаблицам

5. Успешно авторизовываемся с полученными данными

Page 30: Attacking MongoDB

Что такое BSON

Что такое BSON?

Это Бинарный Это Бинарный JSONJSON. . BSON это расширение JSON, которое позволяет хранить данные в различных форматах: дата и время, бинарные данные и т.п.

Пример?

Типы данных

string – строкаint - целое числоdouble - двойное число с плавающей запятойDateTime – датаbyte[] - массив байт (бинарные данные)bool - булевые (true/false)null - нольBsonObject - BSON объектBsonObject[] - массив BSON объектов

Page 31: Attacking MongoDB

Перезапись переменных

Имеется таблица с двумя записями:

Также запрос, в который мы можем внедриться:

Вставляем BSON документ, который перезаписывает переменную isadmin:

Проверяем:

Page 32: Attacking MongoDB

Чтение произвольных участков памяти

Exploit:

В действии:

LengthLength

Page 33: Attacking MongoDB

Чтение произвольных участков памяти

В действии:

Page 34: Attacking MongoDB

Особенности разных ЯП

Ruby on Rails

nodejs

PHP

Page 35: Attacking MongoDB

Особенности разных ЯП

Ruby on Rails

Page 36: Attacking MongoDB

Особенности разных ЯП

Mass assignment в Ruby on Rails:

Page 37: Attacking MongoDB

Особенности разных ЯП

Mass assignment в Ruby on Rails:

Page 38: Attacking MongoDB

Особенности разных ЯП

NodeJS

Page 39: Attacking MongoDB

Особенности разных ЯП

JSON injection в NodeJS + MongoDB:

VULNERABLE SOURCE CODE:VULNERABLE SOURCE CODE:VULNERABLE SOURCE CODE:VULNERABLE SOURCE CODE:

RESULT QUERY:RESULT QUERY:RESULT QUERY:RESULT QUERY:

SENDSEND SENDSEND

Хакер 02/12 (157)

Page 40: Attacking MongoDB

Особенности разных ЯП

PHP

Page 41: Attacking MongoDB

Уязвимости

Типы обнаруженных уязвимостей:

Обход авторизации через подстановку массива в php

Внедрение SSJS (Server Side JavaScript) кода

Слепое внедрение SSJS, Time-based

Page 42: Attacking MongoDB

Особенности разных ЯП

Как известно, php обрабатывает символы “[]” из GPC как массив:

В официальном классе mongoDB для для php есть ф-ция find()

password[$ne]=parol1password[$ne]=parol1

Page 43: Attacking MongoDB

Особенности разных ЯП

Формируется вот такой NoSQL запрос к MongoDB, и авторизация проходит успешно:

Таким образом, если в коде нет проверки, мы можем обойти авторизацию разными способами:

Page 44: Attacking MongoDB

Особенности разных ЯП

Внедрение напрямую в js запрос.

Предположим в коде вот такие вот строки:

Также в ответ выводятся наш id и login.

Теперь пробуем внедриться в запрос:

Видно, что тут идет перезапись переменной «loginn» на результат команды db.version()

$q = “function() { var loginn = ‘$login’; var passs = ‘$pass’; db.members.insert({id : 2, $q = “function() { var loginn = ‘$login’; var passs = ‘$pass’; db.members.insert({id : 2, login : loginn, pass : passs}); }”;login : loginn, pass : passs}); }”;$db->execute($q);$db->execute($q);

Page 45: Attacking MongoDB

Особенности разных ЯП

Иногда невозможно увидеть результат исполнения SSJS-кода.

Для этих случаем лучше использовать технику Time-based:

Специально для этого был написан скрипт для перебора и вывода нужных пользователю данных.

Page 46: Attacking MongoDB

NoSQL-injection Cheat Sheet

db.getName() - имя текущей БД можно просто db

db.members.count() - количество записей в таблице members

db.members.validate({ full : true}) - основная информация о таблице members

db.members.stats() - почти то же что и предыдущее, но немного в укороченном варианте

db.members.remove() - очистить таблицу members, синтаксис такой-же как и у ф-ции find()

db.members.find().skip(0).limit(1) - еще один способ получения записи. Просто перебираем значение skip.

db.getMongo().getDBNames().toString() – Получаем список всех доступных БД

db.members.find()[0][‘pass’] – получаем значение поля pass из первой записи

Page 47: Attacking MongoDB

Спасибо за внимание!

Фирстов МихаилНоябрь 2012