From 83e7ac84fe6eb095bed213ca02df9188f2c01a5c Mon Sep 17 00:00:00 2001 From: Sanjai kumar <119435129+sanjai-AK47@users.noreply.github.com> Date: Mon, 19 Feb 2024 22:06:40 +0530 Subject: [PATCH] Add files via upload --- requirements.txt | 9 + setup.py | 27 + subprober/__init__.py | 0 .../__pycache__/subprober.cpython-311.pyc | Bin 0 -> 394 bytes subprober/modules/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 161 bytes .../__pycache__/handle.cpython-311.pyc | Bin 0 -> 673 bytes .../__pycache__/handler.cpython-311.pyc | Bin 0 -> 444 bytes .../modules/__pycache__/lib.cpython-311.pyc | Bin 0 -> 36352 bytes subprober/modules/handler.py | 11 + subprober/modules/lib/__init__.py | 0 .../lib/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 173 bytes .../lib/__pycache__/lib.cpython-311.pyc | Bin 0 -> 41527 bytes subprober/modules/lib/lib.py | 933 ++++++++++++++++++ subprober/subprober.py | 10 + 15 files changed, 990 insertions(+) create mode 100644 requirements.txt create mode 100644 setup.py create mode 100644 subprober/__init__.py create mode 100644 subprober/__pycache__/subprober.cpython-311.pyc create mode 100644 subprober/modules/__init__.py create mode 100644 subprober/modules/__pycache__/__init__.cpython-311.pyc create mode 100644 subprober/modules/__pycache__/handle.cpython-311.pyc create mode 100644 subprober/modules/__pycache__/handler.cpython-311.pyc create mode 100644 subprober/modules/__pycache__/lib.cpython-311.pyc create mode 100644 subprober/modules/handler.py create mode 100644 subprober/modules/lib/__init__.py create mode 100644 subprober/modules/lib/__pycache__/__init__.cpython-311.pyc create mode 100644 subprober/modules/lib/__pycache__/lib.cpython-311.pyc create mode 100644 subprober/modules/lib/lib.py create mode 100644 subprober/subprober.py diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..04bb7d4 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,9 @@ +aiofiles>=23.2.1 +aiohttp>=3.9.1 +alive_progress>=3.1.4 +beautifulsoup4>=4.11.1 +httpx==0.25.0 +colorama>=0.4.6 +Requests>=2.31.0 +urllib3>=1.26.18 +anyio>=4.2.0 diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..3c846e2 --- /dev/null +++ b/setup.py @@ -0,0 +1,27 @@ +from setuptools import setup, find_packages + +setup( + name='subprober', + version='1.0.7', + author='D. Sanjai Kumar', + author_email='bughunterz0047@gmail.com', + description='Subprober - A Fast Probing Tool for Penetration testing', + packages=find_packages(), + install_requires=[ + 'aiofiles>=23.2.1', + 'aiohttp>=3.9.1' , + 'alive_progress>=3.1.4' , + 'beautifulsoup4>=4.11.1' , + 'colorama>=0.4.6' , + 'httpx==0.25.0', + 'Requests>=2.31.0' , + 'anyio>=4.2.0', + 'urllib3>=1.26.18' + + ], + entry_points={ + 'console_scripts': [ + 'subprober = subprober.subprober:main' + ] + }, +) \ No newline at end of file diff --git a/subprober/__init__.py b/subprober/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/subprober/__pycache__/subprober.cpython-311.pyc b/subprober/__pycache__/subprober.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf7164ca8296c7fd473b94425952401f1b612a18 GIT binary patch literal 394 zcmZ3^%ge<81hrl(QzL=&V-N=hn4pZ$3P8qmh7^Vr#vF!R#wbQc5SuB7DT*nDxrHH$ zIfW^hL6hYrNcl>}TkORpiA5!;MSjU30T=)o#tg)tm4L)_h7v}Y1Ovk|AagaG3o;yN z9HUJ&mfs!y80RUxvBcaiFsLxnfk${Nd-muNvTEp#h5I;g34Pgxrv#1MVvsL ztUz4M45hH#7zC*(xif-{G`+({bD#PH$SB`C$(5VK0Y%qvm`!Vub}c5hYdv3u80+A2*{dZ UejxFInURt40|SgGVg`x<067XK5C8xG literal 0 HcmV?d00001 diff --git a/subprober/modules/__pycache__/handle.cpython-311.pyc b/subprober/modules/__pycache__/handle.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b1492ab695806dc4d1aa422630202b7151727bac GIT binary patch literal 673 zcmb_Zv2MaZ4D}@eQfM0W7b=!4MCx31hapQgmMZC;AXO5OlMLNJ;ve{fBGjMhSTVNh z&<%-=srEsT%G%!L?B}!fp3hl1P8(=_jMi#J{*!}x8Aq_|5?F!+DN@M9PzaF50)~b( z$(qt4Ysp3kUh`W}=~`@BMHN3}rF^Wp*fXC=XLmzp2_@Ga*9-aAIsoE_kZ1zr@-^%@ zv%mGnlT7(Vls`p@A6D@cC$U1Gq>drk;Hf%*qUDB?T1 z7Kx$CiWs^@%GQZ5W{Ydx|&fi*8(I`oNg=7s37!mLQticRH zMugE7jF1n(ZXO6)Y?6}egH9TZHC9297&!7fgf&FkTgJ5JQL|bD*dR@6xj|1-`v}&7 zHw(K6Z~ml^zr;?Q3YdtEXB literal 0 HcmV?d00001 diff --git a/subprober/modules/__pycache__/lib.cpython-311.pyc b/subprober/modules/__pycache__/lib.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8213f4ff772f2226b29ea214c352d752c4b08c0c GIT binary patch literal 36352 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 cat subprober-results.txt | grep OK + This will show the results with 200-299 range codes + + -ar, --allow-redirect Enabling these flag will make Subprober to follow the redirection and ger results + + -dhp. --disable-http-probe Disables the subprober from probing to http protocols and only for https when no protocol is specified + + {bold}[{bold}{blue}MATCHERS{reset}{bold}{white}]{reset}:{reset}{bold}{white} + + -ex, --exclude Exclude specific response status code(s) from the analysis. + + -mc, --match Specify specific response status code(s) to include in the analysis. + + {bold}[{bold}{blue}OUTPUT{reset}{bold}{white}]{reset}:{reset}{bold}{white} + + -o, --output Define the output filename to store the results of the probing operation. + + -das, ---disable-auto-save Disable the autosave of the results when no output file is specified + + {bold}[{bold}{blue}Rate-Limits{reset}{bold}{white}]{reset}:{reset}{bold}{white} + + + -c, --concurrency Set the concurrency level for multiple processes. Default is 50. + + -to, --timeout Set a custom timeout value for sending requests. + + + {bold}[{bold}{blue}UPDATES{reset}{bold}{white}]{reset}:{reset}{bold}{white} + + + -up, --update Update Subprober to the latest version (pip required to be installed) + + {bold}[{bold}{blue}DEBUG{reset}{bold}{white}]{reset}:{reset}{bold}{white} + + + -h, --help Show this help message for you and exit! + + -s, --silent Enable silent mode to suppress the display of Subprober banner and version information. + + -v, --verbose Enable verbose mode to display error results on the console. + + -nc, --no-color Enabling the --no-color will display the output without any CLI colors{reset}""") + + quit() + + + + +banner = f''' + + _____ __ ____ __ + / ___/__ __/ /_ / __ \_________ / /_ ___ _____ + \__ \/ / / / __ \/ /_/ / ___/ __ \/ __ \/ _ \/ ___/ + ___/ / /_/ / /_/ / ____/ / / /_/ / /_/ / __/ / +/____/\__,_/_.___/_/ /_/ \____/_.___/\___/_/ + + + + {bold}{white}Author : D.Sanjai Kumar @CyberRevoltSecurities{reset} + + + ''' + +parser = argparse.ArgumentParser(add_help=False) + +parser.add_argument("-f", "--filename", type=str) + +parser.add_argument("-h", "--help", action="store_true") + +parser.add_argument("-u", "--url", type=str ) + +parser.add_argument("-o", "--output", type=str) + +parser.add_argument("-c", "--concurrency", type=int, default=50) + +parser.add_argument("-tl", "--title", action="store_true") + +parser.add_argument("-to", "--timeout", type=int, default=5) + +parser.add_argument("-sv", "--server", action="store_true") + +parser.add_argument("-l", "--location", action="store_true") + +parser.add_argument("-wc", "--word-count", action="store_true") + +parser.add_argument("-apt", "--application-type", action="store_true") + +parser.add_argument("-ex", "--exclude", type=str, nargs="*") + +parser.add_argument("-mc", "--match", type=str, nargs="*") + +parser.add_argument("-s", "--silent", action="store_true") + +parser.add_argument("-v", "--verbose", action="store_true") + +parser.add_argument("-p", "--path", type=str) + +parser.add_argument("-px", "--proxy", type=str) + +parser.add_argument("-gw", "--grep-word", action="store_true") + +parser.add_argument("-ar", "--allow-redirect", action="store_true") + +parser.add_argument("-nc", "--no-color", action="store_true") + +parser.add_argument("-up", "--update", action="store_true") + +parser.add_argument("-das", "--disable-auto-save", action="store_true") + +parser.add_argument("-dhp", "--disable-http-probe", action="store_true") + + + + +args = parser.parse_args() + + +async def get_version(): + + + version = "v1.0.7" + + url = f"https://api.github.com/repos/sanjai-AK47/Subprober/releases/latest" + + try: + + response = requests.get(url, timeout=10) + + if response.status_code == 200: + + + data = response.json() + + latest = data.get('tag_name') + + if latest == version: + + + print(f"[{blue}Version{reset}]: {bold}{white}Subprober current version {version} ({green}latest{reset})") + + + else: + + + print(f"[{blue}Version{reset}]: {bold}{white}Subprober current version {version} ({red}outdated{reset})") + + + else: + + pass + + + + except KeyboardInterrupt as e: + + print(f"[{blue}INFO{reset}]: {bold}{white}Subprober exits..{reset}") + + SystemExit + + + except Exception as e: + + pass + + +async def limit_extender(): + + try: + + soft , hard = resource.getrlimit(resource.RLIMIT_NOFILE) + + new = 1000000 + + osname = platform.system() + + if osname == "Linux" or osname == "Darwin": + + resource.setrlimit(resource.RLIMIT_NOFILE, (new, hard)) + + except KeyboardInterrupt as e: + + quit() + + except Exception as e: + + pass + + + +async def save(url, args): + + try: + + + if args.output: + + + + if os.path.isfile(args.output): + + filename = args.output + + elif os.path.isdir(args.output): + + filename = os.path.join(args.output, f"subprober_results.txt") + + else: + + filename = args.output + + else: + if not args.disable_auto_save: + + filename = "subprober_results.txt" + + + async with aiofiles.open(filename, "a") as w: + + await w.write(url + '\n') + + except KeyboardInterrupt as e: + + + print(f"\n[{bold}{blue}INFO{reset}]: {bold}{white}Subprober exits..{reset}") + + quit() + + except asyncio.CancelledError as e: + + + SystemExit + + + + except Exception as e: + + pass + + + + +async def probe(url, args, session, sem, bar): + + + try: + + + async with sem: + + + warnings.filterwarnings("ignore", category=ResourceWarning) + + urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + + requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + + + proxies = { + "http": args.proxy, + "https": args.proxy + } if args.proxy else None + + timeout = args.timeout + + redirect = True if args.allow_redirect else False + + async with session.get(url, ssl=False, proxy=proxies, timeout=timeout, allow_redirects=redirect) as response: + + + response_text = await response.content.read() + + server1 = response.headers.get("server") + + server = server1 if server1 else "None" + + content_type = response.headers.get("Content-Type") + + rd = response.url if response.url else "" + + + + if content_type: + + content_type = content_type.split(";")[0].strip() + + + with warnings.catch_warnings(): + + + warnings.filterwarnings("ignore", category=UserWarning) + + warnings.filterwarnings('ignore', category=XMLParsedAsHTMLWarning) + + warnings.filterwarnings("ignore", category=MarkupResemblesLocatorWarning) + + soup = BeautifulSoup(response_text, "html.parser",from_encoding="iso-8859-1") + + + text = soup.get_text() + + + word_count = len(text.split()) + + title_tag = soup.title + + title = title_tag.string if title_tag else "" + + if not args.no_color: + + redirect = f"{bold}{white}[{reset}{bold}{white}{reset}{bold}{magenta}{rd}{reset}{bold}{white}]{reset} " if args.location else "" + + else: + + redirect = f"[{rd}]" if args.location else "" + + + if not args.no_color: + + server = f"{bold}{white}[{reset}{bold}{white}{reset}{bold}{magenta}{server}{reset}{bold}{white}]{reset} " if args.server else "" + + else: + + server = f"[{server}]" if args.server else "" + + if not args.no_color: + + content = f"{bold}{white}[{reset}{bold}{yellow}{content_type}{reset}{bold}{white}]{reset}" if args.application_type else "" + + else: + + content = f"[{content_type}]" if args.application_type else "" + + if not args.no_color: + + word = f"{bold}{white}[{reset}{bold}{green}{word_count}{reset}{bold}{white}]{reset}" if args.word_count else "" + + else: + + word = f"[{word_count}]" if args.word_count else "" + + if not args.no_color: + + title = f"{bold}{white}[{reset}{bold}{cyan}{title}{reset}{bold}{white}]{reset}" if args.title else "" + + else: + + title = f"[{title}]" if args.title else "" + + + if response.status >=200 and response.status <=299: + + if not args.no_color: + + status =f"{bold}{white}[{reset}{bold}{bold}{green}{response.status}{reset}{bold}{white}]{reset}" + + else: + + status =f"[{response.status}]" + + + elif response.status >= 300 and response.status <=399: + + if not args.no_color: + + status =f"{bold}{white}[{reset}{bold}{bold}{yellow}{response.status}{reset}{bold}{white}]{reset}" + + else: + + status =f"[{response.status}]" + + else: + + if not args.no_color: + + status =f"{bold}{white}[{reset}{bold}{red}{response.status}{reset}{bold}{white}]{reset}" + + else: + + status =f"[{response.status}]" + + + if response.status >=200 and response.status <=299: + + if args.grep_word: + + if not args.no_color: + + grep =f"{bold}{white}[{reset}{bold}{green}OK{reset}{bold}{white}]{reset}" + + else: + + grep =f"[OK]" + + + elif response.status >= 300 and response.status <=399: + + if args.grep_word: + + if not args.no_color: + + grep =f"{bold}{white}[{reset}{bold}{cyan}RD{reset}{bold}{white}]{reset}" + + else: + + grep =f"[RD]" + + else: + + if args.grep_word: + + if not args.no_color: + + grep =f"{bold}{white}[{reset}{bold}{red}ER{reset}{bold}{white}]{reset}" + + else: + + grep =f"[ER]" + + gword = grep if args.grep_word else "" + + + if not args.no_color: + + url = f"{bold}{white}{url}{reset}" + + else: + + url = f"{url}" + + + + if args.exclude and str(response.status) in args.exclude: + + pass + + if not args.exclude and not args.match: + + + + result = f"""{url} {gword}{status}{title}{server}{content}{word}{redirect}""" + + print(f"{result}\n") + + await save(result, args) + + if args.exclude and not args.match: + + + if str(response.status) not in args.exclude: + + result = f"""{url} {gword}{status}{title}{server}{content}{word}{redirect}""" + + print(f"{result}\n") + + await save(result, args) + + + if args.match and str(response.status) in args.match: + + result = f"""{url} {gword}{status}{title}{server}{content}{word}""" + + print(f"{result}\n") + + await save(result, args) + + + + except KeyboardInterrupt as e: + + print(f"[{blue}INFO{reset}]: {bold}{white}Subprober exits..{reset}") + + SystemExit + + except aiohttp.ClientConnectionError as e: + + + if args.verbose: + + + print(f"[{bold}{red}INFO{reset}]: {bold}{white}Client Connection Exceeds for: {url}{reset}") + + + except asyncio.TimeoutError as e: + + if args.verbose: + + + print(f"[{bold}{red}INFO{reset}]: {bold}{white}Client Timeout Exceeds for: {url}{reset}") + + except asyncio.CancelledError as e: + + SystemExit + + except InvalidURL as e: + + pass + + except UnicodeError as e: + + pass + + except (ClientResponseError, ClientPayloadError) as e: + + if not args.no_color: + + result = f"{bold}{white}{url}{reset} {bold}{white}[Invalid Response]{reset}" + + else: + + result = f"{url} [Invalid Response]" + + print(result) + + await save(result, args) + + except Exception as e: + + pass + + + finally: + + bar() + + + +async def concurrents(): + + try: + + url_lists = list(set(url_list)) + + sem = asyncio.Semaphore(args.concurrency) + + async with aiohttp.ClientSession() as session: + + with alive_bar(title=f"SubProber", total=len(url_lists), enrich_print=False) as bar: + + tasks = [probe(url, args, session, sem, bar) for url in url_lists] + + await asyncio.gather(*tasks,return_exceptions=False) + + except KeyboardInterrupt as e: + + print(f"\n[{bold}{blue}INFO{reset}]: {bold}{white}Subprober exits..{reset}") + SystemExit + + except asyncio.CancelledError as e: + + + SystemExit + + except Exception as e: + + pass + + + + +async def all_sub(): + + try: + + await limit_extender() + + if args.url and not args.filename: + + if not args.silent: + + print(f"{bold}{random_color}{banner}{reset}", file=sys.stderr) + + await get_version() + + + if args.url and args.output: + + print(f"[{green}INFO{reset}]: {bold}{white}Output will be saved in {args.output}{reset}") + + elif args.url and not args.output: + + if not args.disable_auto_save: + + print(f"[{green}INFO{reset}]: {bold}{white}Output will be saved in subprober_results.txt{reset}") + + + + if args.url and not args.filename: + + + url = args.url + + path =f"/{args.path}" if args.path else "" + + if url.startswith("https://") or url.startswith("http://"): + + url = f"{url}/{path}" + + url_list.append(url) + + elif not url.startswith("https://") or url.startswith("http://"): + + new_url = f"https://{url}{path}" + + if not args.disable_http_probe: + + new_http = f"http://{url}{path}" + + url_list.append(new_url) + + if not args.disable_http_probe: + + url_list.append(new_http) + + await concurrents() + + + + if args.filename and not args.url: + + if not args.silent: + + print(f"{bold}{random_color}{banner}{reset}") + + await get_version() + + + if args.output: + + print(f"[{green}INFO{reset}]: {bold}{white}Output will be saved in {args.output}{reset}") + + elif not args.output: + + if not args.disable_auto_save: + + + print(f"[{green}INFO{reset}]: {bold}{white}Output will be saved in subprober_results.txt{reset}") + + + if args.filename and not args.url: + + + try: + + filename = args.filename + + + + async with aiofiles.open(filename, "r") as urls: + + async for url in urls: + + url = url.strip() + + path =f"/{args.path}" if args.path else "" + + url = f"{url}{path}" + + if url.startswith("https://") or url.startswith("http://") : + + url_list.append(url) + + elif not url.startswith("https://") or url.startswith("http://") : + + new_url = f"https://{url}{path}" + + if not args.disable_http_probe: + + new_http = f"http://{url}{path}" + + url_list.append(new_url) + + if not args.disable_http_probe: + + url_list.append(new_http) + + await concurrents() + + + except FileNotFoundError as e: + + print(f"[{red}INFO{reset}]: {bold}{white}{args.filename} not found. please check the file or file path exist or not!{reset}") + + quit() + + except Exception as e: + + pass + + + if args.update: + + version = "v1.0.7" + + url = f"https://api.github.com/repos/sanjai-AK47/Subprober/releases/latest" + + try: + + async with aiohttp.ClientSession() as req: + + async with req.get(url) as response: + + if response.status == 200: + + data = await response.json() + + latest = data.get('tag_name') + + if latest == version: + + + print(f"[{bold}{blue}Version{reset}]: {bold}{white}Subprober already in latest version dont worry :){reset}") + + + quit() + + else: + + try: + + print(f"[{bold}{blue}UPDATE{reset}]: {bold}{white}Updating the Subprober{reset}") + + os.system("pip install git+https://github.com/sanjai-AK47/Subprober.git") + + print(f"[{bold}{blue}INFO{reset}]: {bold}{white}Please check whether Subprober updated to latest version or update it through manually{reset}") + + quit() + + + except Exception as e: + + print(f"[{bold}{blue}INFO{reset}]: {bold}{white}Subprober update failed due to some error{reset}") + + quit() + + else: + + print(f"[{bold}{blue}INFO{reset}]: {bold}{white}Subprober update failed due to some error{reset}") + + quit() + + except KeyboardInterrupt as e: + + print(f"[{blue}INFO{reset}]: {bold}{white}Subprober exits..{reset}") + + quit() + + except aiohttp.TimeoutError as e: + + print(f"[{bold}{blue}INFO{reset}]: {bold}{white}Subprober update failed due to failed to reach Subprober Repository please report this issue{reset}") + + quit() + + except Exception as e: + + print(f"[{bold}{blue}INFO{reset}]: {bold}{white}Subprober update failed due to failed to reach Subprober Repository please report this issue{reset}") + + quit() + + + if args.help: + + print(f"{bold}{random_color}{banner}{reset}", file=sys.stderr) + + await help_me() + + + if not args.filename and not args.url: + + try: + + if not args.silent: + + print(f"{bold}{random_color}{banner}{reset}") + + + await get_version() + + path =f"/{args.path}" if args.path else "" + + for line in sys.stdin: + + url = f"{line.strip()}{path}" + + if url.startswith("https://") or url.startswith("http://"): + + + + + url_list.append(url) + + + else: + + new_url = f"https://{url}{path}" + + if not args.disable_http_probe: + + new_http = f"http://{url}{path}" + + url_list.append(new_url) + + if not args.disable_http_probe: + + url_list.append(new_http) + + await concurrents() + + except KeyboardInterrupt as e: + + + print(f"[{blue}INFO{reset}]: {bold}{white}Subprober exits..{reset}") + + + quit() + + + except Exception as e: + + pass + + except KeyboardInterrupt as e: + + + print(f"[{blue}INFO{reset}]: {bold}{white}Subprober exits..{reset}") + + SystemExit + + + except asyncio.CancelledError as e: + + SystemExit + + except Exception as e: + + print(f"[{blue}INFO{reset}]:Unknow error occured due to : {e}, please report this issue in Subprober github page") + + quit() + \ No newline at end of file diff --git a/subprober/subprober.py b/subprober/subprober.py new file mode 100644 index 0000000..ab5a7f1 --- /dev/null +++ b/subprober/subprober.py @@ -0,0 +1,10 @@ +from .modules.handler import * + +def main(): + + starter() + + +if __name__ == '__main__': + + main()