Updating to v0.3

This commit is contained in:
root
2014-08-10 16:31:21 +02:00
parent 481972a6cb
commit 156fc12a4c
18 changed files with 7241 additions and 396 deletions

3
lib/__init__.py Normal file
View File

@@ -0,0 +1,3 @@
#!/usr/bin/env python
pass

93
lib/extensions.py Normal file
View File

@@ -0,0 +1,93 @@
#!/usr/bin/env python
"""
Copyright (c) 2014 Jan Rude
"""
import re
import time
import urllib2
from Queue import Queue
from colorama import Fore
from os.path import isfile
from threading import Thread, Lock
from lib import settings
def generate_list():
if not isfile('extensions'):
print(Fore.RED + "\nExtensionfile not found!\nPlease update Typo-Enumerator (python typoenum.py -u)" + Fore.RESET)
sys.exit(-2)
with open('extensions', 'r') as f:
count = 0
for extension in f:
if settings.TOP_EXTENSION > count:
settings.EXTENSION_LIST.append(extension.split('\n')[0])
count += 1
else:
f.close()
return
def copy():
for extension in settings.EXTENSION_LIST:
settings.in_queue.put(extension)
# Searching installed extensions
# Check on version if we get 200 or 403.
def check_extension():
while True:
extension = settings.in_queue.get()
for path in settings.EXTENSION_PATHS:
try:
req = urllib2.Request('http://' + settings.DOMAIN + path + extension + '/', None, settings.user_agent)
connection = urllib2.urlopen(req, timeout = settings.TIMEOUT)
connection.close()
check_extension_version(path, extension)
settings.in_queue.task_done()
return
except urllib2.HTTPError, e:
if e.code == 403:
check_extension_version(path, extension)
settings.in_queue.task_done()
return
except urllib2.URLError, e:
pass
#retry = raw_input('Error on checking ' + extension + ': ' + str(e.reason) + '\nRetrying? (y/n) ')
#if retry:
# settings.in_queue.put(extension)
# if extension is not in any given path, it's not installed
if settings.verbose:
settings.out_queue.put(extension.ljust(32) + Fore.RED + 'not installed' + Fore.RESET)
settings.in_queue.task_done()
# Searching version of installed extension
def check_extension_version(path, extension):
# if no version information is available, skip version search
if extension in settings.NO_VERSIONINFO:
if settings.verbose:
settings.out_queue.put(extension.ljust(32) + Fore.GREEN + 'installed' + Fore.RESET + ' (no version information available)')
else:
settings.out_queue.put(extension.ljust(32) + Fore.GREEN + 'installed' + Fore.RESET)
else:
try:
request = urllib2.Request('http://' + settings.DOMAIN + path + extension +'/ChangeLog', None, settings.user_agent)
response = urllib2.urlopen(request, timeout = settings.TIMEOUT)
changelog = response.read(1500)
response.close()
try:
regex = re.compile("(\d{1,2}\.\d{1,2}\.?[0-9]?[0-9]?[' '\n])")
searchVersion = regex.search(changelog)
version = searchVersion.groups()
settings.out_queue.put(extension.ljust(32) + Fore.GREEN + 'installed (v' + version[0].split()[0] + ')' + Fore.RESET)
except:
try:
regex = re.compile("(\d{2,4}[\.\-]\d{1,2}[\.\-]\d{1,4})")
search = regex.search(changelog)
version = search.groups()
settings.out_queue.put(extension.ljust(32) + Fore.GREEN + 'installed (last entry from ' + version[0] + ')' + Fore.RESET)
except:
if settings.verbose:
settings.out_queue.put(extension.ljust(32) + Fore.GREEN + "installed" + Fore.RESET + " (no version information found)")
else:
settings.out_queue.put(extension.ljust(32) + Fore.GREEN + "installed" + Fore.RESET)
except:
settings.out_queue.put(extension.ljust(32) + Fore.GREEN + "installed" + Fore.RESET)

100
lib/login.py Normal file
View File

@@ -0,0 +1,100 @@
#!/usr/bin/env python
"""
Copyright (c) 2014 Jan Rude
"""
import re
import sys
import requests
import urllib2
from colorama import Fore
from lib import settings
# Searching Typo3 login page
def search_login(domain):
try:
r = requests.get('http://' + domain + '/typo3/index.php', allow_redirects=False, timeout=settings.TIMEOUT, headers=settings.user_agent)
statusCode = r.status_code
httpResponse = r.text
if statusCode == 200:
return check_title(httpResponse, r.url)
elif (statusCode == 301) or (statusCode == 302):
location = r.headers['location']
if ("http://") in location:
locsplit = location.split("//")
new_location = locsplit[1].split("/")
search_login(new_location[0])
elif ("https://") in location:
r = requests.get(location, timeout=settings.TIMEOUT, headers=settings.user_agent, verify=False)
statusCode = r.status_code
httpResponse = r.text
return check_title(httpResponse, r.url)
elif statusCode == 404:
return check_main_page()
else:
print "Oops! Got unhandled code:".ljust(32) + str(statusCode) + ": " + str(r.raise_for_status())
except requests.exceptions.Timeout:
print Fore.RED + "Connection timed out" + Fore.RESET
except requests.exceptions.TooManyRedirects:
print Fore.RED + "Too many redirects" + Fore.RESET
except requests.exceptions.RequestException as e:
print Fore.RED + str(e) + Fore.RESET
# Searching for Typo3 references in title
def check_title(response, url):
try:
regex = re.compile("<title>(.*)</title>", re.IGNORECASE)
searchTitle = regex.search(response)
title = searchTitle.groups()[0]
if 'TYPO3' in title or 'TYPO3 SVN ID:' in response:
print "Typo3 Login:".ljust(32) + Fore.GREEN + url + Fore.RESET
return True
except:
pass
return check_main_page()
# Searching for Typo3 references in HTML comments
def check_main_page():
req = urllib2.Request('http://' + settings.DOMAIN, None, settings.user_agent)
req.add_header('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8')
try:
connection = urllib2.urlopen(req, timeout = settings.TIMEOUT)
response = connection.read()
connection.close()
try:
cookie = connection.info().getheader('Set-Cookie')
if 'fe_typo_user' in cookie:
return bad_url()
except:
try:
regex = re.compile("TYPO3(.*)", re.IGNORECASE)
searchHTML = regex.search(response)
searchHTML.groups()[0]
try:
regex = re.compile("[Tt][Yy][Pp][Oo]3 (\d{1,2}\.\d{1,2}\.[0-9][0-9]?[' '\n])")
searchVersion = regex.search(response)
version = searchVersion.groups()
settings.TYPO_VERSION = 'Typo3 ' + version[0].split()[0]
except:
pass
return bad_url()
except:
pass
except Exception, e:
if "404" in str(e):
print Fore.RED + str(e) + "\nPlease ensure you entered the right url" + Fore.RESET
else:
print Fore.RED + "Got \"" + str(e) + "\" on testing main page." + Fore.RESET
return False
print "Typo3 Login:".ljust(32) + Fore.RED + "Typo3 is not used on this domain" + Fore.RESET
return False
def bad_url():
print "Typo3 Login:".ljust(32) + Fore.GREEN + "Typo3 is used, but could not find login" + Fore.RESET
print "".ljust(32) + "This will mostly result in \"no extensions are installed\"."
print "".ljust(32) + "Seems like something is wrong with the given url."
var = raw_input("".ljust(32) + "Try anyway (y/n)? ")
if var is 'y':
return True
return False

20
lib/output.py Normal file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/env python
"""
Copyright (c) 2014 Jan Rude
"""
from Queue import Queue
from colorama import Fore
from threading import Thread, Lock
from lib import settings
# Output thread
def thread():
while settings.out_queue is not settings.out_queue.empty():
try:
extension = settings.out_queue.get()
print(extension)
settings.out_queue.task_done()
except Exception, e:
print "Oops! Got:", e

43
lib/privoxy_only.py Normal file
View File

@@ -0,0 +1,43 @@
import socket
import urllib2
import os, sys
import re
from colorama import Fore
try:
import socks
except:
print "The module 'SocksiPy' is not installed.\nPlease install it with: sudo apt-get install python-socksipy"
sys.exit(-2)
def start_daemon():
os.system('service privoxy start')
print '[' + Fore.GREEN + ' ok ' + Fore.RESET + '] Starting privoxy daemon...done.'
# Using Privoxy for all connections
def connect(port):
print "\nChecking connection..."
socks.setdefaultproxy(socks.PROXY_TYPE_HTTP, "127.0.0.1", port, True)
socket.socket = socks.socksocket
try:
url = urllib2.Request('https://check.torproject.org/')
torcheck = urllib2.urlopen(url)
response = torcheck.read()
torcheck.close()
except:
print Fore.RED + "Failed to connect through Privoxy!" + Fore.RESET
print "Please make sure your configuration is right!\n"
sys.exit(-2)
try:
# TODO: Check on privoxy at http://ha.ckers.org/weird/privoxy.html
regex = re.compile("(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})")
searchIP = regex.search(response)
IP = searchIP.groups()[0]
print "Your IP is: ", IP
except:
print "It seems like Privoxy is not used.\nAborting...\n"
sys.exit(-2)
def stop():
print "\n"
os.system('service privoxy stop')
print '[' + Fore.GREEN + ' ok ' + Fore.RESET + '] Stopping privoxy daemon...done.'

94
lib/settings.py Normal file
View File

@@ -0,0 +1,94 @@
#!/usr/bin/env python
"""
Copyright (c) 2014 Jan Rude
"""
from Queue import Queue
from threading import Thread, Lock
# Domain to check
# Valid: string
DOMAIN = ""
# Maximum number of threads (avoiding connection issues and/or DoS)
MAX_NUMBER_OF_THREADS = 10
# Default port used by Tor
DEFAULT_TOR_PORT = 9050
# Default ports used in Tor proxy bundles
DEFAULT_PRIVOXY_PORT = 8118
# List with selected extensions
EXTENSION_LIST = []
# List with extensions, where no versioninformation is available
NO_VERSIONINFO = ['wt_spamshield', 'introduction'] #introduction has ChangeLog, but will use "Typo3 4.5.0" as version info!
# Check only top X extensions
# Default: all
TOP_EXTENSION = 'all'
# HTTP User-Agent header value. Useful to fake the HTTP User-Agent header value at each HTTP request
# Default: Mozilla/5.0
user_agent = {'User-Agent' : "Mozilla/5.0"}
# Maximum number of concurrent HTTP(s) requests (handled with Python threads)
# Valid: integer
# Default: 7
THREADS = 7
# Verbosity.
verbose = False
#Input and output queues
in_queue = ""
in_queue2 = ""
out_queue = ""
# Seconds to wait before timeout connection.
# Valid: int
# Default: 20
TIMEOUT = 20
# Possible paths to Typo3 loginpage !! not used atm !!
LOGIN_PATHS = ()
# Possible paths and regex to typo3 version information
TYPO3_VERSION_INFO = {'/typo3_src/ChangeLog':'RELEASE] Release of TYPO3 (.*)', '/typo3_src/NEWS.txt':'http://wiki.typo3.org/TYPO3_(\d{1,2}\.\d{1,2})', '/typo3_src/NEWS.md':"(.*) - WHAT'S NEW",
'/ChangeLog':'RELEASE] Release of TYPO3 (.*)', '/NEWS.txt':'http://wiki.typo3.org/TYPO3_(\d{1,2}\.\d{1,2})', '/NEWS.md':"(.*) - WHAT'S NEW"}
# Typo3 verision details
TYPO_VERSION = None
# Possible paths to an extension
EXTENSION_PATHS = ('/typo3conf/ext/', '/typo3/sysext/')
# Possible version info file
EXTENSION_VERSION_INFO = ('ChangeLog', 'README.txt')
EXTENSIONS_FOUND = {}
## Not used atm ##
# Maximum total number of redirections (regardless of URL) - before assuming we're in a loop
MAX_TOTAL_REDIRECTIONS = 10
# Maximum number of connection retries (to prevent problems with recursion)
MAX_CONNECT_RETRIES = 100
# Delay in seconds between each HTTP request.
# Valid: float
# Default: 0
delay = 0
# Maximum number of retries when the HTTP connection timeouts.
# Valid: integer
# Default: 3
retries = 3
# Use persistent HTTP(s) connections.
KEEPALIVE = False

64
lib/start.py Normal file
View File

@@ -0,0 +1,64 @@
#!/usr/bin/env python
"""
Copyright (c) 2014 Jan Rude
"""
import time
from Queue import Queue
from os.path import isfile
from threading import Thread, Lock
from colorama import Fore, Back
from lib import settings
from lib import versioninfo
from lib import login
from lib import output
from lib import extensions
# Startmethod
def start(domain):
settings.in_queue = Queue()
settings.out_queue = Queue()
settings.DOMAIN = domain
print '\n\n' + Fore.CYAN + '[ Checking ' + domain + ' ]' + '\n' + "-"* 70 + Fore.RESET
if login.search_login(domain) is True:
versioninfo.search_version_info()
versioninfo.output()
if not settings.EXTENSION_LIST:
extensions.generate_list()
extensions.copy()
extensions_to_check = settings.in_queue.qsize()
if extensions_to_check is not 0:
print '\nChecking', extensions_to_check, 'extension(s)...'
# Thanks to 'RedSparrow': http://stackoverflow.com/questions/17991033/python-cant-kill-main-thread-with-keyboardinterrupt
try:
while True:
if settings.in_queue.empty() == False:
time.sleep(0.1)
for i in xrange(0, settings.THREADS):
t = Thread(target=extensions.check_extension, args=())
t.daemon = True
t.start()
else:
break
settings.in_queue.join()
except KeyboardInterrupt:
print Fore.RED + "\nReceived keyboard interrupt.\nQuitting..." + Fore.RESET
exit(-1)
installed_ext = settings.out_queue.qsize()
if installed_ext is 0:
print Fore.RED + "No extensions installed" + Fore.RESET
else:
t = Thread(target=output.thread, args=())
t.daemon = True
t.start()
settings.out_queue.join()
print Fore.GREEN + '\n', str(installed_ext) + '/' + str(extensions_to_check),'extension(s) installed' + Fore.RESET
else:
print '\nSkipping check for extensions...'

BIN
lib/tor.pyc Normal file

Binary file not shown.

45
lib/tor_only.py Normal file
View File

@@ -0,0 +1,45 @@
import socket
import urllib2
import os, sys
import re
from colorama import Fore
try:
import socks
except:
print "The module 'SocksiPy' is not installed.\nPlease install it with: sudo apt-get install python-socksipy"
sys.exit(-2)
def start_daemon():
os.system('service tor start')
# Using TOR for all connections
def connect(port):
print "\nChecking connection..."
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", port, True)
socket.socket = socks.socksocket
try:
url = urllib2.Request('https://check.torproject.org/')
torcheck = urllib2.urlopen(url)
response = torcheck.read()
torcheck.close()
except Exception, e:
print e
print Fore.RED + "Failed to connect through TOR!" + Fore.RESET
print "Please make sure your configuration is right!\n"
sys.exit(-2)
try:
regex = re.compile('Congratulations. This browser is configured to use Tor.')
searchVersion = regex.search(response)
version = searchVersion.groups()
print Fore.GREEN + "Connection to TOR established" + Fore.RESET
regex = re.compile("(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})")
searchIP = regex.search(response)
IP = searchIP.groups()[0]
print "Your IP is: ", IP
except:
print "It seems like TOR is not used.\nAborting...\n"
sys.exit(-2)
def stop():
print "\n"
os.system('service tor stop')

49
lib/tor_with_privoxy.py Normal file
View File

@@ -0,0 +1,49 @@
import socket
import urllib2
import os, sys
import re
from colorama import Fore
try:
import socks
except:
print "The module 'SocksiPy' is not installed.\nPlease install it with: sudo apt-get install python-socksipy"
sys.exit(-2)
def start_daemon():
os.system('service tor start')
os.system('service privoxy start')
print '[' + Fore.GREEN + ' ok ' + Fore.RESET + '] Starting privoxy daemon...done.'
# Using Privoxy and TOR for all connections
def connect(port):
print "\nChecking connection..."
socks.setdefaultproxy(socks.PROXY_TYPE_HTTP, "127.0.0.1", port, True)
socket.socket = socks.socksocket
try:
url = urllib2.Request('https://check.torproject.org/')
torcheck = urllib2.urlopen(url)
response = torcheck.read()
torcheck.close()
except:
print Fore.RED + "Failed to connect through Privoxy and/or TOR!" + Fore.RESET
print "Please make sure your configuration is right!\n"
sys.exit(-2)
try:
regex = re.compile('Congratulations. This browser is configured to use Tor.')
searchVersion = regex.search(response)
version = searchVersion.groups()
print Fore.GREEN + "Connection to TOR established" + Fore.RESET
regex = re.compile("(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})")
searchIP = regex.search(response)
IP = searchIP.groups()[0]
print "Your IP is: ", IP
except Exception, e:
print e
print "It seems like TOR is not used.\nAborting...\n"
sys.exit(-2)
def stop():
print "\n"
os.system('service tor stop')
os.system('service privoxy stop')
print '[' + Fore.GREEN + ' ok ' + Fore.RESET + '] Stopping privoxy daemon...done.'

44
lib/update.py Normal file
View File

@@ -0,0 +1,44 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os, sys, gzip, urllib
from collections import OrderedDict
import xml.etree.ElementTree as ElementTree
# Progressbar
def dlProgress(count, blockSize, totalSize):
percent = int(count*blockSize*100/totalSize)
sys.stdout.write("\rDownloading extentions: " + "%d%%" % percent)
sys.stdout.flush()
# Download extensions from typo3 repository
def download_ext():
try:
urllib.urlretrieve('http://ter.sitedesign.dk/ter/extensions.xml.gz', 'extensions.gz', reporthook=dlProgress)
inf = gzip.open('extensions.gz', 'rb')
file_content = inf.read()
inf.close()
outF = file("extensions.xml", 'wb')
outF.write(file_content)
outF.close()
os.remove('extensions.gz')
except Exception, e:
print "Oops! Got:".ljust(32), e
# Parse extensions.xml and save extensions in file
def generate_list():
extension = 'extensions.xml'
print "\nParsing file..."
tree = ElementTree.parse(extension)
tag_dict = tree.getroot()
exten_Dict = {}
for extensions in tag_dict.getchildren():
ext = {extensions.get('extensionkey'):extensions[0].text}
exten_Dict.update(ext)
sorted_dict = sorted(exten_Dict.iteritems(), key=lambda x: int(x[1]), reverse=True)
f = open('extensions','w')
for i in xrange(0,len(exten_Dict)):
f.write(sorted_dict[i][0]+'\n')
f.close()
print 'Loaded', len(exten_Dict), 'extensions\n'
os.remove('extensions.xml')

35
lib/versioninfo.py Normal file
View File

@@ -0,0 +1,35 @@
#!/usr/bin/env python
"""
Copyright (c) 2014 Jan Rude
"""
import re
import urllib2
from colorama import Fore
from lib import settings
# Searching for Typo3 version
def search_version_info():
for path, regex in settings.TYPO3_VERSION_INFO.iteritems():
try:
request = urllib2.Request('http://' + settings.DOMAIN + path, None, settings.user_agent)
response = urllib2.urlopen(request, timeout = settings.TIMEOUT)
news = response.read(700)
response.close()
regex = re.compile(regex)
search = regex.search(news)
version = search.groups()
if settings.TYPO_VERSION is None or (len('Typo3' + version[0]) > len(settings.TYPO_VERSION)):
settings.TYPO_VERSION = 'Typo3 ' + version[0]
return
except:
pass
# Output of Typo3 version
def output():
if settings.TYPO_VERSION is None:
print "Typo3 Version:".ljust(32) + Fore.RED + "Not found" + Fore.RESET
else:
print "Typo3 Version:".ljust(32) + Fore.GREEN + settings.TYPO_VERSION + Fore.RESET
print "Link to vulnerabilities:".ljust(32) + "http://www.cvedetails.com/version-search.php?vendor=&product=Typo3&version=" + settings.TYPO_VERSION.split()[1]