From bb747098219f04138de7edfd21ce5c61131cecd0 Mon Sep 17 00:00:00 2001 From: whoot Date: Tue, 28 Jun 2022 17:47:44 +0200 Subject: [PATCH] v1.1 --- doc/CHANGELOG.md | 8 +++ lib/domain.py | 5 +- lib/request.py | 5 ++ lib/typo3scan.db | Bin 1953792 -> 1953792 bytes lib/update.py | 134 +++++++++++++++++++++++++++++------------------ requirements.txt | 1 + typo3scan.py | 18 +++---- 7 files changed, 108 insertions(+), 63 deletions(-) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 592e0a0..f499375 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,3 +1,11 @@ +## Version 1.1 + +* Add severity for core and exention vulns +* Use beautifulsoup to parse html +* Bugfix for version parsing +* Bugfix on detection error +* Remove -r parameter + ## Version 1.0.2 * Bugfix for core and extensions advisory URLs diff --git a/lib/domain.py b/lib/domain.py index c547a45..45fb199 100644 --- a/lib/domain.py +++ b/lib/domain.py @@ -176,14 +176,14 @@ def search_typo3_version(self): 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,)) + c.execute('SELECT advisory, vulnerability, subcomponent, affected_version_max, affected_version_min, severity 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())}) + json_list.append({'Advisory': vulnerability[0], 'Type': vulnerability[1], 'Subcomponent': vulnerability[2], 'Affected': '{} - {}'.format(vulnerability[3], vulnerability[4]), 'Severity':vulnerability[5], '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') @@ -192,6 +192,7 @@ def search_typo3_version(self): print(' \u251c Vulnerability Type:'.ljust(28) + vulnerability['Type']) print(' \u251c Subcomponent:'.ljust(28) + vulnerability['Subcomponent']) print(' \u251c Affected Versions:'.ljust(28) + vulnerability['Affected']) + print(' \u251c Severity:'.ljust(28) + vulnerability['Severity']) print(' \u2514 Advisory URL:'.ljust(28) + vulnerability['Advisory URL'] + '\n') if not json_list: print(' \u2514 No Known Vulnerabilities') diff --git a/lib/request.py b/lib/request.py index 58fa5ff..192bdca 100644 --- a/lib/request.py +++ b/lib/request.py @@ -33,6 +33,7 @@ def get_request(url, config): Connection timeout Connection error anything else + If a RequestException occurs, then we will return an empty html response body. This will cancel the root detection. """ try: response = {} @@ -52,6 +53,10 @@ def get_request(url, config): exit(-1) except requests.exceptions.RequestException as e: print(Fore.RED + str(e) + Fore.RESET) + # Return an empty response['html'] element. + # If this error occurs within the first request made (TYPO3 detection), then all following scans will be canceled + response['html'] = '' + return response def head_request(url, config): """ diff --git a/lib/typo3scan.db b/lib/typo3scan.db index c3126135881be551c7b7c64bed7105f56569237d..9e95d0997d933261f44f5917651dea69bff71b10 100755 GIT binary patch delta 43771 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

Nv6g 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 EKUw5ej{pDw delta 38015 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

v;0;*-|!Q@ZLQY- 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 PK5E{1|N8+|PbMFKD{P@j diff --git a/lib/update.py b/lib/update.py index dccb167..35ab36f 100644 --- a/lib/update.py +++ b/lib/update.py @@ -19,6 +19,7 @@ #------------------------------------------------------------------------------- import os.path +from bs4 import BeautifulSoup from pkg_resources import parse_version import xml.etree.ElementTree as ElementTree import re, os, sys, gzip, urllib.request, sqlite3, requests @@ -43,6 +44,20 @@ def __init__(self): self.load_extensions() self.load_extension_vulns() + def get_next_page_from_advisory(self, response): + """ + This function will get a link to the advisory pages + response: The response object from which the link will be extracted + returns: The relative link to the next page + """ + # Get the "li.next.page-item" element from response text and extract URL + soup = BeautifulSoup(response.text, 'html.parser') + for next_item_list in soup.find_all('li', {"class": "next page-item"}): + next_page_link = next_item_list.find_all('a') + next_page_link_href = next_page_link[0].get('href') + + return next_page_link_href + def load_core_vulns(self): """ Grep the CORE vulnerabilities from the security advisory website @@ -53,29 +68,23 @@ def load_core_vulns(self): Vulnerability Type Subcomponent(s) Affected Versions - CVE Numbers + Severity """ print('\n[+] Searching for new CORE vulnerabilities...') update_counter = 0 - next_page = 2 + current_page = 1 last_page = 99 - cHash = '' + url = 'https://typo3.org/help/security-advisories/typo3-cms/' - for current_page in range(1, last_page+1): - if current_page == 1: - url = 'https://typo3.org/help/security-advisories/typo3-cms/' - else: - url = 'https://typo3.org/help/security-advisories/typo3-cms/page?tx_news_pi1%5BcurrentPage%5D={}&tx_sfeventmgt_pieventlist%5Baction%5D=list&tx_sfeventmgt_pieventlist%5Bcontroller%5D=Event&cHash={}'.format(current_page, cHash) + while url: + advisory_list = [] response = requests.get(url, timeout=6) - content = re.findall(' 1: print_help() - elif args.reset: - from lib.initdb import DB_Init - DB_Init() - elif args.update: from lib.update import Update Update() @@ -212,13 +206,13 @@ def print_help(): database = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'lib', 'typo3scan.db') conn = sqlite3.connect('lib/typo3scan.db') c = conn.cursor() - c.execute('SELECT advisory, vulnerability, subcomponent, affected_version_max, affected_version_min FROM core_vulns WHERE (?<=affected_version_max AND ?>=affected_version_min)', (args.core, args.core,)) + c.execute('SELECT advisory, vulnerability, subcomponent, affected_version_max, affected_version_min, severity FROM core_vulns WHERE (?<=affected_version_max AND ?>=affected_version_min)', (args.core, args.core,)) data = c.fetchall() json_list = {} if data: for vulnerability in data: if parse_version(args.core) <= parse_version(vulnerability[3]): - json_list[vulnerability[0]] = {'Type': vulnerability[1], 'Subcomponent': vulnerability[2], 'Affected': '{} - {}'.format(vulnerability[3], vulnerability[4]), 'Advisory': 'https://typo3.org/security/advisory/{}'.format(vulnerability[0].lower())} + json_list[vulnerability[0]] = {'Type': vulnerability[1], 'Subcomponent': vulnerability[2], 'Affected': '{} - {}'.format(vulnerability[3], vulnerability[4]), 'Severity': vulnerability[5],'Advisory': 'https://typo3.org/security/advisory/{}'.format(vulnerability[0].lower())} if json_list: print(Style.BRIGHT + '\n[+] Known Vulnerabilities for Typo3 v{}\n'.format(args.core) + Style.RESET_ALL) for vulnerability in json_list.keys(): @@ -226,6 +220,7 @@ def print_help(): print(' \u251c Vulnerability Type:'.ljust(28) + json_list[vulnerability]['Type']) print(' \u251c Subcomponent:'.ljust(28) + json_list[vulnerability]['Subcomponent']) print(' \u251c Affected Versions:'.ljust(28) + json_list[vulnerability]['Affected']) + print(' \u251c Severity:'.ljust(28) + json_list[vulnerability]['Severity']) print(' \u2514 Advisory URL:'.ljust(28) + json_list[vulnerability]['Advisory'] + '\n') if not json_list: print('\n' + Fore.GREEN + Style.BRIGHT + '[+] Typo3 v{} has no known vulnerabilities\n'.format(args.core) + Style.RESET_ALL) @@ -249,13 +244,13 @@ def print_help(): print('\n' + Fore.RED + Style.BRIGHT + '[!] Extension \'{}\' does not exist\n'.format(name) + Style.RESET_ALL) sys.exit(-1) else: - c.execute('SELECT advisory, vulnerability, affected_version_max, affected_version_min FROM extension_vulns WHERE (extensionkey=? AND ?<=affected_version_max AND ?>=affected_version_min)', (name, version, version,)) + c.execute('SELECT advisory, vulnerability, affected_version_max, affected_version_min, severity FROM extension_vulns WHERE (extensionkey=? AND ?<=affected_version_max AND ?>=affected_version_min)', (name, version, version,)) data = c.fetchall() json_list = {} if data: for vulnerability in data: if parse_version(version) <= parse_version(vulnerability[2]): - json_list[vulnerability[0]] = {'Type': vulnerability[1], 'Affected': '{} - {}'.format(vulnerability[2], vulnerability[3]), 'Advisory': 'https://typo3.org/security/advisory/{}'.format(vulnerability[0].lower())} + json_list[vulnerability[0]] = {'Type': vulnerability[1], 'Affected': '{} - {}'.format(vulnerability[2], vulnerability[3]), 'Severity': vulnerability[4], 'Advisory': 'https://typo3.org/security/advisory/{}'.format(vulnerability[0].lower())} if json_list: if version == '0.0.0': print(Style.BRIGHT + '\n[+] Known vulnerabilities for \'{}\'\n'.format(name) + Style.RESET_ALL) @@ -265,6 +260,7 @@ def print_help(): print(Style.BRIGHT + ' [!] {}'.format(Fore.RED + vulnerability + Style.RESET_ALL)) print(' \u251c Vulnerability Type: '.ljust(28) + json_list[vulnerability]['Type']) print(' \u251c Affected Versions: '.ljust(28) + '{}'.format(json_list[vulnerability]['Affected'])) + print(' \u251c Severity:'.ljust(28) + json_list[vulnerability]['Severity']) print(' \u2514 Advisory URL:'.ljust(28) + '{}\n'.format(json_list[vulnerability]['Advisory'].lower())) if not json_list: print('\n' + Fore.GREEN + Style.BRIGHT + '[+] \'{}\' v{} has no known vulnerabilities\n'.format(name, version) + Style.RESET_ALL)