• 🔥 Бесплатный курс от Академии Кодебай: «Анализ защищенности веб-приложений»

    🛡 Научитесь находить и использовать уязвимости веб-приложений.
    🧠 Изучите SQLi, XSS, CSRF, IDOR и другие типовые атаки на практике.
    🧪 Погрузитесь в реальные лаборатории и взломайте свой первый сайт!
    🚀 Подходит новичкам — никаких сложных предварительных знаний не требуется.

    Доступ открыт прямо сейчас Записаться бесплатно

Статья SQL DB как песочница для новичка: учимся скрывать данные и понимать логику ИБ

Автор: n0_mad
Источник: ex. DaMaGeLab

Уровень: Novice.
Итак, перед нами стоит задача:
Создать защищённую базу данных, используя 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', '[EMAIL]client@******[/EMAIL]', 'John', 'Doe');

Шаг 2. Добавляем информацию о сотруднике.

SQL:
INSERT INTO employees (phone, email, first_name, last_name)
VALUES ('0987654321', '[EMAIL]employee@******[/EMAIL]', '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 файле вносим следующее:

INI:
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.
Например:
Bash:
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('[EMAIL='client@******']client@example.is[/EMAIL]', 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" [EMAIL='example@******']example@example.is[/EMAIL]';
    PERFORM dblink_exec('dbname=mydb', cmd);
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Данным действием мы вызываем с помощью mail -s отправку письма с темой "Data breach alert" на адрес example@example.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 инструменты так же предлагают довольно широкий спектр защитных опций, что позволяет иметь защищённое пространство, хотя бы для каких-то собственных или рабочих данных.

Всем успехов!
 
  • Нравится
Реакции: N1GGA
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

Курс AD