forked from MASTERMONTYOFFICIAL/js_analyzer
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjs.py
More file actions
136 lines (120 loc) · 4.43 KB
/
Copy pathjs.py
File metadata and controls
136 lines (120 loc) · 4.43 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
from bs4 import BeautifulSoup
import requests
import argparse
import re
import json
import threading
from urllib.parse import urljoin
def load_patterns(path="patterns.txt"):
patterns = []
try:
with open(path, 'r', encoding='utf-8') as f:
for ln in f:
ln = ln.strip()
if not ln or ln.startswith('#'):
continue
if ':' in ln:
name, rx = ln.split(':', 1)
else:
name, rx = ln, ln
try:
patterns.append((name.strip(), re.compile(rx)))
except re.error:
print(f"[BAD PATTERN] {ln}")
except FileNotFoundError:
print(f"[WARN] pattern file not found: {path}")
return patterns
def scan_js_for_patterns(js_url, patterns, report_out="report.jsonl"):
try:
r = requests.get(js_url, timeout=10)
except requests.RequestException:
return
if r.status_code != 200:
return
text = r.text
findings = []
for name, pat in patterns:
for m in pat.finditer(text):
snippet = m.group(0)
findings.append({"type": name, "url": js_url, "match": snippet[:200]})
print("[FIND]" + f" {name} -> {js_url} -> {snippet[:80]}")
if findings:
with open(report_out, 'a', encoding='utf-8') as fo:
for f in findings:
fo.write(json.dumps(f) + "\n")
def js_out(url,output):
with open(output,'a') as f:
f.write(url+"\n")
def extract_urls(url,output):
try:
res = requests.get(url,timeout=5)
if res.status_code == 200:
soap = BeautifulSoup(res.text,'html.parser')
for arg in soap.find_all("a"):
js_url = arg.get("href")
if js_url and re.search(r"\.js$",js_url):
full_url = urljoin(url,js_url)
print("[JS]" + f" {full_url}")
js_out(full_url,output)
for arg in soap.find_all("script"):
js_url = arg.get("src")
if js_url and re.search(r"\.js$",js_url):
full_url = urljoin(url,js_url)
print("[JS]" + f" {full_url}")
js_out(full_url,output)
patterns = load_patterns("patterns.txt") # optional: move this outside the loop for efficiency
if patterns:
scan_js_for_patterns(full_url, patterns, "report.jsonl")
except Exception:
print(f"[ERROR] {url}")
def banner():
print('''
◣ ◢
█◣ ◢█
█████
▉┃▉┃█
█████ ◢◤
◥████ █ Author : zeropwned
████◣ ◥◣ Finding Hidden Secrets :)
█████◣ █
██████ █
██████ █
██████◢█
███████◤
◥█████◤
''')
def main():
try:
parser = argparse.ArgumentParser(description="Deep Analyze for credentials in JS files.")
banner()
parser.add_argument("--url","-u",help="Url to parse js links.")
parser.add_argument("--sub","-s",help="Path to enter subdomains")
parser.add_argument("--output","-o",help="Path to save output.")
args = parser.parse_args()
if args.url == "" and args.sub == "":
return
if not args.output:
args.output = "js.txt"
if args.url:
extract_urls(args.url,args.output)
if args.sub:
threads = []
with open(args.sub,'r') as f:
for subs in f:
subs = subs.strip()
if not subs:
continue
for scheme in ("https://","http://"):
url = scheme + subs
try:
t = threading.Thread(target=extract_urls,args=(url,args.output))
threads.append(t)
t.start()
except Exception:
print(f"[ERROR] Could not fetch {url}")
for t in threads:
t.join()
except KeyboardInterrupt:
print(f"\nBye Bye :)")
if __name__ == '__main__':
main()