☰
AWD攻防实战:一站式多目标托管、权限维持与Flag自动化提交方案
2026/9/28 5:43:59 网站建设 项目流程

上周末打了一场四个小时的AWD,靶机一共五台,刚开局十五分钟,我已经记不清哪台加固过、哪台后门被删了、哪台flag还没提交。等比赛结束复盘,真正浪费时间的不是漏洞分析,而是这些"管理类"杂活。从那次之后我开始认真收拾自己的比赛工作流,把之前的各种零散脚本和笔记整理成一套专为AWD/CTF攻防场景设计的一站式管理方案,核心覆盖多目标资产梳理、权限维持、基线加固和Flag读取,跟本文标题里的思路完全对应。这篇文章把我沉淀下来的东西写透,包括模块怎么设计、每一步为什么要这样做、比赛里哪些坑我踩过,适合准备打AWD但还在用手忙脚乱方式管靶机的选手参考。

1. AWD规则下的时间账:为什么手忙脚乱等于送分

想理解一款AWD管理工具该怎么做,先得把AWD的比赛节奏盘清楚。不同于常规CTF的解题模式,AWD是每个队伍维护自己的靶机,同时互相攻击对手靶机,既要防住别人进来拿分,又要攻破别人拿分。比赛时长通常2到4小时,大部分平台的靶机在开局阶段会有一段"关站期"或者"环境确认期",这期间不能被攻击,用来让选手检查初始状态。开局阶段一过,全场立刻进入混战,漏洞利用流量满天飞,Flag的读取和提交窗口也会周期性刷新。

在这种赛制下,每个选手要管的靶机可能是1台,也可能是5台甚至更多。很多团队分工是两三个人守一台,但单兵作战或者小团队轮转时,一个人同时管多台目标极为常见。多台靶机带来的核心问题不是"不会攻击",而是"记不住状态"——哪台改了SSH端口?哪台加固了但漏了一条路径?哪台的Flag读取脚本还连着旧密码?这些状态一旦记错或者记混,轻则自己绕晕,重则把自己锁在门外,彻底失去防守能力。

更麻烦的是时间维度。利用漏洞打进一台机器只是起点,之后要做的全套动作包括:确认权限、布置权限维持、排查并清除别人的后门、加固关键服务、写Flag读取脚本,这些步骤在每台机器上都要重复一遍。如果每台都手动操作,四小时比赛大概有两个半小时都在敲重复命令,真正用来思考攻防策略的时间所剩无几。所以AWD管理工具的第一个价值不是替你做攻击,而是把最机械、最重复、最容易出错的环节批量化、自动化、状态化。看清了这个"时间账",后面的模块设计才有依据。

2. 多目标资产清单与状态看板:先把自己管住

2.1 资产清单的字段设计

做多目标管理,第一步永远是资产清单。我见过不少人用记事本记IP,结果打到一半自己在混乱中迷失,因为AWD中的信息远不止一个IP那么简单。一份能用的资产清单至少要包含这些字段:队伍编号、目标IP、SSH端口、SSH用户名和密码、Web端口、中间件类型、Web框架语言、已知漏洞列表、加固完成状态、后门存活状态、Flag最近提交时间、备注。

我不建议把所有信息堆在一个表格里就算完,而是要给每个目标生成一条独立的"状态记录",类似一个小档案。字段设置得越细,后面做自动化就越顺。比如SSH端口,有的队伍会把默认22改成22022,如果清单里不写清楚,脚本默认连22端口就会全部失败。又比如Web框架,TP5的路由格式和ThinkPHP的路由格式不同,批量检查后门时需要按框架类型匹配特征。

在实际部署中,我推荐用JSON或者YAML保存这份清单,而不是用Excel。原因很简单:脚本可以直接读取。Excel虽然方便人工看,但解析麻烦,比赛现场也没时间写一堆pandas处理逻辑。JSON结构清晰,Python和Bash都能轻松读取。每一条记录除了基本信息外,还可以加上一个"健康状态"字段,由下面要讲的轮询模块自动更新,这样你一眼就能看出当前哪些目标掉线、哪些目标还没做好加固。

2.2 批量存活检测与状态轮询

状态看板的核心是一个轮询脚本,定时探测所有目标的关键端口是否在线。我会同时探测SSH端口和Web端口,因为靶机在线不代表Web服务在线,有时候服务挂了但端口还在,有时候对方把80端口改了。探测结果分为三类:完全失联、SSH通但Web不通、全部正常。每轮探测结果写入状态记录,并在终端上用不同颜色区分,一眼扫过去就清楚当前全局情况。

轮询脚本还应该带上"关键凭据有效性检测"。比如每次循环尝试用清单里记录的SSH凭据做一次真正的SSH连接,如果连接失败,就要告警,因为这代表两种情况:要么是对方改了密码,要么是自己的后门权限被清了。这两种情况都需要人工介入,早发现比晚发现强得多。实战里我经常看到有人权限早就丢了还在那里写Flag读取脚本,最后提交失败才发现连不上了,浪费了一整段比赛时间。

2.3 批量操作执行器的设计思路

有了清单和状态轮询之后,下一步就是批量执行器。这个模块不需要多复杂,核心就是读取清单,遍历所有目标SSH主机,在每台上执行同样的命令。我用的是Paramiko库写了一个统一执行函数,把连接、执行、输出、断开封装好,所有后续模块(权限维持、加固、Flag读取)都复用这个函数。这个执行器要支持两个模式:全目标执行和按目标过滤执行。

按目标过滤执行非常关键。AWD中经常会遇到"只有某台机器需要紧急处理"的情况,比如有一台被对手打进去丢了后门,你不可能对所有目标都做一遍应急响应。所以执行器要允许传入目标IP或者队伍编号来做过滤。这个功能听起来简单,实际比赛里帮我省了不少事。有一次我只需要对所有Web框架为PHP的目标做一遍disable_functions加固,如果手动一台台登录,至少十分钟;用过滤器加一条命令,几秒钟就全跑完了。

3. 权限维持的三个层次:从跑通漏洞到持续可控

3.1 进程级与临时性后门:最容易被清但也最常见

很多刚开始打AWD的人会把权限维持理解成"种个木马",其实这个理解太粗了。比赛中的权限维持至少有三个层次,每一层的持久性、隐蔽性、被发现风险和保留成本都不一样。第一层是进程级后门,也是最初级、最常见、最容易丢的。典型做法是反弹Shell或者直接在Web目录写入一个一句话木马,靠Web服务进程去执行命令。这层后门的生命周期非常脆弱:靶机一旦重启进程就没了,checker扫描Web目录会直接删文件,对手可能用同样的漏洞路径把你后门清掉,甚至直接替换成他自己的后门。所以它只适合在刚拿到权限的几分钟内快速建立控制,不能作为长期依赖。

3.2 系统机制持久化:比赛中最可靠的保底选择

第二层是利用系统本身的机制和正常服务做持久化,比如SSH公钥、计划任务、系统服务、启动脚本等。这类后门的特点是"看起来像正常系统文件",checker通常不会一刀切删除,因为它们可能是系统正常运维的一部分。比如往authorized_keys里写入自己的公钥就是最简单可靠的保底手段:只要SSH服务开着、密钥没被清,比赛全程随时都能直接登录,不需要依赖任何Web漏洞。

计划任务和系统服务也很有用,但要注意存活条件和启动频率。有些选手喜欢加一个每分钟执行的反弹任务,结果因为反弹脚本里连接的IP写的是自己本机的外网地址,而比赛内网根本不通外网,白折腾半小时。我在做批量权限维持时,会把这三类方式混合布设:SSH公钥作为主通道,计划任务作为备用通道,Web后门只作为应急快速通道。混合布设的思想是"鸡蛋不放一个篮子",即使其中一两个被对手发现并清除,还有底层通道兜底。

3.3 网络层与配置层面的长期存活技巧

第三层相比前两层更隐蔽,也更适合团队比赛。它不是再放一个后门文件,而是利用现有服务的配置做权限维持,比如创建一个带有特殊权限的系统用户、修改服务运行参数、在启动脚本中追加命令。这类做法检查难度大,普通对手不会去看系统服务配置,checker也一般不会跑到这么深的层面去做语义判断。但它也有明确短板:比赛规则和平台检查尺度不同,有些平台会限制某些行为,所以在使用前必须确认规则。

我这里要说一个重要原则:权限维持宁可多,也不要只依赖一条路。比赛后半段所有队伍都在互相清后门,同一时间可能有多个对手在扫描你的靶机。如果你只放了一个Web后门,被清掉之后就只能从头开始打漏洞;但如果你同时保留了SSH公钥、计划任务、服务自启和Web后门,对手至少需要同时发现并清掉这四条路,才能彻底剥夺你对靶机的控制权,这个成本对他来说很高,实际操作中几乎做不到。

维持方案持久性隐蔽性被自动扫描发现风险维护成本
Web一句话木马低,重启即失低,路径易被扫高低
SSH公钥登录高,除非被查中,登录日志可见中极低
计划任务反弹中,依赖任务周期中中中
系统服务自启高,融合系统机制高,检查难低中
特殊系统用户高高低中

4. 基线加固的优先级与冲突处理:先保命再谈反打

4.1 加固优先级排序

很多人拿到靶机第一件事就是冲进去删文件、改配置,但到底先加固什么,很多人的思路是乱的。AWD里加固的本质是"减少对手可利用的攻击面",所以加固顺序应该严格按"暴露程度和利用难度"来排。我自己的优先级排序是:先堵Web层通用漏洞入口,再清账户和弱口令,然后封禁危险函数和危险配置,最后是有选择地关闭非必要服务。为什么Web层排第一?因为大多数AWD攻击流量都走Web端口,Web层暴露面最大、对手的攻击成本和门槛最低,一个简单的文件上传漏洞或者命令执行漏洞可能几秒钟就打进来。先堵这层,能挡住大部分"低水平轰炸式"攻击。

4.2 加固动作的细节与陷阱

Web层加固动作有几个细节容易出问题。比如修改默认后台路径时,很多人只改了路径,但旧路径还是能访问,等于没改。处理办法是改完路径后要在旧路径上做一次访问测试,返回404才算成功。又比如删除安装目录或者卸载文件时,有些文件是Web运行必需的,删完服务直接崩。比赛里我见过有人把某CMS的install目录删了,结果整个后台登录都失败了,等于自断一臂。稳妥做法是先用规则拦截访问而不是物理删除,比如在Nginx或Apache配置里加一条Deny规则,既堵了路径又不破坏程序完整性。

账户和口令这块也容易踩坑。批量改密码时一定要确认密码策略和复杂度,有些系统要求密码必须包含特定字符,如果改的密码不满足策略,命令执行会成功但密码没有生效。更隐蔽的问题是,改了root密码但忘了系统里还有别的管理员账户,对手直接用那个账户登录进来,你改密码等于白改。所以加固时要做的是"枚举所有可登录用户,逐一处理",不能只盯着root。

4.3 加固与权限维持的冲突处理

这里必须单独强调一个矛盾点:你的加固操作可能把你自己的权限维持也给堵了。最典型的是封禁危险函数。在PHP里设置disable_functions时,如果封得过狠,可能连系统函数都被禁用,Web后门里的命令执行功能直接失效。我在第一次打比赛时就把exec、system、passthru全封了,结果自己的PHP后门也执行不了命令,等于亲手把自己权限给断了。

解决这个冲突的思路是分层处理:权限维持的通道不要只依赖Web层命令执行,系统层的SSH公钥和计划任务不受disable_functions影响。如果你的保底通道在系统层,那么Web层即使封得很死也不怕,这正好回到前面说的"三层权限维持"的价值。加固前建议先把SSH公钥这类保底通道布好,再去做Web层封禁,这样就算封错了也有退路。

5. Flag自动读取与提交:把重复劳动交给脚本

5.1 Flag的常见位置与时序

AWD拿分的主要方式是读取目标机器上的Flag文件并按平台要求提交。Flag文件的位置通常有规律:有的在根目录下叫flag,有的放在Web目录,有的放在/tmp下,还有的会按队伍分隔目录存放。比赛中Flag还会定期刷新,也就是所谓的"Flag轮换",每隔几分钟所有队伍的Flag都会变化一次,你必须反复提交才能持续得分。如果你手动去每台机器上找Flag,光是在SSH和平台之间来回切换就够呛,所以这一步特别值得自动化。

要写好Flag自动读取脚本,先得把目标信息摸清楚。对每台目标机器,我需要知道Flag文件的准确路径、格式特征、以及是否在Web目录下可被HTTP直接读取。通常我会先手动登录一台机器,把Flag文件所在的目录结构和命名规律搞清楚,然后写进配置。这样脚本再对其他目标做同样操作时,路径就是准确的。

5.2 批量读取脚本的关键设计点

批量读取脚本的骨架是:读取资产清单,逐个SSH登录,在远端执行寻找Flag的命令,把输出传回本地,按平台要求的格式生成提交串。我会用Paramiko写这个脚本,核心逻辑可以复用。在远端执行寻找Flag的命令时,不能只靠一个固定路径,要留有余量,比如用find / -name "flag*" 2>/dev/null去搜,但要注意控制执行时间,避免在每台机器上等太久。更效率的做法是先试已知路径,如果读不到再触发全盘搜索。

读取到Flag内容后,脚本要做两步处理:一是校验合法性,AWD平台的Flag一般有固定前缀和长度,比如"flag{...}"或者一长串base64字符,如果读取结果明显不符合格式,说明找错了文件或者权限不足,这时候要主动告警而不是强行提交;二是按平台要求做编码或加密,有的平台要求提交前用base64编码,有的要求带时间戳防重放,这些细节必须提前从比赛规则里确认。我见过有人脚本跑得很欢,但提交格式不对,一整天全在提交无效数据,等于白忙。

5.3 提交策略与防止误判

自动提交不是无脑狂提交,这里要注意几个策略问题。首先是防重放,有些平台会在后台检查提交记录,如果同一时间频繁提交相同Flag,可能会被判定为异常操作,轻则无效,重则封掉你队伍的上分通道。所以脚本里要加去重逻辑,每轮提交前先对比上次成功提交的内容和时间,相同就不提交,避免重复无效请求。

其次是限速和随机延时。批量脚本如果同时从多台机器向平台提交,可能瞬间造成大量请求,容易触发平台的限流机制。我会在每次提交之间加一个随机延时,比如1到3秒,分散请求时间。这个操作看起来没什么技术含量,但在实战中真的能防止很多无谓的封禁风险。还有一点:提交历史要全部记录下来,包括时间、目标IP、Flag内容和提交结果,方便比赛结束后复盘,也方便赛中出现"为什么这轮没得分"时快速定位问题。

6. 实战事故复盘与我的应急习惯

6.1 误操作把自己锁在门外

比赛中最常见的事故之一是加固时把自己锁在门外。典型场景是修改SSH配置,比如把PermitRootLogin改成no,或者改了端口,但没改防火墙放行规则,结果新端口进不去。这类事故修复成本极高,因为你已经无法登录机器了,只能去Web层另找入口,如果Web后门又被清掉,基本等于放弃防守。我现在的习惯是在做任何可能影响SSH连接的操作前,先用脚本开一个临时防火墙放行规则,并把新规则写入资产清单,做完之后马上验证SSH还是否可用,确认没问题再继续下一步。临时规则在验证成功后再清理,整个过程不超过30秒。

还有一个非常隐蔽的坑是批量改密码。如果资产清单里记录的密码本来就有一台是错的,批量脚本在那一台上执行失败,脚本会继续跑后面的目标,但你可能没注意到失败。等到需要登录那台机器时才发现凭据不对,然后翻日志,发现改密码命令根本没执行成功。所以批量执行的输出一定要收集回来做检查,不能用"看起来跑了就是跑了"的心态了事。

6.2 黑吃黑问题:别人留下的后门不能只看到就删

AWD比赛到后半段,几乎每台目标机器上都布满了多个队伍留下的后门。删除别人的后门是防守的一部分,但这里有个尺寸问题。有些后门伪装得和正常文件一模一样,你随手一删,可能连靶机原本的关键功能都给删了。更麻烦的是有的对手会把后门藏在系统缓存或临时目录里,文件名随机,想靠手动删除根本不现实。最好的做法是提前准备好一组Web目录和系统关键目录的"已知坏文件"黑名单,结合文件hash来判定哪些是后门、哪些是正常文件。删除前先用hash校验做一次确认,只删除黑名单命中项,最大限度减少误删。

清理后门时还要注意"不要只清可见的"。比如你在Web目录发现一个木马文件,手工删掉了,但对方的计划任务还会在下一分钟把它重新写回来。所以清理动作要连带查计划任务、启动脚本、系统服务和SSH公钥,这些位置都可能藏着后门的"复活机制"。如果只清一个文件,不清理源头,等于没有防守。

6.3 比赛后半段的资源与注意力管理

比赛进入后半段,体力下降、注意力分散是真实的,很多人这时候就开始疯狂漏操作。我的习惯是给状态看板加一个"紧急队列",把所有未完成的关键操作列出来,按优先级排序:第一优先级是所有目标都失去权限维持的情况,第二优先级是Flag自动提交还在报错的情况,第三优先级是还有目标没完成Web层加固的情况。后半段只看紧急队列,不再把时间消耗在"全面检查所有东西"上。这样虽然可能会漏掉某台机器上的小问题,但能保证核心得分链路和防守底线不崩,总比分心管理每一台最后全都没管好要强。

另外要特别注意:下半场很多对手的注意力也从攻击转向了防守,他们会主动清掉你的后门并布设他们自己的权限维持。所以即使前半段一切正常,后半段也要定期做一次权限存活检测,不能以为布完就永远安全。我的状态轮询脚本会在后半段跑得更勤,每隔5分钟就检测一次SSH凭据是否还能登录,一旦发现丢失马上走应急方案,重新用其他通道恢复控制。

6.4 工具本身的安全性与日志清理

最后想说一个很多人忽略的层面:管理工具本身也要安全。比赛里你可能在一台被对手控制的机器上跑脚本,如果你把敏感信息写在脚本里,比如密码、后门路径、Flag配置,这些信息可能被对手看到。所以批量操作脚本里的凭据建议采用从本地配置文件读取的方式,不直接硬编码在任何线上文件里。同时,脚本执行完的临时文件、日志都要及时清理,避免在目标机器上留下过多痕迹,给对手反向追踪你的操作手法提供素材。

日志清理也是同样的道理。AWD比赛中留下的操作日志不仅暴露你的路径,还可能暴露你的工具链和习惯。我每次批量操作之后都会顺手清理几条关键日志记录,比如删除自己本次连接对应的时间段记录,让对手看到的信息尽量少。不过这里要拿捏分寸,如果清理得太干净反而引起警觉,所以我会选择性地保留一部分看起来无害的历史记录,伪装成正常的系统运维行为。

比赛打得多了,我越来越深地体会到一件事:AWD拼的不只是漏洞利用的熟练度,更是把重复性工作压缩到极致的能力。真正拉开分数差距的往往不是谁能更早打进一台机器,而是谁能在打进之后迅速站稳、持续稳住、高效拿分。一套设计合理的一站式管理方案,恰好就是从这个角度切入的:多目标资产清单让你不迷路,三层权限维持让你不掉线,按优先级排序的加固让你不崩溃,自动化的Flag读取和提交把你从重复劳动中解放出来。希望这篇文章能帮你理顺自己的工具思路,下次开赛,别再手忙脚乱。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询