打了多次线上解题赛之后,我第一次走进AWD线下攻防赛的机房时,发现自己引以为傲的“解题速度”基本派不上用场。旁边队伍键盘敲得飞快,我的服务在几十秒内就被拿下了权限,这种现场压迫感,只有线下AWD才有。AWD(Attack With Defense,攻防兼备)真的不是单纯的抢分游戏——你得一边像攻击手那样快速打穿对手,一边像运维工程师一样守好自己的靶机,两边都不能松。这篇文章是我对AWD线下赛的完整复盘:赛前该准备什么、开局怎么抢时间、攻防回合里怎么拿分、哪些坑让我白送了不少分,以及赛后怎么把经验沉淀下来。无论你是第一次准备打线下赛,还是已经打过几场仍觉得吃力,这篇总结应该都能给你一些实在的东西。
1. AWD不是拼手速,而是拼“赛前积累”
很多人以为AWD拼的是临场反应,其实一进赛场你就会发现,真正让你拉开差距的,是你带进机房的那些“积累”。我说的积累不是脑子里记了多少漏洞利用姿势,而是你的操作台、队伍分工、脚本工具,是不是都已经固化成了肌肉记忆。
1.1 先把操作台固化成肌肉记忆
赛前最值得做的事,不是刷新题,而是整理自己的操作环境。AWD的靶机大多是Linux系统,你的本机就是你的“指挥中心”。我建议赛前专门花一个下午,搭一个干净的虚拟机模板,把下面这套工具链全部装好:
- 端口扫描工具:Nmap这类是必须的,开局扫网段、确认服务清单全靠它。
- HTTP请求拦截工具:用来快速改包、重放请求,分析漏洞参数非常顺手。
- 流量抓包工具:Wireshark或者同类工具,用于比赛中期观察对手的进攻路径。
- 目录扫描脚本:快速发现备份文件、后台路径、敏感文件。
- WebShell管理工具:拿到权限后管理入口用,能省大量重复操作。
- 数据库客户端:很多服务连数据库,方便直接查看数据内容。
- 日志分析命令集合:grep、awk等常用命令的固定组合,直接写成脚本。
- 文件监控和快速备份脚本:这两个后面细说,属于开局保命用的。
工具装好只是第一步,关键是把它们的调用方式变成肌肉记忆。我会在自己的虚拟机里反复模拟比赛开场流程:打开终端、启动扫描、挂上抓包、确认备份脚本路径,整套动作练到不需要想就能完成。别小看这个练习,线下赛的前几分钟,别人已经开始拿分,你还在找工具的话,节奏就全乱了。
1.2 分工:不是所有人都在打
AWD一般是3到5人一队,赛前一定要把分工定死,不要进赛场之后自由发挥。我见过不少队伍一开场所有人都扑出去打进攻,结果自家靶机被人摸透了也没人发现,等分数掉下来才慌慌张张回去防守,这时候已经晚了。合理分工大概是这样的:
- 进攻手:负责漏洞挖掘、打点、拿flag,是队伍得分的主力。
- 防守手:负责备份、加固、盯服务存活状态,同时负责修复被攻击的漏洞。
- 监控手:盯流量、日志和文件变化,发现对手打法后及时反馈给进攻手。
三个人各干各的,但信息要实时同步。最简单的方式是拉一个内部群,进攻手发现对手的漏洞,马上甩给防守手去查自己靶机有没有同样的问题;监控手在日志里看到对手的payload,立刻告诉进攻手可以“反打回去”。分工明确后,每个人都只操心自己那块,反而能把事情做深。
1.3 那几个能在关键时刻救命的“小脚本”
赛前一定要写好几类防御性质的小脚本,别到赛场上手敲命令。第一是快速备份脚本,比赛一开始就执行,把网站源码和数据库打包到一个安全位置。第二是文件监控脚本,专门盯web目录里的新增和修改文件,一旦发现异常文件马上记录。第三是进程监控脚本,查是否有可疑的外联进程。我放两个最基础的模板,你可以根据自己的习惯改:
#!/bin/bash # 快速备份脚本:将web目录打包,并记录hash src=/var/www/html backup_dir=/tmp/system_bak stamp=$(date +%H%M%S) mkdir -p $backup_dir tar czf $backup_dir/web_$stamp.tar.gz $src 2>/dev/null sha256sum $backup_dir/web_$stamp.tar.gz >> $backup_dir/backup_hash.txt echo "[+] backup done: $backup_dir/web_$stamp.tar.gz"#!/bin/bash # 文件监控脚本:每60秒扫描一次web目录新增文件 while true; do find /var/www/html -type f -mmin -1 -exec ls -la {} \; >> /tmp/change.log sleep 60 done这两个脚本真的能救命。备份脚本让你被对手删了源码后能快速恢复,文件监控脚本能第一时间告诉你对手有没有写入奇怪的文件。别看不起这些基础操作,AWD里能稳定赢下来的队伍,往往就是把基础动作做到极致的队伍。
2. 开局30分钟:从资产盘点到第一波先手
比赛开局前30分钟,是整个AWD最关键的窗口。这段时间内,谁先把服务摸清楚,谁先找到第一个漏洞,谁就能建立心理优势。而所谓“先手”,不是盲目地到处打,而是有条理地把信息吃透。
2.1 先把手里的资料榨干
赛方通常会提供一批信息:靶机IP列表、服务列表、账号密码、甚至部分源码。很多人一拿到IP就急着开扫,但我建议先冷静下来,把手里的资料过一遍。特别是服务列表,它直接告诉你比赛涉及哪些技术栈。如果赛方提供了源码,那这条路径优先级最高——源码审计比黑盒测试快得多,直接看代码就能定位注入点、文件上传点、命令执行点,效率是黑盒的好几倍。
打开浏览器逐个访问服务页面也是必须的动作。很多题目会在前端页面留下提示,比如注释里的调试信息、报错页面暴露的中间件版本、甚至一份遗留的管理后台。这些信息白纸黑字写在那里,比扫描器更快更准确。记住一句话:先看人给的东西,再自己动手找。
2.2 首轮扫描要回答三个问题
开局扫描不能漫无目的地扫,至少要让扫描结果回答三个问题:对手开了哪些端口?跑的是什么服务?有没有明显的历史遗留文件?
先对本机做一次完整扫描,确认自己靶机的服务基线,再对其他靶机做同样的扫描。端口不局限于80、8080这类常见端口,一定要看高位端口和非常规端口,比赛题目经常把服务藏在诡异的位置。比如我曾经遇到一次比赛,目标服务开在9789端口,大多数队伍扫完常规端口就走了,但那个端口上其实跑着一个带弱口令的管理后台。
目录扫描也要做,重点找以下几种文件:压缩备份包(常见后缀zip、tar.gz、bak)、源码仓库泄露文件、编辑器留下的临时文件、后台路径。这些文件一旦存在,价值往往比直接挖漏洞还高。一个备份包可能直接包含数据库配置文件,拿到手基本就等于掌控了整台机器。
2.3 防御动作必须抢在攻击前面
很多队伍开局只顾进攻,防御动作完全滞后,这是大忌。我个人的节奏是:扫描的同时,让防守手立刻执行备份脚本,然后启动文件监控,最后检查默认账号和弱口令。前三件事一定要在比赛开始后就做,不要等对手来打了才反应。
为什么这么急?因为AWD的防守分通常与服务和靶机存活状态绑定,你要是被对手删了文件、改了配置,服务就会出问题,防守分会持续扣。备份能让你快速恢复,监控能让你感知威胁,弱口令排查能堵住最无脑的攻击。这几件事做完也就几分钟,但能让你后面打得很省心。
开局还有一个容易被忽略的点:确认自己靶机上有没有赛方故意预留的漏洞文件。很多AWD在初始化环境中就带着一个明显的“欢迎漏洞”,比如一个可直接命令执行的后台或一个不安全的文件上传接口。先在自己靶机上确认这些口子,一是方便防守,二是可以快速把同样打法复制到对手靶机上,形成第一波攻击收益。
3. 攻防拉锯中,真正拉开分差的三个动作
开局过去之后,比赛进入漫长的攻防拉锯阶段。这个阶段看起来是持续不断地互相攻击,实际上真正能拉开分差的,往往只有几个关键动作。把它们做好,比无目的地乱打更加有效。
3.1 把流量分析变成自己的情报来源
AWD里最经典的信息循环其实是防守侧的“反打”:对手打你的时候,会在你的流量和日志里留下大量痕迹。利用好这些痕迹,你的进攻效率能翻倍。
我习惯让监控手用抓包工具挂在本机入口,同时持续查看访问日志。一旦发现某个来自对手IP的请求路径特别奇怪,比如对方在尝试一个特定参数的注入,或者在读取某个特定文件,那基本就等于对方把漏洞位置和打法都“示范”了一遍。这时候我们要做的是:把完整请求保存下来,分析它为什么有效,然后把同样的请求改到对手靶机上重放。
这个循环一次可能没什么,但整场比赛累积下来,防守情报转进攻的转化率,决定了你们队伍的“续航能力”。所以别把监控理解为被动的活,它其实是整支队伍的信息中台。
3.2 加固的度:让服务活着,但难啃
防守端的核心矛盾是:既要让服务存活,又不能让对手轻易利用。常见的加固手段包括改后台路径、限制上传目录的执行权限、对输入参数做过滤、清理已知WebShell文件、修复已发现的漏洞。但加固不是越猛越好,因为比赛还要进攻,你把自己的服务加固到无法利用,也会给防守分带来压力。
我吃过大亏:有一场比赛,我把一个服务的参数全部加上过滤,结果自己后续的利用脚本也打不进去了,等于自断一条路。所以加固要有“度”,核心原则是:修复已知漏洞,但保留必要的正常功能;对攻击面做收敛,但别让服务直接失效。每次加固前先把原文件备份好,不要直接覆盖原配置,免得改坏无法回滚。加固后立刻访问一遍关键功能,确认服务没有异常,再继续下一个动作。
还有个细节:尽量把加固动作脚本化。比如批量修改上传目录权限的命令,写成一行脚本,给所有靶机统一执行,避免一台一台手工操作时遗漏,也防止出现不同靶机加固状态不一致的混乱情况。
3.3 攻击节奏:稳定输出比一把梭更划算
AWD的计分周期通常不连续,而是按轮次结算。这意味着你不需要一次把所有漏洞全打出去,而是要在每一轮保持稳定输出。一波流打完所有“存货”,后面就会进入空窗期,分数增长停滞,对手却可以趁机反扑。
我建议团队维护一张“进度表”,记下每台靶机已经确认的漏洞类型、是否已打点、flag是否已提交。这样能避免多个人重复打同一台机器,浪费时间也容易暴露意图。每次打点前先确认目标服务响应正常,别因为自己操作过猛把对方服务打崩。很多比赛的规则里,把对手服务打挂反而会扣分或导致该轮次无法继续得分,所以“破坏性攻击”多数时候不划算。
被反打也是常见的事。当你用某个入口登入对手服务器时,对手也可能通过流量感知到你的动作,然后反过来清理你的通道。所以攻击动作要轻、要快、要避免留下明显的访问特征。拿到flag提交之后,不要一直霸占着通道,尽量清理现场,降低暴露概率。
4. 复盘自己人制造的几个“反向伤害”
每次AWD打完,最值得聊的往往不是打赢了哪几台靶机,而是我们自己人制造的那些“反向伤害”。这些错误非常典型,写出来希望下回大家别踩同样的坑。
4.1 备份包放错了目录,等于给对面送装备
有一场我们让防守手快速备份,他图省事,直接把web目录打包放在了网站根目录下,文件名叫backup.tar.gz。结果对手第一次扫描就发现了这个包,下载之后从里面翻出了数据库配置文件,拿到了数据库密码,随后直接登录数据库把我们所有数据清空。更讽刺的是,对手顺手还把这个备份包删了,我们连自我恢复都要从头再来。
教训很明确:备份的位置绝对不能放在web目录里。要放在web目录之外,或者至少在系统内找一个不显眼的路径。命名也尽量别用backup、web_bak这种一眼就能认出的名字,最好伪装成无关的系统文件。备份之后别忘了做完整性校验,比如记录hash,方便确认备份是否被篡改。抢救冗余才是备份的核心价值,放得再近不安全等于没备份。
4.2 批量脚本没有限速,自己把靶机打崩了
另一场比赛,我们为了让进攻手更快地同时检测多台靶机,写了一个批量请求脚本。脚本本身逻辑没问题,但完全没有限速和超时控制,导致全是并发请求直接打同一个目标。目标服务扛不住压力,直接崩溃,然后我们自己的服务状态也受到影响。最搞笑的是,当时还以为是那个对手的防护很强,后来一看日志,才发现大量请求都来自我们自己的IP。
这件事让我学会三件事:第一,任何批量脚本都必须带延迟和超时参数,比如单次请求间隔控制在几百毫秒,失败自动跳过;第二,脚本上线前先在自己的靶机上小范围跑一遍,验证稳定再用于对手;第三,针对不同目标要设置并发上限,不要给同一台靶机“地毯式轰炸”。这些参数看起来不酷,但能在关键轮次让你少扣很多分。
4.3 留着的权限维持入口,被对手改成了进攻跳板
AWD比赛过程中,为了让后续轮次持续得分,通常会在已拿下的靶机上留一个权限维持入口。这个思路本身没错,问题在于入口文件往往千篇一律。有一场,我们在某靶机上留了一个WebShell文件,放的位置和命名都非常常规。对手扫到这个特征文件后,没有直接删除,而是把文件内容改成了一个反向连接的后门。我们下一次连上去时,等于主动连接到了对手控制的通道,差点把本机信息也泄露出去。
经过这次之后,我对权限维持入口的要求变得很严格:尽量伪装文件名和内容,避免使用默认路径;定期检查入口是否被改过,比如比对文件hash;如果某个入口已经不再需要,宁愿删除也不要留着让对方利用。AWD里最怕的不是丢分,而是你留下的“工具”变成对手打你的跳板。
5. 把一次线下赛的经验变成可复制的能力
比赛总有结束的时候,但经验不能就停在赛场里。赛后如果不复盘,下一次还会犯同样的错误。我觉得线下赛经验最好的处理方式,是把它变成一套可复制、可复用、可迭代的能力集合。
5.1 复盘别只写漏洞,要写时间线
普通CTF比赛赛后写writeup,主要写漏洞成因和解题步骤。但AWD复盘的维度要更宽:一定要把时间线拉出来。比如第几分钟我们完成了备份,第几分钟发现第一个漏洞,第几分钟靶机被对手打穿,第几分钟补上了缺口。这能帮你找出自己的“拖沓点”。
我习惯用表格记录:
| 时间点 | 事件 | 影响 | 根因 |
|---|---|---|---|
| 开赛第3分钟 | 完成备份 | 正常 | 赛前脚本准备充分 |
| 开赛第12分钟 | 对手用文件上传拿权 | 丢失第一滴血 | 未提前修复已知上传点 |
| 开赛第25分钟 | 完成修复 | 停止掉分 | 备份帮助快速恢复 |
| 开赛第40分钟 | 利用对手备份文件得flag | 加分 | 目录扫描发现敏感文件 |
这种时间线式复盘,能让你看见自己每轮操作的代价和收益,比单纯记录漏洞结论要高一个维度。
5.2 把常用操作沉淀成模板脚本包
赛后一定把自己在比赛中手动敲过的命令、写过的临时脚本,整理成结构化的模板脚本包。最简单的做法是建一个仓库,按功能分目录:备份恢复、文件监控、端口扫描、目录扫描、日志分析、批量请求等。每个脚本都要写清楚参数说明和适用场景,别只放代码不写注释,不然下次比赛根本不记得当初为什么这么写。
这样做的好处很直接:下一次比赛开场,你不是从零开始,而是直接把仓库拉到本机,按需执行。工具链越完整,你的前几分钟就越从容。而且脚本包在平时训练中也能持续迭代,赛后复盘发现哪个脚本有问题改掉就好,永远不白费。
5.3 AWD练出来的能力,出去同样有用
最后说个很多人没意识到的点:AWD是竞赛,但它的能力模型一点都不比赛事本身“窄”。比赛中练出来的应急响应意识、日志分析能力、加固修复能力、漏洞研判能力,放在日常的安全运维、企业红蓝对抗演练、系统安全评估中都是很核心的素质。
如果你想把这项能力延续下去,我建议平时多约线上AWD训练赛,或者找几台虚拟机自己搭一个模拟靶场,两个人一对一练攻防。重点不是练“打穿一台机器”的速度,而是练“从被打到反打”的完整闭环:感知威胁、确认原因、快速恢复、逆向反制。这套闭环一旦成为习惯,你的安全综合能力会有一个非常明显的提升。
打了多次线下AWD之后,我最深的体会是:AWD的胜负,七成在赛前,两成在开局,最后一成才是临场爆发。很多队伍输不是输在技术,而是输在备份被删了没人发现,或者所有队员都在往前冲,没人在家看门。所以如果你正准备参加下一场,建议从今天开始就把脚本写好、分工练熟、流程跑通。能赢的从来不是手最快的那一队,而是犯错更少的那一队。希望这篇总结能帮你在下一场少犯一点错,多拿几分。