很多人做渗透测试,就是东一榔头西一棒子,看到什么测什么。这样效率低,还容易漏掉重要的问题。这一节课,我们分享一下渗透测试的方法论,这是很多人的实际项目中总结出来的,能帮你系统性地进行测试,提高效率和覆盖率。
一个完整的渗透测试,通常会遵循这个流程:
这个流程不是线性的,而是循环的。发现一个漏洞后,可能能发现更多漏洞;一个攻击路径走不通,就换另一个。
1. 前期准备
这个阶段很多人会忽略,但其实很重要。包括明确测试范围和目标,要知道测试什么,要达到什么目的。获取测试授权,这是必须的,没有授权就是违法的。了解业务背景,知道这个系统是做什么的,业务流程是什么,这样才能更好地测试。准备测试环境,包括工具、代理、VPN等,确保测试能顺利进行。
在实际项目中,测试员会先和客户开个会,明确测试哪些系统,测试时间窗口是什么,可以用哪些测试方法,不能做什么操作,有没有测试账号。这些都要事先说清楚,避免后续出现问题。
2. 信息收集
信息收集是渗透测试的基础。收集的信息越多,攻击面越大。包括域名、子域名,了解目标的网络结构。IP地址、端口,了解系统暴露的攻击面。技术栈,知道用的什么框架、什么数据库,可以针对性查找漏洞。员工信息,可能用于社会工程学攻击。历史漏洞,看看这个系统以前出过什么问题,可能还有类似的问题。
3. 攻击面分析
基于收集的信息,分析哪些地方可能有问题。包括功能点分析,看看哪些功能可能有漏洞。技术栈漏洞,如果用的框架有已知漏洞,可以针对性测试。业务流程分析,看看业务流程是否有逻辑漏洞。架构分析,看看系统架构是否有设计问题。
4. 漏洞发现
通过各种手段发现漏洞。可以使用自动化扫描,快速发现一些明显的漏洞。但更重要的是手工测试,通过手工测试能发现很多工具发现不了的问题。如果有源码,还可以进行代码审计,直接从代码层面找问题。
5. 漏洞验证
发现漏洞后,要验证是否真实存在,不是误报。很多自动化工具会误报,需要人工验证。
6. 漏洞利用
如果授权允许,可以尝试利用漏洞,证明危害。这样可以更清楚地说明漏洞的影响。
7. 权限维持
如果目标是长期控制,想办法维持访问。比如创建隐藏账号、留后门等。
8. 报告撰写
把发现的问题整理成报告,提供修复建议。报告要详细,包括漏洞原理、影响、修复方案等。

让我们用一个案例,给你展示这个流程:
项目背景:一个在线教育平台,包含用户系统、课程系统、支付系统。
阶段1:前期准备
和客户明确测试主站和API,不包括支付系统,因为涉及真实交易,不能测试。获取测试账号,包括普通用户账号、教师账号,这样可以测试不同权限的功能。测试时间是2周,时间比较充足。
阶段2:信息收集
发现域名是edu.example.com,通过子域名枚举发现了api.edu.example.com、admin.edu.example.com、cdn.edu.example.com等多个子域名。技术栈是前端React,后端PHP,数据库MySQL。还发现GitHub上有部分源码泄露,这是一个重要的发现。
阶段3:攻击面分析
主站有用户注册、登录、课程浏览、购买等功能,这些功能点都可能有问题。API是RESTful API,可能有认证问题,需要测试。管理后台可能有未授权访问,如果找到漏洞,可以直接控制。GitHub泄露可能有敏感信息,需要仔细分析。
阶段4:漏洞发现
在GitHub泄露的代码中,发现数据库密码,这是一个严重的信息泄露。API接口发现未授权访问,可以直接获取用户信息。登录功能发现SQL注入,可以获取管理员密码。
阶段5:漏洞验证
用泄露的数据库密码,成功连接数据库,验证了信息泄露漏洞。未授权访问API,成功获取用户信息,验证了未授权访问漏洞。SQL注入成功执行,获取管理员密码,验证了SQL注入漏洞。
阶段6:漏洞利用
用管理员密码登录后台,成功进入管理后台。在后台发现文件上传功能,上传Webshell,成功上传。通过Webshell控制服务器,获得了服务器的控制权。
阶段7:权限维持
创建隐藏的管理员账号,这样即使原来的账号被删除,还能继续访问。在服务器上留后门,在授权范围内,方便后续测试。
阶段8:报告撰写
整理所有漏洞,包括信息泄露、未授权访问、SQL注入、文件上传等。评估风险等级,根据漏洞的影响和利用难度,评估风险。提供修复建议,包括漏洞原理、影响、修复方案等。
信息收集是渗透测试的第一步,也是最关键的一步。收集的信息越多,攻击面越大,发现漏洞的概率越高。
很多漏洞其实都是通过信息收集发现的,而不是直接测试出来的。比如通过子域名枚举,发现测试环境,测试环境通常防护较弱,可能更容易找到漏洞。 通过GitHub搜索,发现泄露的源码和配置文件,这些泄露的信息可能包含敏感信息,比如数据库密码、API密钥等。通过员工社交媒体,发现技术栈信息,用于针对性攻击,如果知道用的什么技术,可以针对性查找漏洞。
子域名枚举是信息收集的基础。一个主域名下,可能有多个子域名,每个子域名都是一个潜在的攻击面。
方法1:DNS枚举
|# 使用subfinder subfinder -d example.com # 使用amass amass enum -d example.com # 使用sublist3r sublist3r -d example.com
方法2:证书透明度日志
证书透明度(Certificate Transparency)日志记录了所有SSL证书的颁发记录,可以用来发现子域名:
|# 使用crt.sh curl -s "https://crt.sh/?q=%.example.com&output=json" | jq -r '.[].name_value' | sort -u
方法3:搜索引擎
在搜索引擎中搜索,比如site:*.example.com可以搜索所有子域名,-site:www.example.com site:example.com可以搜索除了www之外的所有子域名。这些搜索技巧可以帮助发现隐藏的子域名。
方法4:DNS暴力破解
如果其他方法找不到,可以尝试暴力破解常见的子域名:
|# 使用gobuster gobuster dns -d example.com -w subdomains.txt
案例:
假设在测试一个系统时,通过子域名枚举发现了admin.example.com,这很明显是管理后台,防护较弱,可能更容易找到漏洞。发现了test.example.com,这是测试环境,完全没有防护,可以直接测试。发现了api.example.com,这是API接口,可能有未授权访问,需要测试。发现了old.example.com,这是旧版本系统,有已知漏洞,同样可以直接利用。
发现子域名后,要扫描目录和文件,发现隐藏的功能和文件。
工具:
|# 使用dirsearch dirsearch -u https://example.com -e php,html,js # 使用gobuster gobuster dir -u https://example.com -w wordlist.txt # 使用ffuf ffuf -w wordlist.txt -u https://example.com/FUZZ
扫描目标:
常见目录,包括/admin、/administrator、/wp-admin,/api、/api/v1、/api/v2,/backup、/backups,/test、/testing,/dev、/development等。
常见文件,包括robots.txt、sitemap.xml,.git、.svn、.env,config.php、config.json,backup.sql、dump.sql,phpinfo.php、test.php等。
识别目标使用的技术栈,可以查找已知漏洞,如果用的框架有已知漏洞,可以针对性利用。可以针对性测试,知道用的什么技术,就可以测试这种技术常见的漏洞。可以选择合适的工具,不同的技术栈需要不同的工具。
识别方法:
HTTP响应头,从响应头可以看出服务器类型和版本,比如Server: nginx/1.18.0说明用的是nginx,X-Powered-By: PHP/7.4.3说明后端是PHP。
文件扩展名,从URL的文件扩展名可以看出后端语言,比如.php表示PHP,.aspx表示ASP.NET,.jsp表示Java,.do表示Struts框架。
默认文件,很多系统有默认文件,比如phpinfo.php表示PHP,web.config表示ASP.NET,WEB-INF表示Java。
JavaScript框架,看前端代码,可以看出用的什么前端框架,比如React、Vue、Angular等。
工具识别,可以使用工具自动识别,比如Wappalyzer浏览器插件,或者whatweb命令行工具。
敏感信息泄露是信息收集的重要部分。泄露的信息可能包括源码,如果源码泄露,可以直接看代码找漏洞。配置文件可能包含数据库密码、API密钥等敏感信息。日志文件可能包含敏感信息,比如用户操作记录。备份文件可能包含数据库备份、源码备份等。
泄露来源:
GitHub/GitLab,在代码仓库中搜索,比如搜索example.com password可能找到密码,搜索example.com api_key可能找到API密钥,搜索example.com database可能找到数据库配置。
搜索引擎,使用搜索引擎搜索,比如site:github.com example.com可以搜索GitHub上的相关内容,filetype:env example.com可以搜索环境配置文件,filetype:sql example.com可以搜索SQL文件。
公开的代码仓库,GitHub、GitLab、Bitbucket等公开的代码仓库,可能包含测试代码、配置文件,这些都可能泄露敏感信息。
错误页面,错误页面可能泄露路径、技术栈、错误信息,这些信息对攻击很有用。
员工信息可以用于社会工程学攻击,比如伪装成员工,获取更多信息。可以用于密码猜测,很多人用公司名+生日做密码,如果知道员工信息,可能可以猜到密码。可以获取技术栈信息,员工可能在社交媒体上分享技术栈、项目信息,这些信息对攻击很有用。
收集方法:
LinkedIn,搜索公司员工,查看他们的技术栈、项目经验,了解公司用的什么技术。
GitHub,搜索员工的GitHub账号,查看他们的代码、技术栈,可能能找到公司项目的代码。
社交媒体,Twitter、微博等社交媒体,员工可能泄露技术栈、项目信息,这些信息对攻击很有用。
攻击面就是所有可能被攻击的点。包括功能点,比如登录、注册、支付等,每个功能点都可能有问题。包括接口,比如API、文件上传等,这些接口可能有问题。包括技术栈,比如框架、数据库等,如果用的技术有已知漏洞,就是攻击面。包括业务流程,比如优惠券、抽奖等,这些业务流程可能有逻辑漏洞。

分析系统的所有功能点,每个功能点都可能有问题。
分析方法:
列出所有功能,包括用户注册、登录、找回密码等用户相关功能,个人信息管理等用户管理功能,内容发布、编辑、删除等内容管理功能,支付、订单管理等业务功能,管理后台功能等。把所有功能都列出来,不要遗漏。
分析每个功能,对每个功能要分析这个功能做什么,涉及哪些参数,有什么验证,可能有什么问题。比如登录功能,涉及用户名和密码参数,可能有验证码验证,可能存在的问题包括SQL注入、暴力破解、Session固定等。
绘制功能地图:
基于识别的技术栈,查找已知漏洞。
分析方法:
查找CVE,在CVE数据库中搜索技术栈的漏洞,比如PHP 7.4.3的CVE。
查找框架漏洞,查找Laravel、Django、Spring等框架的已知漏洞。
查找组件漏洞,查找使用的第三方库、组件的漏洞。
工具:
|# 使用nmap扫描 nmap -sV -sC target.com # 使用nikto扫描Web漏洞 nikto -h https://example.com # 使用searchsploit查找exp searchsploit laravel
业务流程中的逻辑漏洞,往往是最有价值的。
分析方法:
理解业务流程,首先要理解正常流程是什么,有哪些步骤,每个步骤有什么验证。只有理解了正常流程,才能找到异常路径。
寻找异常路径,看看能否跳过某些步骤,如果能跳过,可能就有漏洞。看看能否重复执行某些步骤,如果能重复执行,可能就有漏洞,比如重复使用优惠券。看看能否修改流程中的参数,如果能修改,可能就能绕过验证。
测试边界条件,测试负数、0、超大数等边界值,这些值可能导致逻辑错误。测试特殊字符、编码,看看系统对这些值的处理是否正确。测试并发请求,看看系统在并发情况下是否有问题。
分析系统架构,发现架构层面的问题。
分析方法:
识别架构类型,首先要识别架构类型,是单体应用、微服务、前后端分离还是Serverless,不同的架构类型有不同的安全问题。
分析组件,分析系统的各个组件,包括负载均衡、应用服务器、数据库、缓存、消息队列等,每个组件都可能有问题。
分析通信,分析组件间如何通信,使用什么协议,有没有认证。如果通信没有认证,或者认证不严格,可能可以伪造通信。
案例:
假设我们分析一个微服务架构,发现服务间通信使用JWT,但JWT密钥强度弱,可以破解。通过破解JWT,伪造服务间通信,成功访问内部服务。这说明架构层面的安全问题也很重要,如果服务间通信不安全,可能导致整个系统被攻破。

优点:自动化测试速度快,能快速发现常见漏洞,覆盖面广,能测试很多点,标准化,结果可重复。这是自动化测试的优势,适合快速扫描。
缺点:自动化测试只能发现已知漏洞模式,对逻辑漏洞、业务漏洞无效,因为工具不理解业务逻辑。误报率高,很多结果可能是误报,需要人工验证。可能被WAF拦截,如果系统有WAF,自动化工具可能被拦截。
优点:手工测试能发现逻辑漏洞、业务漏洞,因为人能理解业务逻辑。能深入分析,理解漏洞原理,不只是发现漏洞,还能理解为什么有漏洞。误报率低,因为是人验证的,准确性高。能绕过WAF,因为人可以灵活调整攻击方式。
缺点:手工测试速度慢,需要花时间。依赖测试人员经验,经验不足可能漏掉问题。可能漏掉一些点,因为人不可能测试所有点。
在实际测试中,采用自动化 + 手工的方式。
先用自动化工具快速扫描,发现明显的漏洞,收集信息,识别技术栈。这样可以快速了解系统的基本情况,发现一些明显的漏洞。
手工深入测试,验证自动化发现的问题,因为很多可能是误报。测试逻辑漏洞,因为自动化工具检测不到。测试业务漏洞,因为自动化工具不理解业务。绕过WAF,因为自动化工具可能被拦截。
结合两者结果,自动化发现的问题,手工验证,确保不是误报。手工发现的问题,自动化工具可能检测不到,这些往往是更有价值的漏洞。
很多人觉得,运行个扫描器,等结果出来就完事了。
问题:自动化工具只能发现30%左右的漏洞,大部分漏洞需要手工测试。逻辑漏洞、业务漏洞检测不到,因为工具不理解业务逻辑。误报率高,需要手工验证,很多结果可能是误报。
正确做法:自动化工具作为辅助,不能完全依赖。重点在手工测试,因为手工测试能发现更多问题。理解业务,测试逻辑漏洞,因为逻辑漏洞往往更有价值。
很多人测试很随意,看到什么测什么。
问题:测试很随意,容易漏掉重要功能,测试不全面,效率低。这样测试,可能花了很多时间,但漏掉了重要的问题。
正确做法:先做信息收集,了解全貌,知道系统有哪些功能。绘制功能地图,系统测试,确保每个功能都测试到。记录测试进度,避免重复,提高效率。
发现漏洞后,不验证就直接报告。
问题:发现漏洞后不验证就直接报告,可能是误报,可能漏洞不存在,影响报告质量。如果报告中有很多误报,客户会对你的能力产生怀疑。
正确做法:每个漏洞都要验证,确保漏洞真实存在。提供POC证明,证明漏洞确实存在。评估真实风险,不是所有漏洞都是高危的,要根据实际情况评估。
只关注技术漏洞,不关注业务逻辑。
问题:只关注技术漏洞,不关注业务逻辑,会漏掉业务漏洞,不理解漏洞的真实影响,修复建议不准确。业务漏洞往往影响更大,比如支付漏洞、优惠券漏洞,可能直接造成经济损失。
正确做法:理解业务流程,知道系统是做什么的,业务流程是什么。测试业务逻辑,看看业务流程是否有逻辑漏洞。评估业务影响,看看漏洞对业务的影响有多大。
这一节课我们学习了渗透测试的方法论。系统化的流程很重要,按照流程进行,提高效率和覆盖率。不要东一榔头西一棒子,要有系统的方法。 深入的信息收集,信息收集越深入,攻击面越大。信息收集是基础,收集的信息越多,发现漏洞的概率越高。
全面的攻击面分析,从功能、技术、业务、架构多个角度分析。不要只关注技术漏洞,也要关注业务漏洞、架构漏洞。 平衡自动化和手工,两者结合,发挥各自优势。
下一节,我们会进入核心攻击面的学习,从认证机制开始。这是Web应用安全的重灾区,也是我们测试的重点。
找一个合法的靶场(如DVWA、WebGoat),按照这一部分的方法论,完整地测试一遍。记录测试过程,总结经验,看看哪些方法有效,哪些方法无效。 对比自动化和手工测试的结果,看看自动化工具发现了什么,手工测试发现了什么。尝试发现逻辑漏洞,而不只是技术漏洞,因为逻辑漏洞往往更有价值。