Update to v0.3.3

This commit is contained in:
whoot
2014-12-08 17:49:03 +01:00
parent ea1fd10e8d
commit 265a0c688d
15 changed files with 247 additions and 6519 deletions

View File

@@ -19,15 +19,17 @@ Typo-Enumerator works with [Python](http://www.python.org/download/) version **2
On Windows you might need to install following packages: On Windows you might need to install following packages:
* [Colorama](https://pypi.python.org/pypi/colorama)
* [Requests](https://pypi.python.org/pypi/requests/2.3.0) * [Requests](https://pypi.python.org/pypi/requests/2.3.0)
On Redhat you can install all needed packages with easy_install: On Redhat you can install all needed packages with easy_install:
easy_install argparse easy_install argparse
easy_install colorama
easy_install requests easy_install requests
To make it look pretty, you may want to install colorama:
* [Colorama](https://pypi.python.org/pypi/colorama)
If you want to use Typo-Enumerator with TOR, you need the [SocksiPy](http://socksipy.sourceforge.net/) module. If you want to use Typo-Enumerator with TOR, you need the [SocksiPy](http://socksipy.sourceforge.net/) module.
On Debian/Ubuntu you can install it with apt-get: On Debian/Ubuntu you can install it with apt-get:
@@ -63,4 +65,4 @@ Links
* Download: [.tar.gz](https://github.com/whoot/Typo-Enumerator/tarball/master) or [.zip](https://github.com/whoot/Typo-Enumerator/archive/master) * Download: [.tar.gz](https://github.com/whoot/Typo-Enumerator/tarball/master) or [.zip](https://github.com/whoot/Typo-Enumerator/archive/master)
* Changelog: [Here](https://github.com/whoot/Typo-Enumerator/blob/master/doc/CHANGELOG.md) * Changelog: [Here](https://github.com/whoot/Typo-Enumerator/blob/master/doc/CHANGELOG.md)
* TODO: [Here](https://github.com/whoot/Typo-Enumerator/blob/master/doc/TODO.md) * TODO: [Here](https://github.com/whoot/Typo-Enumerator/blob/master/doc/TODO.md)
* Issue tracker: https://github.com/whoot/Typo-Enumerator/issues * Issue tracker: https://github.com/whoot/Typo-Enumerator/issues

View File

@@ -1,3 +1,9 @@
## Version 0.3.3
* Extensions are now saved into different files, separated by state (experimental | alpha | beta | stable | outdated | all). This makes it possible to check more specific ones.
* Colorama is only used if installed. It doesn't need to be installed anymore.
* Installed extensions are shown immediately
## Version 0.3.2 ## Version 0.3.2
* Added support for Windows and Red Hat systems * Added support for Windows and Red Hat systems
@@ -8,7 +14,7 @@
* Domains must be specified with 'http://' or 'https://' (for example: https://127.0.0.1). * Domains must be specified with 'http://' or 'https://' (for example: https://127.0.0.1).
* Login page redirections can be followed or not. * Login page redirections can be followed or not.
* Fixed the 'all extensions are installed' bug in the summary when using verbose mode. * Fixed the 'all extensions are installed' bug in the summary when using verbose mode.
* Set sleep between threads to 0.5, to fix time out errors when checking a huge amount of extensions. * Set sleep between threads to 0.5 to fix time out errors when checking a huge amount of extensions.
## Version 0.3 ## Version 0.3
@@ -68,4 +74,4 @@
## Version 0.1 ## Version 0.1
* Prototype * Prototype

View File

@@ -5,4 +5,5 @@
* Some extensions don't have any version information. These extensions must be listed in settings.NO_VERSIONINFO. * Some extensions don't have any version information. These extensions must be listed in settings.NO_VERSIONINFO.
* Maybe use one library for all requests * Maybe use one library for all requests
* Add screenshot * Add screenshot
* Give the possibility to use POST instead of GET requests
* verbose gruscht gscheid behandeln

6414
extensions

File diff suppressed because it is too large Load Diff

View File

@@ -5,27 +5,37 @@ Copyright (c) 2014 Jan Rude
""" """
import re import re
import os
import sys
import time import time
import urllib2 import urllib2
from Queue import Queue from Queue import Queue
from colorama import Fore try:
from colorama import Fore
except:
pass
from os.path import isfile from os.path import isfile
from threading import Thread, Lock from threading import Thread, Lock
from lib import settings from lib import settings
def generate_list(): def generate_list():
if not isfile('extensions'): print ''
print(Fore.RED + "\nExtensionfile not found!\nPlease update Typo-Enumerator (python typoenum.py -u)" + Fore.RESET) for ext_file in settings.EXTENSION_FILE:
sys.exit(-2) if not isfile(os.path.join('extensions', ext_file)):
with open('extensions', 'r') as f: output("Could not find extension file " + ext_file
count = 0 + "\nPossible values are: experimental | alpha | beta | stable | outdated | all", False)
for extension in f: sys.exit(-1)
if settings.TOP_EXTENSION > count:
settings.EXTENSION_LIST.append(extension.split('\n')[0]) with open(os.path.join('extensions', ext_file), 'r') as f:
count += 1 count = 0
else: print "[+] Loading:", ext_file
f.close() for extension in f:
return if settings.TOP_EXTENSION > count:
settings.EXTENSION_LIST.append(extension.split('\n')[0])
count += 1
else:
f.close()
return
def copy(): def copy():
for extension in settings.EXTENSION_LIST: for extension in settings.EXTENSION_LIST:
@@ -56,17 +66,18 @@ def check_extension():
# settings.in_queue.put(extension) # settings.in_queue.put(extension)
# if extension is not in any given path, it's not installed # if extension is not in any given path, it's not installed
if settings.verbose: if settings.verbose:
settings.out_queue.put(extension.ljust(32) + Fore.RED + 'not installed' + Fore.RESET) output(extension.ljust(32) + 'not installed', False)
settings.in_queue.task_done() settings.in_queue.task_done()
# Searching version of installed extension # Searching version of installed extension
def check_extension_version(path, extension): def check_extension_version(path, extension):
settings.EXTENSIONS_FOUND += 1
# if no version information is available, skip version search # if no version information is available, skip version search
if extension in settings.NO_VERSIONINFO: if extension in settings.NO_VERSIONINFO:
if settings.verbose: if settings.verbose:
settings.out_queue.put(extension.ljust(32) + Fore.GREEN + 'installed' + Fore.RESET + ' (no version information available)') output(extension.ljust(32) + 'installed (no version information available)', True)
else: else:
settings.out_queue.put(extension.ljust(32) + Fore.GREEN + 'installed' + Fore.RESET) output(extension.ljust(32) + 'installed', True)
else: else:
try: try:
request = urllib2.Request(settings.DOMAIN + path + extension +'/ChangeLog', None, settings.user_agent) request = urllib2.Request(settings.DOMAIN + path + extension +'/ChangeLog', None, settings.user_agent)
@@ -77,17 +88,26 @@ def check_extension_version(path, extension):
regex = re.compile("(\d{1,2}\.\d{1,2}\.?[0-9]?[0-9]?[' '\n])") regex = re.compile("(\d{1,2}\.\d{1,2}\.?[0-9]?[0-9]?[' '\n])")
searchVersion = regex.search(changelog) searchVersion = regex.search(changelog)
version = searchVersion.groups() version = searchVersion.groups()
settings.out_queue.put(extension.ljust(32) + Fore.GREEN + 'installed (v' + version[0].split()[0] + ')' + Fore.RESET) output(extension.ljust(32) + 'installed (v' + version[0].split()[0] + ')', True)
except: except:
try: try:
regex = re.compile("(\d{2,4}[\.\-]\d{1,2}[\.\-]\d{1,4})") regex = re.compile("(\d{2,4}[\.\-]\d{1,2}[\.\-]\d{1,4})")
search = regex.search(changelog) search = regex.search(changelog)
version = search.groups() version = search.groups()
settings.out_queue.put(extension.ljust(32) + Fore.GREEN + 'installed (last entry from ' + version[0] + ')' + Fore.RESET) output(extension.ljust(32) + 'installed (last entry from ' + version[0] + ')', True)
except: except:
if settings.verbose: if settings.verbose:
settings.out_queue.put(extension.ljust(32) + Fore.GREEN + "installed" + Fore.RESET + " (no version information found)") output(extension.ljust(32) + 'installed (no version information found)', True)
else: else:
settings.out_queue.put(extension.ljust(32) + Fore.GREEN + "installed" + Fore.RESET) output(extension.ljust(32) + 'installed', True)
except: except:
settings.out_queue.put(extension.ljust(32) + Fore.GREEN + "installed" + Fore.RESET) output(extension.ljust(32) + "installed", True)
def output(message, status):
if settings.COLORAMA:
if status:
print Fore.GREEN + message + Fore.RESET
else:
print Fore.RED + message + Fore.RESET
else:
print message

View File

@@ -40,11 +40,11 @@ def search_login():
else: else:
print 'Oops! Got unhandled code:'.ljust(32) + str(statusCode) + ': ' + str(r.raise_for_status()) print 'Oops! Got unhandled code:'.ljust(32) + str(statusCode) + ': ' + str(r.raise_for_status())
except requests.exceptions.Timeout: except requests.exceptions.Timeout:
print Fore.RED + 'Connection timed out' + Fore.RESET output('Connection timed out')
except requests.exceptions.TooManyRedirects: except requests.exceptions.TooManyRedirects:
print Fore.RED + 'Too many redirects' + Fore.RESET output('Too many redirects')
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
print Fore.RED + str(e) + Fore.RESET output(str(e))
# Searching for Typo3 references in title # Searching for Typo3 references in title
def check_title(response, url): def check_title(response, url):
@@ -72,7 +72,7 @@ def check_main_page():
if 'fe_typo_user' in cookie: if 'fe_typo_user' in cookie:
return bad_url() return bad_url()
except KeyboardInterrupt: except KeyboardInterrupt:
print Fore.RED + '\nReceived keyboard interrupt.\nQuitting...' + Fore.RESET output('\nReceived keyboard interrupt.\nQuitting...')
exit(-1) exit(-1)
except: except:
try: try:
@@ -91,14 +91,14 @@ def check_main_page():
pass pass
except Exception, e: except Exception, e:
if '404' in str(e): if '404' in str(e):
print Fore.RED + str(e) + '\nPlease ensure you entered the right url' + Fore.RESET output(str(e) + '\nPlease ensure you entered the right url')
else: else:
print Fore.RED + str(e) + Fore.RESET output(str(e))
return 'skip' return 'skip'
return False return False
def bad_url(): def bad_url():
print 'Typo3 Login:'.ljust(32) + Fore.GREEN + 'Typo3 is used, but could not find login' + Fore.RESET print 'Typo3 Login:'.ljust(32) + 'Typo3 is used, but could not find login'
print ''.ljust(32) + 'This could result in \'no extensions are installed\'.' print ''.ljust(32) + 'This could result in \'no extensions are installed\'.'
print ''.ljust(32) + 'Seems like something is wrong with the given url.' print ''.ljust(32) + 'Seems like something is wrong with the given url.'
answer = '' answer = ''
@@ -110,3 +110,11 @@ def bad_url():
if answer is 'y': if answer is 'y':
return True return True
return 'skip' return 'skip'
# printing error messages
def output(message):
if settings.COLORAMA:
print Fore.RED
print message
if settings.COLORAMA:
print Fore.RESET

View File

@@ -2,7 +2,7 @@ import socket
import urllib2 import urllib2
import os, sys import os, sys
import re import re
from colorama import Fore
try: try:
import socks import socks
except: except:
@@ -16,7 +16,7 @@ except:
def start_daemon(): def start_daemon():
if sys.platform.startswith('linux'): if sys.platform.startswith('linux'):
os.system('service privoxy start') os.system('service privoxy start')
print '[' + Fore.GREEN + ' ok ' + Fore.RESET + '] Starting privoxy daemon...done.' print '[ ok ] Starting privoxy daemon...done.'
elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'): elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'):
print "Please make sure Privoxy is running..." print "Please make sure Privoxy is running..."
else: else:
@@ -34,7 +34,7 @@ def connect(port):
response = torcheck.read() response = torcheck.read()
torcheck.close() torcheck.close()
except: except:
print Fore.RED + "Failed to connect through Privoxy!" + Fore.RESET print "Failed to connect through Privoxy!"
print "Please make sure your configuration is right!\n" print "Please make sure your configuration is right!\n"
sys.exit(-2) sys.exit(-2)
try: try:
@@ -51,6 +51,6 @@ def stop():
print "\n" print "\n"
if sys.platform.startswith('linux'): if sys.platform.startswith('linux'):
os.system('service privoxy stop') os.system('service privoxy stop')
print '[' + Fore.GREEN + ' ok ' + Fore.RESET + '] Stopping privoxy daemon...done.' print '[ ok ] Stopping privoxy daemon...done.'
elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'): elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'):
print "You can close Privoxy now..." print "You can close Privoxy now..."

View File

@@ -8,8 +8,7 @@ from Queue import Queue
from threading import Thread, Lock from threading import Thread, Lock
# Domain to check # Domain to check
# Valid: string DOMAIN = ''
DOMAIN = ""
# Maximum number of threads (avoiding connection issues and/or DoS) # Maximum number of threads (avoiding connection issues and/or DoS)
MAX_NUMBER_OF_THREADS = 10 MAX_NUMBER_OF_THREADS = 10
@@ -20,6 +19,10 @@ DEFAULT_TOR_PORT = 9050
# Default ports used in Tor proxy bundles # Default ports used in Tor proxy bundles
DEFAULT_PRIVOXY_PORT = 8118 DEFAULT_PRIVOXY_PORT = 8118
# Default extension file
# Default: all available Typo3 extensions
EXTENSION_FILE = ['all_extensions']
# List with selected extensions # List with selected extensions
EXTENSION_LIST = [] EXTENSION_LIST = []
@@ -27,7 +30,7 @@ EXTENSION_LIST = []
NO_VERSIONINFO = ['wt_spamshield', 'introduction'] #introduction has ChangeLog, but will use "Typo3 4.5.0" as version info! NO_VERSIONINFO = ['wt_spamshield', 'introduction'] #introduction has ChangeLog, but will use "Typo3 4.5.0" as version info!
# Check only top X extensions # Check only top X extensions
# Default: all # Default: all extensions
TOP_EXTENSION = 'all' TOP_EXTENSION = 'all'
# HTTP User-Agent header value. Useful to fake the HTTP User-Agent header value at each HTTP request # HTTP User-Agent header value. Useful to fake the HTTP User-Agent header value at each HTTP request
@@ -35,19 +38,16 @@ TOP_EXTENSION = 'all'
user_agent = {'User-Agent' : "Mozilla/5.0"} user_agent = {'User-Agent' : "Mozilla/5.0"}
# Maximum number of concurrent HTTP(s) requests (handled with Python threads) # Maximum number of concurrent HTTP(s) requests (handled with Python threads)
# Valid: integer
# Default: 7 # Default: 7
THREADS = 7 THREADS = 7
# Verbosity. # Verbosity.
verbose = False verbose = False
#Input and output queues #Input queue
in_queue = "" in_queue = ''
out_queue = ""
# Seconds to wait before timeout connection. # Seconds to wait before timeout connection.
# Valid: int
# Default: 20 # Default: 20
TIMEOUT = 20 TIMEOUT = 20
@@ -67,8 +67,12 @@ EXTENSION_PATHS = ('/typo3conf/ext/', '/typo3/sysext/')
# Possible version info file # Possible version info file
EXTENSION_VERSION_INFO = ('ChangeLog', 'README.txt') EXTENSION_VERSION_INFO = ('ChangeLog', 'README.txt')
# Installed extensions on targed domain
EXTENSIONS_FOUND = 0 EXTENSIONS_FOUND = 0
# Colorama is not used, if not installed
COLORAMA = False
## Not used atm ## ## Not used atm ##

View File

@@ -8,7 +8,10 @@ import time
from Queue import Queue from Queue import Queue
from os.path import isfile from os.path import isfile
from threading import Thread, Lock from threading import Thread, Lock
from colorama import Fore, Back try:
from colorama import Fore, Back
except:
pass
from lib import settings from lib import settings
from lib import versioninfo from lib import versioninfo
from lib import login from lib import login
@@ -18,7 +21,12 @@ from lib import extensions
# Startmethod # Startmethod
def check_typo_installation(domain): def check_typo_installation(domain):
settings.DOMAIN = domain settings.DOMAIN = domain
print '\n\n' + Fore.CYAN + '[ Checking ' + domain + ' ]' + '\n' + "-"* 70 + Fore.RESET settings.EXTENSIONS_FOUND = 0
if settings.COLORAMA:
output = Fore.CYAN + '[ Checking ' + domain + ' ]' + '\n' + "-"* 70 + Fore.RESET
else:
output = '[ Checking ' + domain + ' ]' + '\n' + "-"* 70
print '\n\n' + output
check = login.search_login() check = login.search_login()
if check is "redirect": if check is "redirect":
@@ -31,21 +39,20 @@ def check_typo_installation(domain):
if mainpage is True: if mainpage is True:
init_extension_search() init_extension_search()
elif mainpage is not "skip": elif mainpage is not "skip":
print "Typo3 Login:".ljust(32) + Fore.RED + "Typo3 is not used on this domain" + Fore.RESET output("Typo3 Login:".ljust(32) + "Typo3 is not used on this domain", False)
def init_extension_search(): def init_extension_search():
settings.in_queue = Queue() settings.in_queue = Queue()
settings.out_queue = Queue()
versioninfo.search_version_info() versioninfo.search_version_info()
versioninfo.output() versioninfo.output()
if not settings.EXTENSION_LIST: if settings.TOP_EXTENSION != 0:
extensions.generate_list() if not settings.EXTENSION_LIST:
extensions.generate_list()
extensions.copy() extensions.copy()
extensions_to_check = settings.in_queue.qsize() extensions_to_check = settings.in_queue.qsize()
if extensions_to_check is not 0:
print '\nChecking', extensions_to_check, 'extension(s)...' print '\nChecking', extensions_to_check, 'extension(s)...'
# Thanks to 'RedSparrow': http://stackoverflow.com/questions/17991033/python-cant-kill-main-thread-with-keyboardinterrupt # Thanks to 'RedSparrow': http://stackoverflow.com/questions/17991033/python-cant-kill-main-thread-with-keyboardinterrupt
try: try:
@@ -59,18 +66,24 @@ def init_extension_search():
else: else:
break break
except KeyboardInterrupt: except KeyboardInterrupt:
print Fore.RED + "\nReceived keyboard interrupt.\nQuitting..." + Fore.RESET output("\nReceived keyboard interrupt.\nQuitting...", False)
exit(-1) exit(-1)
settings.in_queue.join() settings.in_queue.join()
installed_ext = settings.out_queue.qsize() installed_ext = settings.EXTENSIONS_FOUND
if installed_ext is 0: if installed_ext == 0:
print Fore.RED + "No extensions installed" + Fore.RESET output("No extensions installed", False)
else: else:
t = Thread(target=output.thread, args=()) output('\n' + str(settings.EXTENSIONS_FOUND) + '/' + str(extensions_to_check) + ' extension(s) installed', True)
t.daemon = True
t.start()
settings.out_queue.join()
print Fore.GREEN + '\n', str(settings.EXTENSIONS_FOUND) + '/' + str(extensions_to_check),'extension(s) installed' + Fore.RESET
else: else:
print '\nSkipping check for extensions...' print '\nSkipping check for extensions...'
# print error messages
def output(message, setting):
if settings.COLORAMA:
if not setting:
print Fore.RED + message + Fore.RESET
if setting:
print Fore.GREEN + message + Fore.RESET
else:
print message

Binary file not shown.

View File

@@ -2,7 +2,7 @@ import socket
import urllib2 import urllib2
import os, sys import os, sys
import re import re
from colorama import Fore
try: try:
import socks import socks
except: except:
@@ -34,14 +34,14 @@ def connect(port):
torcheck.close() torcheck.close()
except Exception, e: except Exception, e:
print e print e
print Fore.RED + "Failed to connect through TOR!" + Fore.RESET print "Failed to connect through TOR!"
print "Please make sure your configuration is right!\n" print "Please make sure your configuration is right!\n"
sys.exit(-2) sys.exit(-2)
try: try:
regex = re.compile('Congratulations. This browser is configured to use Tor.') regex = re.compile('Congratulations. This browser is configured to use Tor.')
searchVersion = regex.search(response) searchVersion = regex.search(response)
version = searchVersion.groups() version = searchVersion.groups()
print Fore.GREEN + "Connection to TOR established" + Fore.RESET print "Connection to TOR established"
regex = re.compile("(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})") regex = re.compile("(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})")
searchIP = regex.search(response) searchIP = regex.search(response)
IP = searchIP.groups()[0] IP = searchIP.groups()[0]
@@ -55,4 +55,4 @@ def stop():
if sys.platform.startswith('linux'): if sys.platform.startswith('linux'):
os.system('service tor stop') os.system('service tor stop')
elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'): elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'):
print "You can close TOR now..." print "You can close TOR now..."

View File

@@ -2,7 +2,7 @@ import socket
import urllib2 import urllib2
import os, sys import os, sys
import re import re
from colorama import Fore
try: try:
import socks import socks
except: except:
@@ -17,7 +17,7 @@ def start_daemon():
if sys.platform.startswith('linux'): if sys.platform.startswith('linux'):
os.system('service tor start') os.system('service tor start')
os.system('service privoxy start') os.system('service privoxy start')
print '[' + Fore.GREEN + ' ok ' + Fore.RESET + '] Starting privoxy daemon...done.' print '[ ok ] Starting privoxy daemon...done.'
elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'): elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'):
print "Please make sure TOR and Privoxy are running..." print "Please make sure TOR and Privoxy are running..."
else: else:
@@ -35,14 +35,14 @@ def connect(port):
response = torcheck.read() response = torcheck.read()
torcheck.close() torcheck.close()
except: except:
print Fore.RED + "Failed to connect through Privoxy and/or TOR!" + Fore.RESET print "Failed to connect through Privoxy and/or TOR!"
print "Please make sure your configuration is right!\n" print "Please make sure your configuration is right!\n"
sys.exit(-2) sys.exit(-2)
try: try:
regex = re.compile('Congratulations. This browser is configured to use Tor.') regex = re.compile('Congratulations. This browser is configured to use Tor.')
searchVersion = regex.search(response) searchVersion = regex.search(response)
version = searchVersion.groups() version = searchVersion.groups()
print Fore.GREEN + "Connection to TOR established" + Fore.RESET print "Connection to TOR established"
regex = re.compile("(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})") regex = re.compile("(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})")
searchIP = regex.search(response) searchIP = regex.search(response)
IP = searchIP.groups()[0] IP = searchIP.groups()[0]
@@ -57,6 +57,6 @@ def stop():
if sys.platform.startswith('linux'): if sys.platform.startswith('linux'):
os.system('service tor stop') os.system('service tor stop')
os.system('service privoxy stop') os.system('service privoxy stop')
print '[' + Fore.GREEN + ' ok ' + Fore.RESET + '] Stopping privoxy daemon...done.' print '[ ok ] Stopping privoxy daemon...done.'
elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'): elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'):
print "You can close TOR and Privoxy now..." print "You can close TOR and Privoxy now..."

View File

@@ -8,12 +8,13 @@ import xml.etree.ElementTree as ElementTree
# Progressbar # Progressbar
def dlProgress(count, blockSize, totalSize): def dlProgress(count, blockSize, totalSize):
percent = int(count*blockSize*100/totalSize) percent = int(count*blockSize*100/totalSize)
sys.stdout.write("\rDownloading extentions: " + "%d%%" % percent) sys.stdout.write("\r[+] Downloading extentions: " + "%d%%" % percent)
sys.stdout.flush() sys.stdout.flush()
# Download extensions from typo3 repository # Download extensions from typo3 repository
def download_ext(): def download_ext():
try: try:
urllib.URLopener.version = 'TYPO3/7.0.0'
urllib.urlretrieve('http://ter.sitedesign.dk/ter/extensions.xml.gz', 'extensions.gz', reporthook=dlProgress) urllib.urlretrieve('http://ter.sitedesign.dk/ter/extensions.xml.gz', 'extensions.gz', reporthook=dlProgress)
inf = gzip.open('extensions.gz', 'rb') inf = gzip.open('extensions.gz', 'rb')
file_content = inf.read() file_content = inf.read()
@@ -23,22 +24,82 @@ def download_ext():
outF.close() outF.close()
os.remove('extensions.gz') os.remove('extensions.gz')
except Exception, e: except Exception, e:
print "Oops! Got:".ljust(32), e print "\nOops! Got:", e
# Parse extensions.xml and save extensions in file # Parse extensions.xml and save extensions in files
def generate_list(): def generate_list():
extension = 'extensions.xml' experimental = {} # everything with 'experimental' and 'test'
print "\nParsing file..." alpha = {}
tree = ElementTree.parse(extension) beta = {}
tag_dict = tree.getroot() stable = {}
exten_Dict = {} outdated = {} # everything with 'obsolete' and 'outdated'
for extensions in tag_dict.getchildren(): allExt = {}
ext = {extensions.get('extensionkey'):extensions[0].text}
exten_Dict.update(ext) print "\n[+] Parsing file..."
sorted_dict = sorted(exten_Dict.iteritems(), key=lambda x: int(x[1]), reverse=True) tree = ElementTree.parse('extensions.xml')
f = open('extensions','w') root = tree.getroot()
for i in xrange(0,len(exten_Dict)): extension = 0
f.write(sorted_dict[i][0]+'\n') # for every extension in file
for child in root:
# insert every extension in "allExt" dictionary
allExt.update({child.get('extensionkey'):child[0].text})
# and search the last version entry
version = 0
for version_entry in root[extension].iter('version'):
version +=1
# get the state of the latest version
state = (str(root[extension][version][2].text)).lower()
if state == 'experimental' or state == 'test':
experimental.update({child.get('extensionkey'):child[0].text})
elif state == 'alpha':
alpha.update({child.get('extensionkey'):child[0].text})
elif state == 'beta':
beta.update({child.get('extensionkey'):child[0].text})
elif state == 'stable':
stable.update({child.get('extensionkey'):child[0].text})
elif state == 'obsolete' or state == 'outdated':
outdated.update({child.get('extensionkey'):child[0].text})
extension+=1
# sorting lists according to number of downloads
print "[+] Sorting according to number of downloads..."
sorted_experimental = sorted(experimental.iteritems(), key=lambda x: int(x[1]), reverse=True)
sorted_alpha = sorted(alpha.iteritems(), key=lambda x: int(x[1]), reverse=True)
sorted_beta = sorted(beta.iteritems(), key=lambda x: int(x[1]), reverse=True)
sorted_stable = sorted(stable.iteritems(), key=lambda x: int(x[1]), reverse=True)
sorted_outdated = sorted(outdated.iteritems(), key=lambda x: int(x[1]), reverse=True)
sorted_allExt = sorted(allExt.iteritems(), key=lambda x: int(x[1]), reverse=True)
print "[+] Generating files..."
f = open(os.path.join('extensions', 'experimental_extensions'),'w')
for i in xrange(0,len(sorted_experimental)):
f.write(sorted_experimental[i][0]+'\n')
f.close() f.close()
print 'Loaded', len(exten_Dict), 'extensions\n'
f = open(os.path.join('extensions', 'alpha_extensions'),'w')
for i in xrange(0,len(sorted_alpha)):
f.write(sorted_alpha[i][0]+'\n')
f.close()
f = open(os.path.join('extensions', 'beta_extensions'),'w')
for i in xrange(0,len(sorted_beta)):
f.write(sorted_beta[i][0]+'\n')
f.close()
f = open(os.path.join('extensions', 'stable_extensions'),'w')
for i in xrange(0,len(sorted_stable)):
f.write(sorted_stable[i][0]+'\n')
f.close()
f = open(os.path.join('extensions', 'outdated_extensions'),'w')
for i in xrange(0,len(sorted_outdated)):
f.write(sorted_outdated[i][0]+'\n')
f.close()
f = open(os.path.join('extensions', 'all_extensions'),'w')
for i in xrange(0,len(sorted_allExt)):
f.write(sorted_allExt[i][0]+'\n')
f.close()
print '[+] Loaded', len(sorted_allExt), 'extensions\n'
os.remove('extensions.xml') os.remove('extensions.xml')

View File

@@ -6,8 +6,11 @@ Copyright (c) 2014 Jan Rude
import re import re
import urllib2 import urllib2
from colorama import Fore
from lib import settings from lib import settings
try:
from colorama import Fore
except:
pass
# Searching for Typo3 version # Searching for Typo3 version
def search_version_info(): def search_version_info():
@@ -29,7 +32,16 @@ def search_version_info():
# Output of Typo3 version # Output of Typo3 version
def output(): def output():
if settings.TYPO_VERSION is None: if settings.TYPO_VERSION is None:
print "Typo3 Version:".ljust(32) + Fore.RED + "Not found" + Fore.RESET print "Typo3 Version:".ljust(32)
if settings.COLORAMA:
print Fore.RED
print "Not found"
if settings.COLORAMA:
Fore.RESET
else: else:
print "Typo3 Version:".ljust(32) + Fore.GREEN + settings.TYPO_VERSION + Fore.RESET if settings.COLORAMA:
output = Fore.GREEN + settings.TYPO_VERSION + Fore.RESET
else:
output = settings.TYPO_VERSION
print "Typo3 Version:".ljust(32) + output
print "Link to vulnerabilities:".ljust(32) + "http://www.cvedetails.com/version-search.php?vendor=&product=Typo3&version=" + settings.TYPO_VERSION.split()[1] print "Link to vulnerabilities:".ljust(32) + "http://www.cvedetails.com/version-search.php?vendor=&product=Typo3&version=" + settings.TYPO_VERSION.split()[1]

View File

@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
############ Version information ############## ############ Version information ##############
__version__ = "0.3.2" __version__ = "0.3.3"
__program__ = "Typo-Enumerator v" + __version__ __program__ = "Typo-Enumerator v" + __version__
__description__ = 'Automatic Typo3 and Typo3 extensions enumeration tool' __description__ = 'Automatic Typo3 and Typo3 extensions enumeration tool'
__author__ = "Jan Rude" __author__ = "Jan Rude"
@@ -14,12 +14,15 @@ import os
import datetime import datetime
import argparse import argparse
import warnings import warnings
from colorama import init, Fore, Style
warnings.filterwarnings(action="ignore", message=".*was already imported", category=UserWarning) warnings.filterwarnings(action="ignore", message=".*was already imported", category=UserWarning)
warnings.filterwarnings(action="ignore", category=DeprecationWarning)
from lib import settings from lib import settings
from lib import update from lib import update
from lib import start from lib import start
try:
from colorama import init, Fore
settings.COLORAMA = True
except:
pass
init() init()
@@ -35,6 +38,7 @@ def main(argv):
parser.add_argument('--user_agent', dest='user_agent', metavar='USER-AGENT (default: Mozilla/5.0)') parser.add_argument('--user_agent', dest='user_agent', metavar='USER-AGENT (default: Mozilla/5.0)')
extensionGroup.add_argument('--top', type=int, dest='top', metavar='VALUE', help='Check only most X downloaded extensions (default: all)') extensionGroup.add_argument('--top', type=int, dest='top', metavar='VALUE', help='Check only most X downloaded extensions (default: all)')
extensionGroup.add_argument('-e', '--extension', type=str, dest='ext', metavar='EXTENSION', help='Check only for this extension(s)', nargs='+') extensionGroup.add_argument('-e', '--extension', type=str, dest='ext', metavar='EXTENSION', help='Check only for this extension(s)', nargs='+')
parser.add_argument('--state', dest='ext_state', help='Check only (experimental | alpha | beta | stable | outdated) extensions', nargs='+')
anonGroup.add_argument('--tor', help='using only TOR for connections', action='store_true') anonGroup.add_argument('--tor', help='using only TOR for connections', action='store_true')
anonGroup.add_argument('--privoxy', help='using only Privoxy for connections', action='store_true') anonGroup.add_argument('--privoxy', help='using only Privoxy for connections', action='store_true')
anonGroup.add_argument('--tp', help='using TOR and Privoxy for connections', action='store_true') anonGroup.add_argument('--tp', help='using TOR and Privoxy for connections', action='store_true')
@@ -51,7 +55,7 @@ def main(argv):
return True return True
if args.threads > settings.MAX_NUMBER_OF_THREADS: if args.threads > settings.MAX_NUMBER_OF_THREADS:
print Fore.RED + "Warning! Threads are set to", args.threads,"(max value is 10)\nThis can cause connection issues and/or DoS\nAborting...." + Fore.RESET output("Warning! Threads are set to", args.threads,"(max value is 10)\nThis can cause connection issues and/or DoS\nAborting....")
sys.exit(-2) sys.exit(-2)
if args.tor: if args.tor:
@@ -94,20 +98,26 @@ def main(argv):
for extension in args.ext: for extension in args.ext:
settings.EXTENSION_LIST.append(extension) settings.EXTENSION_LIST.append(extension)
if args.ext_state:
settings.EXTENSION_FILE = []
for ext_list in args.ext_state:
ext_file = ext_list + '_extensions'
settings.EXTENSION_FILE.append(ext_file)
if args.domain: if args.domain:
for dom in args.domain: for dom in args.domain:
start.check_typo_installation(dom) start.check_typo_installation(dom)
elif args.file: elif args.file:
if not isfile(args.file): if not isfile(args.file):
print(Fore.RED + "\nFile not found: " + args.file + "\nAborting..." + Fore.RESET) output("\nFile not found: " + args.file + "\nAborting...")
sys.exit(-2) sys.exit(-2)
else: else:
with open(args.file, 'r') as f: with open(args.file, 'r') as f:
for line in f: for line in f:
start.check_typo_installation(line.strip('\n')[0]) start.check_typo_installation(line.strip('\n')[0])
except KeyboardInterrupt: except KeyboardInterrupt:
print Fore.RED + "\nReceived keyboard interrupt.\nQuitting..." + Fore.RESET output("\nReceived keyboard interrupt.\nQuitting...")
exit(-1) exit(-1)
except Exception, e: except Exception, e:
import traceback import traceback
@@ -123,19 +133,24 @@ def main(argv):
elif args.tp: elif args.tp:
tp.stop() tp.stop()
print '\n'
now = datetime.datetime.now() now = datetime.datetime.now()
print __program__ + ' finished at ' + now.strftime("%Y-%m-%d %H:%M:%S") + '\n' print '\n' + __program__ + ' finished at ' + now.strftime("%Y-%m-%d %H:%M:%S") + '\n'
Style.RESET_ALL
return True return True
# print error messages
def output(message):
if settings.COLORAMA:
print Fore.RED + message + Fore.RESET
else:
print message
if __name__ == "__main__": if __name__ == "__main__":
import sys import sys
print(Style.BRIGHT + '\n' + 70*'*') print('\n' + 70*'*')
print('\t' + __program__ ) print('\t' + __program__ )
print('\t' + __description__) print('\t' + __description__)
print('\t' + '(c)2014 by ' + __author__) print('\t' + '(c)2014 by ' + __author__)
print('\t' + 'Status:\t' + __status__) print('\t' + 'Status:\t' + __status__)
print('\t' + 'For legal purposes only!') print('\t' + 'For legal purposes only!')
print(70*'*' + '\n') print(70*'*' + '\n')
sys.exit( not main( sys.argv ) ) sys.exit( not main( sys.argv ) )