agent-bypass 2.11.6 → 2.12.0

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/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 argparse, json, re, ssl, sys, urllib.parse
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 argparse, ssl, sys, urllib.parse
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()
@@ -12,7 +12,8 @@
12
12
 
13
13
  输出: jsonl(每行一个开放端口)
14
14
  """
15
- import asyncio, json, sys, argparse
15
+ import argsmini as argparse
16
+ import asyncio, json, sys
16
17
 
17
18
  TOP100 = [21,22,23,25,53,80,110,111,135,139,143,443,445,993,995,1433,1521,1723,
18
19
  2049,3306,3389,5432,5900,5984,6379,7001,8000,8008,8080,8081,8443,8888,
@@ -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, concurrent.futures
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
- st, hd, bd = req(f"https://{domain}/")
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
- for p in PROBE_PATHS:
59
- s, h, b = req(f"https://{domain}{p}")
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
- domains = sys.argv[1:]
72
- if not domains:
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
- with concurrent.futures.ThreadPoolExecutor(max_workers=6) as ex:
76
- for r in ex.map(scan, domains):
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__":