jseye 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- jseye/__init__.py +9 -0
- jseye/banner.py +37 -0
- jseye/cli.py +137 -0
- jseye/data/regex.yaml +1050 -0
- jseye/data/vendor_blacklist.txt +65 -0
- jseye/installer.py +190 -0
- jseye/modules/__init__.py +1 -0
- jseye/modules/analyze_ast.py +116 -0
- jseye/modules/analyze_regex.py +123 -0
- jseye/modules/correlate.py +140 -0
- jseye/modules/harvest.py +124 -0
- jseye/modules/js_download.py +82 -0
- jseye/modules/js_filter.py +186 -0
- jseye/modules/linkfinder.py +56 -0
- jseye/modules/secrets.py +71 -0
- jseye/modules/sinks.py +132 -0
- jseye/pipeline.py +230 -0
- jseye/utils/__init__.py +1 -0
- jseye/utils/fs.py +98 -0
- jseye/utils/hashing.py +42 -0
- jseye/utils/logger.py +50 -0
- jseye/utils/shell.py +83 -0
- jseye-1.0.0.dist-info/METADATA +264 -0
- jseye-1.0.0.dist-info/RECORD +28 -0
- jseye-1.0.0.dist-info/WHEEL +5 -0
- jseye-1.0.0.dist-info/entry_points.txt +2 -0
- jseye-1.0.0.dist-info/licenses/LICENSE +21 -0
- jseye-1.0.0.dist-info/top_level.txt +1 -0
jseye/__init__.py
ADDED
jseye/banner.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""
|
|
2
|
+
JSEye Banner Display
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
from rich.text import Text
|
|
7
|
+
from rich.align import Align
|
|
8
|
+
|
|
9
|
+
console = Console()
|
|
10
|
+
|
|
11
|
+
def show_banner():
|
|
12
|
+
"""Display the JSEye banner with proper alignment"""
|
|
13
|
+
banner = """
|
|
14
|
+
|
|
15
|
+
▄▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄▄▄
|
|
16
|
+
█▀ ██ ██▀▀▀▀█▄ █▀██▀▀▀
|
|
17
|
+
██ ▀██▄ ▄▀ ██
|
|
18
|
+
██ ▀██▄▄ ████ ██ ██ ▄█▀█▄
|
|
19
|
+
██ ▄ ▀██▄ ██ ██▄██ ██▄█▀
|
|
20
|
+
██ ▀██████▀ ▀█████▄▄▀██▀▄▀█▄▄▄
|
|
21
|
+
▄ ██ ██
|
|
22
|
+
▀████▀ ▀▀▀
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
# Display banner in cyan, centered
|
|
26
|
+
banner_text = Text(banner.strip(), style="cyan bold")
|
|
27
|
+
console.print(Align.center(banner_text))
|
|
28
|
+
console.print()
|
|
29
|
+
|
|
30
|
+
# Tagline and author info, centered
|
|
31
|
+
tagline = Text("JSEye — See What JavaScript Hides", style="green bold")
|
|
32
|
+
console.print(Align.center(tagline))
|
|
33
|
+
|
|
34
|
+
author = Text("Author: Lakshmikanthan K (letchupkt)", style="purple")
|
|
35
|
+
console.print(Align.center(author))
|
|
36
|
+
|
|
37
|
+
console.print()
|
jseye/cli.py
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
JSEye CLI - Main entry point
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import sys
|
|
8
|
+
import argparse
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from rich.console import Console
|
|
11
|
+
|
|
12
|
+
from .banner import show_banner
|
|
13
|
+
from .installer import check_and_install_tools
|
|
14
|
+
from .pipeline import JSEyePipeline
|
|
15
|
+
|
|
16
|
+
console = Console()
|
|
17
|
+
|
|
18
|
+
def clear_terminal():
|
|
19
|
+
"""Clear terminal screen (cross-platform)"""
|
|
20
|
+
import platform
|
|
21
|
+
if platform.system() == "Windows":
|
|
22
|
+
os.system("cls")
|
|
23
|
+
else:
|
|
24
|
+
os.system("clear")
|
|
25
|
+
|
|
26
|
+
def create_parser():
|
|
27
|
+
"""Create argument parser"""
|
|
28
|
+
parser = argparse.ArgumentParser(
|
|
29
|
+
description="JSEye - JavaScript Intelligence & Attack Surface Discovery",
|
|
30
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
31
|
+
epilog="""
|
|
32
|
+
Examples:
|
|
33
|
+
jseye -i subs.txt -o output # Full pipeline (default)
|
|
34
|
+
jseye -i subs.txt -o output --js-only # Stop after JS discovery
|
|
35
|
+
jseye -i subs.txt -o output --no-secrets # Skip secrets detection
|
|
36
|
+
jseye -i subs.txt -o output --regex-only # Only regex analysis
|
|
37
|
+
"""
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# Required arguments (but not when listing modules)
|
|
41
|
+
parser.add_argument("-i", "--input",
|
|
42
|
+
help="Input file containing subdomains")
|
|
43
|
+
parser.add_argument("-o", "--output",
|
|
44
|
+
help="Output directory for results")
|
|
45
|
+
|
|
46
|
+
# Module control flags (disable/isolate modules)
|
|
47
|
+
parser.add_argument("--js-only", action="store_true",
|
|
48
|
+
help="Stop after JavaScript discovery")
|
|
49
|
+
parser.add_argument("--no-install", action="store_true",
|
|
50
|
+
help="Do not auto-install missing tools")
|
|
51
|
+
parser.add_argument("--skip-ast", action="store_true",
|
|
52
|
+
help="Skip AST analysis")
|
|
53
|
+
parser.add_argument("--regex-only", action="store_true",
|
|
54
|
+
help="Only perform regex analysis")
|
|
55
|
+
parser.add_argument("--no-secrets", action="store_true",
|
|
56
|
+
help="Skip secrets detection (mantra)")
|
|
57
|
+
parser.add_argument("--no-sinks", action="store_true",
|
|
58
|
+
help="Skip sink detection")
|
|
59
|
+
parser.add_argument("--no-correlate", action="store_true",
|
|
60
|
+
help="Skip correlation engine")
|
|
61
|
+
parser.add_argument("--list-modules", action="store_true",
|
|
62
|
+
help="Show available modules and exit")
|
|
63
|
+
|
|
64
|
+
return parser
|
|
65
|
+
|
|
66
|
+
def list_modules():
|
|
67
|
+
"""List available modules"""
|
|
68
|
+
modules = [
|
|
69
|
+
"harvest - URL harvesting (gau, waybackurls, katana)",
|
|
70
|
+
"js_filter - JavaScript file filtering",
|
|
71
|
+
"js_download - JavaScript file downloading",
|
|
72
|
+
"analyze_regex - Regex-based analysis",
|
|
73
|
+
"analyze_ast - AST-based analysis",
|
|
74
|
+
"linkfinder - Endpoint discovery",
|
|
75
|
+
"secrets - Secret detection (mantra)",
|
|
76
|
+
"sinks - Sink detection",
|
|
77
|
+
"correlate - Intelligence correlation"
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
console.print("\n[bold cyan]Available JSEye Modules:[/bold cyan]")
|
|
81
|
+
for module in modules:
|
|
82
|
+
console.print(f" • {module}")
|
|
83
|
+
console.print()
|
|
84
|
+
|
|
85
|
+
def main():
|
|
86
|
+
"""Main CLI entry point"""
|
|
87
|
+
parser = create_parser()
|
|
88
|
+
args = parser.parse_args()
|
|
89
|
+
|
|
90
|
+
# Clear terminal and show banner
|
|
91
|
+
clear_terminal()
|
|
92
|
+
show_banner()
|
|
93
|
+
|
|
94
|
+
# List modules if requested
|
|
95
|
+
if args.list_modules:
|
|
96
|
+
list_modules()
|
|
97
|
+
return 0
|
|
98
|
+
|
|
99
|
+
# Validate required arguments for normal operation
|
|
100
|
+
if not args.input or not args.output:
|
|
101
|
+
parser.error("Input and output arguments are required for normal operation")
|
|
102
|
+
|
|
103
|
+
# Validate input file
|
|
104
|
+
if not Path(args.input).exists():
|
|
105
|
+
console.print(f"[red]Error: Input file '{args.input}' not found[/red]")
|
|
106
|
+
return 1
|
|
107
|
+
|
|
108
|
+
# Create output directory
|
|
109
|
+
output_dir = Path(args.output)
|
|
110
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
111
|
+
|
|
112
|
+
try:
|
|
113
|
+
# Check and install tools if needed
|
|
114
|
+
if not args.no_install:
|
|
115
|
+
console.print("[yellow]Checking required tools...[/yellow]")
|
|
116
|
+
if not check_and_install_tools():
|
|
117
|
+
console.print("[red]Failed to install required tools[/red]")
|
|
118
|
+
return 1
|
|
119
|
+
|
|
120
|
+
# Initialize and run pipeline
|
|
121
|
+
pipeline = JSEyePipeline(args.input, args.output, args)
|
|
122
|
+
results = pipeline.run()
|
|
123
|
+
|
|
124
|
+
# Show summary
|
|
125
|
+
pipeline.show_summary(results)
|
|
126
|
+
|
|
127
|
+
return 0
|
|
128
|
+
|
|
129
|
+
except KeyboardInterrupt:
|
|
130
|
+
console.print("\n[yellow]Interrupted by user[/yellow]")
|
|
131
|
+
return 1
|
|
132
|
+
except Exception as e:
|
|
133
|
+
console.print(f"[red]Error: {e}[/red]")
|
|
134
|
+
return 1
|
|
135
|
+
|
|
136
|
+
if __name__ == "__main__":
|
|
137
|
+
sys.exit(main())
|