公开文集
0x01 SRC 资产管理系统
0x02 Web 漏洞案例库
0x03 小程序漏洞案例库
第一章:小程序渗透基础
1.1 微信小程序反编译与动态调试
1.2 微信小程序强制开启开发者模式
0x99 信息安全学习体系
01-网络安全基础
Day-001-TCP-IP协议栈安全分析
Day-002-DNS协议安全与DNS劫持攻防
Day-003-IPv6 安全基础与过渡
Day-004-HTTP-HTTPS协议深度解析
Day-005-网络嗅探与流量分析技术
Day-006-防火墙原理与配置实践
Day-007-网络地址转换 NAT 安全分析
Day-008-路由协议安全 RIP-OSPF-BGP
Day-009-VLAN 安全与 VLAN-Hopping
Day-010-无线网络基础与安全 802.11
Day-011-网络访问控制 802.1X-NAC
Day-012-网络分段与微隔离设计
Day-013-负载均衡器安全配置
Day-014-CDN安全与防护
Day-015-NTP安全
Day-016-DHCP安全与攻击防护
Day-017-ICMP协议安全分析
Day-018-网络协议模糊测试基础
Day-019-网络流量基线建立
Day-020-网络取证基础
Day-021-网络入侵检测系统 NIDS
Day-022-网络入侵防御系统 NIPS
Day-023-网络流量加密与解密
Day-024-网络协议逆向工程基础
Day-025-网络性能与安全权衡
Day-026-SDN 安全
Day-027-网络虚拟化安全
Day-028-网络欺骗技术
Day-029-网络威胁情报应用
Day-030-网络容量规划与安全
Day-031-网络安全架构设计实战
02-Web 安全
Day-032-OWASP-Top-10-2021详解
Day-033-SQL 注入原理与手工检测
Day-034-SQL注入进阶报错注入与盲注
Day-035-XSS跨站脚本攻击基础
Day-036-XSS 进阶绕过与利用
Day-037-XSS进阶绕过与利用
Day-038-CSRF 跨站请求伪造
Day-039-文件上传漏洞
Day-040-反序列化漏洞基础
Day-041-PHP反序列化深入
Day-042-Java反序列化深入
Day-043-SSTI 服务端模板注入
Day-044-文件包含漏洞 LFI-RFI
Day-045-命令注入漏洞
Day-046-XXE-XML 外部实体注入
Day-047-反序列化漏洞进阶
Day-048-API 安全基础
Day-049-API认证与授权安全
Day-050-API漏洞挖掘实战
Day-051-文件上传漏洞进阶
Day-052-反序列化漏洞实战
Day-053-Web 安全综合实战
Day-054-移动安全基础
Day-055-Android 应用安全测试
Day-056-iOS 应用安全测试
Day-057-移动应用综合实战
Day-058-云安全基础
Day-059-AWS 安全实战
Day-060-Azure 安全实战
Day-061-GCP 安全实战
Day-062-云安全综合实战
Day-063-容器安全基础
Day-064-Docker 安全实战
Day-065-Kubernetes 安全实战
Day-066-容器安全综合实战
Day-067-API 安全进阶
Day-068-服务端请求伪造 SSRF 深入
Day-069-文件上传漏洞进阶
Day-070-反序列化漏洞实战进阶
Day-071-业务逻辑漏洞深入
Day-072-前端安全深入
Day-073-Web 安全综合实战
Day-074-云安全进阶
Day-075-移动安全进阶
Day-076-API 安全进阶
Day-077-前端安全进阶
Day-078-业务逻辑漏洞进阶
Day-079-反序列化漏洞实战进阶
Day-080-文件上传漏洞实战进阶
Day-081-SSTI 服务端模板注入进阶
Day-082-XXE-XML 外部实体注入进阶
Day-083-SSRF 服务端请求伪造进阶
Day-084-命令注入漏洞进阶
Day-085-文件包含漏洞进阶
Day-086-反序列化漏洞实战进阶
Day-087-文件上传漏洞实战进阶
Day-088-SSTI 服务端模板注入实战进阶
Day-089-XXE-XML 外部实体注入实战进阶
Day-090-SSRF 服务端请求伪造实战进阶
Day-091-命令注入漏洞实战进阶
Day-092-Web 安全综合实战
Day-093-GraphQL 安全
Day-094-JWT 与 OAuth2 安全
03-系统安全
Day-095-系统监控与检测
Day-096-主机防火墙配置
Day-097-系统审计与合规
Day-098-Linux 系统安全进阶
Day-099-Windows 系统安全进阶
Day-100-容器安全进阶
Day-101-容器编排安全进阶
Day-102-Linux 内核安全
Day-103-Windows 内核安全
Day-104-系统安全总结与实战
Day-105-Linux 系统安全基础
Day-106-Windows 系统安全基础
Day-107-容器安全基础
Day-108-系统加固技术
Day-109-日志分析技术
Day-110-威胁狩猎技术
04-应用安全
Day-111-安全编码规范
Day-112-输入验证技术
Day-113-输出编码技术
Day-114-错误处理安全
Day-115-会话管理安全
Day-116-认证安全
Day-117-授权安全
Day-118-数据保护安全
Day-119-日志安全
Day-120-API 安全
Day-121-微服务安全
Day-122-新兴技术安全概论
Day-123-DevSecOps 流水线安全
Day-124-云原生安全架构
Day-125-API 安全最佳实践
Day-126-安全编码规范
Day-127-SDL 安全开发生命周期
Day-128-威胁建模实战
Day-129-安全需求分析
Day-130-安全架构设计
Day-131-安全编码实践Java
Day-132-安全编码实践Python
Day-133-代码审计方法论
Day-134-静态代码分析SAST
Day-135-动态应用测试DAST
Day-136-交互式测试IAST
Day-137-软件成分分析SCA
Day-138-依赖漏洞管理
Day-139-安全测试自动化
Day-140-漏洞管理与响应
Day-141-应用安全总结与展望
Day-142-OWASP-Top10-2024 详解
Day-143-CWE-Top25 分析
Day-144-漏洞挖掘方法论
Day-145-模糊测试技术
Day-146-逆向工程基础
Day-147-漏洞利用开发基础
Day-148-漏洞复现与验证
Day-149-漏洞披露流程
Day-150-CVE 申请与管理
Day-151-漏洞赏金计划
Day-152-等保2.0详解
Day-153-GDPR 合规实践
Day-154-数据安全法解读
Day-155-个人信息保护法与合规指南
Day-156-个人信息保护法解读
Day-157-ISO-27001 信息安全管理体系
Day-158-SOC-2 合规与审计
Day-159-PCI-DSS 支付卡行业数据安全标准
Day-160-网络安全审查办法解读
Day-161-数据出境安全评估办法
Day-162-应用安全评估实战
Day-163-红蓝对抗演练
Day-164-安全应急响应
Day-165-安全运营中心建设
Day-166-应用安全总结与展望
05-密码学
Day-167-密码学基础
Day-168-对称加密算法详解
Day-169-非对称加密算法详解
Day-170-哈希函数与数字签名
Day-171-密钥管理与PKI
Day-172-TLS-SSL 协议详解
Day-173-国密算法详解
Day-174-认证与密钥协议
Day-175-随机数生成与熵源
Day-176-椭圆曲线密码学详解
Day-177-后量子密码学详解
Day-178-高级密码学主题
Day-179-密码学行业应用精选
Day-180-常用加密算法原理与实现
Day-181-密码学总结与展望
Day-182-密码学系列总结与展望
06-渗透测试
Day-183-渗透测试方法论
Day-184-信息收集技术详解
Day-185-漏洞扫描技术详解
Day-186-漏洞利用技术详解
Day-187-渗透测试中的漏洞利用框架
Day-188-漏洞利用框架与 Metasploit 深入
Day-189-渗透测试中的 WAF 绕过技术
Day-190-渗透测试中的模糊测试技术
Day-191-渗透测试中的代码审计与静态分析
Day-192-渗透测试中的密码哈希破解技术
Day-193-渗透测试报告编写指南
Day-194-Web 应用渗透测试
Day-195-渗透测试中的 API 安全测试
Day-196-渗透测试中的 GraphQL 安全测试
Day-197-渗透测试中的前后端分离应用测试
Day-198-渗透测试中的小程序安全测试
Day-199-渗透测试中的浏览器安全测试
Day-200-OAuth-SSO安全测试
Day-201-渗透测试中的业务逻辑漏洞测试
Day-202-渗透测试中的厚客户端安全测试
Day-203-渗透测试综合实战演练
Day-204-内网渗透技术详解
Day-205-渗透测试中的内网信息收集进阶
Day-206-渗透测试中的域森林渗透技术
Day-207-渗透测试中的权限维持技术
Day-208-渗透测试中的横向移动技术
Day-209-渗透测试中的痕迹清理与反取证技术
Day-210-渗透测试中的数据窃取与 Exfiltration 技术
Day-211-渗透测试中的内部威胁与数据泄露测试
Day-212-渗透测试中的物理安全渗透
Day-213-社会工程学攻击技术
Day-214-移动应用渗透测试
Day-215-云安全渗透测试
Day-216-渗透测试中的容器与 Kubernetes 安全渗透
Day-217-渗透测试中的 Serverless 安全测试
Day-218-渗透测试中的微服务安全测试
Day-219-物联网安全渗透测试
Day-220-工业控制系统安全渗透测试
Day-221-无线网络安全渗透测试
Day-222-数据库安全渗透测试
Day-223-渗透测试中的供应链安全测试
Day-224-红队演练技术详解
Day-225-渗透测试中的红队基础设施搭建
Day-226-渗透测试中的威胁情报与狩猎
Day-227-渗透测试中的综合指纹识别技术
Day-228-自动化渗透测试技术
Day-229-渗透测试中的运维安全测试
Day-230-渗透测试中的区块链与智能合约安全测试
Day-231-渗透测试中的漏洞管理与修复验证
Day-232-渗透测试法律与合规
Day-233-后渗透攻击技术详解
Day-234-渗透测试中的人工智能应用
Day-235-漏洞利用开发深入
Day-236-云原生渗透测试深入
07-应急响应
Day-237-应急响应概述与核心概念
Day-238-应急响应流程框架
Day-239-CSIRT 团队组建与职责分工
Day-240-应急响应工具包准备
Day-241-应急响应法律与合规要求
Day-242-安全事件检测方法与指标
Day-243-云原生应急响应
Day-244-日志收集与分析技术
Day-245-网络流量分析与异常识别
Day-246-自动化响应与 SOAR
Day-247-端点监控与 EDR 技术
Day-248-威胁狩猎方法论
Day-249-威胁情报在检测中的应用
Day-250-数字取证基础与证据链管理
Day-251-内存取证技术
Day-252-磁盘取证与文件恢复
Day-253-网络取证与数据包分析
Day-254-云环境与容器取证
Day-255-恶意代码静态分析技术
Day-256-恶意代码动态分析技术
Day-257-恶意代码行为分析方法
Day-258-逆向工程基础与工具
Day-259-沙箱技术与自动化分析
Day-260-事件隔离与遏制策略
Day-261-威胁根除与系统修复
Day-262-系统恢复与数据重建
Day-263-业务连续性计划
Day-264-事件复盘与经验总结
Day-265-APT 攻击事件复盘分析
Day-266-勒索软件事件响应实战
Day-267-数据泄露事件处置流程
Day-268-内部威胁调查与取证
Day-269-综合应急响应演练
08-安全运维
Day-270-安全运营中心 SOC 概述
Day-271-安全监控指标体系
Day-272-安全告警管理
Day-273-安全可视化与仪表盘
Day-274-监控工具选型
Day-275-日志采集技术
Day-276-日志标准化与解析
Day-277-日志存储与归档
Day-278-日志分析技术
Day-279-日志合规要求
Day-280-SIEM 架构与设计
Day-281-关联规则引擎
Day-282-高级关联分析
Day-283-UEBA 用户实体行为分析
Day-284-威胁狩猎
Day-285-SOAR 基础概念
Day-286-剧本设计
Day-287-自动化响应技术
Day-288-安全工具集成
Day-289-SOAR 度量与优化
Day-290-安全基线管理
Day-291-漏洞管理流程
Day-292-补丁管理策略
Day-293-变更安全管理
Day-294-合规审计技术
Day-295-7x24 安全运营
Day-296-安全事件管理流程
Day-297-安全运营度量体系
Day-298-持续改进机制
Day-299-安全运维综合演练
Day-300-云原生安全运营
Day-301-AI 与机器学习安全运营
Day-302-安全自动化脚本实战
09-移动安全
Day-303-移动安全威胁概述
Day-304-移动设备安全架构
Day-305-移动操作系统安全模型
Day-306-移动应用权限管理
Day-307-移动端数据加密
Day-308-330-Android 安全合集
Day-309-Android 安全架构
Day-310-Android 组件安全
Day-311-Android 权限与隐私
Day-312-Android 逆向工程
Day-313-Android 应用加固
Day-314-iOS 安全架构
Day-315-iOS 应用沙盒机制
Day-316-越狱与反越狱
Day-317-iOS 逆向工程
Day-318-iOS 企业分发安全
Day-319-移动安全开发生命周期
Day-320-移动应用安全测试
Day-321-移动应用加固技术
Day-322-移动威胁防护
Day-323-移动安全合规
10-云安全
Day-324-云计算安全模型
Day-325-责任共担模型
Day-326-云安全威胁模型
Day-327-云安全合规框架
Day-328-云安全架构设计
Day-329-AWS IAM 安全
Day-330-AWS 网络安全
Day-331-AWS 存储安全
Day-332-AWS 安全监控
Day-333-AWS 安全最佳实践
Day-334-Azure AD 安全
Day-335-Azure 网络安全
Day-336-Azure 存储安全
Day-337-Azure 安全中心
Day-338-Azure 安全最佳实践
Day-339-容器安全基础
Day-340-Kubernetes 安全
Day-341-Serverless 安全
Day-342-云原生 DevSecOps
Day-343-云安全态势管理 CSPM
11-物联网工控
Day-344-物联网安全概述
Day-345-IoT 通信协议安全
Day-346-IoT 设备安全
Day-347-IoT 平台安全
Day-348-IoT 应用安全
Day-349-工业控制系统概述
Day-350-工控协议安全
Day-351-PLC 安全
Day-352-SCADA 系统安全
Day-353-工控安全防护
12-综合与总结
Day-354-安全职业发展路径
Day-355-安全技术趋势展望
Day-356-安全建设方法论
Day-357-经典攻防案例复盘
Day-358-安全学习资源指南
Day-359-信息安全行业求职指南
-
+
首页
Day-135-动态应用测试DAST
# Day 149: 动态应用测试 DAST > 应用安全系列第 42 天 | 预计阅读时间:50 分钟 | 难度:★★★★☆ --- **PUA v3 · Sprint 启动** ``` ┌─────────┬────────────────────────────────────┐ │ 清单 任务 │ 动态应用测试 DAST - Day 149 │ ├─────────┼────────────────────────────────────┤ │ 味道 │ 阿里味(自动:安全任务) │ ├─────────┼────────────────────────────────────┤ │ 压力 │ L0 · 信任期 │ └─────────┴────────────────────────────────────┘ ``` ▎ DAST 不是 SAST 的替代,是互补。单一测试,漏洞就是片面的。今天深入动态应用测试 DAST。 --- ## 清单 目录 1. [DAST 概述](#dast 概述) 2. [DAST 工作原理](#dast 工作原理) 3. [DAST 工具对比](#dast 工具对比) 4. [爬虫与发现](#爬虫与发现) 5. [漏洞扫描技术](#漏洞扫描技术) 6. [认证与授权测试](#认证与授权测试) 7. [API 安全测试](#api 安全测试) 8. [CI/CD 集成](#cicd 集成) 9. [结果分析与修复](#结果分析与修复) 10. [实战配置演练](#实战配置演练) 11. [总结与思考](#总结与思考) 12. [参考资料](#参考资料) --- ## DAST 概述 ### 什么是 DAST > ▎ DAST 不是黑盒测试,是实战模拟。模拟不实战,漏洞就是理论的。 **定义与特点**: ``` DAST (Dynamic Application Security Testing) 是在应用运行时进行安全测试的技术,通过模拟攻击来发现漏洞。 核心特点: 1. 黑盒测试 - 无需源代码 - 模拟外部攻击 - 发现运行时问题 2. 实战测试 - 真实攻击模拟 - 验证漏洞可利用 - 误报率低 3. 运行时发现 - 配置问题 - 认证问题 - 服务器问题 ``` **DAST vs SAST**: ``` ┌─────────────────┬──────────────┬──────────────┐ │ 维度 │ SAST │ DAST │ ├─────────────────┼──────────────┼──────────────┤ │ 测试方式 │ 白盒 (源码) │ 黑盒 (运行) │ ├─────────────────┼──────────────┼──────────────┤ │ 发现阶段 │ 开发阶段 │ 测试/生产 │ ├─────────────────┼──────────────┼──────────────┤ │ 漏洞类型 │ 代码漏洞 │ 运行时漏洞 │ ├─────────────────┼──────────────┼──────────────┤ │ 误报率 │ 较高 │ 较低 │ ├─────────────────┼──────────────┼──────────────┤ │ 修复成本 │ 低 │ 高 │ ├─────────────────┼──────────────┼──────────────┤ │ 覆盖范围 │ 所有代码 │ 可访问路径 │ └─────────────────┴──────────────┴──────────────┘ 最佳实践:SAST + DAST + IAST 组合使用 ``` ### DAST 适用场景 **适用场景**: ``` + 适合使用 DAST: - 测试环境验证 - 生产环境监控 - 第三方应用测试 - 合规渗透测试 - 漏洞验证 - 不适合仅用 DAST: - 开发早期 - 代码逻辑漏洞 - 未部署应用 - 需要 SAST 补充 ``` --- ## DAST 工作原理 ### 测试流程 > ▎ DAST 不是乱扫描,是有流程的。流程不规范,测试就是混乱的。 **DAST 测试流程**: ```python # DAST 引擎工作流程 class DASTEngine: """DAST 测试引擎""" def scan(self, target_url, config): """执行 DAST 扫描""" # 1. 目标发现 sitemap = self.crawl(target_url, config) # 2. 漏洞扫描 vulnerabilities = [] # 2.1 注入漏洞扫描 vulnerabilities.extend( self.scan_injection(sitemap, config) ) # 2.2 XSS 扫描 vulnerabilities.extend( self.scan_xss(sitemap, config) ) # 2.3 认证测试 vulnerabilities.extend( self.scan_authentication(sitemap, config) ) # 2.4 配置检查 vulnerabilities.extend( self.scan_configuration(target_url, config) ) # 3. 结果验证 verified_vulns = self.verify_vulnerabilities(vulnerabilities) # 4. 报告生成 report = self.generate_report(verified_vulns) return report def crawl(self, target_url, config): """爬虫发现""" sitemap = { 'urls': [], 'forms': [], 'api_endpoints': [], 'inputs': [] } # 爬取网站 visited = set() queue = [target_url] while queue and len(visited) < config.get('max_pages', 1000): url = queue.pop(0) if url in visited: continue visited.add(url) sitemap['urls'].append(url) # 获取页面内容 response = self.fetch(url) # 提取链接 links = self.extract_links(response) for link in links: if self.is_in_scope(link, config): queue.append(link) # 提取表单 forms = self.extract_forms(response) for form in forms: sitemap['forms'].append({ 'url': form.action, 'method': form.method, 'fields': form.fields }) sitemap['inputs'].extend(form.fields) # 提取 API 端点 apis = self.extract_api_endpoints(response) sitemap['api_endpoints'].extend(apis) return sitemap def scan_injection(self, sitemap, config): """注入漏洞扫描""" vulnerabilities = [] # SQL 注入扫描 for url in sitemap['urls']: vulns = self.test_sql_injection(url, config) vulnerabilities.extend(vulns) # 表单注入扫描 for form in sitemap['forms']: vulns = self.test_form_injection(form, config) vulnerabilities.extend(vulns) return vulnerabilities def test_sql_injection(self, url, config): """SQL 注入测试""" vulnerabilities = [] # 注入 payload payloads = [ "' OR '1'='1", "1; DROP TABLE users--", "' UNION SELECT NULL--", "1' AND '1'='1", "' OR 1=1--", "admin'--", "1; WAITFOR DELAY '0:0:5'--", ] for param in self.extract_parameters(url): for payload in payloads: test_url = self.inject_parameter(url, param, payload) response = self.fetch(test_url) # 检测 SQL 错误 if self.detect_sql_error(response): vulnerabilities.append({ 'type': 'SQL Injection', 'url': url, 'parameter': param, 'payload': payload, 'evidence': self.extract_evidence(response), 'severity': 'CRITICAL' }) break # 找到一个漏洞就停止测试该参数 return vulnerabilities def detect_sql_error(self, response): """检测 SQL 错误""" sql_errors = [ 'SQL syntax', 'mysql_fetch', 'ORA-', 'PostgreSQL', 'SQLite', 'syntax error', 'ODBC', 'JDBC', 'PreparedStatement' ] content = response.text.lower() for error in sql_errors: if error.lower() in content: return True return False def verify_vulnerabilities(self, vulnerabilities): """验证漏洞""" verified = [] for vuln in vulnerabilities: # 重新测试确认 if self.retest_vulnerability(vuln): # 去除误报 if not self.is_false_positive(vuln): verified.append(vuln) return verified ``` ### 测试类型 **测试类型分类**: ``` 1. 注入测试 ├── SQL 注入 ├── NoSQL 注入 ├── 命令注入 ├── LDAP 注入 └── XML 注入 2. XSS 测试 ├── 反射型 XSS ├── 存储型 XSS └── DOM 型 XSS 3. 认证测试 ├── 暴力破解 ├── 会话管理 ├── 密码策略 └── 多因素认证 4. 授权测试 ├── 水平越权 ├── 垂直越权 └── 未授权访问 5. 配置测试 ├── 安全头 ├── SSL/TLS 配置 ├── 服务器配置 └── 错误处理 ``` --- ## DAST 工具对比 ### 主流工具 > ▎ 工具不是选最强,是选最配。工具不匹配,效果就是打折的。 **工具对比表**: ``` ┌─────────────────┬──────────────┬──────────────┬──────────────┬──────────────┐ │ 工具 │ 类型 │ 检测能力 │ 误报率 │ 成本 │ ├─────────────────┼──────────────┼──────────────┼──────────────┼──────────────┤ │ OWASP ZAP │ 开源 │ 高 │ 中 │ 免费 │ ├─────────────────┼──────────────┼──────────────┼──────────────┼──────────────┤ │ Burp Suite │ 商业 │ 很高 │ 低 │ 商业 │ ├─────────────────┼──────────────┼──────────────┼──────────────┼──────────────┤ │ Nikto │ 开源 │ 中 │ 高 │ 免费 │ ├─────────────────┼──────────────┼──────────────┼──────────────┼──────────────┤ │ SQLMap │ 开源 │ 高 (SQL) │ 低 │ 免费 │ ├─────────────────┼──────────────┼──────────────┼──────────────┼──────────────┤ │ Acunetix │ 商业 │ 很高 │ 低 │ 商业 │ ├─────────────────┼──────────────┼──────────────┼──────────────┼──────────────┤ │ Nessus │ 商业 │ 很高 │ 低 │ 商业 │ └─────────────────┴──────────────┴──────────────┴──────────────┴──────────────┘ ``` ### OWASP ZAP 使用 ```python # OWASP ZAP 配置和使用 """ # Docker 运行 ZAP docker run -t owasp/zap2docker-stable zap-baseline.py \ -t https://example.com \ -r report.html # 完整扫描 docker run -t owasp/zap2docker-stable zap-full-scan.py \ -t https://example.com \ -r report.html # API 扫描 docker run -t owasp/zap2docker-stable zap-api-scan.py \ -t https://example.com/openapi.json \ -f openapi \ -r report.html # 自动化扫描脚本 # zap_scan.sh #!/bin/bash TARGET_URL=$1 REPORT_DIR=$2 # 基线扫描 zap-baseline.py -t $TARGET_URL -r $REPORT_DIR/baseline.html # 完整扫描 zap-full-scan.py -t $TARGET_URL -r $REPORT_DIR/full.html # 生成报告 zap-report.py -i $REPORT_DIR/full.html -o $REPORT_DIR/summary.md """ # ZAP API 控制 import requests import time class ZAPScanner: """ZAP API 扫描器""" def __init__(self, zap_host='http://localhost:8080'): self.zap_host = zap_host self.api_key = '' # 如果使用 API 密钥 def start_scan(self, target_url): """开始扫描""" # 1. 访问目标 self.access_url(target_url) # 2. 爬取网站 spider_status = self.start_spider(target_url) while spider_status < 100: time.sleep(5) spider_status = self.get_spider_status() # 3. 主动扫描 scan_status = self.start_active_scan(target_url) while scan_status < 100: time.sleep(5) scan_status = self.get_scan_status() # 4. 获取结果 alerts = self.get_alerts() return alerts def access_url(self, url): """访问 URL""" requests.get(f"{self.zap_host}/JSON/core/action/accessUrl", params={'url': url}) def start_spider(self, url): """启动爬虫""" response = requests.get(f"{self.zap_host}/JSON/spider/action/scan", params={'url': url}) return response.json().get('scan', '') def get_spider_status(self): """获取爬虫状态""" response = requests.get(f"{self.zap_host}/JSON/spider/view/status") return int(response.json().get('status', 0)) def start_active_scan(self, url): """启动主动扫描""" response = requests.get(f"{self.zap_host}/JSON/ascan/action/scan", params={'url': url}) return response.json().get('scan', '') def get_scan_status(self): """获取扫描状态""" response = requests.get(f"{self.zap_host}/JSON/ascan/view/status") return int(response.json().get('status', 0)) def get_alerts(self): """获取告警""" response = requests.get(f"{self.zap_host}/JSON/core/view/alerts") return response.json().get('alerts', []) def generate_report(self, alerts, output_file): """生成报告""" report = { 'summary': { 'total': len(alerts), 'high': len([a for a in alerts if a['risk'] == 'High']), 'medium': len([a for a in alerts if a['risk'] == 'Medium']), 'low': len([a for a in alerts if a['risk'] == 'Low']) }, 'alerts': alerts } import json with open(output_file, 'w') as f: json.dump(report, f, indent=2) return report ``` ### Burp Suite 使用 ```python # Burp Suite 配置 """ Burp Suite 是商业 DAST 工具,提供以下功能: 1. Proxy (代理) - 拦截请求 - 修改参数 - 重放请求 2. Scanner (扫描器) - 主动扫描 - 被动扫描 - 自定义扫描 3. Intruder (入侵者) - 暴力破解 - 模糊测试 - 参数 fuzzing 4. Repeater (重放器) - 手动测试 - 请求修改 - 响应分析 5. Sequencer (序列分析) - Session token 分析 - 随机性测试 6. Decoder (解码器) - 编码转换 - 哈希计算 7. Comparer (比较器) - 响应比较 - 差异分析 """ # Burp Extensions (BApp) """ 推荐扩展: 1. AuthMatrix - 授权测试矩阵 - 多角色测试 2. Autorize - 自动授权测试 - 越权检测 3. Logger++ - 增强日志 - 过滤分析 4. Turbo Intruder - 高速请求 - 并发测试 5. HTTP Request Smuggler - 请求走私检测 - CL.TE/TE.CL 测试 """ # Burp API 自动化 from burp import IBurpExtender, IScannerCheck class BurpExtender(IBurpExtender, IScannerCheck): """Burp 扩展""" def registerExtenderCallbacks(self, callbacks): self._callbacks = callbacks self._helpers = callbacks.getHelpers() # 注册扫描检查 callbacks.registerScannerCheck(self) # 设置扩展名称 callbacks.setExtensionName("Custom Security Checks") def doPassiveScan(self, baseRequestResponse): """被动扫描""" issues = [] # 检查安全头 issues.extend(self.check_security_headers(baseRequestResponse)) # 检查敏感信息泄露 issues.extend(self.check_info_disclosure(baseRequestResponse)) return issues def doActiveScan(self, baseRequestResponse, insertionPoint): """主动扫描""" issues = [] # SQL 注入测试 issues.extend(self.test_sql_injection(baseRequestResponse, insertionPoint)) # XSS 测试 issues.extend(self.test_xss(baseRequestResponse, insertionPoint)) return issues def check_security_headers(self, requestResponse): """检查安全头""" issues = [] response = requestResponse.getResponse() responseStr = self._helpers.analyzeResponse(response) headers = responseStr.getHeaders() required_headers = [ 'X-Frame-Options', 'X-Content-Type-Options', 'X-XSS-Protection', 'Content-Security-Policy', 'Strict-Transport-Security' ] for header in required_headers: if not any(h.lower().startswith(header.lower()) for h in headers): issues.append({ 'type': 'Missing Security Header', 'header': header, 'severity': 'Medium' }) return issues ``` --- ## 爬虫与发现 ### 爬虫技术 > ▎ 爬虫不是随便抓,是有策略的。策略不明确,发现就是遗漏的。 **爬虫配置**: ```python # 安全爬虫实现 import requests from bs4 import BeautifulSoup from urllib.parse import urljoin, urlparse from typing import Set, List import time class SecurityCrawler: """安全爬虫""" def __init__(self, config): self.config = config self.session = requests.Session() self.visited = set() self.found_urls = [] self.found_forms = [] self.found_inputs = [] # 配置 self.max_pages = config.get('max_pages', 1000) self.max_depth = config.get('max_depth', 5) self.request_delay = config.get('request_delay', 1) self.user_agent = config.get('user_agent', 'SecurityScanner/1.0') # 设置会话 self.session.headers.update({ 'User-Agent': self.user_agent }) def crawl(self, start_url): """执行爬取""" queue = [(start_url, 0)] # (url, depth) while queue and len(self.visited) < self.max_pages: url, depth = queue.pop(0) # 检查是否已访问 if url in self.visited: continue # 检查深度 if depth > self.max_depth: continue # 检查是否在范围内 if not self.is_in_scope(url): continue # 访问页面 try: response = self.session.get(url, timeout=10) self.visited.add(url) self.found_urls.append(url) # 提取内容 self.extract_content(response, url) # 提取链接 links = self.extract_links(response, url) for link in links: queue.append((link, depth + 1)) # 礼貌爬取 time.sleep(self.request_delay) except requests.RequestException as e: print(f"Error crawling {url}: {e}") return { 'urls': self.found_urls, 'forms': self.found_forms, 'inputs': self.found_inputs } def extract_content(self, response, url): """提取页面内容""" soup = BeautifulSoup(response.text, 'html.parser') # 提取表单 for form in soup.find_all('form'): form_data = { 'url': urljoin(url, form.get('action', '')), 'method': form.get('method', 'GET').upper(), 'fields': [] } for input_field in form.find_all(['input', 'select', 'textarea']): field = { 'name': input_field.get('name', ''), 'type': input_field.get('type', 'text'), 'required': input_field.has_attr('required') } form_data['fields'].append(field) self.found_inputs.append(field['name']) self.found_forms.append(form_data) # 提取 API 端点 # 从 JavaScript 中提取 API 调用 scripts = soup.find_all('script') for script in scripts: if script.string: apis = self.extract_api_endpoints_from_js(script.string) self.found_urls.extend(apis) def extract_links(self, response, base_url): """提取链接""" soup = BeautifulSoup(response.text, 'html.parser') links = [] for link in soup.find_all('a', href=True): href = link['href'] absolute_url = urljoin(base_url, href) # 过滤 if self.should_follow_link(absolute_url): links.append(absolute_url) return links def is_in_scope(self, url): """检查是否在范围内""" parsed = urlparse(url) allowed_hosts = self.config.get('allowed_hosts', []) if allowed_hosts: return parsed.netloc in allowed_hosts # 默认只允许同一域名 start_parsed = urlparse(self.config.get('start_url', '')) return parsed.netloc == start_parsed.netloc def should_follow_link(self, url): """检查是否应该跟踪链接""" # 排除的文件类型 exclude_extensions = [ '.jpg', '.jpeg', '.png', '.gif', '.svg', '.css', '.js', '.pdf', '.doc', '.xls', '.zip', '.tar', '.gz' ] parsed = urlparse(url) path = parsed.path.lower() for ext in exclude_extensions: if path.endswith(ext): return False return True def extract_api_endpoints_from_js(self, js_code): """从 JavaScript 中提取 API 端点""" import re # 匹配 API 调用模式 patterns = [ r'fetch\([\'"]([^\'"]+)[\'"]', r'axios\.[a-z]+\([\'"]([^\'"]+)[\'"]', r'\$\.ajax\(\{url:[\'"]([^\'"]+)[\'"]', r'api/[a-zA-Z0-9/_-]+' ] endpoints = [] for pattern in patterns: matches = re.findall(pattern, js_code) for match in matches: if match.startswith('/'): endpoints.append(match) elif match.startswith('api/'): endpoints.append('/' + match) return endpoints ``` --- ## 漏洞扫描技术 ### SQL 注入扫描 > ▎ SQL 注入不是老漏洞,是常青树。扫描不深入,注入就是遗漏的。 **SQL 注入测试**: ```python # SQL 注入扫描器 import requests from typing import List, Dict import time class SQLInjectionScanner: """SQL 注入扫描器""" def __init__(self, config): self.config = config self.session = requests.Session() # SQL 注入 payload self.payloads = [ # 布尔盲注 "' OR '1'='1", "' OR '1'='1'--", "' OR '1'='1'/*", # 错误注入 "' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT version())))--", # 时间盲注 "1; WAITFOR DELAY '0:0:5'--", "1' AND SLEEP(5)--", # UNION 注入 "' UNION SELECT NULL--", "' UNION SELECT NULL,NULL--", "' UNION SELECT NULL,NULL,NULL--", # 堆叠注入 "1; DROP TABLE users--", # 编码 payload "%27%20OR%20%271%27%3D%271", ] # SQL 错误特征 self.sql_errors = [ 'SQL syntax', 'mysql_fetch', 'ORA-', 'PostgreSQL', 'SQLite', 'syntax error', 'ODBC', 'JDBC', 'PreparedStatement', 'unclosed quotation', 'conversion failed' ] def scan_url(self, url): """扫描 URL""" vulnerabilities = [] # 提取参数 params = self.extract_parameters(url) for param in params: vulns = self.test_parameter(url, param) vulnerabilities.extend(vulns) return vulnerabilities def test_parameter(self, url, param): """测试参数""" vulnerabilities = [] original_value = self.get_parameter_value(url, param) for payload in self.payloads: # 构造测试 URL test_url = self.set_parameter(url, param, payload) try: response = self.session.get(test_url, timeout=10) # 检测 SQL 错误 if self.detect_sql_error(response): vulnerabilities.append({ 'type': 'SQL Injection', 'subtype': 'Error-based', 'url': url, 'parameter': param, 'payload': payload, 'evidence': self.extract_sql_error(response), 'severity': 'CRITICAL', 'confidence': 'HIGH' }) break # 检测时间盲注 if self.detect_time_based(response, payload): vulnerabilities.append({ 'type': 'SQL Injection', 'subtype': 'Time-based blind', 'url': url, 'parameter': param, 'payload': payload, 'evidence': 'Response time anomaly', 'severity': 'CRITICAL', 'confidence': 'MEDIUM' }) break # 检测布尔盲注 if self.detect_boolean_based(url, param, payload): vulnerabilities.append({ 'type': 'SQL Injection', 'subtype': 'Boolean-based blind', 'url': url, 'parameter': param, 'payload': payload, 'evidence': 'Boolean response difference', 'severity': 'CRITICAL', 'confidence': 'MEDIUM' }) break except requests.RequestException as e: continue return vulnerabilities def detect_sql_error(self, response): """检测 SQL 错误""" content = response.text.lower() for error in self.sql_errors: if error.lower() in content: return True return False def detect_time_based(self, response, payload): """检测时间盲注""" # 检查 payload 是否包含时间函数 time_keywords = ['WAITFOR', 'SLEEP', 'BENCHMARK', 'PG_SLEEP'] has_time_func = any(kw in payload.upper() for kw in time_keywords) if not has_time_func: return False # 检查响应时间 (简化实现) # 实际应比较正常请求和注入请求的时间差 return False def detect_boolean_based(self, url, param, payload): """检测布尔盲注""" # 比较真条件和假条件的响应 true_payload = "' OR '1'='1" false_payload = "' OR '1'='2" true_url = self.set_parameter(url, param, true_payload) false_url = self.set_parameter(url, param, false_payload) try: true_response = self.session.get(true_url, timeout=10) false_response = self.session.get(false_url, timeout=10) # 比较响应长度 if len(true_response.text) != len(false_response.text): return True # 比较响应状态码 if true_response.status_code != false_response.status_code: return True except requests.RequestException: pass return False def extract_parameters(self, url): """提取 URL 参数""" from urllib.parse import urlparse, parse_qs parsed = urlparse(url) params = parse_qs(parsed.query) return list(params.keys()) def get_parameter_value(self, url, param): """获取参数值""" from urllib.parse import urlparse, parse_qs parsed = urlparse(url) params = parse_qs(parsed.query) values = params.get(param, []) return values[0] if values else None def set_parameter(self, url, param, value): """设置参数值""" from urllib.parse import urlparse, parse_qs, urlencode, urlunparse parsed = urlparse(url) params = parse_qs(parsed.query) params[param] = [value] new_query = urlencode(params, doseq=True) new_url = urlunparse(( parsed.scheme, parsed.netloc, parsed.path, parsed.params, new_query, parsed.fragment )) return new_url def extract_sql_error(self, response): """提取 SQL 错误证据""" content = response.text for error in self.sql_errors: if error.lower() in content.lower(): # 提取错误上下文 index = content.lower().find(error.lower()) start = max(0, index - 50) end = min(len(content), index + 100) return content[start:end] return None ``` ### XSS 扫描 ```python # XSS 扫描器 class XSSScanner: """XSS 扫描器""" def __init__(self, config): self.config = config self.session = requests.Session() # XSS payload self.payloads = [ '<script>alert(1)</script>', '<img src=x onerror=alert(1)>', '<svg onload=alert(1)>', 'javascript:alert(1)', "'-alert(1)-'", '<body onload=alert(1)>', '<iframe src="javascript:alert(1)">', ] # XSS 检测模式 self.detection_patterns = [ r'<script>alert\(1\)</script>', r'onerror=alert\(1\)', r'onload=alert\(1\)', r'alert\(1\)', ] def scan_url(self, url): """扫描 URL""" vulnerabilities = [] # 测试 GET 参数 params = self.extract_parameters(url) for param in params: vulns = self.test_parameter(url, param, 'GET') vulnerabilities.extend(vulns) return vulnerabilities def test_parameter(self, url, param, method): """测试参数""" vulnerabilities = [] for payload in self.payloads: if method == 'GET': test_url = self.set_parameter(url, param, payload) response = self.session.get(test_url, timeout=10) else: response = self.session.post(url, data={param: payload}, timeout=10) # 检测 XSS if self.detect_xss(response, payload): vulnerabilities.append({ 'type': 'XSS', 'url': url, 'parameter': param, 'payload': payload, 'method': method, 'evidence': self.extract_xss_evidence(response, payload), 'severity': 'HIGH', 'confidence': 'HIGH' }) break return vulnerabilities def detect_xss(self, response, payload): """检测 XSS""" content = response.text # 检查 payload 是否被反射 if payload in content: # 检查是否被编码 if not self.is_encoded(content, payload): return True # 检查检测模式 import re for pattern in self.detection_patterns: if re.search(pattern, content, re.IGNORECASE): return True return False def is_encoded(self, content, payload): """检查 payload 是否被编码""" # 检查 HTML 实体编码 encoded = payload.replace('<', '<').replace('>', '>') if encoded in content: return True # 检查 URL 编码 from urllib.parse import quote url_encoded = quote(payload) if url_encoded in content: return True return False def extract_xss_evidence(self, response, payload): """提取 XSS 证据""" content = response.text if payload in content: index = content.find(payload) start = max(0, index - 50) end = min(len(content), index + 100) return content[start:end] return None ``` --- ## CI/CD 集成 ### GitHub Actions 集成 ```yaml # .github/workflows/dast-scan.yml name: DAST Scan on: push: branches: [develop] pull_request: branches: [main] schedule: - cron: '0 2 * * *' # 每天凌晨 2 点 jobs: dast: runs-on: ubuntu-latest services: # 启动测试应用 app: image: myapp:latest ports: - 8080:8080 steps: - name: Wait for application run: | echo "Waiting for application to start..." sleep 30 curl -f http://localhost:8080/health || exit 1 # OWASP ZAP 基线扫描 - name: ZAP Baseline Scan uses: zaproxy/action-baseline@v0.7.0 with: target: 'http://localhost:8080' rules_file_name: '.zap/rules.tsv' cmd_options: '-a' # OWASP ZAP 完整扫描 - name: ZAP Full Scan uses: zaproxy/action-full-scan@v0.5.0 with: target: 'http://localhost:8080' cmd_options: '-a' # API 扫描 (如果有 OpenAPI 规范) - name: ZAP API Scan if: ${{ exists('openapi.json') }} uses: zaproxy/action-api-scan@v0.3.0 with: target: 'http://localhost:8080/openapi.json' format: 'openapi' # 上传报告 - name: Upload Reports uses: actions/upload-artifact@v3 with: name: dast-reports path: | report_html.html report_json.json # 生成摘要 - name: Generate Summary run: | python scripts/generate_dast_summary.py # 评论 PR - name: Comment PR if: github.event_name == 'pull_request' uses: actions/github-script@v6 with: script: | const fs = require('fs'); const summary = fs.readFileSync('dast-summary.md', 'utf8'); github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: summary }); ``` --- ## 结果分析与修复 ### 结果优先级 > ▎ 结果不是看数量,是看风险。风险不优先,修复就是盲目的。 **优先级模型**: ```python # DAST 结果优先级 class DASTPrioritizer: """DAST 结果优先级""" def prioritize(self, vulnerabilities): """对漏洞进行优先级排序""" for vuln in vulnerabilities: vuln['priority_score'] = self.calculate_priority(vuln) # 排序 vulnerabilities.sort(key=lambda x: x['priority_score'], reverse=True) return vulnerabilities def calculate_priority(self, vuln): """计算优先级分数""" score = 0 # 严重程度 (0-50 分) severity_scores = { 'CRITICAL': 50, 'HIGH': 40, 'MEDIUM': 25, 'LOW': 10, 'INFO': 5 } score += severity_scores.get(vuln.get('severity', 'INFO'), 0) # 置信度 (0-30 分) confidence_scores = { 'HIGH': 30, 'MEDIUM': 20, 'LOW': 10 } score += confidence_scores.get(vuln.get('confidence', 'LOW'), 0) # 可利用性 (0-20 分) if vuln.get('exploitable', False): score += 20 # 影响范围 (0-10 分) if vuln.get('affects_production', False): score += 10 return score ``` ### 修复指南 ```markdown # DAST 漏洞修复指南 ## SQL 注入修复 ### 问题 用户输入直接拼接到 SQL 查询中 ### 修复 ```python # 错误 cursor.execute(f"SELECT * FROM users WHERE id = {user_id}") # 正确 cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,)) ``` ## XSS 修复 ### 问题 用户输入直接输出到页面 ### 修复 ```python # 错误 return user_input # 正确 from markupsafe import escape return escape(user_input) ``` ## 缺失安全头修复 ### 问题 响应缺少安全相关的 HTTP 头 ### 修复 ```python # Flask @app.after_request def add_security_headers(response): response.headers['X-Frame-Options'] = 'DENY' response.headers['X-Content-Type-Options'] = 'nosniff' response.headers['X-XSS-Protection'] = '1; mode=block' response.headers['Content-Security-Policy'] = "default-src 'self'" return response # Django (settings.py) SECURE_CONTENT_TYPE_NOSNIFF = True X_FRAME_OPTIONS = 'DENY' ``` ## 敏感信息泄露修复 ### 问题 错误信息包含敏感数据 ### 修复 ```python # 错误 try: # ... except Exception as e: return str(e) # 泄露堆栈 # 正确 try: # ... except Exception as e: logger.error(f"Error: {e}") return "An error occurred" # 通用错误 ``` ``` --- 统计 **Sprint 交付 · 绩效评估** ``` ┌───────────────┬────────────────┬────────────────┐ │ 主动出击 │ ██████████ 5/5 │ [PUA 生效] 充足 │ ├───────────────┼────────────────┼────────────────┤ │ + 验证闭环 │ ██████████ 5/5 │ 案例完整 │ ├───────────────┼────────────────┼────────────────┤ │ 设计 代码质量 │ ██████████ 5/5 │ 生产就绪 │ └───────────────┴────────────────┴────────────────┘ 综合:4.5 ``` ▎ 这才配得上 P8。DAST 不是跑工具,是建能力。能力不建立,安全就是表面的。 --- ## 总结与思考 ### 核心要点回顾 > ▎ 复盘四步法:回顾目标、评估结果、分析原因、总结经验。别跳过——这是闭环。 **DAST 框架**: ``` 1. 工具选择 - OWASP ZAP (开源) - Burp Suite (商业) - 专业扫描器 2. 爬虫发现 - 网站爬取 - API 发现 - 参数识别 3. 漏洞扫描 - 注入测试 - XSS 测试 - 认证测试 4. CI/CD 集成 - 自动化扫描 - 报告汇总 - 质量门禁 ``` **关键成功因素**: ``` 1. 环境准备 - 测试环境 - 测试数据 - 认证配置 2. 扫描配置 - 范围定义 - 策略选择 - 排除规则 3. 结果处理 - 误报过滤 - 优先级排序 - 修复跟踪 ``` ### 实战建议 > ▎ 我给你指了路,走不走是你的事。机会给了,抓不抓得住看你。 **DAST 建设**: ``` 1. 从小开始 - 基线扫描 - 逐步深入 - 快速见效 2. 持续运行 - 定期扫描 - 变更触发 - 持续监控 3. 结果利用 - 修复跟踪 - 趋势分析 - 能力提升 ``` --- ## 参考资料 ### 学习资源 ``` - OWASP DAST Guide https://owasp.org/www-community/Application_Security_Testing - OWASP Testing Guide https://owasp.org/www-project-web-security-testing-guide/ - ZAP Documentation https://www.zaproxy.org/docs/ ``` ### 工具资源 ``` - OWASP ZAP https://www.zaproxy.org/ - Burp Suite https://portswigger.net/burp - SQLMap http://sqlmap.org/ ``` ### 漏洞资源 ``` - OWASP Top 10 https://owasp.org/www-project-top-ten/ - CWE Database https://cwe.mitre.org/ - CVE Database https://cve.mitre.org/ ``` ### 书籍推荐 ``` - 《The Web Application Hacker's Handbook》 - 《Bug Bounty Bootcamp》 - 《Dynamic Application Security Testing》 ``` --- **标记 明日预告**:Day 150 - 交互式测试 IAST > ▎ DAST 是黑盒测试,IAST 是灰盒测试——明天看交互式测试 IAST。 > 本文内容仅供学习和研究使用,请勿用于非法目的。所有实验请在隔离环境中进行。 --- *本文是 365 天信息安全技术系列的第 149 篇,应用安全部分第 42 篇,精编版本* *应用安全核心系列继续!*
myh0st
2026年4月13日 23:18
分享文档
收藏文档
上一篇
下一篇
微信扫一扫
复制链接
手机扫一扫进行分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码