v0.5.1
This commit is contained in:
@@ -7,7 +7,7 @@ Typo3Scan does not exploit any vulnerabilities! It´s soley purpose was to enume
|
|||||||
|
|
||||||
**Note:**
|
**Note:**
|
||||||
When I started this project many years ago, the version information could be easily read from text files (Readmes, Changelogs, etc.). Since then a lot has changed.
|
When I started this project many years ago, the version information could be easily read from text files (Readmes, Changelogs, etc.). Since then a lot has changed.
|
||||||
Typo3 now restricts access to directories and files by default and since the use of [Composer](https://github.com/composer/composer), version information of extensions are not available in files anymore.
|
Typo3 now restricts access to directories and files by default and version information of extensions may not available in files anymore.
|
||||||
In addition, various basic functions have changed over time.
|
In addition, various basic functions have changed over time.
|
||||||
For these reasons this tool will probably *not receive further major releases*.
|
For these reasons this tool will probably *not receive further major releases*.
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
## Version 0.5.1
|
||||||
|
|
||||||
|
* Output and version detection fix
|
||||||
|
|
||||||
## Version 0.5
|
## Version 0.5
|
||||||
|
|
||||||
* Rename to Typo3Scan
|
* Rename to Typo3Scan
|
||||||
|
|||||||
@@ -232,4 +232,4 @@ class Domain:
|
|||||||
print(' \u251c Subcomponent:'.ljust(29), vuln[2])
|
print(' \u251c Subcomponent:'.ljust(29), vuln[2])
|
||||||
print(' \u2514 Affected Versions:'.ljust(29), '{} - {}\n'.format(vuln[3], vuln[4]))
|
print(' \u2514 Affected Versions:'.ljust(29), '{} - {}\n'.format(vuln[3], vuln[4]))
|
||||||
else:
|
else:
|
||||||
print(' \u251c', Fore.RED + 'No version information found' + Fore.RESET)
|
print(' \u2514', Fore.RED + 'No version information found.' + Fore.RESET)
|
||||||
@@ -36,7 +36,7 @@ class Extensions:
|
|||||||
This method loads the extensions from the database and searches for installed extensions.
|
This method loads the extensions from the database and searches for installed extensions.
|
||||||
/typo3conf/ext/: Local installation path. This is where extensions usually get installed.
|
/typo3conf/ext/: Local installation path. This is where extensions usually get installed.
|
||||||
/typo3/ext/: Global installation path (not used atm)
|
/typo3/ext/: Global installation path (not used atm)
|
||||||
/typo3/sysext/: Extensions shipped with core
|
/typo3/sysext/: Extensions shipped with core
|
||||||
"""
|
"""
|
||||||
found_extensions = {}
|
found_extensions = {}
|
||||||
thread_pool = ThreadPool()
|
thread_pool = ThreadPool()
|
||||||
@@ -60,12 +60,15 @@ class Extensions:
|
|||||||
thread_pool = ThreadPool()
|
thread_pool = ThreadPool()
|
||||||
for extension,values in found_extensions.items():
|
for extension,values in found_extensions.items():
|
||||||
thread_pool.add_job((request.version_information, (values['url'] + 'Documentation/ChangeLog/Index.rst', None)))
|
thread_pool.add_job((request.version_information, (values['url'] + 'Documentation/ChangeLog/Index.rst', None)))
|
||||||
|
thread_pool.add_job((request.version_information, (values['url'] + 'Documentation/Changelog/Index.rst', None)))
|
||||||
thread_pool.add_job((request.version_information, (values['url'] + 'Documentation/Settings.cfg', None)))
|
thread_pool.add_job((request.version_information, (values['url'] + 'Documentation/Settings.cfg', None)))
|
||||||
thread_pool.add_job((request.version_information, (values['url'] + 'Documentation/Settings.yml', None)))
|
thread_pool.add_job((request.version_information, (values['url'] + 'Documentation/Settings.yml', '(?:release:)\s?([0-9]+\.[0-9]+\.?[0-9]?[0-9]?)')))
|
||||||
thread_pool.add_job((request.version_information, (values['url'] + 'Settings.yml', None)))
|
thread_pool.add_job((request.version_information, (values['url'] + 'Settings.yml', '(?:release:)\s?([0-9]+\.[0-9]+\.?[0-9]?[0-9]?)')))
|
||||||
|
thread_pool.add_job((request.version_information, (values['url'] + 'Documentation/ChangeLog', None)))
|
||||||
thread_pool.add_job((request.version_information, (values['url'] + 'Documentation/Index.rst', None)))
|
thread_pool.add_job((request.version_information, (values['url'] + 'Documentation/Index.rst', None)))
|
||||||
thread_pool.add_job((request.version_information, (values['url'] + 'composer.json', '(?:"dev-master":|"version":)\s?"([0-9]+\.[0-9]+\.[0-9x][0-9x]?)')))
|
thread_pool.add_job((request.version_information, (values['url'] + 'composer.json', '(?:"dev-master":|"version":)\s?"([0-9]+\.[0-9]+\.[0-9x][0-9x]?)')))
|
||||||
thread_pool.add_job((request.version_information, (values['url'] + 'Index.rst', None)))
|
thread_pool.add_job((request.version_information, (values['url'] + 'Index.rst', None)))
|
||||||
|
thread_pool.add_job((request.version_information, (values['url'] + 'doc/manual.sxw', None)))
|
||||||
thread_pool.add_job((request.version_information, (values['url'] + 'ChangeLog', None)))
|
thread_pool.add_job((request.version_information, (values['url'] + 'ChangeLog', None)))
|
||||||
thread_pool.add_job((request.version_information, (values['url'] + 'CHANGELOG.md', None)))
|
thread_pool.add_job((request.version_information, (values['url'] + 'CHANGELOG.md', None)))
|
||||||
thread_pool.add_job((request.version_information, (values['url'] + 'ChangeLog.txt', None)))
|
thread_pool.add_job((request.version_information, (values['url'] + 'ChangeLog.txt', None)))
|
||||||
@@ -81,6 +84,8 @@ class Extensions:
|
|||||||
name = version_path[0][0]
|
name = version_path[0][0]
|
||||||
if 'Documentation/' in name:
|
if 'Documentation/' in name:
|
||||||
name = name[:name.rfind('Documentation/')+1]
|
name = name[:name.rfind('Documentation/')+1]
|
||||||
|
if 'doc/' in name:
|
||||||
|
name = name[:name.rfind('doc/')+1]
|
||||||
name = name[name.find('ext/')+4:name.rfind('/')]
|
name = name[name.find('ext/')+4:name.rfind('/')]
|
||||||
found_extensions[name]['version'] = version
|
found_extensions[name]['version'] = version
|
||||||
found_extensions[name]['file'] = path
|
found_extensions[name]['file'] = path
|
||||||
@@ -90,7 +95,7 @@ class Extensions:
|
|||||||
def output(self, extension_dict, database):
|
def output(self, extension_dict, database):
|
||||||
conn = sqlite3.connect(database)
|
conn = sqlite3.connect(database)
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
print('\n\n [+] Extension information\n \\')
|
print('\n |\n [+] Extension information\n \\')
|
||||||
for extension,info in extension_dict.items():
|
for extension,info in extension_dict.items():
|
||||||
c.execute('SELECT title FROM extensions where extensionkey=?', (extension,))
|
c.execute('SELECT title FROM extensions where extensionkey=?', (extension,))
|
||||||
title = c.fetchone()[0]
|
title = c.fetchone()[0]
|
||||||
|
|||||||
@@ -123,6 +123,8 @@ def version_information(url, regex):
|
|||||||
else:
|
else:
|
||||||
r = requests.get(url, stream=True, timeout=config['timeout'], headers=custom_headers, verify=False)
|
r = requests.get(url, stream=True, timeout=config['timeout'], headers=custom_headers, verify=False)
|
||||||
if r.status_code == 200:
|
if r.status_code == 200:
|
||||||
|
if 'manual.sxw' in url:
|
||||||
|
return 'check manually'
|
||||||
try:
|
try:
|
||||||
for content in r.iter_content(chunk_size=400, decode_unicode=False):
|
for content in r.iter_content(chunk_size=400, decode_unicode=False):
|
||||||
search = re.search(regex, str(content))
|
search = re.search(regex, str(content))
|
||||||
@@ -130,5 +132,11 @@ def version_information(url, regex):
|
|||||||
r.close()
|
r.close()
|
||||||
return version
|
return version
|
||||||
except:
|
except:
|
||||||
r.close()
|
try:
|
||||||
return None
|
search = re.search('([0-9]+-[0-9]+-[0-9]+)', str(content))
|
||||||
|
version = search.group(1)
|
||||||
|
r.close()
|
||||||
|
return version
|
||||||
|
except:
|
||||||
|
r.close()
|
||||||
|
return None
|
||||||
@@ -23,7 +23,7 @@ from queue import Queue
|
|||||||
from progressbar import Bar, AdaptiveETA, Percentage, ProgressBar
|
from progressbar import Bar, AdaptiveETA, Percentage, ProgressBar
|
||||||
|
|
||||||
bar = None
|
bar = None
|
||||||
number = 1
|
number = 0
|
||||||
class ThreadPoolSentinel:
|
class ThreadPoolSentinel:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ class ThreadPool:
|
|||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
global number
|
global number
|
||||||
number = 1
|
number = 0
|
||||||
self.__work_queue = Queue()
|
self.__work_queue = Queue()
|
||||||
self.__result_queue = Queue()
|
self.__result_queue = Queue()
|
||||||
self.__active_threads = 0
|
self.__active_threads = 0
|
||||||
@@ -114,6 +114,6 @@ def _work_function(job_q, result_q, version_search):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
finally:
|
finally:
|
||||||
bar.update(number)
|
|
||||||
number = number+1
|
number = number+1
|
||||||
|
bar.update(number)
|
||||||
job_q.task_done()
|
job_q.task_done()
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
# along with this program. If not, see [http://www.gnu.org/licenses/](http://www.gnu.org/licenses/)
|
# along with this program. If not, see [http://www.gnu.org/licenses/](http://www.gnu.org/licenses/)
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
__version__ = '0.5'
|
__version__ = '0.5.1'
|
||||||
__program__ = 'Typo3Scan'
|
__program__ = 'Typo3Scan'
|
||||||
__description__ = 'Automatic Typo3 enumeration tool'
|
__description__ = 'Automatic Typo3 enumeration tool'
|
||||||
__author__ = 'https://github.com/whoot'
|
__author__ = 'https://github.com/whoot'
|
||||||
@@ -145,7 +145,7 @@ Options:
|
|||||||
check.search_typo3_version()
|
check.search_typo3_version()
|
||||||
|
|
||||||
# Search extensions
|
# Search extensions
|
||||||
print(' [+] Extension Search')
|
print('\n [+] Extension Search')
|
||||||
if not self.__extensions:
|
if not self.__extensions:
|
||||||
conn = sqlite3.connect(database)
|
conn = sqlite3.connect(database)
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
|
|||||||
Reference in New Issue
Block a user