├── README.md ├── requirements.txt └── subzer0.py /README.md: -------------------------------------------------------------------------------- 1 | # subzer0 2 | A tool that scans a list of given domains, and returns the status codes for each domain on both port 80 & 443 3 | 4 | ![screenshot of subzer0](https://i.gyazo.com/a2cf94596e7a9e3fb9d423b3518cc1ef.png) 5 | 6 | ## Install 7 | 8 | ```sh 9 | git clone https://github.com/0xApt/subzer0.git 10 | cd subzer0 11 | pip3 install -r requirements.txt 12 | python3 subzer0.py -f domains.txt 13 | ``` 14 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | 3 | -------------------------------------------------------------------------------- /subzer0.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # subzer0 4 | # created by ~ 0xApt_ 5 | 6 | # subzer0 takes a list of subdomains, and sends a get request to each one, returning the status code 7 | # will go over the same subdomain TWICE, the first one for http (port 80) and the second for https (port 443) 8 | 9 | 10 | import requests 11 | from requests.exceptions import HTTPError 12 | import sys 13 | import time 14 | import os 15 | 16 | 17 | #colors 18 | OKBLUE = '\033[94m' 19 | OKGREEN = '\033[92m' 20 | WARNING = '\033[93m' 21 | FAIL = '\033[91m' 22 | ENDC = '\033[0m' 23 | BOLD = '\033[1m' 24 | 25 | 26 | 27 | #head title 28 | def title(): 29 | 30 | print( OKBLUE + """ 31 | ______ __ ______ 32 | / \ / | / \ 33 | /$$$$$$ | __ __ $$ |____ ________ ______ ______ /$$$$$$ | 34 | $$ \__$$/ / | / |$$ \ / | / \ / \ $$$ \$$ | 35 | $$ \ $$ | $$ |$$$$$$$ |$$$$$$$$/ /$$$$$$ |/$$$$$$ |$$$$ $$ | 36 | $$$$$$ |$$ | $$ |$$ | $$ | / $$/ $$ $$ |$$ | $$/ $$ $$ $$ | 37 | / \__$$ |$$ \__$$ |$$ |__$$ | /$$$$/__ $$$$$$$$/ $$ | $$ \$$$$ | 38 | $$ $$/ $$ $$/ $$ $$/ /$$ |$$ |$$ | $$ $$$/ 39 | $$$$$$/ $$$$$$/ $$$$$$$/ $$$$$$$$/ $$$$$$$/ $$/ $$$$$$/ 1.0 40 | 41 | """ + ENDC) 42 | 43 | print(BOLD + """ Created by 0xApt_ 44 | 45 | 46 | """ + ENDC) 47 | 48 | # for when the user needs help on how to use the tool 49 | def help(): 50 | 51 | print(""" 52 | 53 | SubZer0 is a tool used to output the status codes of a list of domains 54 | 55 | {Checks both http & https status codes} 56 | 57 | -h -Display help information 58 | 59 | -f - Specify subdomain file 60 | 61 | Ex. 'python3 subzer0.py -f ' 62 | 63 | 64 | To save the output, you can do so using following command 65 | 66 | 'python3 subzer0.py -f list_of_domains.txt > filetosaveoutput.txt' 67 | 68 | Note: It may seem like it is hanging, but it's just program running in the background until it is done. 69 | 70 | 71 | That's about it. 72 | 73 | """) 74 | 75 | 76 | #shows the status codes along with domain name for https 77 | def ez_status(name,TYPE): 78 | 79 | code = response_code(name) 80 | if code == 200: 81 | ncode = "200 -> OK" 82 | print(OKGREEN + "[*] "+ TYPE + " -> %s -> " % (name) + "%s" % (ncode) + ENDC) 83 | elif code == 401: 84 | ncode = "401 -> Unauthorized" 85 | print( WARNING + "[*] "+ TYPE + " -> %s -> " % (name) + "%s" % (ncode) + ENDC) 86 | elif code == 403: 87 | ncode = "403 -> Forbidden @_@" 88 | print( WARNING + "[*] "+ TYPE + " -> %s -> " % (name) + "%s" % (ncode) + ENDC) 89 | elif code == 404: 90 | ncode = "404 -> Not found | Possible Subdomain Takeover?" 91 | print(OKBLUE + "[*] "+ TYPE + " -> %s -> " % (name) + "%s" % (ncode) + ENDC) 92 | elif code == 408: 93 | ncode = "408 -> Request Timed out" 94 | print( WARNING + "[*] "+ TYPE + " -> %s -> " % (name) + "%s" % (ncode) + ENDC) 95 | elif code == 500: 96 | ncode = "500 -> Internal Server Error" 97 | print( FAIL + "[*] "+ TYPE + "-> %s -> " % (name) + "%s" % (ncode) + ENDC) 98 | elif code == 502: 99 | ncode = "502 -> Bad Gateway" 100 | print( WARNING + "[*] "+ TYPE + " -> %s -> " % (name) + "%s" % (ncode) + ENDC) 101 | elif code == 503: 102 | ncode = "503 -> Service Unavailable" 103 | print( WARNING + "[*] "+ TYPE + " -> %s -> " % (name) + "%s" % (ncode) + ENDC) 104 | elif code == 504: 105 | ncode = "504 -> Gateway Timeout" 106 | print( WARNING + "[*] "+ TYPE + " -> %s -> " % (name) + "%s" % (ncode) + ENDC) 107 | elif code == 999: 108 | ncode = "Can't Connect..." 109 | print( FAIL + "[*] " + TYPE + " -> %s -> " % (name) + "%s" % (ncode) + ENDC) 110 | else: 111 | ncode = "Error" 112 | print( FAIL + "[*] "+ TYPE + " -> %s -> " % (name) + "%s" % (ncode) + ENDC) 113 | 114 | 115 | # create a function that takes the usersfile and outputs the details on the screen 116 | def subdomain_list(list): 117 | 118 | os.system("clear") 119 | title() 120 | print("[*] Sit back.. this may take some time...") 121 | print("[*] Starting scan...\n") 122 | 123 | 124 | li = [i.strip().split() for i in open(list).readlines()] 125 | 126 | for domain in li[:-1]: 127 | 128 | each_domain = ''.join(domain) 129 | 130 | # if it contains https already, don't alter it, and scan with it, then scan using http 131 | if each_domain[:8] == "https://": 132 | 133 | print(BOLD + "[*] Testing -> %s" % (each_domain) + ENDC) 134 | 135 | ez_status(each_domain,"HTTPS") 136 | 137 | new_http_val = each_domain.replace("https://", "http://") 138 | 139 | ez_status(new_http_val,"HTTP") 140 | 141 | 142 | # if it contains http already, don't alter it; scan with it; then switch to https 143 | elif each_domain[:7] == "http://": 144 | 145 | print(BOLD + "[*] Testing -> %s" % (each_domain) + ENDC) 146 | 147 | ez_status(each_domain,"HTTP") 148 | 149 | new_https_val = each_domain.replace("http://", "https://") 150 | 151 | ez_status(new_https_val,"HTTPS") 152 | 153 | 154 | # elif it doesn't contain either; add 'http://' scan it, then add 'https://' and scan with it 155 | elif each_domain[:7] != "http://" or each_domain[:8] != "https://": 156 | 157 | print(BOLD + "[*] Testing -> %s" % (each_domain) + ENDC) 158 | 159 | new_http_val = ("http://" + each_domain) 160 | 161 | ez_status(new_http_val,"HTTP") 162 | 163 | new_https_val = ("https://" + each_domain) 164 | 165 | ez_status(new_https_val, "HTTPS") 166 | 167 | 168 | # create a function that deals with the response codes 169 | def response_code(name): 170 | 171 | try: 172 | response = requests.get(name, timeout=(3.05, 27)) 173 | stat_code = response.status_code 174 | return stat_code 175 | 176 | except requests.Timeout: 177 | stat_code = 408 178 | return stat_code 179 | 180 | except requests.ConnectionError: 181 | stat_code = 999 182 | return stat_code 183 | 184 | except Exception as err: 185 | pass 186 | 187 | except KeyboardInterrupt as key_err: 188 | print("\n[*] Stopping..") 189 | exit() 190 | 191 | try: 192 | if sys.argv[1] == "-h": 193 | help() 194 | elif sys.argv[1] == "-f": 195 | try: 196 | domain_file = sys.argv[2] 197 | subdomain_list(domain_file) 198 | print("[*] Done!\n") 199 | except FileNotFoundError as fnf: 200 | print("[*] No such file known as {}".format(domain_file)) 201 | elif sys.argv > sys.argv[2]: 202 | pass 203 | else: 204 | pass 205 | except TypeError as typerr: 206 | sys.stderr.write("[*] Please use -h for help \n") 207 | sys.stout.flush() 208 | except IndexError as idxerr: 209 | sys.stderr.write("[*] Please use -h for help \n") 210 | sys.stout.flush() 211 | --------------------------------------------------------------------------------