
Self-Defeating Audits: воспроизводимый лабораторный стенд, демонстрирующий, как роль PostgreSQL с низкими привилегиями обратимо ослепляет триггерного аудитора, а также отравляет атрибуцию (PG14/16), с описанием мер защиты. Синтетические данные; упомянуты примитивы CVE-2018-1058.
Лицензия: MIT (код) / CC BY 4.0 (документация)
Исследование в области защитной безопасности, проверяющее, может ли малопривилегированная, только-инъекционная роль базы данных обратимо ослепить триггерный аудит и отравить атрибуцию на стандартном PostgreSQL — и какие защиты это реально останавливают. Всё запускается в одноразовых локальных Docker-контейнерах с полностью синтетическими данными (документационные IP из RFC 5737, вымышленные личности). Никакие реальные системы, учётные данные или данные не задействованы.
См. краткое описание лаборатории в self-defeating-audits-lab.md.
Строит широко копируемую с wiki PostgreSQL «аудиторную триггерную» жертву, затем проходит матрицу выполнимости ячейка за ячейкой на PostgreSQL 14 и 16, измеряя — вне полосы — действительно ли каждый вектор атаки останавливает запись от аудита, обратим ли он с нулевым остатком, и какие защиты его убивают.
cd scripts
./00_up.sh 16 # поднять postgres:16-alpine на localhost:55432
./run_matrix.sh 16 # прогнать все ячейки матрицы + защиты -> ../results/RESULTS_pg16.md
docker rm -f sda_pg16 # освободить порт между версиями
./00_up.sh 14
./run_matrix.sh 14 # -> ../results/RESULTS_pg14.md
./teardown.sh # удалить все контейнеры лаборатории
Требуется Docker. Используются образы -alpine (функционально идентичный движок).
Исследование воспроизведено ещё на двух семействах движков. Семейство MySQL (MariaDB, модель триггеров DEFINER) — в scripts/mysql/:
cd scripts/mysql
./00_up.sh 10.11 && ./run_matrix_mysql.sh 10.11 # -> results/RESULTS_mariadb_10.11.md
docker rm -f sda_maria_10_11 && ./00_up.sh 10.6 && ./run_matrix_mysql.sh 10.6
SQL Server (модель ownership-chaining) — в scripts/mssql/; выполняется на локальном экземпляре LocalDB через хост-sqlcmd (без Docker; малопривилегированный атакующий моделируется имперсонацией EXECUTE AS USER):
cd scripts/mssql
./run_matrix_mssql.sh # -> results/RESULTS_mssql.md ; затем ./teardown.sh
Оговорка о воспроизводимости (SQL Server). В отличие от Docker-движков, третья часть на SQL Server имеет зависимость от хоста: она запускается на локальном экземпляре SQL Server LocalDB через
sqlcmd(путь жёстко прописан вrun_matrix_mssql.sh), поэтому работает только в Windows и не может быть привязана к дайджесту образа. Малопривилегированный атакующий моделируется имперсонациейEXECUTE AS USER(LocalDB поддерживает только Windows-аутентификацию). Выводы о поведении движка (DISABLE с нулевым остатком; DDL-защита не замечает DISABLE) не зависят от типа сессии и сохранились бы для реального логина; выводы о правах на объекты честно воспроизводятся имперсонацией. Это наименее переносимая из трёх частей — указано честно.
Главный кросс-движковый результат: класс теней search_path (1A/1B) не переносится ни на MySQL, ни на SQL Server (там нет search_path), а вот замена триггера, спящий обход и отравление атрибуции — переносятся. Привязка привилегий DEFINER в MySQL делает ослепление более обнаружимым; SQL Server, как и PostgreSQL, допускает побайтно точное восстановление и добавляет примитив DISABLE TRIGGER с нулевым остатком, который не замечает его собственная DDL-защита. Полное сравнение трёх движков — в FINDINGS.md.
CREATE SCHEMA), а не потому что «побеждает pg_catalog». Внедрение в уже записываемый public создаёт тень: и 1S (та же сигнатура, порядок схем), и 1T (точная перегрузка побеждает встроенную даже при pg_catalog первом — изолирует специфику типов) ослепляют (payload обнулён).row_to_json для составного типа — ослепляет аудитора, когда public доступен на запись, а search_path триггера не закреплён. Достижимо на стандартном PostgreSQL ≤14; на 15+ — при неправильной конфигурации. Закрепление search_path побеждает её везде.pgaudit/) + — это защиты, которые закрывают весь набор.Воспроизведено на стандартном PostgreSQL в локальной лаборатории с анонимизированными/синтетическими данными. SQL атак ограничен схемой лаборатории, построенной здесь; это исследование выполнимости/защит, а не оружизированный payload. Базовые примитивы уже публичны (CVE-2018-1058; эскалация search_path в SECURITY DEFINER) — вклад состоит в композиции и в оценке защит. Никакая реальная система не идентифицируется.
| Путь | Что это |
|---|
scripts/00_up.sh | одноразовый контейнер с зафиксированной версией (PostgreSQL) |
scripts/mysql/ | жертва, атаки, защиты и оркестратор для семейства MySQL (MariaDB) |
scripts/mssql/ | жертва, атаки, защиты и оркестратор для SQL Server (LocalDB) |
results/RESULTS_mariadb_*.md | матрицы выполнимости и защит для семейства MySQL |
results/RESULTS_mssql.md | матрица выполнимости и защит для SQL Server |
scripts/10_victim.sql | аудиторная жертва по wiki-шаблону (триггер SECURITY DEFINER); параметры: pub_create, pin_path, app_owns |
scripts/20_attacks.sql | все векторы атак (1A/1B/1C, GUC-спячка, отравление атрибуции), по одной \if-защите на ячейку |
scripts/30_defenses.sql | DDL event-trigger защита + хэш-связанное append-only хранилище |
scripts/40_snapshot.sql | снимок каталога для RQ2-сравнения объектов |
scripts/run_matrix.sh | оркестратор: собирает каждую ячейку, измеряет, пишет results/RESULTS_pg<VER>.md |
scripts/teardown.sh | удаление контейнеров |
results/RESULTS_pg14.md, results/RESULTS_pg16.md | заполненные матрицы выполнимости и защит по каждой версии |
results/_evidence_pg*.log, results/_snap_1C_*.txt | сырые свидетельства команд/вывода |
FINDINGS.md | выводы RQ1–RQ5 простым языком, матрица защит×атак, позиционирование новизны, аннотация |
log_statement