Невозможно отучить людей изучать самые ненужные предметы.
Введение в CSS
Преимущества стилей
Добавления стилей
Типы носителей
Базовый синтаксис
Значения стилевых свойств
Селекторы тегов
Классы
CSS3
Надо знать обо всем понемножку, но все о немногом.
Идентификаторы
Контекстные селекторы
Соседние селекторы
Дочерние селекторы
Селекторы атрибутов
Универсальный селектор
Псевдоклассы
Псевдоэлементы
Кто умеет, тот делает. Кто не умеет, тот учит. Кто не умеет учить - становится деканом. (Т. Мартин)
Группирование
Наследование
Каскадирование
Валидация
Идентификаторы и классы
Написание эффективного кода
Вёрстка
Изображения
Текст
Цвет
Линии и рамки
Углы
Списки
Ссылки
Дизайны сайтов
Формы
Таблицы
CSS3
HTML5
Блог для вебмастеров
Новости мира Интернет
Сайтостроение
Ремонт и советы
Все новости
Справочник от А до Я
HTML, CSS, JavaScript
Афоризмы о учёбе
Статьи об афоризмах
Все Афоризмы
Помогли мы вам |
Статья имеет ознакомительный характер и предназначена для специалистов по безопасности, проводящих тестирование в рамках контракта. Автор и редакция не несут ответственности за любой вред, причиненный с применением изложенной информации. Распространение вредоносных программ, нарушение работы систем и нарушение тайны переписки преследуются по закону.
Недавно я участвовал в создании управляемого Greenplum для Yandex.Cloud. Greenplum — это аналитическая база на основе старого доброго PostgreSQL. Про добрый — это такая присказка. А вот старый Postgres там во весь рост. Greenplum 6 сделан на основе PostgreSQL 9.4, для которого обновления безопасности не выпускаются с доковидных времен.
Что значит термин «управляемый» применительно к Greenplum? Наши обвязки — Control Plane — автоматически соединяются с базой, делают бэкапы, мониторят, не сломалось ли чего, устанавливают обновления и все такое прочее. Исторически во всех базах данных есть суперпользователь. Это — уровень, на котором пользователь может все, что доступно процессу базы. В частности, он может атаковать Control Plane. Поэтому в управляемых базах привилегии суперпользователя обычно недоступны, а если доступны — это представляет серьезную опасность для данных. Какой‑нибудь буйный сосед может атаковать Control Plane, а потом и всю нашу базу. Поэтому каждую уязвимость «Постгреса» я теперь рассматриваю как повод пропатчить Greenplum.
Вообще, у «Постгреса» имеется тонна форков. Потенциально все они уязвимы ко всему, что будет перечислено в этой статье. В результате на таких базах начинают майнить или случаются истории как с фотками Скарлет. Кроме того, многие облака не заставляют пользователей апгрейдиться после end of life мажорной версии. У некоторых, как, например, у Redshift, есть программы bug bounty. Если у тебя в запасе уйма свободного времени — это хороший шанс конвертировать знания в деньги.
Может показаться, что эпичные дыры в безопасности — верный признак «решета», которым лучше не пользоваться. Это не так. Открытая публикация всех исторических уязвимостей — то, что не дает заметать под ковер zero day. Понятный процесс поддержки и обновления мажорных версий пилит комитет PostgreSQL security. Он не зависит от одной коммерческой компании и прозрачно формируется из множества членов сообщества, известных своим дотошным ревью кода. Хочешь поместить закладку в код «Постгреса», как это случилось с ядром Linux? Для одной попытки потребуются многие годы работы, если не десятилетия.
Что ж, перейдем, наконец, к сути. Чем можно себя развлечь, встретив недопатченный «Постгрес»?
Уязвимости CVE-2018-10915 подвержены версии 10.4, 9.6.9 и более древние. Сама уязвимость называется Certain host connection parameters defeat client-side security defenses, и может показаться, будто что речь идет об опасности на стороне клиента, а не сервера. Но CVSS score 8,5 намекает, что все не так просто.
Когда сервер открывает соединения по просьбе клиента — это всегда потенциальная угроза. Если твой веб‑сервер проходит по URL’у, полученному от клиента, — клиент обязательно подсунет URL для заказа пиццы в ваш дата‑центр.
Один раз мы пришли в сообщество с предложением разрешить непривилегированным пользователям создавать подписки логической репликации. В сообществе нам намекнули, что создание исходящих соединений — уже отличный способ остаться с голой базой против ежа. И действительно, немного подумав, мы нашли способ взломать собственный набор патчей.
В PostgreSQL для обращения к данным на соседних серверах есть специальные расширения — dblink и postgres_fdw. Они позволяют использовать таблицы на других серверах (необязательно PostgreSQL) в SQL-запросах.
Postgres_fdw — это чуть более удобный способ сделать ровно то же самое. Пользователь не передает запросы текстом, а локально видит удаленную таблицу как обычную.
Если в базе данных уже создано одно из этих двух расширений, пользователь может сходить с адреса сервера PostgreSQL куда‑нибудь за данными. Уже сам по себе этот факт когда‑то создавал прикольную уязвимость CVE-2007-6601. Причем не нужно даже лазить куда‑то далеко — можно просто прийти от сервера к самому себе и попросить локальное соединение.
Такой Уроборос возможен потому, что в host based authentication (pg_hba.
) часто можно видеть какие‑нибудь прикольные строчки вроде тех, что приведены ниже. Дословно они означают «локальным соединениям — верить».
# "local" is for Unix domain socket connections only
local allalltrust
# IPv4 local connections:
host allall127.0.0.1/32trust
# IPv6 local connections:
host allall ::1/128trust
Они туда приезжают из докер‑образа или при инициализации с initdb
. Что же делать с такой возможностью?
dblink_exec ------------- ALTER ROLE(1 row)postgres=# c postgresYou are now connected to database "postgres" as user "x4m".postgres=# CREATE TABLE pwn(t TEXT);CREATE TABLEpostgres=# COPY pwn FROM '/etc/passwd';COPY 27postgres=# SELECT * FROM pwn;
Сразу отмечу два момента.
1. Конечно, это стриггерит мониторинги — для защиты от таких взломов необходимо постоянно проверять whitelist суперъюзеров в системе. Это совсем несложно технически и в хороших системах давно сделано. Но неприятности могут начаться еще до того, как на хост прибегут безопасники с щипцами и паяльником.
2. Хорошую инструкцию по основам хакинга PostgreSQL можно найти на pentest-wiki. Некоторые примеры в этой статье взяты оттуда.
Разумеется, такую уязвимость запатчили еще в далеком 2007 году (Дуров, верни стену!). Причем запатчили нехитрым способом, теперь dblink и postgres_fdw не согласны идти куда‑либо без пароля!
static void
dblink_security_check(PGconn *conn, remoteConn *rconn)
{
if (!superuser())
{
if (!PQconnectionUsedPassword(conn))
{
PQfinish(conn);
if (rconn)
pfree(rconn);
ereport(ERROR,
(errcode(ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED),
errmsg("password is required"),
errdetail("Non-superuser cannot connect if the server does not request a password."),
errhint("Target server's authentication method must be changed.")));
}
}
}
Вот и славно, теперь все безопасно, мы не используем беспарольные соединения от адреса нашего сервера. Защитили себя от самих себя. Но прогресс (как и «Постгрес») не стоит на месте, новые фичи принесут новые баги!
В 2010-х сообщество Postgres активно пилило фичи для захода в рынок Enterprise-систем. Одна из таких фич — построение высокодоступной (highly available) базы данных. Дело в том, что любое железо может рано или поздно отказать: диски иногда сыплются как песок, память страдает от космических лучей, проц перегревается, сетевой свич получает бажную прошивку, кабель до дата‑центра перегрызает злобный хомяк и так далее. Стандартный подход для решения таких проблем — дублирование систем. У авиалайнера как минимум два двигателя, у парашютиста два парашюта, у Вупсеня — Пупсень, у Пупы — Лупа.
Так и PostgreSQL умеет реплицировать полную бинарную копию данных на другое железо, где вероятность одновременного отказа минимизирована. При этом клиент имеет два или больше hostname’ов и не знает, кто есть кто, до открытия соединения.
Клиент может указать в строке соединения, нужен ли ему Primary для записи, или подойдет любой живой Standby, где можно выполнить только читающие запросы. Строка соединения при этом выглядит так.
postgresql://host1:port2,host2:port2/?target_session_attrs=read-write
Это фича PostgreSQL 10, о ней можно подробнее почитать тут. Но и в PostgreSQL 9.6 можно сделать то же самое, если один DNS name вернет несколько IP-адресов.
|
|