create-dwy 0.5.1 → 0.6.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.
Files changed (156) hide show
  1. package/bin/index.js +1 -1
  2. package/package.json +2 -2
  3. package/src/create.js +61 -37
  4. package/src/sync.js +212 -61
  5. package/templates/claude-global/CLAUDE.md +92 -0
  6. package/templates/claude-global/rules/dwy-android-core.md +610 -0
  7. package/templates/claude-global/rules/dwy-api-design.md +110 -0
  8. package/templates/claude-global/rules/dwy-db-migration.md +46 -0
  9. package/templates/claude-global/rules/dwy-flutter-core.md +564 -0
  10. package/templates/claude-global/rules/dwy-flutter-network.md +222 -0
  11. package/templates/claude-global/rules/dwy-flutter-router.md +97 -0
  12. package/templates/claude-global/rules/dwy-flutter-testing.md +94 -0
  13. package/templates/claude-global/rules/dwy-git-commit-convention.md +82 -0
  14. package/templates/claude-global/rules/dwy-git-security.md +53 -0
  15. package/templates/claude-global/rules/dwy-payload-limits.md +178 -0
  16. package/templates/claude-global/rules/{prefer-open-source.md → dwy-prefer-open-source.md} +4 -0
  17. package/templates/claude-global/rules/dwy-project-structure.md +181 -0
  18. package/templates/claude-global/rules/{python-code-style.md → dwy-python-core.md} +292 -358
  19. package/templates/claude-global/rules/dwy-python-fastapi.md +272 -0
  20. package/templates/claude-global/rules/dwy-python-orm.md +61 -0
  21. package/templates/claude-global/rules/{backend-security.md → dwy-python-security.md} +99 -72
  22. package/templates/claude-global/rules/dwy-python-testing.md +53 -0
  23. package/templates/claude-global/rules/{server-security.md → dwy-server-security.md} +1 -2
  24. package/templates/claude-global/rules/dwy-tdd-development.md +70 -0
  25. package/templates/claude-global/rules/dwy-tech-stack.md +60 -0
  26. package/templates/claude-global/rules/dwy-vue-api.md +146 -0
  27. package/templates/claude-global/rules/{vue-code-style.md → dwy-vue-core.md} +338 -152
  28. package/templates/claude-global/rules/dwy-vue-pinia.md +75 -0
  29. package/templates/claude-global/rules/dwy-vue-testing.md +102 -0
  30. package/templates/claude-global/skills/dwy-deploy-audit/SKILL.md +481 -0
  31. package/templates/claude-global/skills/dwy-deploy-audit/references/checks-data.md +117 -0
  32. package/templates/claude-global/skills/dwy-deploy-audit/references/checks-network.md +74 -0
  33. package/templates/claude-global/skills/dwy-deploy-audit/references/checks-runtime.md +184 -0
  34. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_base.sh +39 -0
  35. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_capacity.sh +278 -0
  36. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_db.sh +122 -0
  37. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_docker.sh +249 -0
  38. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_env.sh +64 -0
  39. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_https.sh +60 -0
  40. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_logs.sh +209 -0
  41. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_nginx.sh +92 -0
  42. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_resilience.sh +157 -0
  43. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_secrets.sh +327 -0
  44. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_services.sh +77 -0
  45. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_ssh.sh +56 -0
  46. package/templates/claude-global/skills/dwy-deploy-audit/scripts/run_all.sh +105 -0
  47. package/templates/claude-global/skills/dwy-docker/SKILL.md +187 -0
  48. package/templates/claude-global/skills/dwy-docker/references/ask-templates.md +142 -0
  49. package/templates/claude-global/skills/dwy-docker/references/templates.md +479 -0
  50. package/templates/claude-global/skills/dwy-docker/references/version-rules.md +76 -0
  51. package/templates/claude-global/skills/dwy-docker/scripts/query_dockerhub.py +204 -0
  52. package/templates/claude-global/skills/dwy-docker/scripts/scan_images.sh +185 -0
  53. package/templates/claude-global/skills/dwy-eapi/SKILL.md +433 -0
  54. package/templates/claude-global/skills/dwy-eapi/references/tasks-integration-guide.md +387 -0
  55. package/templates/claude-global/skills/dwy-ekit/SKILL.md +85 -0
  56. package/templates/claude-global/skills/dwy-ekit/references/data.md +135 -0
  57. package/templates/claude-global/skills/dwy-ekit/references/form.md +68 -0
  58. package/templates/claude-global/skills/dwy-ekit/references/request.md +183 -0
  59. package/templates/claude-global/skills/dwy-ekit/references/ui.md +109 -0
  60. package/templates/claude-global/skills/{dwy-frontend-eui → dwy-eui}/SKILL.md +129 -15
  61. package/templates/claude-global/skills/dwy-eui/references/eui-design-guide.md +257 -0
  62. package/templates/claude-global/skills/dwy-eui/references/eui-integration-guide.md +302 -0
  63. package/templates/claude-global/skills/dwy-eui/references/eui-landing-design-guide.md +437 -0
  64. package/templates/claude-global/skills/dwy-fullstack-scaffold/SKILL.md +214 -0
  65. package/templates/claude-global/skills/dwy-mirror-source/SKILL.md +275 -0
  66. package/templates/claude-global/skills/dwy-mirror-source/references/dockerfile-snippets.md +228 -0
  67. package/templates/claude-global/skills/dwy-mirror-source/references/mirror-providers.md +150 -0
  68. package/templates/claude-global/skills/dwy-mirror-source/scripts/__pycache__/check_mirrors.cpython-313.pyc +0 -0
  69. package/templates/claude-global/skills/dwy-mirror-source/scripts/apply_mirrors.py +666 -0
  70. package/templates/claude-global/skills/dwy-mirror-source/scripts/check_mirrors.py +868 -0
  71. package/templates/claude-global/skills/dwy-pentest/SKILL.md +344 -0
  72. package/templates/claude-global/skills/dwy-pentest/scripts/lib/__init__.py +1 -0
  73. package/templates/claude-global/skills/dwy-pentest/scripts/lib/__pycache__/__init__.cpython-311.pyc +0 -0
  74. package/templates/claude-global/skills/dwy-pentest/scripts/lib/__pycache__/config.cpython-311.pyc +0 -0
  75. package/templates/claude-global/skills/dwy-pentest/scripts/lib/__pycache__/executor.cpython-311.pyc +0 -0
  76. package/templates/claude-global/skills/dwy-pentest/scripts/lib/__pycache__/severity.cpython-311.pyc +0 -0
  77. package/templates/claude-global/skills/dwy-pentest/scripts/lib/__pycache__/validator.cpython-311.pyc +0 -0
  78. package/templates/claude-global/skills/dwy-pentest/scripts/lib/config.py +109 -0
  79. package/templates/claude-global/skills/dwy-pentest/scripts/lib/executor.py +157 -0
  80. package/templates/claude-global/skills/dwy-pentest/scripts/lib/severity.py +96 -0
  81. package/templates/claude-global/skills/dwy-pentest/scripts/lib/validator.py +113 -0
  82. package/templates/claude-global/skills/dwy-pentest/scripts/pentest_auth.py +289 -0
  83. package/templates/claude-global/skills/dwy-pentest/scripts/pentest_recon.py +217 -0
  84. package/templates/claude-global/skills/dwy-pentest/scripts/pentest_report.py +343 -0
  85. package/templates/claude-global/skills/dwy-pentest/scripts/pentest_scan.py +205 -0
  86. package/templates/claude-global/skills/dwy-pentest/scripts/pentest_ssl.py +208 -0
  87. package/templates/claude-global/skills/dwy-pentest/scripts/pentest_vuln.py +205 -0
  88. package/templates/claude-global/skills/dwy-pentest/scripts/pentest_web.py +330 -0
  89. package/templates/claude-global/skills/dwy-pentest/scripts/pyproject.toml +14 -0
  90. package/templates/claude-global/skills/dwy-pentest/scripts/setup_tools.sh +97 -0
  91. package/templates/claude-global/skills/dwy-pentest/scripts/uv.lock +415 -0
  92. package/templates/claude-global/skills/{dwy-release → dwy-publish}/SKILL.md +42 -18
  93. package/templates/claude-global/skills/dwy-vue-core/SKILL.md +890 -0
  94. package/templates/project/backend/.dwy.hbs +5 -0
  95. package/templates/project/backend/.python-version +1 -0
  96. package/templates/project/backend/CLAUDE.md.hbs +40 -0
  97. package/templates/project/{web/backend → backend}/alembic/script.py.mako +2 -0
  98. package/templates/project/{web/backend → backend}/alembic.ini.hbs +0 -1
  99. package/templates/project/backend/deploy.sh.hbs +18 -0
  100. package/templates/project/{web → backend}/docker-compose.prod.yml.hbs +1 -1
  101. package/templates/project/{web/backend → backend}/pyproject.toml.hbs +4 -5
  102. package/templates/project/{web/backend → backend}/src/app/config.py.hbs +1 -1
  103. package/templates/project/backend/src/app/database.py +10 -0
  104. package/templates/project/backend/src/app/dependencies.py +5 -0
  105. package/templates/project/{web/backend → backend}/src/app/main.py.hbs +3 -3
  106. package/templates/project/backend/src/app/models/base.py +5 -0
  107. package/templates/project/web/CLAUDE.md.hbs +29 -36
  108. package/templates/project/web/{frontend → apps/web}/index.html.hbs +1 -0
  109. package/templates/project/web/{frontend → apps/web}/package.json.hbs +4 -3
  110. package/templates/project/web/apps/web/src/App.vue +9 -0
  111. package/templates/project/web/apps/web/src/api/client.ts +5 -0
  112. package/templates/project/web/apps/web/src/composables/.gitkeep +0 -0
  113. package/templates/project/web/apps/web/src/layouts/DefaultLayout.vue +8 -0
  114. package/templates/project/web/{frontend → apps/web}/src/router/index.ts +1 -1
  115. package/templates/project/web/{frontend → apps/web}/src/stores/auth.ts +4 -2
  116. package/templates/project/web/apps/web/src/style.css +2 -0
  117. package/templates/project/web/apps/web/src/types/router.d.ts +8 -0
  118. package/templates/project/web/apps/web/src/views/HomeView.vue +8 -0
  119. package/templates/project/web/apps/web/tsconfig.app.json +18 -0
  120. package/templates/project/web/apps/web/tsconfig.json +6 -0
  121. package/templates/project/web/{frontend → apps/web}/vite.config.ts.hbs +7 -1
  122. package/templates/project/web/package.json.hbs +16 -0
  123. package/templates/project/web/packages/.gitkeep +0 -0
  124. package/templates/project/web/pnpm-workspace.yaml +3 -0
  125. package/templates/claude-global/hooks/post-sync-claude-global.sh +0 -72
  126. package/templates/claude-global/rules/agent-team-execution.md +0 -138
  127. package/templates/claude-global/rules/agent-team-patterns.md +0 -157
  128. package/templates/claude-global/rules/git-commit-convention.md +0 -106
  129. package/templates/claude-global/rules/git-security.md +0 -144
  130. package/templates/claude-global/skills/dwy-backend-base/SKILL.md +0 -279
  131. package/templates/claude-global/skills/dwy-frontend-core/SKILL.md +0 -181
  132. package/templates/project/web/.claude/commands/deploy.md +0 -4
  133. package/templates/project/web/backend/src/app/models/base.py +0 -5
  134. package/templates/project/web/deploy.sh.hbs +0 -113
  135. package/templates/project/web/frontend/src/App.vue +0 -3
  136. package/templates/project/web/frontend/src/api/client.ts +0 -13
  137. package/templates/project/web/frontend/src/style.css +0 -1
  138. package/templates/project/web/frontend/src/views/HomeView.vue +0 -5
  139. package/templates/project/web/frontend/tsconfig.app.json +0 -14
  140. package/templates/project/web/frontend/tsconfig.json +0 -4
  141. /package/templates/{project/web/backend → claude-global/skills/dwy-pentest/scripts}/.python-version +0 -0
  142. /package/templates/project/{web/backend → backend}/Dockerfile +0 -0
  143. /package/templates/project/{web/backend → backend}/alembic/env.py.hbs +0 -0
  144. /package/templates/{claude-global/skills → project/backend/alembic/versions}/.gitkeep +0 -0
  145. /package/templates/project/{web → backend}/docker-compose.dev.yml.hbs +0 -0
  146. /package/templates/project/{web/backend → backend}/src/app/__init__.py +0 -0
  147. /package/templates/project/{web/backend → backend}/src/app/models/__init__.py +0 -0
  148. /package/templates/project/{web/backend → backend}/src/app/routers/__init__.py +0 -0
  149. /package/templates/project/{web/backend → backend}/src/app/routers/health.py +0 -0
  150. /package/templates/project/{web/backend → backend}/src/app/schemas/__init__.py +0 -0
  151. /package/templates/project/{web/backend → backend}/src/app/services/__init__.py +0 -0
  152. /package/templates/project/{web/backend → backend}/tests/__init__.py +0 -0
  153. /package/templates/project/{web/backend → backend}/tests/conftest.py.hbs +0 -0
  154. /package/templates/project/{web/backend/alembic/versions → mobile}/.gitkeep +0 -0
  155. /package/templates/project/web/{frontend → apps/web}/src/components/.gitkeep +0 -0
  156. /package/templates/project/web/{frontend → apps/web}/src/main.ts +0 -0
@@ -0,0 +1,344 @@
1
+ ---
2
+ name: dwy-pentest
3
+ description: "白帽渗透测试:对指定服务器执行全面安全评估。触发条件:用户说'渗透测试'、'pentest'、'安全测试'、'漏洞扫描'、'安全审计' 时。"
4
+ ---
5
+
6
+ # 白帽渗透测试
7
+
8
+ 对指定目标执行全面安全评估,发现漏洞后报警提示,不执行破坏性操作。
9
+
10
+ **脚本目录:** `~/.claude/skills/dwy-pentest/scripts/`(以下简称 `{scripts}`)
11
+
12
+ ## 流程总览
13
+
14
+ ```
15
+ 输入目标 → 环境准备 → 信息收集 → 端口扫描 → 漏洞扫描 → Web 测试 → SSL 审计 → 认证测试 → 漏洞验证 → 报告生成 → 安全告警
16
+ ```
17
+
18
+ **共 10 步,不可跳步,不可调换顺序。**
19
+
20
+ ---
21
+
22
+ ## 第 0 步:获取目标
23
+
24
+ 向用户询问测试目标,支持以下格式:
25
+ - IP 地址:`192.168.1.100`
26
+ - 域名:`example.com`
27
+ - URL:`https://example.com:8443`
28
+ - IP:端口:`10.0.0.1:8080`
29
+
30
+ ```
31
+ 请输入要测试的目标(IP/域名/URL):
32
+ ```
33
+
34
+ 收到目标后:
35
+ 1. 确认目标格式有效
36
+ 2. 如果是私网/本地地址,提示用户确认
37
+ 3. 创建输出目录:`{项目根目录}/.pentest-results/{YYYYMMDD-HHmmss}/`
38
+ 4. 将输出目录路径记为 `{output}`,后续所有步骤引用此路径
39
+
40
+ ---
41
+
42
+ ## 第 1 步:环境准备
43
+
44
+ 检查并安装所需工具:
45
+
46
+ ```bash
47
+ bash {scripts}/setup_tools.sh
48
+ ```
49
+
50
+ 如果脚本 Python 依赖未安装:
51
+
52
+ ```bash
53
+ cd {scripts} && uv sync
54
+ ```
55
+
56
+ **工具清单(必需 + 可选):**
57
+
58
+ | 工具 | 必需 | 用途 | 不可用时的降级 |
59
+ |------|------|------|--------------|
60
+ | nmap | 是 | 端口扫描 + NSE 漏洞脚本 | 无法降级,必须安装 |
61
+ | nuclei | 否 | 模板驱动漏洞扫描 | 仅用 nmap NSE |
62
+ | testssl.sh | 否 | SSL/TLS 审计 | 用 Python ssl 模块 |
63
+ | gobuster | 否 | 目录枚举 | 用 ffuf 或内置路径列表 |
64
+ | sqlmap | 否 | SQL 注入检测 | 用基础 HTTP 探针 |
65
+ | hydra | 否 | 凭据暴力测试 | 跳过认证测试 |
66
+ | ffuf | 否 | Web fuzzer(gobuster 备选) | 用内置路径列表 |
67
+ | whatweb | 否 | 技术栈指纹 | 用 HTTP 头分析 |
68
+
69
+ **nmap 是唯一强依赖**,其余工具脚本内置降级方案。
70
+
71
+ 缺少可选工具时,向用户报告缺失项和影响,然后继续执行。
72
+
73
+ ---
74
+
75
+ ## 第 2 步:信息收集(3 Agent 并行)
76
+
77
+ **在同一条消息中**派出 3 个 Agent 并行执行:
78
+
79
+ ### Agent-Recon-DNS
80
+ ```
81
+ 目标:对 {target} 执行 DNS 和 WHOIS 信息收集
82
+ 上下文:渗透测试第 2 步,需要获取目标的 IP 地址、DNS 记录、注册信息
83
+ 范围:仅执行 DNS 查询和 WHOIS,不发送任何攻击流量
84
+ 规范:使用 {scripts} 目录下的脚本
85
+ 产出:执行命令并返回结果摘要
86
+
87
+ 执行:
88
+ cd {scripts} && uv run pentest_recon.py --target {target} --mode dns --output-dir {output}
89
+ ```
90
+
91
+ ### Agent-Recon-Tech
92
+ ```
93
+ 目标:识别 {target} 的技术栈和 Web 指纹
94
+ 上下文:渗透测试第 2 步,需要知道目标运行什么软件和版本
95
+ 范围:HTTP 请求 + whatweb 指纹,不发送攻击 payload
96
+ 规范:使用 {scripts} 目录下的脚本
97
+ 产出:执行命令并返回结果摘要
98
+
99
+ 执行:
100
+ cd {scripts} && uv run pentest_recon.py --target {target} --mode tech --output-dir {output}
101
+ ```
102
+
103
+ ### Agent-Recon-OSINT
104
+ ```
105
+ 目标:搜索 {target} 相关的已知漏洞和安全事件
106
+ 上下文:渗透测试第 2 步,需要了解目标是否有已知的安全问题
107
+ 范围:仅使用 WebSearch 搜索公开信息
108
+ 产出:返回搜索结果摘要,包含 CVE 编号和关键发现
109
+
110
+ 使用 WebSearch 搜索以下关键词(分多次搜索):
111
+ 1. "{target}" CVE vulnerability
112
+ 2. "{target}" security breach
113
+ 3. "{target}" 使用的技术栈(从 Agent-Recon-Tech 结果获取)的最新 CVE
114
+ ```
115
+
116
+ **等待所有 Agent 完成后**,汇总信息收集结果,向用户报告发现:
117
+ - 解析到的 IP 地址
118
+ - 技术栈和版本信息
119
+ - 发现的敏感文件
120
+ - 公开的安全信息
121
+
122
+ ---
123
+
124
+ ## 第 3 步:端口扫描
125
+
126
+ 依赖第 2 步的 DNS 结果确认真实 IP。脚本内部 TCP / UDP 并发执行,版本探测与 OS 指纹识别也并发。
127
+
128
+ ```bash
129
+ cd {scripts} && uv run pentest_scan.py --target {target} --output-dir {output}
130
+ ```
131
+
132
+ 扫描完成后,提取关键信息供后续步骤使用:
133
+ - `open_ports`:所有开放端口列表
134
+ - `http_ports`:HTTP 服务端口(用于 Web 测试)
135
+ - `ssl_ports`:SSL/TLS 端口(用于 SSL 审计)
136
+ - `ssh_port`:SSH 端口(用于认证测试)
137
+ - `ftp_port`:FTP 端口(用于认证测试)
138
+
139
+ 向用户报告端口扫描结果。
140
+
141
+ ---
142
+
143
+ ## 第 4 步:漏洞扫描 + Web 枚举 + SSL(最多 5 Agent 并行)
144
+
145
+ 根据第 3 步发现的服务,**在同一条消息中**派出 Agent:
146
+
147
+ ### Agent-Vuln-Nuclei(始终执行)
148
+ ```
149
+ 目标:对 {target} 执行 Nuclei 漏洞模板扫描
150
+ 上下文:渗透测试第 4 步,基于端口扫描发现的服务进行漏洞匹配
151
+ 范围:使用 nuclei 官方模板库,限速 50 req/s
152
+ 规范:使用 {scripts} 目录下的脚本
153
+ 产出:执行命令并返回发现的漏洞列表
154
+
155
+ 执行:
156
+ cd {scripts} && uv run pentest_vuln.py --target {target} --mode nuclei --output-dir {output}
157
+ ```
158
+
159
+ ### Agent-Vuln-NSE(始终执行)
160
+ ```
161
+ 目标:对 {target} 的开放端口执行 Nmap 漏洞脚本扫描
162
+ 上下文:渗透测试第 4 步,使用 nmap 内置 NSE 漏洞检测脚本
163
+ 范围:仅 --script vuln,不执行 exploit 脚本
164
+ 产出:执行命令并返回发现的漏洞列表
165
+
166
+ 执行:
167
+ cd {scripts} && uv run pentest_vuln.py --target {target} --mode nse --ports {open_ports} --output-dir {output}
168
+ ```
169
+
170
+ ### Agent-Web-Dir(仅 HTTP 端口存在时)
171
+ ```
172
+ 目标:对 {target} 的 Web 服务执行目录枚举
173
+ 上下文:渗透测试第 4 步,发现隐藏路径和敏感文件
174
+ 范围:目录枚举,不修改任何数据
175
+ 产出:执行命令并返回发现的路径列表
176
+
177
+ 执行:
178
+ cd {scripts} && uv run pentest_web.py --target {web_url} --mode dir --output-dir {output}
179
+ ```
180
+
181
+ ### Agent-SSL(仅 SSL/TLS 端口存在时)
182
+ ```
183
+ 目标:对 {target} 执行 SSL/TLS 安全审计
184
+ 上下文:渗透测试第 4 步,检查证书和加密配置
185
+ 范围:SSL/TLS 握手分析,不攻击
186
+ 产出:执行命令并返回 SSL 审计结果
187
+
188
+ 执行:
189
+ cd {scripts} && uv run pentest_ssl.py --target {target} --port {ssl_port} --output-dir {output}
190
+ ```
191
+
192
+ ### Agent-CVE-Research(始终执行)
193
+ ```
194
+ 目标:搜索第 3 步发现的服务版本对应的 CVE
195
+ 上下文:渗透测试第 4 步,端口扫描已发现以下服务和版本:{services_versions}
196
+ 范围:WebSearch 搜索公开 CVE 数据库
197
+ 产出:返回每个服务的已知 CVE 列表和利用条件
198
+
199
+ 对每个 {service} {version} 组合,使用 WebSearch 搜索:
200
+ 1. "{service} {version}" CVE exploit
201
+ 2. 在搜索结果中重点关注 CVSS >= 7.0 的高危漏洞
202
+ ```
203
+
204
+ ---
205
+
206
+ ## 第 5 步:Web 深度测试(2 Agent 并行)
207
+
208
+ **仅当第 4 步 Agent-Web-Dir 发现了 Web 路径时执行。**
209
+
210
+ ### Agent-Web-SQLi
211
+ ```
212
+ 目标:对 {target} 的 Web 应用进行 SQL 注入探测
213
+ 上下文:渗透测试第 5 步,目录枚举已发现以下路径:{discovered_paths}
214
+ 范围:仅检测注入点,禁止数据提取(sqlmap --technique=BEU, 无 --dump)
215
+ 规范:使用 {scripts} 目录下的脚本
216
+ 产出:执行命令并返回发现的注入点
217
+
218
+ 执行:
219
+ cd {scripts} && uv run pentest_web.py --target {web_url} --mode sqli --output-dir {output}
220
+ ```
221
+
222
+ ### Agent-Web-XSS
223
+ ```
224
+ 目标:对 {target} 的 Web 应用进行 XSS 反射探测
225
+ 上下文:渗透测试第 5 步,使用无害探针检测反射点
226
+ 范围:发送无害标记 <dwy-xss-test>,不执行真实 XSS payload
227
+ 规范:使用 {scripts} 目录下的脚本
228
+ 产出:执行命令并返回发现的 XSS 反射点
229
+
230
+ 执行:
231
+ cd {scripts} && uv run pentest_web.py --target {web_url} --mode xss --output-dir {output}
232
+ ```
233
+
234
+ ---
235
+
236
+ ## 第 6 步:认证测试
237
+
238
+ 脚本内部 SSH / FTP / HTTP 三个服务并发执行,FTP 的匿名探测与 hydra 弱密码并发,HTTP 的登录路径探测与默认凭据尝试也都是异步并发。
239
+
240
+ **执行前向用户确认:**
241
+
242
+ ```
243
+ 认证测试将尝试常见弱密码(最多 20 组),可能触发目标的安全防护。
244
+ 发现的服务:SSH({ssh_port}), FTP({ftp_port}), HTTP({http_ports})
245
+ 是否执行?(y/n)
246
+ ```
247
+
248
+ 用户同意后:
249
+
250
+ ```bash
251
+ cd {scripts} && uv run pentest_auth.py --target {target} --output-dir {output} --services ssh,ftp,http
252
+ ```
253
+
254
+ 用户拒绝 → 跳过此步。
255
+
256
+ ---
257
+
258
+ ## 第 7 步:漏洞验证与利用评估
259
+
260
+ 读取 `{output}` 下所有 JSON 结果,对 Critical 和 High 级别的漏洞进行验证:
261
+
262
+ 1. 分析每个高危漏洞的详细信息
263
+ 2. 使用 WebSearch 搜索该漏洞的公开 PoC 和利用方式
264
+ 3. 评估是否可实际利用获取服务器控制权
265
+ 4. **仅做到验证漏洞确实存在为止**,不执行实际利用
266
+
267
+ 对每个高危漏洞输出评估结论:
268
+ - **已确认可利用** — 有成熟 PoC,理论上可获取 shell/控制权
269
+ - **可能可利用** — CVE 存在但需要特定条件
270
+ - **信息泄露** — 不直接导致控制权获取但构成风险
271
+
272
+ **如果发现可获取控制权的漏洞,立即告警:**
273
+
274
+ ```
275
+ =============================================================
276
+ !! 安全告警 — 可获取服务器控制权 !!
277
+ =============================================================
278
+
279
+ 漏洞: {vuln_title} (CVE-XXXX-XXXX)
280
+ CVSS: {score}
281
+ 评估: 存在公开 PoC,攻击者可利用此漏洞获取服务器控制权
282
+
283
+ !! 此处仅做告警,未执行实际利用 !!
284
+
285
+ 建议立即修复。
286
+ =============================================================
287
+ ```
288
+
289
+ ---
290
+
291
+ ## 第 8 步:报告生成
292
+
293
+ ```bash
294
+ cd {scripts} && uv run pentest_report.py --input-dir {output} --output {output}/report.md
295
+ ```
296
+
297
+ 报告包含:基本信息、执行摘要、目标概况、漏洞详情、SSL 审计、修复优先级、免责声明。
298
+
299
+ ---
300
+
301
+ ## 第 9 步:安全告警与总结
302
+
303
+ 向用户展示最终结果:
304
+
305
+ 1. **按严重性分级展示所有发现**(Critical → High → Medium → Low)
306
+ 2. **给出修复优先级建议**
307
+ 3. **告知报告位置**:`{output}/report.md`
308
+ 4. **如果发现 Critical 级漏洞**,强烈建议立即修复并重新测试
309
+
310
+ ---
311
+
312
+ ## 安全保障
313
+
314
+ ### 脚本内置的安全限制
315
+
316
+ - `executor.py` 仅允许执行 8 个预定义工具命令(白名单)
317
+ - `executor.py` 拦截危险参数(`--os-shell`, `--dump-all`, `--file-write` 等)
318
+ - 所有命令 `shell=False`,参数列表传入,防止命令注入
319
+ - 单次扫描最大超时 300 秒
320
+ - 认证测试每服务最多 20 次尝试
321
+ - sqlmap 禁止 Stacked Queries(`--technique=BEU`)
322
+ - hydra 找到第一个弱密码即停止(`-f`)
323
+
324
+ ### 禁止事项
325
+
326
+ - **禁止**在未经用户同意的目标上执行任何扫描
327
+ - **禁止**执行任何 exploit(Metasploit、手写 exploit、PoC 执行)
328
+ - **禁止**在目标服务器上植入代码、webshell、后门
329
+ - **禁止**提取目标数据库中的实际数据
330
+ - **禁止**进行 DoS/DDoS 测试
331
+ - **禁止**修改目标系统的任何配置或文件
332
+ - **禁止**使用社会工程学手段
333
+ - **禁止**绕过脚本的安全限制(SAFETY_LIMITS)
334
+ - **禁止**将发现的漏洞详情(PoC/exploit 细节)输出给用户以外的人
335
+
336
+ ### 降级策略
337
+
338
+ 工具不可用时,脚本自动降级:
339
+ - nuclei 不可用 → 仅用 nmap NSE 扫描
340
+ - gobuster/ffuf 不可用 → 用内置常见路径列表 + httpx 探测
341
+ - sqlmap 不可用 → 用基础 HTTP SQL 错误探针
342
+ - testssl.sh 不可用 → 用 Python ssl 模块基础检测
343
+ - hydra 不可用 → 跳过暴力认证测试
344
+ - whatweb 不可用 → 用 HTTP 头分析识别技术栈
@@ -0,0 +1,109 @@
1
+ """全局配置:安全限制、工具白名单、危险参数黑名单。"""
2
+
3
+ from pathlib import Path
4
+
5
+ # 扫描参数
6
+ SCAN_TIMEOUT = 300 # 单次扫描最大时长(秒)
7
+ SCAN_RATE_LIMIT = 50 # 每秒最大请求数
8
+ NMAP_TIMING = "T3" # 扫描速度(T1-T5)
9
+ MAX_AUTH_ATTEMPTS = 20 # 认证测试最大尝试次数
10
+
11
+ # 工具命令白名单 — executor 仅允许执行这些命令
12
+ ALLOWED_COMMANDS = frozenset({
13
+ "nmap",
14
+ "nuclei",
15
+ "gobuster",
16
+ "ffuf",
17
+ "sqlmap",
18
+ "hydra",
19
+ "testssl",
20
+ "testssl.sh",
21
+ "whatweb",
22
+ "curl",
23
+ "dig",
24
+ "whois",
25
+ })
26
+
27
+ # 危险参数黑名单 — executor 拦截包含这些参数的调用
28
+ BLOCKED_ARGS = frozenset({
29
+ # sqlmap 危险参数
30
+ "--os-shell",
31
+ "--os-cmd",
32
+ "--os-pwn",
33
+ "--dump-all",
34
+ "--file-read",
35
+ "--file-write",
36
+ "--file-dest",
37
+ "--priv-esc",
38
+ "--reg-read",
39
+ "--reg-add",
40
+ "--reg-del",
41
+ # nmap exploit 脚本
42
+ "--script=exploit",
43
+ # hydra 无限制
44
+ "-x", # 密码生成器(可生成无限组合)
45
+ # 通用危险
46
+ "--reverse-shell",
47
+ "--backdoor",
48
+ })
49
+
50
+ # 硬编码安全限制
51
+ SAFETY_LIMITS = {
52
+ "no_exploit_execution": True,
53
+ "no_reverse_shell": True,
54
+ "no_payload_upload": True,
55
+ "no_data_exfiltration": True,
56
+ "sqlmap_no_stacked": True,
57
+ "sqlmap_no_dump": True,
58
+ "hydra_stop_on_first": True,
59
+ }
60
+
61
+ # 内置 Top 20 弱密码列表(认证测试用)
62
+ WEAK_PASSWORDS = [
63
+ "123456",
64
+ "password",
65
+ "admin",
66
+ "12345678",
67
+ "123456789",
68
+ "1234567890",
69
+ "root",
70
+ "toor",
71
+ "admin123",
72
+ "password123",
73
+ "P@ssw0rd",
74
+ "qwerty",
75
+ "abc123",
76
+ "111111",
77
+ "letmein",
78
+ "welcome",
79
+ "monkey",
80
+ "dragon",
81
+ "master",
82
+ "login",
83
+ ]
84
+
85
+ # 常见默认凭据组合
86
+ DEFAULT_CREDENTIALS = [
87
+ ("admin", "admin"),
88
+ ("admin", "password"),
89
+ ("admin", "admin123"),
90
+ ("admin", "123456"),
91
+ ("root", "root"),
92
+ ("root", "toor"),
93
+ ("root", "password"),
94
+ ("root", "123456"),
95
+ ("test", "test"),
96
+ ("user", "user"),
97
+ ("guest", "guest"),
98
+ ("administrator", "administrator"),
99
+ ("postgres", "postgres"),
100
+ ("mysql", "mysql"),
101
+ ("ftp", "ftp"),
102
+ ]
103
+
104
+ # 输出目录
105
+ DEFAULT_OUTPUT_DIR = Path(".pentest-results")
106
+
107
+ # nuclei 扫描模板标签
108
+ NUCLEI_TAGS = "cve,kev,misconfig,exposure"
109
+ NUCLEI_SEVERITY = "critical,high,medium"
@@ -0,0 +1,157 @@
1
+ """安全命令执行器:shell=False + 命令白名单 + 参数黑名单 + 超时 + 审计日志。"""
2
+
3
+ import json
4
+ import subprocess
5
+ import time
6
+ from dataclasses import asdict, dataclass, field
7
+ from pathlib import Path
8
+
9
+ from .config import ALLOWED_COMMANDS, BLOCKED_ARGS, SCAN_TIMEOUT
10
+
11
+
12
+ @dataclass
13
+ class ExecResult:
14
+ """命令执行结果。"""
15
+
16
+ command: list[str]
17
+ returncode: int
18
+ stdout: str
19
+ stderr: str
20
+ duration: float
21
+ blocked: bool = False
22
+ block_reason: str = ""
23
+
24
+
25
+ @dataclass
26
+ class AuditLog:
27
+ """审计日志管理器。"""
28
+
29
+ log_file: Path
30
+ entries: list[dict] = field(default_factory=list)
31
+
32
+ def __post_init__(self):
33
+ self.log_file.parent.mkdir(parents=True, exist_ok=True)
34
+
35
+ def record(self, result: ExecResult):
36
+ entry = {
37
+ "timestamp": time.strftime("%Y-%m-%d %H:%M:%S"),
38
+ "command": " ".join(result.command),
39
+ "returncode": result.returncode,
40
+ "duration": round(result.duration, 2),
41
+ "blocked": result.blocked,
42
+ "block_reason": result.block_reason,
43
+ }
44
+ self.entries.append(entry)
45
+ with open(self.log_file, "a") as f:
46
+ f.write(json.dumps(entry, ensure_ascii=False) + "\n")
47
+
48
+
49
+ def validate_command(cmd: list[str]) -> tuple[bool, str]:
50
+ """校验命令是否在白名单内、参数是否安全。
51
+
52
+ Returns:
53
+ (is_safe, reason) — is_safe=False 时 reason 说明拒绝原因。
54
+ """
55
+ if not cmd:
56
+ return False, "空命令"
57
+
58
+ binary = Path(cmd[0]).name
59
+ if binary not in ALLOWED_COMMANDS:
60
+ return False, f"命令 '{binary}' 不在白名单中,允许的命令: {', '.join(sorted(ALLOWED_COMMANDS))}"
61
+
62
+ for arg in cmd[1:]:
63
+ normalized = arg.lower().strip()
64
+ for blocked in BLOCKED_ARGS:
65
+ if normalized == blocked or normalized.startswith(f"{blocked}="):
66
+ return False, f"危险参数 '{arg}' 已被安全策略拦截"
67
+
68
+ # sqlmap 额外检查:禁止 stacked queries
69
+ if binary == "sqlmap":
70
+ for i, arg in enumerate(cmd):
71
+ if arg == "--technique" and i + 1 < len(cmd):
72
+ technique = cmd[i + 1].upper()
73
+ if "S" in technique:
74
+ return False, "sqlmap --technique 禁止使用 S(tacked queries)"
75
+ if arg.startswith("--technique="):
76
+ technique = arg.split("=", 1)[1].upper()
77
+ if "S" in technique:
78
+ return False, "sqlmap --technique 禁止使用 S(tacked queries)"
79
+
80
+ return True, ""
81
+
82
+
83
+ def run_command(
84
+ cmd: list[str],
85
+ timeout: int = SCAN_TIMEOUT,
86
+ audit: AuditLog | None = None,
87
+ cwd: str | Path | None = None,
88
+ ) -> ExecResult:
89
+ """安全执行外部命令。
90
+
91
+ - shell=False,参数列表传入
92
+ - 命令白名单 + 参数黑名单校验
93
+ - 强制超时
94
+ - 可选审计日志记录
95
+ """
96
+ is_safe, reason = validate_command(cmd)
97
+ if not is_safe:
98
+ result = ExecResult(
99
+ command=cmd,
100
+ returncode=-1,
101
+ stdout="",
102
+ stderr=reason,
103
+ duration=0.0,
104
+ blocked=True,
105
+ block_reason=reason,
106
+ )
107
+ if audit:
108
+ audit.record(result)
109
+ return result
110
+
111
+ start = time.time()
112
+ try:
113
+ proc = subprocess.run(
114
+ cmd,
115
+ capture_output=True,
116
+ text=True,
117
+ timeout=timeout,
118
+ shell=False,
119
+ cwd=cwd,
120
+ )
121
+ duration = time.time() - start
122
+ result = ExecResult(
123
+ command=cmd,
124
+ returncode=proc.returncode,
125
+ stdout=proc.stdout,
126
+ stderr=proc.stderr,
127
+ duration=duration,
128
+ )
129
+ except subprocess.TimeoutExpired:
130
+ duration = time.time() - start
131
+ result = ExecResult(
132
+ command=cmd,
133
+ returncode=-2,
134
+ stdout="",
135
+ stderr=f"命令超时({timeout}s)",
136
+ duration=duration,
137
+ )
138
+ except FileNotFoundError:
139
+ duration = time.time() - start
140
+ result = ExecResult(
141
+ command=cmd,
142
+ returncode=-3,
143
+ stdout="",
144
+ stderr=f"命令未找到: {cmd[0]}(请先运行 setup_tools.sh 安装)",
145
+ duration=duration,
146
+ )
147
+
148
+ if audit:
149
+ audit.record(result)
150
+ return result
151
+
152
+
153
+ def save_json_result(data: dict, output_path: Path):
154
+ """将扫描结果保存为 JSON。"""
155
+ output_path.parent.mkdir(parents=True, exist_ok=True)
156
+ with open(output_path, "w") as f:
157
+ json.dump(data, f, ensure_ascii=False, indent=2)