Projects STRLCPY opensquat Commits 1d6288e4
🤬
  • ■ ■ ■ ■ ■ ■
    CHANGELOG
     1 +v2.0.0 (2023-xx-xx)
     2 ++ Improved VirusTotal integration and support for VT API v3
     3 ++ Adopted Semantic Versioning (https://semver.org)
     4 + 
    1 5  v1.99 (2022-05-21)
    2 6  + Bug correction (#50) - Suspicious certificate results not showing in results.txt
    3 7   
    skipped 75 lines
  • ■ ■ ■ ■
    opensquat/__init__.py
    1 1  # -*- coding: utf-8 -*-
    2 2  # Module: __init__.py
    3 3  """openSquat Version."""
    4  -__VERSION__ = "1.99"
     4 +__VERSION__ = "2.0.0"
    5 5   
  • ■ ■ ■ ■ ■ ■
    opensquat/check_update.py
    skipped 2 lines
    3 3  """
    4 4  openSquat
    5 5   
    6  -(c) CERT-MZ
    7  - 
    8  -* https://www.cert.mz
    9 6  * https://github.com/atenreiro/opensquat
    10 7   
    11 8  software licensed under GNU version 3
    skipped 1 lines
    13 10  import requests
    14 11  from colorama import Fore, Style
    15 12  from opensquat import __VERSION__
    16  - 
     13 +from packaging import version
    17 14   
    18 15  class CheckUpdate:
    19 16   """
    skipped 9 lines
    29 26   
    30 27   def __init__(self):
    31 28   """Initiator."""
    32  - self.URL = ("https://feeds.opensquat.com/latest.txt")
     29 + self.URL = ("https://feeds.opensquat.com/latest_version.txt")
    33 30   self.current = __VERSION__
    34 31   
    35 32   def check(self):
    skipped 10 lines
    46 43   if (response.status_code != 200):
    47 44   return False
    48 45   
    49  - latest_ver = float(response.content)
     46 + latest_ver = response.content
     47 + latest_ver = latest_ver.decode()
    50 48   response.close()
    51 49   
    52  - current_ver = float(self.current)
     50 + current_ver = self.current
    53 51   
    54  - if current_ver < latest_ver:
     52 + if version.parse(latest_ver) > version.parse(current_ver):
    55 53   print(
    56 54   Style.BRIGHT+Fore.MAGENTA +
    57 55   "[INFO] New version avaiable!" +
    skipped 12 lines
    70 68   print(
    71 69   Style.BRIGHT+Fore.WHITE + "-> update now: $ git pull\n" +
    72 70   Style.RESET_ALL)
     71 + return True
    73 72   
    74  - return True
     73 + return False
    75 74   
    76 75   def main(self):
    77 76   self.check()
    skipped 1 lines
  • ■ ■ ■ ■ ■ ■
    opensquat/vt.py
    skipped 2 lines
    3 3  """
    4 4  openSquat
    5 5   
    6  -(c) CERT-MZ
    7  - 
    8  -* https://www.cert.mz
    9 6  * https://github.com/atenreiro/opensquat
    10 7   
    11 8  software licensed under GNU version 3
    12 9  """
     10 +import os
     11 +import json
    13 12  import requests
    14  -import json
    15  -import time
    16 13   
    17 14   
    18 15  class VirusTotal:
     16 + """
     17 + This domain class validates a domain on VirusTotal
     18 + 
     19 + To use:
     20 + VirusTotal.main("opensquat.com")
     21 + 
     22 + Attribute:
     23 + domain: a domain name
     24 + """
    19 25   def __init__(self):
    20 26   """Initiator."""
    21 27   self.domain = ""
    22  - self.subdomains = []
    23  - self.URL = ""
    24  - self.content = ""
    25  - self.op = ""
     28 + self.api_key = ""
     29 + self.api_key_file = ""
     30 + 
     31 + def set_apikey(self, api_key_file):
     32 + 
     33 + self.api_key_file = api_key_file
     34 + 
     35 + if not os.path.isfile(self.api_key_file):
     36 + print(
     37 + "[*] VT API Key File",
     38 + self.api_key_file ,
     39 + "not found or not readable! Exiting... \n",
     40 + )
     41 + exit(-1)
     42 + 
     43 + file_vt = open(self.api_key_file, "r")
     44 + 
     45 + for line in file_vt:
     46 + if (
     47 + (line[0] != "#") and
     48 + (line[0] != " ") and
     49 + (line[0] != "") and
     50 + (line[0] != "\n")
     51 + ):
     52 + self.api_key = line
     53 + 
     54 + file_vt.close()
     55 + 
     56 + return True
     57 + 
    26 58   
    27 59   def set_domain(self, domain):
    28 60   self.domain = domain
    29 61   
    30  - def set_operation(self, op):
    31  - self.op = op
     62 + def domain_report(self):
    32 63   
    33  - def get_content(self):
    34  - 
    35  - if self.op == "subdomains":
    36  - self.URL = "https://www.virustotal.com/ui/domains/" + self.domain \
    37  - + "/subdomains"
    38  - else:
    39  - self.URL = "https://www.virustotal.com/ui/domains/" + self.domain
     64 + url = "https://www.virustotal.com/api/v3/domains/" + self.domain
    40 65   
    41  - # User-Agent Headers
    42 66   headers = {
    43  - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
    44  - "AppleWebKit/537.36 (KHTML, like Gecko)"
    45  - "Chrome/78.0.3904.108 Safari/537.36"
     67 + "accept": "application/json",
     68 + "x-apikey": self.api_key
    46 69   }
    47 70   
    48  - # Get response content
    49  - response = requests.get(self.URL, stream=True, headers=headers)
    50  - content = json.loads(response.content)
     71 + response = requests.get(url, headers=headers, timeout=30)
    51 72   
    52  - self.content = content
     73 + json_data = json.loads(response.text)
    53 74   
    54  - def get_subdomains(self):
     75 + if response.status_code == 200:
    55 76   
    56  - try:
    57  - if "error" in self.content:
    58  - print(" \_ VirusTotal might be throttling/blocking")
    59  - return False
    60  - elif self.content.get('data'):
    61  - for item in self.content['data']:
    62  - if item['type'] == 'domain':
    63  - subdomain = item['id']
    64  - self.subdomains.append(subdomain)
    65  - except Exception:
    66  - return False
     77 + if "data" in json_data and \
     78 + "attributes" in json_data['data'] and \
     79 + "total_votes" in json_data['data']['attributes']:
    67 80   
    68  - if self.subdomains:
    69  - return self.subdomains
    70  - else:
    71  - return False
     81 + harmless = json_data['data']['attributes']['total_votes']['harmless']
     82 + malicious = json_data['data']['attributes']['total_votes']['malicious']
     83 + harmless = int(harmless)
     84 + malicious = int(malicious)
     85 + total_votes = [harmless, malicious]
    72 86   
    73  - def get_malicious(self):
     87 + return total_votes
    74 88   
    75  - try:
    76  - malicious = (
    77  - self.content
    78  - ['attributes']
    79  - ['last_analysis_stats']
    80  - ['malicious']
     89 + else:
     90 + 
     91 + if "error" in json_data:
     92 + message = json_data['error']['message']
     93 + print("[*] VT API ERROR:", message)
     94 + exit(-1)
     95 + else:
     96 + print(
     97 + "[*] Unexpected VT Response. HTTP Code: ",
     98 + response.status_code,
     99 + " Exiting... \n",
    81 100   )
    82  - except KeyError:
    83  - return -1
    84  - 
    85  - return malicious
     101 + exit(-1)
    86 102   
    87  - def main(self, domain, op):
     103 + def main(self, domain, api_key_file="vt_key.txt"):
    88 104   self.set_domain(domain)
    89  - self.set_operation(op)
    90  - self.get_content()
    91  - 
    92  - if (op == "subdomains"):
    93  - return self.get_subdomains()
    94  - else:
    95  - return self.get_malicious()
     105 + self.set_apikey(api_key_file)
     106 + return self.domain_report()
    96 107   
  • ■ ■ ■ ■ ■ ■
    opensquat.py
    skipped 3 lines
    4 4  """
    5 5  openSquat.
    6 6   
    7  -(c) CERT-MZ
    8  - 
    9  -* https://www.cert.mz
    10 7  * https://github.com/atenreiro/opensquat
    11 8   
    12 9  software licensed under GNU version 3
    skipped 2 lines
    15 12  import signal
    16 13   
    17 14  from colorama import init, Fore, Style
    18  -from opensquat import __VERSION__
    19  -from opensquat import arg_parser, output, app, phishing, check_update, vt
     15 +from opensquat import __VERSION__, vt
     16 +from opensquat import arg_parser, output, app, phishing, check_update
    20 17  from opensquat import port_check
    21 18   
    22 19   
    skipped 31 lines
    54 51   ░███ ░███
    55 52   █████ █████
    56 53   ░░░░░ ░░░░░
    57  - (c) CERT-MZ - https://github.com/atenreiro/opensquat
     54 + (c) Andre Tenreiro - https://github.com/atenreiro/opensquat
    58 55   """ + Style.RESET_ALL
    59 56   )
    60 57   
    skipped 38 lines
    99 96   file_content = list_aux
    100 97   print("[*] Total found:", len(file_content))
    101 98   
    102  - # Check for VirusTotal
     99 + # Check for VirusTotal (if domain is flagged as malicious)
    103 100   if (args.vt):
    104 101   list_aux = []
    105 102   print("\n+---------- VirusTotal ----------+")
    106 103   time.sleep(1)
    107 104   for domain in file_content:
    108  - malicious = vt.VirusTotal().main(domain, "malicious")
     105 + total_votes = vt.VirusTotal().main(domain)
     106 + 
     107 + # total votes
     108 + harmless = total_votes[0]
     109 + malicious = total_votes[1]
    109 110   
    110 111   if malicious > 0:
    111 112   print(
    skipped 61 lines
  • ■ ■ ■ ■ ■
    requirements.txt
    skipped 11 lines
    12 12  flake8
    13 13  beautifulsoup4
    14 14  dnspython==1.16.0
     15 +packaging
Please wait...
Page is in error, reload to recover