Exemplo n.º 1
0
 def search_login(self):
     """
     This method requests the default login page
         and searches for a specific string in the title or the response.
         If the access is forbidden (403), extension search is still possible.
     """
     print('[+] Backend Login')
     # maybe /typo3_src/typo3/index.php too?
     response = request.get_request('{}/typo3/index.php'.format(
         self.get_path()))
     searchTitle = re.search('<title>(.*)</title>', response['html'])
     if searchTitle and 'Login' in searchTitle.group(0):
         print(' \u251c {}'.format(
             Fore.GREEN + '{}/typo3/index.php'.format(self.get_path()) +
             Fore.RESET))
         self.set_backend('{}/typo3/index.php'.format(self.get_path()))
     elif ('Backend access denied: The IP address of your client'
           in response['html']) or (response['status_code'] == 403):
         print(' \u251c {}'.format(
             Fore.GREEN + '{}/typo3/index.php'.format(self.get_path()) +
             Fore.RESET))
         print(' \u251c {}'.format(
             Fore.YELLOW +
             'But access is forbidden (IP Address Restriction)' +
             Fore.RESET))
         self.set_backend('{}/typo3/index.php'.format(self.get_path()))
     else:
         print(' \u251c {}'.format(Fore.RED + 'Could not be found' +
                                   Fore.RESET))
Exemplo n.º 2
0
 def check_default_files(self):
     """
     This method requests different files, which are generated on installation.
         Note: They are not accessible anymore on newer Typo3 installations
     """
     files = {
         'typo3_src/README.md': 'TYPO3 CMS',
         'typo3_src/README.txt': 'TYPO3 CMS',
         'typo3_src/INSTALL.md': 'INSTALLING TYPO3',
         'typo3_src/INSTALL.txt': 'INSTALLING TYPO3',
         'typo3_src/LICENSE.txt': 'TYPO3',
         'typo3_src/CONTRIBUTING.md': 'TYPO3 CMS',
         'typo3_src/composer.json': 'TYPO3'
     }
     for path, regex in files.items():
         try:
             response = request.get_request('{}/{}'.format(
                 self.get_path(), path))
             regex = re.compile(regex)
             searchInstallation = regex.search(response['html'])
             installation = searchInstallation.groups()
             self.set_typo3()
             return True
         except:
             pass
     return False
Exemplo n.º 3
0
 def check_404(self):
     """
     This method requests a site which is not available by using a random generated string.
         TYPO3 installations usually generate a default error page,
         which can be used as an indicator.
     """
     random_string = ''.join(random.choice(string.ascii_lowercase) for i in range(10))
     response = request.get_request('{}/{}'.format(self.get_path(), random_string))
     search404 = re.search('[Tt][Yy][Pp][Oo]3 CMS', response['html'])
     if search404:
         self.set_typo3()
Exemplo n.º 4
0
 def check_root(self):
     """
     This method requests the root page and searches for a specific string.
         Usually there are some TYPO3 notes in the HTML comments.
         If found, it searches for a Typo3 path reference
         in order to determine the Typo3 installation path.
     """
     full_path = self.get_name()
     response = request.get_request('{}'.format(self.get_name()))
     if re.search('powered by TYPO3', response['html']):
         self.set_typo3()
         path = re.search(
             '="(?:{})/?(\S*?)/?(?:typo3temp|typo3conf)/'.format(
                 self.get_name()), response['html'])
         if path and path.group(1) != '':
             full_path = '{}/{}'.format(self.get_name(), path)
     self.set_path(full_path)
Exemplo n.º 5
0
    def search_typo3_version(self):
        """
        This method will aggressively search for version information by comparing file hashes
        """
        version = None
        paths = set()
        hash_vers = dict()
        database = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                'typo3scan.db')
        conn = sqlite3.connect(database)
        c = conn.cursor()
        c.execute('SELECT * FROM core_versions')
        data = c.fetchall()

        for entry in data:
            paths.add(entry[1])
            hash_vers[entry[0]] = entry[2]

        for path in paths:
            response = request.get_request('{}/{}'.format(
                self.get_path(), path))
            if response and response['status_code'] == 200:
                md5_hash = hashlib.md5()
                md5_hash.update(response['html'].encode())
                digest = md5_hash.hexdigest()
                if digest in hash_vers:
                    version = hash_vers[digest]
                    if len(version) <= 4:
                        continue
                    else:
                        break

        print('  | \n [+] Version Information')
        if version:
            self.set_typo3_version(version)
            print('  \u251c Identified Version: '.ljust(28) +
                  '{}'.format(Style.BRIGHT + Fore.GREEN + version +
                              Style.RESET_ALL))
            if len(version) <= 4:
                print('  \u251c Could not identify exact version.')
                react = input(
                    '  \u251c Do you want to print all vulnerabilities for branch {}? (y/n): '
                    .format(version))
                if react.startswith('y'):
                    version = version + '.0'
                else:
                    return False
            c.execute(
                'SELECT advisory, vulnerability, subcomponent, affected_version_max, affected_version_min FROM core_vulns WHERE (?<=affected_version_max AND ?>=affected_version_min)',
                (
                    version,
                    version,
                ))
            data = c.fetchall()
            json_list = []
            if data:
                for vulnerability in data:
                    # maybe instead use this: https://zxq9.com/archives/797
                    if parse_version(version) <= parse_version(
                            vulnerability[3]):
                        json_list.append({
                            'Advisory':
                            vulnerability[0],
                            'Type':
                            vulnerability[1],
                            'Subcomponent':
                            vulnerability[2],
                            'Affected':
                            '{} - {}'.format(vulnerability[3],
                                             vulnerability[4]),
                            'Advisory URL':
                            'https://typo3.org/security/advisory/{}'.format(
                                vulnerability[0].lower())
                        })
                if json_list:
                    self.set_typo3_vulns(json_list)
                    print('  \u2514 Known Vulnerabilities:\n')
                    for vulnerability in json_list:
                        print(Style.BRIGHT +
                              '     [!] {}'.format(Fore.RED +
                                                   vulnerability['Advisory'] +
                                                   Style.RESET_ALL))
                        print('      \u251c Vulnerability Type:'.ljust(28) +
                              vulnerability['Type'])
                        print('      \u251c Subcomponent:'.ljust(28) +
                              vulnerability['Subcomponent'])
                        print('      \u251c Affected Versions:'.ljust(28) +
                              vulnerability['Affected'])
                        print('      \u2514 Advisory URL:'.ljust(28) +
                              vulnerability['Advisory URL'] + '\n')
            if not json_list:
                print('  \u2514 No Known Vulnerabilities')
        else:
            print('  \u2514',
                  Fore.RED + 'Could not be determined.' + Fore.RESET)