-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c8fc644
commit 12f3a0f
Showing
41 changed files
with
1,272 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
aiofiles>=23.2.1 | ||
aiohttp>=3.9.3 | ||
art>=6.1 | ||
beautifulsoup4>=4.11.1 | ||
click>=8.1.7 | ||
colorama>=0.4.4 | ||
fake_useragent>=1.2.1 | ||
Requests>=2.31.0 | ||
urllib3>=1.26.18 | ||
lxml>=5.1.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
from setuptools import setup, find_packages | ||
|
||
with open("README.md", "r") as fh: | ||
long_description = fh.read() | ||
|
||
setup( | ||
name='shodanx', | ||
version='1.0.1', | ||
author='D.Sanjai Kumar', | ||
author_email='[email protected]', | ||
description='ShodanX is a tool to gather information of targets using shodan dorks⚡.', | ||
long_description=long_description, | ||
long_description_content_type="text/markdown", | ||
url="https://github.com/sanjai-AK47/ShodanX", | ||
packages=find_packages(), | ||
install_requires=[ | ||
'aiofiles>=23.2.1', | ||
'aiohttp>=3.9.1', | ||
'art>=6.1', | ||
'beautifulsoup4>=4.11.1', | ||
'colorama>=0.4.6', | ||
'click>=8.1.7', | ||
'requests>=2.31.0', | ||
'anyio>=4.2.0', | ||
'fake_useragent>=1.2.1', | ||
'lxml>=5.1.0', | ||
'urllib3>=1.26.18' | ||
], | ||
entry_points={ | ||
'console_scripts': [ | ||
'shodanx = shodanx.shodanx:cli' | ||
] | ||
}, | ||
classifiers=[ | ||
"Programming Language :: Python :: 3", | ||
"License :: OSI Approved :: MIT License", | ||
"Operating System :: OS Independent", | ||
], | ||
) |
Empty file.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Empty file.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#!/usr/bin/env python3 | ||
from colorama import Fore,Back,Style | ||
from art import * | ||
import random | ||
import random | ||
|
||
|
||
red = Fore.RED | ||
|
||
green = Fore.GREEN | ||
|
||
magenta = Fore.MAGENTA | ||
|
||
cyan = Fore.CYAN | ||
|
||
mixed = Fore.RED + Fore.BLUE | ||
|
||
blue = Fore.BLUE | ||
|
||
yellow = Fore.YELLOW | ||
|
||
white = Fore.WHITE | ||
|
||
reset = Style.RESET_ALL | ||
|
||
bold = Style.BRIGHT | ||
|
||
colors = [ green, cyan, blue] | ||
|
||
random_color = random.choice(colors) | ||
|
||
|
||
def banner(): | ||
|
||
tool_name = "shodanX" | ||
|
||
fonts = ["big", "ogre", "shadow", "script", "colossal" , "smslant", "graffiti", "slant"] | ||
selected_font = random.choice(fonts) | ||
banner = text2art(f"{tool_name}", font=selected_font) | ||
|
||
banner = f"""{banner} | ||
{bold}{white}Author : D.SanjaiKumar @CyberRevoltSecurities{reset}\n""" | ||
|
||
|
||
|
||
return banner |
Empty file.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import appdirs | ||
import os | ||
|
||
|
||
def config(): | ||
|
||
try: | ||
|
||
dir = appdirs.user_config_dir() | ||
|
||
config = f"{dir}/shodanx" | ||
|
||
if not os.path.exists(config): | ||
|
||
os.makedirs(config) | ||
|
||
return config | ||
|
||
except Exception as e: | ||
|
||
pass |
Empty file.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,262 @@ | ||
import aiohttp | ||
import asyncio | ||
import aiofiles | ||
from colorama import Fore, Style, Back | ||
from bs4 import XMLParsedAsHTMLWarning, MarkupResemblesLocatorWarning, BeautifulSoup | ||
from requests.packages.urllib3.exceptions import InsecureRequestWarning | ||
import urllib.parse as encoder | ||
from fake_useragent import UserAgent | ||
import warnings | ||
import os | ||
|
||
red = Fore.RED | ||
|
||
green = Fore.GREEN | ||
|
||
magenta = Fore.MAGENTA | ||
|
||
cyan = Fore.CYAN | ||
|
||
mixed = Fore.RED + Fore.BLUE | ||
|
||
blue = Fore.BLUE | ||
|
||
yellow = Fore.YELLOW | ||
|
||
white = Fore.WHITE | ||
|
||
lm = Fore.LIGHTMAGENTA_EX | ||
|
||
reset = Style.RESET_ALL | ||
|
||
bold = Style.BRIGHT | ||
|
||
|
||
async def save(url, output): | ||
|
||
try: | ||
|
||
|
||
if output: | ||
|
||
|
||
|
||
if os.path.isfile(output): | ||
|
||
filename = output | ||
|
||
elif os.path.isdir(output): | ||
|
||
filename = os.path.join(output, f"ShodanX_results.txt") | ||
|
||
else: | ||
|
||
filename = output | ||
|
||
else: | ||
|
||
|
||
filename = "shodanX_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}ShodanX exits{reset}") | ||
|
||
quit() | ||
|
||
except asyncio.CancelledError as e: | ||
|
||
|
||
SystemExit | ||
|
||
async def core_request(query, facet, agents, timeout, redirects, username, output): | ||
|
||
try: | ||
|
||
total = [] | ||
|
||
encoded = encoder.quote(query) | ||
|
||
url = f"https://www.shodan.io/search/facet?query={encoded}&facet={facet}" | ||
|
||
if agents: | ||
|
||
agent = UserAgent().random | ||
|
||
else: | ||
|
||
agent = "ShodanX+https://github.com/sanjai-AK47/ShodanX" | ||
|
||
headers = {'User-Agent': agent} | ||
|
||
redirect = True if redirects else False | ||
|
||
|
||
async with aiohttp.ClientSession() as session: | ||
|
||
async with session.get(url, ssl=False, timeout=timeout, allow_redirects=redirect, headers=headers) as response: | ||
|
||
responsed = await response.text() | ||
|
||
|
||
with warnings.catch_warnings(): | ||
|
||
|
||
warnings.filterwarnings("ignore", category=UserWarning) | ||
|
||
warnings.filterwarnings('ignore', category=XMLParsedAsHTMLWarning) | ||
|
||
warnings.filterwarnings("ignore", category=MarkupResemblesLocatorWarning) | ||
|
||
soup = BeautifulSoup(responsed, "lxml") | ||
|
||
|
||
|
||
results = soup.find_all('strong') | ||
|
||
for result in results: | ||
|
||
total.append(result.get_text()) | ||
|
||
if len(total) == 0: | ||
|
||
print(f"[{bold}{red}ALERT{reset}]: {bold}{white}Sorry {username} There is no data available for your queries and facet in shodan{reset}") | ||
|
||
quit() | ||
|
||
|
||
print(f"""[{bold}{blue}INFO{reset}]: {bold}{white}Results Found for your query and facet: {query} & facet:"{facet}"{reset}""") | ||
|
||
|
||
for result in total: | ||
|
||
|
||
print(f"[{bold}{blue}INFO{reset}]: {bold}{white}{result}{reset}") | ||
|
||
await save(result, output) | ||
|
||
print(f"[{bold}{blue}INFO{reset}]: {bold}{white}Total Results Found: {len(total)}{reset}") | ||
|
||
|
||
except KeyboardInterrupt as e: | ||
|
||
print(f"[{blue}INFO{reset}]: {bold}{white}ShodanX exits..{reset}") | ||
|
||
SystemExit | ||
|
||
except aiohttp.ClientConnectionError as e: | ||
|
||
print(f"[{bold}{red}INFO{reset}]: {bold}{white}Client Connection Exceeds for: {url} , {username} please try again your query{reset}") | ||
|
||
except asyncio.TimeoutError as e: | ||
|
||
print(f"[{bold}{red}INFO{reset}]: {bold}{white}Client Timeout Exceeds for: {url}, {username} please try again your query{reset}") | ||
|
||
except asyncio.CancelledError as e: | ||
|
||
SystemExit | ||
|
||
except Exception as e: | ||
|
||
pass | ||
|
||
|
||
async def enum_request(query, agents, timeout, redirects, username, output): | ||
|
||
try: | ||
|
||
total = [] | ||
|
||
url = f"https://www.shodan.io/domain/{query}" | ||
|
||
if agents: | ||
|
||
agent = UserAgent().random | ||
|
||
else: | ||
|
||
agent = "ShodanX+https://github.com/sanjai-AK47/ShodanX" | ||
|
||
headers = {'User-Agent': agent} | ||
|
||
redirect = True if redirects else False | ||
|
||
|
||
async with aiohttp.ClientSession() as session: | ||
|
||
async with session.get(url, ssl=False, timeout=timeout, allow_redirects=redirect, headers=headers) as response: | ||
|
||
responsed = await response.text() | ||
|
||
if response.status != 200: | ||
|
||
print(f"[{bold}{red}ALERT{reset}]: {bold}{white}Sorry {username} unable to fetch subdomains for {query} because of bad response from shodan: {response.status}{reset}") | ||
|
||
quit() | ||
|
||
|
||
with warnings.catch_warnings(): | ||
|
||
|
||
warnings.filterwarnings("ignore", category=UserWarning) | ||
|
||
warnings.filterwarnings('ignore', category=XMLParsedAsHTMLWarning) | ||
|
||
warnings.filterwarnings("ignore", category=MarkupResemblesLocatorWarning) | ||
|
||
soup = BeautifulSoup(responsed, "lxml") | ||
|
||
ul = soup.find('ul', id='subdomains') | ||
|
||
if ul: | ||
|
||
subdomains = ul.findAll("li") | ||
|
||
for result in subdomains: | ||
|
||
subdomain = result.text.strip() + f".{query}" | ||
|
||
print(f"[{bold}{blue}INFO{reset}]: {bold}{white}{subdomain}{reset}") | ||
|
||
await save(subdomain, output) | ||
|
||
print(f"[{bold}{blue}INFO{reset}]: {bold}{white}Total Subdomains found for {query}: {len(subdomains)}{reset}") | ||
|
||
else: | ||
|
||
print(f"[{bold}{red}ALERT{reset}]: {bold}{white}Sorry {username} unable to fetch subdomains for {query} because of bad response from shodan{reset}") | ||
|
||
|
||
|
||
except KeyboardInterrupt as e: | ||
|
||
print(f"[{blue}INFO{reset}]: {bold}{white}ShodanX exits..{reset}") | ||
|
||
SystemExit | ||
|
||
except aiohttp.ClientConnectionError as e: | ||
|
||
print(f"[{bold}{red}INFO{reset}]: {bold}{white}Client Connection Exceeds for: {url} , {username} please try again for subdomain enumeration{reset}") | ||
|
||
except asyncio.TimeoutError as e: | ||
|
||
print(f"[{bold}{red}INFO{reset}]: {bold}{white}Client Timeout Exceeds for: {url}, {username} please try again for subdomain enumeration{reset}") | ||
|
||
except asyncio.CancelledError as e: | ||
|
||
SystemExit | ||
|
||
except Exception as e: | ||
|
||
print(e) | ||
|
||
|
||
|
||
|
||
|
Empty file.
Binary file not shown.
Binary file not shown.
Oops, something went wrong.