SQL-DB как способ попробовать свои силы и понять принцип работы сокрытия данных.

D2

Администратор
Регистрация
19 Фев 2025
Сообщения
4,380
Реакции
0
Автор: NomadSP
Источник: XSS.is


Итак, перед нами стоит задача:
Создать защищённую базу данных, используя SQL, чтобы потом интегрировать honeypot с триггером на неё.
В данном случае мы создаём некую песочницу для дальнейшего тестирования на проникновение или изучения утилит.

Начнём.
Нам понадобится PostgreSQL. Обновляемся через sudo apt update и приступаем.

Шаг 1. Установка PostgreSQL.
Bash: Скопировать в буфер обмена
sudo apt install postgresql postgresql-contrib -y

Обратите внимание, что используется postgresql - основная серверная часть + postgresql-contrib - пакет дополнительных модулей и утилит, которые могут быть нам полезны.

Шаг 2. Проверяем состояние службы.
Bash: Скопировать в буфер обмена
sudo systemctl status postgresql
Если служба не запущена, то используем:
Bash: Скопировать в буфер обмена
sudo systemctl start postgresql

Шаг 3. Настраиваем PostgreSQL.
При установке, по умолчанию, задаётся имя пользователя postgres, поэтому чтобы войти в систему как данный пользователь, используем:
Bash: Скопировать в буфер обмена
sudo -i -u postgres

Далее открываем консоль через команду:
Bash: Скопировать в буфер обмена
psql

Шаг 4. Создаём первую базу данных.
В консоли можно создать новую базу данных, я предлагаю обыграть это ситуативно:

1. База данных содержит информацию о клиентах, сотрудниках, а так же авторизованных устройствах.
2. Каждая таблица имеет свои значения.
3. Создаётся список "белых IP адресов".

SQL: Скопировать в буфер обмена
CREATE DATABASE my_database;

После создания базы данных, подключаемся с помощью:
SQL: Скопировать в буфер обмена
c my_database;

Шаг 5. Создаём таблицы.

Шаг 5.1. Таблица clients:
SQL: Скопировать в буфер обмена
Код:
CREATE TABLE clients (
    userid SERIAL PRIMARY KEY,
    phone VARCHAR(15),
    email VARCHAR(255) UNIQUE,
    first_name VARCHAR(50),
    last_name VARCHAR(50)
);
Где используются такие значения как: userid, номер телефона, адрес почты, имя и фамилия.

Шаг 5.2. Таблица employees:
SQL: Скопировать в буфер обмена
Код:
CREATE TABLE employees (
    userid SERIAL PRIMARY KEY,
    phone VARCHAR(15),
    email VARCHAR(255) UNIQUE,
    first_name VARCHAR(50),
    last_name VARCHAR(50)
);
Здесь тоже зададим: userid, номер телефона, адрес почты, имя и фамилия.

Шаг 5.3. Таблица authorized_devices:
SQL: Скопировать в буфер обмена
Код:
CREATE TABLE authorized_devices (
    id SERIAL PRIMARY KEY,
    user_id INT,
    device_info VARCHAR(255),
    ip_address INET,
    browser_fingerprint VARCHAR(255),
    FOREIGN KEY (user_id) REFERENCES clients(userid) ON DELETE CASCADE,
    FOREIGN KEY (user_id) REFERENCES employees(userid) ON DELETE CASCADE
);
Тут используем интересующие нас: userid, информация об устройстве, IP, отпечаток браузера(сессии).

Шаг 6. Таблица IP whitelist.
SQL: Скопировать в буфер обмена
Код:
CREATE TABLE ip_whitelist (
    id SERIAL PRIMARY KEY,
    ip_address INET UNIQUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
В данной таблице будут хранится все IP, которые были одобрены.

Для автоматического добавления можно использовать адаптированную версию скрипта ниже:
SQL: Скопировать в буфер обмена
Код:
CREATE OR REPLACE FUNCTION add_ip_to_whitelist()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO ip_whitelist (ip_address)
    VALUES (NEW.ip_address)
    ON CONFLICT (ip_address) DO NOTHING; -- Например, гнорировать, если IP уже есть
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Шаг 7. Задаём триггер.
Для того, чтобы наша база данных поплнялась, необходимо задать условия, например:
SQL: Скопировать в буфер обмена
Код:
CREATE TRIGGER insert_ip_whitelist
AFTER INSERT ON authorized_devices
FOR EACH ROW EXECUTE PROCEDURE add_ip_to_whitelist();
В финальном варианте мы имеем относительно содержательную базу данных, которую стоит защищать, так как там есть данные и о клиентах, и о сотрудниках, и чувствительные данные об устройствах.

Внесём первые данные для большей содержательности.


Шаг 1. Добавляем клиентскую информацию.
SQL: Скопировать в буфер обмена
Код:
INSERT INTO clients (phone, email, first_name, last_name)
VALUES ('1234567890', 'client@xss.is', 'John', 'Doe');

Шаг 2. Добавляем информацию о сотруднике.
SQL: Скопировать в буфер обмена
Код:
INSERT INTO employees (phone, email, first_name, last_name)
VALUES ('0987654321', 'employee@xss.is', 'Jane', 'Doe');

Шаг 3. Добавляем авторизованные устройства.
SQL: Скопировать в буфер обмена
Код:
INSERT INTO authorized_devices (user_id, device_info, ip_address, browser_fingerprint)
VALUES (1, 'Device Info', 'IP_here', 'fingerprint_data');

Теперь наша база ещё и имеет внутри данные. Поэтому необходим первичный слой защиты.

Да, еще и на всякий случай, можно подключаться к PostgreSQL через удобную GUI утилиту pgAdmin:
Bash: Скопировать в буфер обмена
sudo apt install pgadmin4
Запустим:
Bash: Скопировать в буфер обмена
pgadmin4

Здесь важно уделить внимание настройкам, после выбора "Server" -> "Create Server".
1. General -> Name: Имя сервера, можно задать любое удобное.
2. Connection -> Host: Адрес сервера где установлен PostgreSQL или localhost, если работаем с локальным сервером.
3. Connection -> Port: Указываем порт, по умолчанию tcp/5432.
4. Connection -> Maintenance database: Имя созданной нами базы.
5. Connection -> Username/Password: Указываем имя и пароль пользователя PostgreSQL.


Далее происходит подключение и вывод вашей DB.

Создаём элемент защиты.
Для создания полноценной картины, можно так же использовать поддержку шифрования.

Для этого детально рассмотрим 2 пути:
- Опция 1, при использовании MySQL -

Шаг 1. Проверяем поддержку шифрования.
В конфигурации MySQL находим файл my.cnf и проверяем, что содержимое равно
INI: Скопировать в буфер обмена
Код:
[mysqld]
   innodb_encrypt_tables=ON
   innodb_encrypt_log=ON

Шаг 2. Создаём ключ шифрования.
SQL: Скопировать в буфер обмена
SET GLOBAL innodb_encryption_keys_rotation = ON;

Шаг 3. Шифруем таблицу.
SQL: Скопировать в буфер обмена
ALTER TABLE "название_таблицы" ENCRYPTION='Y';

Обращаем так же наше внимание, что для каждой таблицы необходимо проделать то же самое.

Шаг 4. Проверяем шифрование.
Сделать это можно с помощью:
SQL: Скопировать в буфер обмена
Код:
SELECT TABLE_NAME, CREATE_OPTIONS
   FROM information_schema.tables
   WHERE TABLE_SCHEMA='название_базы';

Здесь уже вводим именно название базы данных, а не таблиц.

- Опция 2, используя PostgerSQL - (более подходит)

Поскольку мы подгрузили все плагины и утилиты postgre, то нам должен быть доступен инструмент pgcrypto.

Шаг 1. Устанавливаем pgcrypto.
SQL: Скопировать в буфер обмена
CREATE EXTENSION pgcrypto;

Шаг 2. Шифруем данные при вводе.
SQL: Скопировать в буфер обмена
Код:
INSERT INTO ваша_таблица (column1, column2) -- Обратите внимание на количество колонок, необходимо ввести все
   VALUES (pgp_sym_encrypt('your_data', 'your_secret_key'), 'other_data');

Шаг 3. Дешифровка данных.
Чтобы получить зашифрованные данные мы можем воспользоваться:
SQL: Скопировать в буфер обмена
Код:
SELECT pgp_sym_decrypt(column1::bytea, 'your_secret_key') AS decrypted_data -- Каждая колонка в выбранной таблице
   FROM your_table;


В итоге мы получаем хотя бы что-то, с чем можно уже взаимодействовать для дальнейших игр в песочнице. Для большего интереса, попробуем ещё и добавить взаимодействие с honeypot, чтобы что-то отвлекало внимание от нашей созданной базы данных.

Создаём honeypot.
Для этой цели используем инструмент honeyd. Он позволит нам обыграть ловушки для дальнейшего тестирования своих знаний.

Шаг 1. Устанавливаем Python зависимости.
Bash: Скопировать в буфер обмена
sudo apt install python3 python3-pip git -y

Шаг 2. Устанавливаем honeyd.
Bash: Скопировать в буфер обмена
sudo apt install honeyd -y

Шаг 3. Создадим конфигурационный файл.
Для дальнейшего взаимодействия нам необходимо вносить свои настройки, поэтому создаём файл через:
Bash: Скопировать в буфер обмена
sudo nano /etc/honeyd/honeyd.conf

Шаг 4. Имитируем MySQL сервер.
В открытом через nano файле вносим следующее:
Код: Скопировать в буфер обмена
Код:
create mysql
   set mysql personality "MySQL 5.7"
   set mysql service "mysql"
   add mysql tcp port 3306 open
   set mysql reply "Welcome to MySQL"
  
   bind <IP_адрес> mysql  # Замените на ваш IP

Сохраняем и выходим.

Шаг 5. Запуск honeyd.
Для запуска используем следующую команду + название созданного файла конфигурации:
Bash: Скопировать в буфер обмена
sudo honeyd -d -f /etc/honeyd/honeyd.conf


Далее нам необходимо перенаправить траффик, который идёт к реальной базе через наш созданный honeypot.

Шаг 1. Установим iptables(если его ещё нет).
Bash: Скопировать в буфер обмена
sudo apt install iptables -y

Шаг 2. Настроим правила iptables.
Например:
sudo iptables -t nat -A PREROUTING -p tcp --dport 3306 -j DNAT --to-destination <IP_адрес>:3306
sudo iptables -A FORWARD -p tcp -d <IP_адрес> --dport 3306 -j ACCEPT

В данном случае траффик перенаправляется на порт honeypot.

Шаг 3. Настроим логирование.
В конфигурационном файле добавляем строку для сохранения данных:
Код: Скопировать в буфер обмена
log mysql /var/log/honeyd/mysql.log


Шаг 4. Создаём директорию для хранения логов.

Bash: Скопировать в буфер обмена
Код:
sudo mkdir /var/log/honeyd
   sudo touch /var/log/honeyd/mysql.log
   sudo chown honeyd:honeyd /var/log/honeyd/mysql.log

Дойдя до этого этапа мы получим базу, имеющую данные, шифрованную с помощью некоторых утилит, вдобавок имеющую honeypot. Всё, что теперь необходимо, это "пощупать" данную конструкцию, перейдём к этому.

SQLmap.
Именно с этого варианта я бы начал, чтобы проверить реакцию honeypot или базы на SQL инъекции.

Шаг 1. Установим sqlmap.

Bash: Скопировать в буфер обмена
sudo apt install sqlmap

Шаг 2. Используем для проверки уязвимости.

Bash: Скопировать в буфер обмена
sqlmap -u "http://<IP_адрес>/index.php?id=1" --batch --dbs

В этом случае мы используем опции:


-u указывает URL для тестирования.

--batch автоматически отвечает на вопросы SQLmap по умолчанию (без участия пользователя).

--dbs выводит список баз данных на целевом сервере.


Шаг 3. Получаем результаты.

После запуска SQLmap, мы увидим вывод с результатами попытки инъекции. Если SQL-инъекция удалась, то мы увидим список баз данных, например:
Bash: Скопировать в буфер обмена
Код:
[INFO] the back-end DBMS is MySQL
[INFO] fetching database names
available databases [2]:
[*] созданная_база_данных
[*] honeypot_база_данных

Шаг 4. Пробуем извлечь данные из базы.

Bash: Скопировать в буфер обмена
sqlmap -u "http://<IP_адрес>/index.php?id=1" -D созданная_база_данных --tables

Шаг 5. Пробуем извлечь данные из таблиц.

Bash: Скопировать в буфер обмена
sqlmap -u "http://<IP_адрес>/index.php?id=1" -D созданная_база_данных -T <параметр> --dump

В обоих случаях есть возможность "вытянуть" чувствительные данные.

Тогда зачем мы применяли шифрование, если это всё спокойно видно в SQLmap?
Разъясняю. pgcrypto даёт нам возможность оставить сюрприз, в виде зашифрованных данных.

Например, мы настроили шифровку столбца "phone" с помощью:

SQL: Скопировать в буфер обмена
Код:
CREATE TABLE clients (
    id serial PRIMARY KEY,
    username text,
    password text
);

-- Зашифруем данные с помощью функции pgcrypto
INSERT INTO clients (phone, email)
VALUES ('123456789', crypt('client@xss.is', gen_salt('bf')));

Конкретно в данном примере, мы используем алгоритм шифрования bcrypt.

Что же тогда мы увидим, применив SQLmap к данной таблице?

Используем:
Bash: Скопировать в буфер обмена
sqlmap -u "http://<IP_адрес>/index.php?id=1" -D clients -T email --dump

При правильной настройке, в ответ мы получим что-то вроде:
Bash: Скопировать в буфер обмена
Код:
[INFO] the back-end DBMS is PostgreSQL
[INFO] fetching entries of table 'emails' in database 'clients'
+----+----------+--------------------------------------+
| id | phone | password                             |
+----+----------+--------------------------------------+
| 1  | 123456789    | $2a$12$KIXLrD4i.LLNzZ7gNBcQF.iErC2J |
+----+----------+--------------------------------------+

Как мы видим, значение "phone" осталось видимым, а "password" зашифрован, следовательно здесь необходимы будут методы дешифровки алгоритма bcrypt для получения данных.

Варианты дешифровки в данном случае, это получение доступа к самим ключам, либо же получение доступа к методу генерации "gen_salt" = "соли", что в целом усложняет сам вектор атаки. Нам в качестве практики самое то!

Как бы нам теперь ещё и создать опцию оповещения о попытках неправомерного доступа?
Возвращаемся к PostgreSQL. Там, где создана наша база.

Шаг 1. Создаём таблицу alerts.

Данная таблица будет содержать все триггреры и алерты при определённых событиях с базой.

SQL: Скопировать в буфер обмена
Код:
CREATE TABLE alerts (
    id serial PRIMARY KEY,
    event_type text,
    query text,
    timestamp timestamp DEFAULT current_timestamp
);

Шаг 2. Создаём триггеры INSERT/UPDATE/DELETE.

При подозрительных действиях, данные триггеры будут передаваться в систему алертинга. Например:

SQL: Скопировать в буфер обмена
Код:
CREATE OR REPLACE FUNCTION путь_к_логу()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO alerts(event_type, query)
    VALUES (TG_OP, current_query());
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

В данном варианте TG_OP - встроенная переменная, содержащая типы операции INSERT/UPDATE/DELETE, а current_query() возвращает текущие SQL запросы.

Шаг 3. Добавим триггер модификации данных.
SQL: Скопировать в буфер обмена
Код:
CREATE TRIGGER activity_trigger
AFTER INSERT OR UPDATE OR DELETE ON название_таблицы
FOR EACH ROW EXECUTE FUNCTION путь_к_логу();

Теперь, при записи событий в таблицу alerts, можно настроить, например e-mail алертинг и протестировать каким образом происходит оповещение при срабатывании выстроенных триггеров.

Используем в завершении Postfix.

Утилита доступна для Linux OS пользователей, поэтому установим через:

Bash: Скопировать в буфер обмена
sudo apt install postfix

Далее приступаем к настройке в PostgreSQL.

Шаг 1. Создаём функцию отправки.

Нам необходимо вызывать системную команду sendmail для отправки письма, поэтому прописываем:

SQL: Скопировать в буфер обмена
Код:
CREATE OR REPLACE FUNCTION send_alert_email()
RETURNS TRIGGER AS $$
DECLARE
    cmd text;
BEGIN
    cmd := 'echo "ALERT: Suspicious activity detected: '  TG_OP  ' on clients table. Query: '  current_query()  '" | mail -s "Data breach Alert" example@xss.is';
    PERFORM dblink_exec('dbname=mydb', cmd);
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Данным действием мы вызываем с помощью mail -s отправку письма с темой "Data breach alert" на адрес example@xss.is.

Шаг 2. Установка dblink.

Так как при установке Postgre мы установили пакет postgresql-contrib, нам доступно расширение dblink:

SQL: Скопировать в буфер обмена
CREATE EXTENSION dblink;

С помощью неё мы будем инициировать отправку.

Шаг 3. Добавляем триггер.

SQL: Скопировать в буфер обмена
Код:
CREATE OR REPLACE FUNCTION log_honeypot_activity()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO alerts(event_type, query)
    VALUES (TG_OP, current_query());
    
    PERFORM send_alert_email(); -- Отправка email уведомления
    
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Теперь вы будете оповещены о любых изменениях в таблице clients.

Заключение.
Таким образом можно создать окружение для тестов своих навыков или других инструментов, которые вам могут пригодится в будущем. Здесь нет особой замысловатости, но вполне подходит для каких-то манипуляций.

Даже общедоступные SQL инструменты так же предлагают довольно широкий спектр защитных опций, что позволяет иметь защищённое пространство, хотя бы для каких-то собственных или рабочих данных.

Всем успехов!
 
Сверху Снизу