-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathScriptHound.py
More file actions
179 lines (151 loc) · 8.29 KB
/
ScriptHound.py
File metadata and controls
179 lines (151 loc) · 8.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
ScriptHound 🐕 — Sniffing out Nmap scripts (and any files) fast.
Author: Harsh Katiyar
"""
import os
import platform
import sys
import time
from tabulate import tabulate
# ============ Color codes ============
class Colors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKCYAN = '\033[96m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
BOLD = '\033[1m'
DIM = '\033[2m'
ENDC = '\033[0m'
# ============ Preferences (edit these to your liking) ============
PREF = {
"name": "ScriptHound",
"emoji": "🐕",
"tagline": "Sniffing out Nmap scripts fast.",
"author": "Harsh Katiyar",
"accent_primary": Colors.OKGREEN,
"accent_secondary": Colors.OKBLUE,
"banner_style": "raptor", # options: "raptor", "block", "dog"
"slow_banner": False, # True = typewriter effect
"slow_delay": 0.0015 # seconds per character when slow_banner=True
}
# ============ Fancy Banner ============
def _banner_art(style: str) -> str:
if style == "dog":
return r"""
{p} __
/{s}^\{p} ( ) {s}ScriptHound{p}
/ {s}• •{p}\ ) {s}Sniffing scripts since 2025
( {s}◡{p} )/
\__{s}w w{p}_/ {s}"""[1:]
if style == "block":
return r"""
█████████ █████████ ███████████ ████████████████ ███████████ █████ █████ ███████ █████ ███████████ ███████████████
███░░░░░███ ███░░░░░███░░███░░░░░███░░███░░███░░░░░███░█░░░███░░░█ ░░███ ░░███ ███░░░░░███░░███ ░░███░░██████ ░░███░░███░░░░███
░███ ░░░ ███ ░░░ ░███ ░███ ░███ ░███ ░███░ ░███ ░ ░███ ░███ ███ ░░███░███ ░███ ░███░███ ░███ ░███ ░░███
░░█████████ ░███ ░██████████ ░███ ░██████████ ░███ ░███████████░███ ░███░███ ░███ ░███░░███░███ ░███ ░███
░░░░░░░░███░███ ░███░░░░░███ ░███ ░███░░░░░░ ░███ ░███░░░░░███░███ ░███░███ ░███ ░███ ░░██████ ░███ ░███
███ ░███░░███ ███ ░███ ░███ ░███ ░███ ░███ ░███ ░███░░███ ███ ░███ ░███ ░███ ░░█████ ░███ ███
░░█████████ ░░█████████ █████ ███████████████ █████ █████ █████░░░███████░ ░░████████ █████ ░░███████████████
░░░░░░░░░ ░░░░░░░░░ ░░░░░ ░░░░░░░░░░░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░░░ ░░░░░░░░ ░░░░░ ░░░░░░░░░░░░░░░
""".rstrip("\n")
# default "raptor" — fun, pointy, memorable
return r"""
{p} __
_/o\-._ / \ {s}S C R I P T H O U N D{p}
.-' _\_/ \ {s}Sniffing out Nmap scripts fast{p}
/ .-.-. {s}🐾{p} .-. \
| / _ \ / _\ |
\ \ (_) / _ \(_)/ /
'-.\___/.-' '-.\__.'
""".rstrip("\n")
def type_out(text: str, delay: float = 0.002):
for ch in text:
print(ch, end='', flush=True)
time.sleep(delay)
print()
def print_banner():
p = PREF["accent_primary"]
s = PREF["accent_secondary"]
emoji = PREF["emoji"]
title = f"{PREF['name']} {emoji}"
tagline = PREF["tagline"]
author = PREF["author"]
art = _banner_art(PREF["banner_style"])
# inject accent placeholders
art_colored = art.format(p=p, s=s)
header = f"{Colors.BOLD}{p}{title}{Colors.ENDC} {Colors.DIM}{s}{tagline}{Colors.ENDC}"
author_line = f"{Colors.DIM}by {author}{Colors.ENDC}"
block = f"{art_colored}\n\n{header}\n{author_line}\n"
if PREF["slow_banner"]:
type_out(block, PREF["slow_delay"])
else:
print(block)
# ============ Core functionality ============
def detect_os():
current_os = platform.system().lower()
print(f"{Colors.DIM}Running on {current_os.capitalize()}{Colors.ENDC}")
return current_os
def search_file_in_directory(directory, file_name):
file_name = file_name.lower()
found_files = []
for root, _, files in os.walk(directory):
for file in files:
if file_name in file.lower():
found_files.append(os.path.join(root, file))
return found_files
def prompt_for_file_name():
print(f"{PREF['accent_secondary']}Enter the file name to search (e.g., 'ftp', 'ssl', 'example.txt'){Colors.ENDC}")
return input("File name: ").strip()
def display_results(results, show_full_path):
if results:
if show_full_path:
headers = ["Index", "File Path"]
table_data = [(i + 1, result) for i, result in enumerate(results)]
else:
headers = ["Index", "File Name"]
table_data = [(i + 1, os.path.basename(result)) for i, result in enumerate(results)]
print("\nSearch Results:")
print(tabulate(table_data, headers=headers, tablefmt="grid"))
print(f"{Colors.DIM}Total matches: {len(results)}{Colors.ENDC}")
else:
print(f"{Colors.WARNING}No matches found.{Colors.ENDC}")
def pick_search_path(current_os):
default_search_path = None
if current_os == 'linux':
default_search_path = os.path.expanduser('/usr/share/nmap')
print(f"Default search path set to: {default_search_path}")
if default_search_path and os.path.isdir(default_search_path):
use_default = input(f"Use default Nmap scripts folder ({default_search_path})? (y/n): ").lower()
if use_default == 'y':
return default_search_path
while True:
file_path = input("Enter the full path of the directory to search in: ").strip()
if os.path.isdir(file_path):
return file_path
else:
print(f"{Colors.FAIL}Invalid directory. Please try again.{Colors.ENDC}")
def main():
print_banner()
current_os = detect_os()
file_path = pick_search_path(current_os)
while True:
file_name = prompt_for_file_name()
print(f"\n{PREF['accent_primary']}Searching for '{file_name}' in '{file_path}'...{Colors.ENDC}\n")
results = search_file_in_directory(file_path, file_name)
display_choice = input("Display results as (1) Full Paths or (2) File Names only? [1/2]: ").strip()
show_full_path = display_choice == '1'
display_results(results, show_full_path)
continue_search = input("Search again? (y/n): ").lower()
if continue_search != 'y':
print(f"{Colors.OKGREEN}Exiting {PREF['name']}. Goodbye!{Colors.ENDC}")
break
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print(f"\n{Colors.WARNING}Interrupted by user.{Colors.ENDC}")
sys.exit(1)