agent-bypass 2.13.5 → 2.13.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.
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env python3
2
+ """Read-only, offline capability discovery for agent-bypass 2.13.6.
3
+
4
+ No network calls, installation, subprocess execution, scanning or file modification.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import argparse
9
+ import json
10
+ import platform
11
+ import shutil
12
+ from pathlib import Path
13
+
14
+ TOOLS = {
15
+ "package_audit": ["python3", "node", "npm", "git", "rg", "jq"],
16
+ "static_code": ["rg", "semgrep", "codeql", "python3"],
17
+ "dependencies": ["osv-scanner", "trivy", "syft", "python3"],
18
+ "binary": ["file", "readelf", "objdump", "strings", "ghidraRun", "r2"],
19
+ "android": ["jadx", "apktool", "aapt", "keytool", "unzip"],
20
+ "pcap": ["tshark", "capinfos", "wireshark", "python3"],
21
+ "web_static": ["rg", "jq", "python3", "node"],
22
+ "authorized_http": ["curl", "httpx", "mitmproxy"],
23
+ "forensics": ["vol", "volatility3", "exiftool", "strings", "file"],
24
+ }
25
+ PACKAGED = [
26
+ "argsmini.py", "basicauth_brute.py", "cvefetch.py", "deck.py", "depscan.py",
27
+ "dirbrute.py", "fastrecon.py", "jsrip.py", "mutate.py", "platf.py",
28
+ "portscan.py", "webprobe.py", "doh_resolve.sh",
29
+ ]
30
+
31
+
32
+ def discover(root: Path, task: str) -> dict:
33
+ if task not in TOOLS:
34
+ raise ValueError("Unknown task")
35
+ tools = [{"name": name, "installed": bool(shutil.which(name)),
36
+ "path": shutil.which(name)} for name in TOOLS[task]]
37
+ scripts = [{"name": name, "present": (root / "scripts" / name).is_file()}
38
+ for name in PACKAGED]
39
+ return {
40
+ "task": task,
41
+ "platform": platform.system(),
42
+ "architecture": platform.machine(),
43
+ "python": platform.python_version(),
44
+ "root": str(root.resolve()),
45
+ "tools": tools,
46
+ "packaged_scripts": scripts,
47
+ "selection_note": "Only checks tool availability. Does not execute tools or authorize external operations.",
48
+ "result_state": "inventory_only",
49
+ }
50
+
51
+
52
+ def main() -> int:
53
+ parser = argparse.ArgumentParser(description="Offline, read-only security analysis tool inventory")
54
+ parser.add_argument("--task", choices=sorted(TOOLS), default="package_audit")
55
+ parser.add_argument("--root", type=Path, default=Path(__file__).resolve().parent.parent)
56
+ parser.add_argument("--json", action="store_true", help="machine-readable inventory")
57
+ args = parser.parse_args()
58
+ if not args.root.is_dir():
59
+ parser.error("--root must be an existing directory")
60
+ result = discover(args.root, args.task)
61
+ if args.json:
62
+ print(json.dumps(result, ensure_ascii=False, indent=2))
63
+ else:
64
+ print("Task:", result["task"], "| OS:", result["platform"], "| Arch:", result["architecture"])
65
+ for item in result["tools"]:
66
+ print(" {} {:<16} {}".format("OK" if item["installed"] else "--", item["name"], item["path"] or "not found"))
67
+ print("Packaged scripts found:", sum(1 for x in result["packaged_scripts"] if x["present"]),
68
+ "/", len(result["packaged_scripts"]))
69
+ print("Inspection only: no tools were run.")
70
+ return 0
71
+
72
+
73
+ if __name__ == "__main__":
74
+ raise SystemExit(main())
@@ -5,12 +5,15 @@ 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 os
9
+ import sys, json, ssl, re, urllib.parse, urllib.request, urllib.error
9
10
 
10
11
  UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0 Safari/537.36"
11
12
  CTX = ssl.create_default_context()
12
- CTX.check_hostname = False
13
- CTX.verify_mode = ssl.CERT_NONE
13
+ # 默认验证证书;确需对自签/异常证书目标作业时设 AB_INSECURE=1 显式降级
14
+ if os.environ.get("AB_INSECURE") == "1":
15
+ CTX.check_hostname = False
16
+ CTX.verify_mode = ssl.CERT_NONE
14
17
 
15
18
  PROBE_PATHS = [
16
19
  "/", "/robots.txt", "/.env", "/.git/HEAD", "/config.json", "/config.js",
@@ -24,6 +27,25 @@ PROBE_PATHS = [
24
27
  "/backup.zip", "/db.sql", "/phpinfo.php", "/info.php", "/server-status",
25
28
  ]
26
29
 
30
+ def parse_target(raw):
31
+ """接受域名 / host:port / 完整 URL,返回 (host[:port], scheme, path_prefix);非法输入抛 ValueError"""
32
+ raw = (raw or "").strip()
33
+ if not raw:
34
+ raise ValueError("空目标")
35
+ if "://" in raw:
36
+ sp = urllib.parse.urlsplit(raw)
37
+ if sp.scheme not in ("http", "https"):
38
+ raise ValueError(f"不支持的协议: {sp.scheme}")
39
+ if not sp.netloc or not re.fullmatch(r"[A-Za-z0-9._\-]+(:\d{1,5})?", sp.netloc):
40
+ raise ValueError(f"非法主机名: {sp.netloc}")
41
+ return sp.netloc, sp.scheme, sp.path.rstrip("/")
42
+ hostport, _, rest = raw.partition("/")
43
+ if not re.fullmatch(r"[A-Za-z0-9._\-]+(:\d{1,5})?", hostport):
44
+ raise ValueError(f"非法主机: {hostport}")
45
+ prefix = ("/" + rest.rstrip("/")) if rest else ""
46
+ return hostport, "https", prefix
47
+
48
+
27
49
  def req(url, method="GET", data=None, timeout=12, headers=None):
28
50
  h = {"User-Agent": UA, "Accept": "*/*"}
29
51
  if headers: h.update(headers)
@@ -74,11 +96,17 @@ def _pool_map(items, fn, workers):
74
96
 
75
97
  def scan(domain):
76
98
  out = {"domain": domain, "hits": [], "errors": []}
99
+ try:
100
+ host, scheme, prefix = parse_target(domain)
101
+ except ValueError as e:
102
+ out["root_status"] = 0
103
+ out["errors"].append(f"目标非法: {e}")
104
+ return out
77
105
  # 指纹(https 失败自动回落 http;都不可达则快速返回)
78
- base = f"https://{domain}"
106
+ base = f"{scheme}://{host}{prefix}"
79
107
  st, hd, bd = req(base + "/")
80
- if st == 0:
81
- base = f"http://{domain}"
108
+ if st == 0 and scheme == "https":
109
+ base = f"http://{host}{prefix}"
82
110
  st, hd, bd = req(base + "/")
83
111
  if st == 0:
84
112
  out["root_status"] = 0
@@ -0,0 +1,40 @@
1
+ """Offline regression tests for the additive tool inventory."""
2
+ import json
3
+ import subprocess
4
+ import sys
5
+ import unittest
6
+ from pathlib import Path
7
+
8
+ ROOT = Path(__file__).resolve().parents[1]
9
+ SCRIPT = ROOT / 'scripts' / 'tool_inventory.py'
10
+ TASKS = ['package_audit','static_code','dependencies','binary','android','pcap','web_static','authorized_http','forensics']
11
+
12
+
13
+ class InventoryTests(unittest.TestCase):
14
+ def test_all_tasks_json(self):
15
+ for task in TASKS:
16
+ with self.subTest(task=task):
17
+ run = subprocess.run([sys.executable, str(SCRIPT), '--root', str(ROOT), '--task', task, '--json'], capture_output=True, text=True, check=True)
18
+ payload = json.loads(run.stdout)
19
+ self.assertEqual(payload['task'], task)
20
+ self.assertEqual(payload['result_state'], 'inventory_only')
21
+ self.assertTrue(payload['tools'])
22
+ self.assertTrue(all(isinstance(x['installed'],bool) for x in payload['tools']))
23
+
24
+ def test_bad_task_rejected(self):
25
+ run = subprocess.run([sys.executable, str(SCRIPT), '--task', 'unauthorized'], capture_output=True, text=True)
26
+ self.assertNotEqual(run.returncode, 0)
27
+
28
+ def test_broken_root_rejected(self):
29
+ run = subprocess.run([sys.executable, str(SCRIPT), '--root', '/nonexistent/a-b-c-directory'], capture_output=True, text=True)
30
+ self.assertNotEqual(run.returncode, 0)
31
+
32
+ def test_documents_linked(self):
33
+ skill = (ROOT / 'SKILL.md').read_text(encoding='utf-8')
34
+ for item in ['agent-routing.md','tool-selection.md','verification-gates.md','framework-comparison-2026.md','tool_inventory.py']:
35
+ self.assertIn(item, skill)
36
+ self.assertEqual(skill.count('<!-- module:'), 33)
37
+
38
+
39
+ if __name__ == '__main__':
40
+ unittest.main()