渗透测试实战:从信息收集到内网横向移动的完整攻防演练
1. 项目概述:从“黑盒”到“白盒”的实战演练
“渗透测试实战步骤”这个标题,听起来像是一份标准操作手册,但真正做过的人都知道,它远不止是几个命令的堆砌。这更像是一场精心策划的“授权入侵”,目标是在不造成实际损害的前提下,像真正的攻击者一样思考、行动,最终找到并证明系统存在的安全弱点。我干了十多年安全,从早期的脚本小子式扫描,到现在面对云原生、微服务架构的复杂环境,核心的实战逻辑其实一脉相承,但细节和工具链早已天翻地覆。今天,我就抛开那些教科书式的流程框图,以一个老兵的视角,拆解一次完整的渗透测试实战,从踩点侦察到报告收尾,把每个环节的“为什么”和“怎么做”讲透,尤其是那些只有踩过坑才知道的细节。
无论你是刚入行的安全分析师,还是想了解如何评估自身系统风险的安全运维,甚至是准备面试的准渗透测试工程师,这篇文章都能给你提供一个清晰的、可落地的实战框架。我们会用到一些常见的工具,但重点在于理解其背后的意图和逻辑,这样你才能举一反三,应对各种千奇百怪的目标环境。
2. 实战前奏:明确规则与信息收集
2.1 授权与范围界定:一切行动的基础
在动手敲下第一个命令之前,最重要的一步往往被新手忽略:明确授权和测试范围。没有书面授权就进行测试,在法律上等同于攻击行为。这份授权文档(通常称为“渗透测试授权书”)必须清晰界定以下内容:
- 测试目标:是单个IP地址、一个域名,还是一个CIDR网段(如192.168.1.0/24)?必须精确到无法产生歧义。
- 测试类型:
- 黑盒测试:你只知道目标名称(如公司名),对内部网络结构、技术栈一无所知。这模拟了外部攻击者的视角。
- 灰盒测试:你拥有部分信息,例如一个低权限的测试账户,或基本的网络拓扑图。
- 白盒测试:你拥有完整或接近完整的信息,如源代码、架构图、甚至管理员权限。这更侧重于深度漏洞挖掘。
- 测试时间窗口:明确开始和结束的日期与具体时间(包括时区)。所有测试活动必须严格在此窗口内进行。
- 禁止行为:明确列出绝对不允许的操作,例如:
- 对生产数据库进行“DROP TABLE”操作。
- 发起可能导致业务中断的拒绝服务(DoS)测试(除非特别授权)。
- 对第三方系统(非授权目标)进行任何形式的扫描或探测。
- 社会工程学攻击(如钓鱼邮件)是否被允许。
- 应急联系:提供双方(测试方与被测方)的紧急联系人及方式,一旦发生意外(如服务意外宕机),能立即沟通处理。
注意:务必保存好授权文件,并在报告中引用。这是你的“护身符”。我曾见过因为范围沟通不清,测试人员扫描了隔壁部门的服务器,差点引发严重内部纠纷的案例。
2.2 被动信息收集:像侦探一样拼图
拿到授权后,不要急着上扫描器。先进行被动的、非侵入式的信息收集。目标是尽可能多地了解目标,而不触发任何警报。
- 域名与子域名枚举:
- 工具:
subfinder,amass,assetfinder,以及在线服务如SecurityTrails, Censys。 - 技巧:除了常规的字典爆破,别忘了检查证书透明度日志(CT Logs,可用
crt.sh),很多子域名会在这里暴露。同时,尝试从robots.txt、sitemap.xml甚至JS文件中寻找线索。
- 工具:
- DNS信息挖掘:
- 操作:使用
dig或nslookup查询A记录、AAAA记录、MX记录(邮件服务器)、TXT记录(可能包含SPF配置甚至泄露的内部信息)。 - 目的:理清目标的网络资产分布,邮件服务器往往是安全链条中较弱的一环。
- 操作:使用
- 搜索引擎黑客技术:
- 方法:利用Google、Shodan、ZoomEye等搜索引擎的特定语法。例如,在Google中搜索
site:target.com filetype:pdf可能找到泄露的内部文档;在Shodan中搜索net:"目标IP段" port:"22"可以找到暴露的SSH服务。 - 心得:花时间构造精准的搜索语句,其收获可能远超一次暴力扫描。我曾通过搜索到的错误日志文件,直接发现了未授权访问的调试接口。
- 方法:利用Google、Shodan、ZoomEye等搜索引擎的特定语法。例如,在Google中搜索
- 公司信息与人员架构:
- 来源:领英、公司官网“关于我们”页面、技术社区(如GitHub)。了解使用的技术栈(如React, Spring Boot)、开发人员的邮箱命名规则(如firstname.lastname@company.com),这对后续的钓鱼攻击或密码爆破很有帮助。
这个阶段输出的成果,应该是一张尽可能详细的“资产地图”,包括域名、子域名、IP地址、可能的服务、相关技术关键词和人员信息。
3. 主动侦察与漏洞扫描
3.1 端口与服务发现
有了资产列表,就可以开始低强度的主动探测了。首要任务是搞清楚这些IP和域名上开放了哪些端口,运行着什么服务。
- 工具首选:
Nmap。它是无可争议的王者。 - 扫描策略:
- 初步快速扫描:
nmap -sS -T4 -p- --open <目标IP>。-sS是SYN半开放扫描,速度快且相对隐蔽;-T4是速度等级;-p-扫描所有65535个端口;--open只显示开放端口。 - 服务与版本探测:针对开放的端口,进行更细致的扫描:
nmap -sV -sC -O -p <开放端口列表> <目标IP>。-sV探测服务版本,-sC运行默认的Nmap脚本,-O尝试识别操作系统。 - 规避策略:在需要更隐蔽时,可以使用
-sS -T2 --scan-delay 1s --max-parallelism 1等参数来降低扫描速度,模拟慢速攻击。
- 初步快速扫描:
- 结果分析:不要只看端口号。重点分析:
- 非常规端口上的常见服务:比如在8080端口运行着Apache,或在2222端口运行着SSH。这可能意味着管理员想隐藏服务,但配置往往更松懈。
- 过时的服务版本:Nmap输出的版本信息直接对应着已知的公开漏洞(CVE)。一个
Apache 2.4.49立刻就能联想到CVE-2021-41773路径穿越漏洞。 - Nmap脚本输出:
-sC脚本可能会直接发现漏洞,比如匿名FTP登录、Redis未授权访问等。
3.2 Web应用信息收集与爬取
如果发现80/443端口开放,Web应用就是主战场。
- 目录与文件枚举:
- 工具:
gobuster,dirsearch,ffuf。 - 字典选择:不要只用默认的小字典。结合目标行业(如PHP的CMS常用
php扩展名字典,Java应用可能关注jsp、action等)、技术栈来选择合适的字典。SecLists项目提供了非常全面的字典集合。 - 技巧:同时进行扩展名枚举(如
-x php,html,bak,txt)和递归扫描。特别注意backup.zip,index.php.bak,.git/,.svn/等可能泄露源码或配置的文件和目录。
- 工具:
- Web技术指纹识别:
- 工具:
Wappalyzer(浏览器插件)、whatweb。 - 目的:快速识别前端框架(如Vue.js, React)、后端语言(PHP, Java, Python)、Web服务器(Nginx, Apache)、中间件(Tomcat, WebLogic)、数据库(通过特定报错或特征)等。这直接决定了后续的漏洞利用方向。
- 工具:
- 爬虫与站点地图绘制:
- 工具:
Burp Suite的爬虫功能、OWASP ZAP的蜘蛛。 - 操作:让工具自动遍历整个网站的所有链接、表单和功能点。这能帮你发现那些隐藏在深层链接或需要特定步骤才能访问到的功能,比如管理员后台的登录入口、文件上传点、API接口等。
- 工具:
3.3 自动化漏洞扫描的定位与使用
很多人把漏洞扫描器(如Nessus, OpenVAS, AWVS)当作“神器”,但老手只把它当作一个高效的“初步筛选器”。
- 定位:自动化扫描器擅长发现已知的、有明确特征的漏洞,比如特定版本的Struts2远程代码执行、心脏滴血漏洞等。它能快速覆盖大量资产,给出一个风险基线。
- 局限:
- 误报和漏报:扫描器会产生大量误报(将无害的配置报告为漏洞),同时也会漏掉很多逻辑漏洞(如越权访问、业务逻辑缺陷)和新型的、未公开的漏洞。
- 破坏性风险:一些扫描器的检测插件具有侵入性,可能造成应用崩溃或数据污染。务必在授权范围内使用,并在测试环境先行验证。
- 噪音大:全量扫描会产生大量日志和流量,极易触发安全设备的告警。
- 使用策略:
- 针对性扫描:不要一上来就对所有IP进行最高强度的扫描。先针对Web应用使用Web漏洞扫描器,针对网络设备使用网络漏洞扫描器。
- 分析而非盲从:对扫描器报告中的每一个“高危”漏洞,都要手动验证。验证方法包括:查看确切的版本号、利用公开的PoC(概念验证代码)进行无害化测试、分析流量包确认漏洞触发点。
- 作为线索:扫描器报告里“中危”或“低危”的发现,有时反而是突破口。比如一个“信息泄露——目录列表已启用”的提示,可能让你直接下载到源码备份。
4. 漏洞利用与权限提升
4.1 Web应用漏洞的深度利用
这是渗透测试中最体现技术差异的环节。自动化工具到此基本失效,需要依靠经验和手动测试。
- SQL注入:
- 手动检测:不仅仅是加个单引号看报错。对于数字型、字符型、搜索型、时间盲注、布尔盲注,都需要不同的测试载荷。使用
Burp Suite的Intruder模块,配合SQLMap的tamper脚本(用于绕过WAF)进行自动化探测和利用。 - 实战技巧:遇到疑似注入点,先别急着
union select。用' and '1'='1和' and '1'='2测试布尔逻辑,用sleep(5)测试时间盲注,确认注入存在且可被利用后,再考虑获取数据。SQLMap的--level和--risk参数可以调整测试强度,--tamper参数在绕过简单过滤时非常有效。
- 手动检测:不仅仅是加个单引号看报错。对于数字型、字符型、搜索型、时间盲注、布尔盲注,都需要不同的测试载荷。使用
- 跨站脚本:
- 不只是弹窗:反射型XSS和存储型XSS的危害天差地别。存储型XSS可能影响所有用户。测试时,要思考利用场景:是窃取Cookie,还是构造钓鱼页面,或是配合其他漏洞(如CSRF)进行组合攻击?
- 绕过过滤:现代前端框架和WAF对XSS的防御很强。需要尝试多种Payload,如利用HTML5新特性、SVG标签、JavaScript事件的黑名单绕过、编码混淆等。
- 文件上传漏洞:
- 绕过检查:前端JS验证、服务端MIME类型检查、文件扩展名黑名单/白名单、文件内容头检查。绕过方法包括:修改HTTP请求包、使用双写扩展名(
shell.php.jpg)、在文件内容开头添加图片魔数(如GIF89a)、利用解析漏洞(如IIS6.0的/xx.asp;.jpg)。 - 获取Shell:上传成功后,如何执行?需要知道文件的绝对路径或Web可访问的URL。结合目录遍历或信息泄露漏洞获取路径。
- 绕过检查:前端JS验证、服务端MIME类型检查、文件扩展名黑名单/白名单、文件内容头检查。绕过方法包括:修改HTTP请求包、使用双写扩展名(
- 业务逻辑漏洞:
- 越权访问:这是自动化工具完全无法发现的。核心测试方法是:用两个不同权限的账户(如普通用户A和管理员B),对比同一功能请求的差异。重点测试:水平越权(用户A操作用户B的数据)、垂直越权(普通用户执行管理员功能)。
- 测试方法:修改请求中的ID参数(如
user_id=123)、替换Cookie或Token、直接访问本应无权访问的API端点(如/admin/deleteUser)。
- 组件与框架漏洞:
- 快速定位:根据之前指纹识别的结果,搜索对应框架/组件的历史漏洞。例如,识别出
Spring Boot Actuator未授权访问,就可以直接尝试/actuator/heapdump下载内存快照寻找敏感信息。 - 利用链构造:单个漏洞可能无法直接getshell,但组合起来就能形成杀伤链。例如,一个文件上传+一个本地文件包含,或者一个反序列化+一个Java内存马注入。
- 快速定位:根据之前指纹识别的结果,搜索对应框架/组件的历史漏洞。例如,识别出
4.2 系统权限提升
获取了Webshell或一个低权限的系统账户后,目标转向获取服务器的最高权限。
- 信息收集:在受限环境下,首先运行一系列命令收集系统信息:
whoami/id:查看当前用户和所属组。uname -a:查看内核版本。cat /etc/passwd:查看所有用户。sudo -l:极其重要!查看当前用户能以root身份无需密码运行哪些命令。如果看到/usr/bin/vim,/usr/bin/python等,很可能直接提权。find / -perm -u=s -type f 2>/dev/null:查找设置了SUID位的文件。ps aux/netstat -tulnp:查看运行进程和网络连接。cat /etc/crontab:查看计划任务,可能有自定义脚本,且权限配置不当。
- 内核漏洞提权:
- 方法:根据收集到的内核版本,在本地或利用在线资源(如
searchsploit)搜索对应的本地提权漏洞。 - 操作:将exp上传到目标服务器,编译(如果需要)并执行。务必先在本地或测试环境验证exp的稳定性和影响,避免导致目标系统崩溃。
- 风险:内核提权是最直接但风险最高的方式,可能引发系统不稳定。
- 方法:根据收集到的内核版本,在本地或利用在线资源(如
- 利用配置错误:
- SUID/SGID文件:如果找到
/usr/bin/find、/usr/bin/nmap(旧版本)等命令具有SUID位,可以利用其特定参数执行命令。例如:find . -exec /bin/sh \; -quit。 - Sudo权限滥用:
sudo -l列出的命令是金矿。例如,如果能以root运行/usr/bin/python,则直接sudo python -c 'import os; os.system("/bin/bash")'。 - 计划任务:检查
/etc/crontab和/var/spool/cron/crontabs/。如果有一个以root身份运行的计划任务脚本,且该脚本当前用户可写,直接修改它,插入反向Shell命令。 - PATH环境变量劫持:如果有一个SUID程序内部调用了系统命令(如
system("ps")),且未使用绝对路径,我们可以通过修改当前用户的PATH环境变量,让其优先执行我们伪造的ps程序。
- SUID/SGID文件:如果找到
- 数据库提权:如果通过SQL注入获得了数据库访问权限(如MySQL的
FILE权限),可以尝试写入Webshell或SSH公钥。例如,在MySQL中:SELECT "<?php system($_GET['cmd']);?>" INTO OUTFILE '/var/www/html/shell.php'。
5. 内网横向移动与权限维持
5.1 突破边界,进入内网
当拿下一台边界服务器(如Web服务器)后,它很可能位于内部网络中。这时,渗透测试进入内网横向移动阶段。
- 网络拓扑探测:
ifconfig/ip addr:查看当前机器的网卡和IP地址,判断是否存在多块网卡(双网卡,可能跨网段)。arp -a/cat /proc/net/arp:查看ARP缓存,发现同一网段的其他主机。netstat -rn/route -n:查看路由表,了解网络结构。cat /etc/resolv.conf:查看DNS服务器,它通常位于核心网络。
- 端口转发与代理:
- 目的:因为我们的攻击机(Kali)在外网,无法直接访问内网IP。需要将边界服务器作为跳板,把内网服务的端口“映射”到我们本地。
- 工具:
ssh -L/-R/-D:如果边界服务器有SSH服务且我们获得了凭证,这是最稳定隐蔽的方式。例如ssh -L 1080:内网目标IP:3389 user@边界服务器IP,将内网Windows的3389端口转发到本地的1080端口。frp/ngrok:功能强大的内网穿透工具,配置稍复杂但更灵活。reGeorg/Neo-reGeorg:基于HTTP/HTTPS的隧道工具,常用于突破严格的网络出口策略,将流量封装在Web请求中。
- 内网扫描:
- 通过代理或端口转发,使用
Nmap、masscan对内网网段进行扫描。策略与外网扫描类似,但可以更“大胆”一些,因为内网的安全监控可能较弱。 - 重点扫描:
445/SMB(Windows文件共享,可能存在永恒之蓝漏洞)、135/139/445(Windows RPC)、1433(MSSQL)、3306(MySQL)、5432(PostgreSQL)、6379(Redis)、5985/5986(WinRM)等常见的企业服务端口。
- 通过代理或端口转发,使用
5.2 凭证获取与密码攻击
内网中,密码重用和弱密码是普遍问题。
- 本地凭证抓取:
- Windows:
Mimikatz:神器。可以抓取内存中的明文密码、哈希值(NTLM Hash)。需要管理员权限。Procdump+ 本地分析:如果无法直接运行Mimikatz,可用微软官方的Procdump工具将lsass.exe进程的内存转储下来,拖回本地用Mimikatz分析。
- Linux:
/etc/shadow:需要root权限才能读取,里面是用户的密码哈希。- 内存中可能存在的明文密码:检查
~/.bash_history历史命令、环境变量、正在运行的进程参数(ps auxww)。
- Windows:
- 哈希传递攻击:
- 原理:在Windows域环境中,很多时候不需要破解密码哈希,直接使用哈希值就可以进行身份验证。这就是Pass-the-Hash。
- 工具:
smbclient,psexec.py(Impacket套件),CrackMapExec。 - 操作:
crackmapexec smb 192.168.1.0/24 -u administrator -H <NTLM哈希> --local-auth,用抓取的本地管理员哈希尝试登录同网段其他机器。
- 密码爆破与喷洒:
- 密码喷洒:针对多个用户名,尝试一个或几个常用密码。避免因单个用户多次失败登录而触发账户锁定。工具:
Hydra,Medusa,CrackMapExec。 - 字典选择:内网爆破应使用更贴合企业环境的字典,如公司名+年份(Company2023!)、季节+年份(Summer2023!)、默认设备密码等。
- 密码喷洒:针对多个用户名,尝试一个或几个常用密码。避免因单个用户多次失败登录而触发账户锁定。工具:
5.3 权限维持与后渗透
在获取域管理员等高权限后,为了模拟高级持续性威胁,需要部署后门,维持访问权限。
- Web后门:在Web目录下留下多个隐蔽的Webshell,使用免杀技术、隐藏在图片中、或利用框架特性(如Spring Boot的Interceptors)。
- 系统后门:
- Linux:添加SSH公钥到
~/.ssh/authorized_keys;创建具有SUID权限的备用后门程序;修改/etc/rc.local等自启动脚本。 - Windows:创建计划任务、服务、WMI事件订阅、注册表启动项(
HKLM\Software\Microsoft\Windows\CurrentVersion\Run)。
- Linux:添加SSH公钥到
- 域持久化:
- 黄金票据:在获取域控的
krbtgt账户哈希后,可以伪造任意用户的TGT票据,从而访问域内任何服务。这是最强大的域持久化手段之一。 - 银票据:针对特定服务(如MSSQL, CIFS)伪造服务票据,不需要与域控交互,更隐蔽。
- DSRM密码同步:修改域控的目录服务还原模式密码,以便在目录服务修复模式下登录。
- Skeleton Key:在域控上注入恶意代码,使所有用户都能使用一个通用密码登录(同时原密码仍有效),但易被检测。
- 黄金票据:在获取域控的
重要心得:权限维持的所有操作,必须严格遵守授权范围。在测试报告中,需要详细记录后门的位置和清除方法,并在测试结束后协助或指导客户彻底清理。这是职业操守的体现。
6. 报告撰写与成果交付
渗透测试的最终价值,不在于你拿到了多少个“flag”,而在于你能否清晰、专业地呈现风险,并推动问题解决。
- 报告结构:
- 概述:测试目标、范围、时间、参与人员、方法论简述。
- 执行摘要:用1-2页向管理层汇报。不使用技术术语,直接说明发现的最关键风险(通常按业务影响排序)、整体安全状况评级、最紧迫的修复建议。
- 详细发现:这是报告的核心。每个漏洞应包含:
- 漏洞标题:简明扼要,如“SQL注入导致用户数据泄露”。
- 风险等级:高、中、低(需定义清晰的评级标准,通常结合CVSS评分和业务影响)。
- 受影响资产:具体的URL、IP、端口。
- 漏洞描述:用技术语言说明漏洞原理。
- 复现步骤:一步一步的操作指南,让开发或运维人员能按照步骤验证漏洞。这是关键,必须清晰到截图和每次点击。
- 请求与响应:附上关键的Burp Suite请求响应数据包(脱敏后),作为证据。
- 影响分析:这个漏洞能被利用来做什么?数据泄露、权限提升、系统控制?
- 修复建议:给出具体、可操作的修复方案。不要说“修复SQL注入”,而要说“在XX接口的YY参数处,使用预编译语句(Prepared Statement)替换字符串拼接,示例代码:...”。
- 附录:测试所用的工具列表、扫描的IP/域名全列表、相关参考链接等。
- 沟通与汇报:
- 报告初稿完成后,最好能进行一次线上的汇报会议,向技术团队和管理层讲解主要发现。
- 对于高风险漏洞,应在发现的第一时间通过预定的应急渠道进行口头通知,而不是等到报告完成。
- 报告不是终点。应提供修复期的技术支持,并在修复完成后进行复测,验证漏洞是否被真正、正确地修复。
渗透测试的实战,是一个循环往复、不断深入的过程。它要求测试者既有攻击者的思维和技巧,又有建设者的责任和严谨。每一次测试,都是对目标系统防御体系的一次压力检验,也是对自身知识库的一次更新和挑战。记住,工具和技术会过时,但那种系统化的思考方式、严谨的操作习惯和对安全的敬畏之心,才是这个领域真正的核心价值。
