Attacking MongoDB

Post on 14-Jan-2015

3424 Views

Category:

Technology

4 Downloads

Preview:

Click to see full reader

DESCRIPTION

My presentation about mongoDB vulns from ZeroNights'12 My E-mail: mfirstov@ptsecurity.ru Programs: https://github.com/cyberpunkych/attacking_mongodb

Transcript

Удар по MongoDB

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

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

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

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

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

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

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

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

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

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

А на чем он?

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

etc)Node.js PerlPHPPythonRubyScala

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

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

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

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

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

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

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

3. The New York Times

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

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

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

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

Что такое RESTful?

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

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

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

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

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

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

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

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

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

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

Our SSJS code

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

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

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

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 интерфейсе будет подгружаться наш скрипт

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

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 в браузере подгружается наш скрипт

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

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 в браузере подгружается наш скрипт

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

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 в браузере подгружается наш скрипт

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

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, и получаем ответ

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

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, и получаем ответ

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

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, и получаем ответ

Видео

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

Стабильный CRASH

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Перехватываем Перехватываем 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

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

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

adminadmin

mongoDBmongoDB

HackerHacker

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

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

adminadmin

mongoDBmongoDB

HackerHacker

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

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

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

adminadmin

mongoDBmongoDB

HackerHacker

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

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

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

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

adminadmin

mongoDBmongoDB

HackerHacker

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

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

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

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

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

adminadmin

mongoDBmongoDB

HackerHacker

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

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

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

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

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

Что такое BSON

Что такое BSON?

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

Пример?

Типы данных

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

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

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

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

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

Проверяем:

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

Exploit:

В действии:

LengthLength

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

В действии:

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

Ruby on Rails

nodejs

PHP

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

Ruby on Rails

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

Mass assignment в Ruby on Rails:

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

Mass assignment в Ruby on Rails:

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

NodeJS

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

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)

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

PHP

Уязвимости

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

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

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

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

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

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

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

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

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

Формируется вот такой NoSQL запрос к 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);

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

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

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

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

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 из первой записи

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

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

top related