agent-bypass 2.11.5 → 2.11.7
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.
- package/README.md +280 -63
- package/SKILL.md +11 -9
- package/assets/banner.svg +91 -0
- package/bin/install.js +1 -0
- package/ck-hunter.md +1 -1
- package/package.json +11 -2
- package/references/mobile-fast-recon.md +102 -0
- package/scripts/argsmini.py +210 -0
- package/scripts/basicauth_brute.py +82 -7
- package/scripts/cvefetch.py +2 -1
- package/scripts/deck.py +2 -1
- package/scripts/depscan.py +2 -1
- package/scripts/dirbrute.py +505 -71
- package/scripts/fastrecon.py +980 -0
- package/scripts/jsrip.py +2 -1
- package/scripts/mutate.py +2 -1
- package/scripts/platf.py +44 -0
- package/scripts/portscan.py +4 -1
- package/scripts/webprobe.py +56 -10
package/scripts/jsrip.py
CHANGED
|
@@ -15,7 +15,8 @@ JS 静态文件提取器(§01 Step 8 侧枝折射)
|
|
|
15
15
|
python3 jsrip.py https://target.com --scan # 自动找页面引用的 JS
|
|
16
16
|
python3 jsrip.py https://target.com/app.js --json
|
|
17
17
|
"""
|
|
18
|
-
import
|
|
18
|
+
import argsmini as argparse
|
|
19
|
+
import json, re, ssl, sys, urllib.parse
|
|
19
20
|
import urllib.request, urllib.error
|
|
20
21
|
|
|
21
22
|
CTX = ssl.create_default_context()
|
package/scripts/mutate.py
CHANGED
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
# 输出全部(含失败)
|
|
23
23
|
python3 mutate.py https://target.com/admin --all
|
|
24
24
|
"""
|
|
25
|
-
import
|
|
25
|
+
import argsmini as argparse
|
|
26
|
+
import ssl, sys, urllib.parse
|
|
26
27
|
import urllib.request, urllib.error
|
|
27
28
|
|
|
28
29
|
CTX = ssl.create_default_context()
|
package/scripts/platf.py
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""平台自适配探测(轻量:仅 os/sys,import 成本近零)。
|
|
2
|
+
被 fastrecon / dirbrute / basicauth_brute 共用。"""
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
_ENV = None
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def env():
|
|
10
|
+
global _ENV
|
|
11
|
+
if _ENV is not None:
|
|
12
|
+
return _ENV
|
|
13
|
+
e = {"platform": "linux", "mobile": False, "scan_workers": 512,
|
|
14
|
+
"http_workers": 96, "dns_workers": 48, "timeout_min": 0.5,
|
|
15
|
+
"engine_hint": "auto", "lazy": False}
|
|
16
|
+
if os.path.exists("/proc/ish"):
|
|
17
|
+
e.update(platform="ish", mobile=True, scan_workers=256,
|
|
18
|
+
http_workers=48, dns_workers=32, timeout_min=0.8, lazy=True)
|
|
19
|
+
elif os.environ.get("TERMUX_VERSION") or os.path.exists("/data/data/com.termux"):
|
|
20
|
+
e.update(platform="termux", mobile=True, scan_workers=512,
|
|
21
|
+
http_workers=64, dns_workers=48, timeout_min=0.6)
|
|
22
|
+
elif os.path.exists("/proc/device-tree/model"):
|
|
23
|
+
try:
|
|
24
|
+
m = open("/proc/device-tree/model", "rb").read().decode("utf-8", "ignore")
|
|
25
|
+
if "Raspberry Pi" in m:
|
|
26
|
+
e.update(platform="rpi", scan_workers=768, http_workers=64)
|
|
27
|
+
except OSError:
|
|
28
|
+
pass
|
|
29
|
+
if sys.platform == "darwin":
|
|
30
|
+
e.update(platform="macos")
|
|
31
|
+
elif os.name == "nt":
|
|
32
|
+
e.update(platform="windows")
|
|
33
|
+
_ENV = e
|
|
34
|
+
return e
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def env_line():
|
|
38
|
+
e = env()
|
|
39
|
+
return "env=%s scan/http/dns=%d/%d/%d" % (
|
|
40
|
+
e["platform"], e["scan_workers"], e["http_workers"], e["dns_workers"])
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
if __name__ == "__main__":
|
|
44
|
+
print(env_line())
|
package/scripts/portscan.py
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
"""
|
|
4
4
|
并发端口扫描(无需 nmap)
|
|
5
5
|
|
|
6
|
+
提示: 手机环境(iSH/Termux)优先用 fastrecon.py scan —— selectors 并发实测快 5-45 倍
|
|
7
|
+
|
|
6
8
|
用法:
|
|
7
9
|
python3 portscan.py <host> [--ports 1-65535] [--conc 500] [--timeout 2]
|
|
8
10
|
python3 portscan.py 1.2.3.4 --ports top100
|
|
@@ -10,7 +12,8 @@
|
|
|
10
12
|
|
|
11
13
|
输出: jsonl(每行一个开放端口)
|
|
12
14
|
"""
|
|
13
|
-
import
|
|
15
|
+
import argsmini as argparse
|
|
16
|
+
import asyncio, json, sys
|
|
14
17
|
|
|
15
18
|
TOP100 = [21,22,23,25,53,80,110,111,135,139,143,443,445,993,995,1433,1521,1723,
|
|
16
19
|
2049,3306,3389,5432,5900,5984,6379,7001,8000,8008,8080,8081,8443,8888,
|
package/scripts/webprobe.py
CHANGED
|
@@ -5,7 +5,7 @@ Web 批量指纹 + 路径探测器
|
|
|
5
5
|
用法: python3 webprobe.py <domain> [<domain> ...] # 或完整 URL
|
|
6
6
|
输出: jsonl(指纹 + 命中路径)
|
|
7
7
|
"""
|
|
8
|
-
import sys, json, ssl, re, urllib.request, urllib.error
|
|
8
|
+
import sys, json, ssl, re, urllib.request, urllib.error
|
|
9
9
|
|
|
10
10
|
UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0 Safari/537.36"
|
|
11
11
|
CTX = ssl.create_default_context()
|
|
@@ -41,10 +41,49 @@ def req(url, method="GET", data=None, timeout=12, headers=None):
|
|
|
41
41
|
except Exception as e:
|
|
42
42
|
return 0, {}, str(e).encode()
|
|
43
43
|
|
|
44
|
+
def _pool_map(items, fn, workers):
|
|
45
|
+
"""保序线程池(替代 concurrent.futures,省 iSH import 成本)"""
|
|
46
|
+
items = list(items)
|
|
47
|
+
if len(items) <= 1:
|
|
48
|
+
return [fn(x) for x in items]
|
|
49
|
+
import threading
|
|
50
|
+
out = [None] * len(items)
|
|
51
|
+
nxt = [0]
|
|
52
|
+
lock = threading.Lock()
|
|
53
|
+
|
|
54
|
+
def worker():
|
|
55
|
+
while True:
|
|
56
|
+
with lock:
|
|
57
|
+
if nxt[0] >= len(items):
|
|
58
|
+
return
|
|
59
|
+
i = nxt[0]
|
|
60
|
+
nxt[0] += 1
|
|
61
|
+
try:
|
|
62
|
+
out[i] = fn(items[i])
|
|
63
|
+
except Exception:
|
|
64
|
+
out[i] = None
|
|
65
|
+
|
|
66
|
+
ts = [threading.Thread(target=worker, daemon=True)
|
|
67
|
+
for _ in range(max(1, min(workers, len(items))))]
|
|
68
|
+
for t in ts:
|
|
69
|
+
t.start()
|
|
70
|
+
for t in ts:
|
|
71
|
+
t.join()
|
|
72
|
+
return out
|
|
73
|
+
|
|
74
|
+
|
|
44
75
|
def scan(domain):
|
|
45
76
|
out = {"domain": domain, "hits": [], "errors": []}
|
|
46
|
-
#
|
|
47
|
-
|
|
77
|
+
# 指纹(https 失败自动回落 http;都不可达则快速返回)
|
|
78
|
+
base = f"https://{domain}"
|
|
79
|
+
st, hd, bd = req(base + "/")
|
|
80
|
+
if st == 0:
|
|
81
|
+
base = f"http://{domain}"
|
|
82
|
+
st, hd, bd = req(base + "/")
|
|
83
|
+
if st == 0:
|
|
84
|
+
out["root_status"] = 0
|
|
85
|
+
out["errors"].append("主机不可达(https/http 均失败)")
|
|
86
|
+
return out
|
|
48
87
|
txt = bd.decode("utf-8", "replace")
|
|
49
88
|
out["root_status"] = st
|
|
50
89
|
out["server"] = hd.get("Server") or hd.get("server")
|
|
@@ -54,9 +93,16 @@ def scan(domain):
|
|
|
54
93
|
r"(dujiaoka|独角数卡|ruoyi|若依|spring|actuator|vue|react|nuxt|next|vite|"
|
|
55
94
|
r"laravel|thinkphp|django|flask|express|gin|subvault|new-api|one-api)",
|
|
56
95
|
txt + str(hd), re.I)))
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
96
|
+
|
|
97
|
+
# 路径探测(6 并发,保序;根不可达时不再打 40 条)
|
|
98
|
+
def probe(p):
|
|
99
|
+
s, h, b = req(base + p)
|
|
100
|
+
return p, s, h, b
|
|
101
|
+
|
|
102
|
+
for rp in _pool_map(PROBE_PATHS, probe, 6):
|
|
103
|
+
if rp is None:
|
|
104
|
+
continue
|
|
105
|
+
p, s, h, b = rp
|
|
60
106
|
if s in (200, 201, 301, 302, 401, 403, 405, 500):
|
|
61
107
|
bt = b[:300].decode("utf-8", "replace")
|
|
62
108
|
# 过滤 SPA 兜底(同 root 长度 + text/html)
|
|
@@ -68,12 +114,12 @@ def scan(domain):
|
|
|
68
114
|
return out
|
|
69
115
|
|
|
70
116
|
def main():
|
|
71
|
-
|
|
72
|
-
if not
|
|
117
|
+
args = sys.argv[1:]
|
|
118
|
+
if not args or any(a in ('-h', '--help') for a in args):
|
|
73
119
|
print(__doc__.strip())
|
|
74
120
|
sys.exit(0)
|
|
75
|
-
|
|
76
|
-
|
|
121
|
+
for r in _pool_map(args, scan, 6):
|
|
122
|
+
if r is not None:
|
|
77
123
|
print(json.dumps(r, ensure_ascii=False))
|
|
78
124
|
|
|
79
125
|
if __name__ == "__main__":
|