news 2026/10/1 7:09:56

AWD攻防赛脚本集合:从手动加固到半自动防守的实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AWD攻防赛脚本集合:从手动加固到半自动防守的实战指南

简介:这是一份面向网络安全竞赛选手与攻防爱好者的AWD实战脚本工具包,围绕攻击与防守两条主线整理,适合具备一定渗透测试基础、希望系统备赛或复盘演练的读者使用。压缩包共34个文件,约3.18MB,以Python脚本、PHP木马与Webshell、txt说明文档为主,另含pyc编译文件、rar工具包、exe程序及md说明,覆盖信息收集、漏洞扫描、渗透利用、Web漏洞检测、日志分析与防御策略等环节。目录按Prepare-for-AWD、Attack、Defense等模块划分,包含不死马生成与克制、批量命令生成、文件监控、WAF及日志安全分析工具等具体脚本,便于读者直接对照赛题场景搭建攻防环境、理解常见利用与防护思路。目前已有688人学习下载,可作为团队协作与应急响应训练的参考资料,请在合法合规前提下使用。

1. AWD攻防赛脚本集合:从“手忙脚乱”到“半自动防守”的落地思路

打AWD攻防赛最让人血压飙升的,不是对手有多强,而是开局前十分钟你还在手动改SSH密码、挨个关服务、满屏找flag提交地址。等你好不容易把第一轮加固做完,别人已经用脚本批量提交了三轮flag。AWD攻防赛脚本集合.zip这个标题,本质上指向的就是把这类重复动作沉淀成可复用脚本,让防守方在有限时间内把精力留给真正的漏洞分析和权限维持。它适合三类人:第一次参赛不知道怎么下手的萌新、打了三四场但每回都靠手速硬扛的中段选手、以及想把自己队伍流程标准化的队长。这一章先把脚本集合要解决的核心问题讲清楚,后面几章再拆具体脚本怎么写、怎么调、怎么避坑。

AWD(Attack With Defense)的赛制决定了脚本的价值边界。每轮通常有固定的check时间、flag刷新周期和提交窗口,防守方要做的事高度重复:改密码、备份源码、监控文件变动、批量提交flag、封禁异常IP。这些动作单次做不费劲,但一轮接一轮做下来,手速和注意力都会被消耗光。脚本集合的意义不是替你打比赛,而是把“必须做但不需要思考”的部分自动化,让你有时间去看日志、分析流量、找对手的入口。我见过太多队伍输在“加固没做完就被打穿”,而不是输在漏洞本身。

需要先明确一点:脚本集合不是拿来即用的银弹。每场比赛的环境、服务端口、flag路径、提交接口都可能不同,直接跑别人的脚本大概率翻车。正确的用法是把它当成模板库,理解每个脚本的输入输出和依赖,再按当场环境改参数。下面几章会按“环境准备 → 核心脚本实现 → 避坑 → 进阶技巧”的顺序展开,每个脚本都给出可复现的代码和参数说明,你照着改就能用。

2. 赛前环境准备与脚本目录结构:把战场先搭起来

2.1 为什么脚本集合要先定目录结构

很多人拿到脚本集合第一反应是直接运行,结果发现路径写死、依赖缺失、日志乱飞。AWD比赛时间紧,脚本跑不起来比没有脚本更让人崩溃。我一般会在赛前十分钟内把目录结构固定下来,所有脚本按功能分目录,配置和日志分离。这样做的好处是:改参数只动config,看结果只翻logs,脚本本身不用动。常见做法是建一个awd_tools根目录,下面分config、scripts、logs、backup四个子目录。config放目标IP列表、提交接口、密码字典;scripts放各类功能脚本;logs存运行输出;backup存源码和数据库备份。这个结构不复杂,但能让你在慌乱中快速定位问题。

2.2 用一条初始化脚本把目录和依赖一次搞定

下面这个bash脚本负责创建目录结构、检查Python依赖、生成默认配置文件。它不涉及任何攻击行为,只是把工作区准备好。

#!/bin/bash # init_awd_env.sh - AWD赛前环境初始化 # 用法: bash init_awd_env.sh BASE_DIR="$HOME/awd_tools" mkdir -p "$BASE_DIR"/{config,scripts,logs,backup} # 生成目标配置文件,比赛时替换为实际IP cat > "$BASE_DIR/config/targets.txt" <<EOF # 每行一个目标,格式: IP:PORT 192.168.1.10:22 192.168.1.11:80 EOF # 生成flag提交接口配置 cat > "$BASE_DIR/config/submit.conf" <<EOF # flag提交接口,按比赛实际填写 SUBMIT_URL="http://10.0.0.1/api/submit" TOKEN="your_team_token_here" EOF # 检查Python3和常用库 python3 -c "import requests, paramiko" 2>/dev/null if [ $? -ne 0 ]; then echo "[!] 缺少依赖,尝试安装..." pip3 install requests paramiko --quiet fi echo "[+] 环境初始化完成: $BASE_DIR"

逻辑说明:脚本先创建四个子目录,然后用heredoc生成两个配置文件。targets.txt存目标列表,submit.conf存提交接口和token。最后检查requests和paramiko是否可用,缺失就装。参数方面,BASE_DIR可以改成你习惯的路径;targets.txt里的IP和端口按当场比赛环境替换;submit.conf里的URL和TOKEN必须从比赛平台获取,不能瞎填。注意pip3 install在某些比赛环境可能没有外网,提前在本地装好或者用离线包。

2.3 目标清单和提交接口的配置要点

targets.txt的格式我习惯用IP:PORT,因为AWD里同一台机器可能开多个服务,端口不同处理方式不同。比如22端口对应SSH改密码,80端口对应Web服务加固。提交接口这块,很多比赛用的是HTTP POST,带token和flag参数,但具体字段名各平台不一样。我一般会先手动提交一次,用浏览器开发者工具或者抓包看请求格式,再写进submit.conf。这一步不能省,否则脚本批量提交全是400错误。另外token有时效性,比赛开始后要确认是否更新。配置文件里不要写死太多东西,留出注释方便当场改。

3. 核心防守脚本实现:改密码、备份、监控、提交

3.1 批量改SSH密码的脚本与参数调优

AWD开局第一件事通常是改SSH密码,防止对手用默认密码或弱口令直接登录。手动改十台机器能累死人,用paramiko批量操作是常见做法。下面这个脚本读取targets.txt,对每个目标的22端口执行改密码命令。

#!/usr/bin/env python3 # change_ssh_pass.py - 批量修改SSH密码 import paramiko import sys def change_password(host, port, old_pass, new_pass): client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: client.connect(host, port=port, username='root', password=old_pass, timeout=5) # 用chpasswd批量改密码,避免交互 cmd = f"echo 'root:{new_pass}' | chpasswd" stdin, stdout, stderr = client.exec_command(cmd) err = stderr.read().decode() if err: print(f"[-] {host} 改密失败: {err}") else: print(f"[+] {host} 密码已更新") except Exception as e: print(f"[!] {host} 连接异常: {e}") finally: client.close() if __name__ == '__main__': old_pass = sys.argv[1] if len(sys.argv) > 1 else '123456' new_pass = sys.argv[2] if len(sys.argv) > 2 else 'Awd@2024!' with open('config/targets.txt') as f: for line in f: line = line.strip() if not line or line.startswith('#'): continue host, port = line.split(':') change_password(host, int(port), old_pass, new_pass)

逻辑说明:脚本用paramiko连接每台目标,执行chpasswd命令改root密码。chpasswd从标准输入读“用户名:新密码”格式,适合非交互场景。参数方面,old_pass是当前密码,比赛初始通常是统一弱口令;new_pass要满足复杂度要求,建议大小写加数字加符号。timeout设5秒,避免卡死。注意有些环境禁用了密码登录或者改了SSH端口,需要提前确认。如果目标数量多,可以加多线程,但AWD里一般就几台到十几台,串行够用。

3.2 源码与数据库的定时备份脚本

AWD里对手可能删你源码、清你数据库,没有备份就只能干瞪眼。备份脚本要解决两个问题:备份什么、多久备一次。我一般用cron每30秒跑一次,备份Web目录和MySQL导出。下面这个脚本把备份打成带时间戳的压缩包。

#!/bin/bash # backup_web.sh - 定时备份Web目录和数据库 BACKUP_DIR="$HOME/awd_tools/backup" TIMESTAMP=$(date +%Y%m%d_%H%M%S) WEB_ROOT="/var/www/html" # 备份Web源码 tar -czf "$BACKUP_DIR/web_$TIMESTAMP.tar.gz" "$WEB_ROOT" 2>/dev/null # 备份MySQL,数据库名和密码按实际改 mysqldump -uroot -p'your_db_pass' --all-databases > "$BACKUP_DIR/db_$TIMESTAMP.sql" 2>/dev/null # 只保留最近20个备份,防止磁盘满 ls -t "$BACKUP_DIR"/web_*.tar.gz | tail -n +21 | xargs -r rm -f ls -t "$BACKUP_DIR"/db_*.sql | tail -n +21 | xargs -r rm -f echo "[+] 备份完成: $TIMESTAMP"

逻辑说明:脚本用tar压缩Web目录,用mysqldump导出所有数据库,文件名带时间戳。保留最近20个备份是为了防止磁盘被撑满,AWD比赛磁盘空间有限,备份太多反而出问题。参数方面,WEB_ROOT按实际Web路径改,mysqldump的密码要填对,否则导出空文件。注意mysqldump在MySQL 8里可能需要加--set-gtid-purged=OFF,具体看版本。cron配置用* * * * * sleep 30; bash backup_web.sh实现每30秒一次。

3.3 文件变动监控与告警脚本

对手拿到权限后通常会留后门、改源码、加webshell。文件监控脚本用inotifywait监听Web目录,发现变动就记录并告警。这个脚本不能阻止攻击,但能让你第一时间知道哪里被动了。

#!/bin/bash # monitor_web.sh - 监控Web目录文件变动 WATCH_DIR="/var/www/html" LOG_FILE="$HOME/awd_tools/logs/file_change.log" inotifywait -m -r -e modify,create,delete,move "$WATCH_DIR" --format '%T %w%f %e' --timefmt '%Y-%m-%d %H:%M:%S' | while read line; do echo "$line" >> "$LOG_FILE" # 发现php文件变动时额外告警 if echo "$line" | grep -qE '\.php'; then echo "[!] PHP文件变动: $line" >> "$LOG_FILE" fi done

逻辑说明:inotifywait的-m表示持续监听,-r递归子目录,-e指定事件类型。--format和--timefmt控制输出格式,方便后续分析。参数方面,WATCH_DIR按实际Web路径改;如果目录文件多,inotifywait可能报“upper limit”错误,需要调大/proc/sys/fs/inotify/max_user_watches。注意这个脚本要后台运行,用nohup bash monitor_web.sh &。日志文件要定期清理,否则也会占空间。

3.4 批量提交flag的脚本与接口适配

flag提交是AWD得分的关键,手动提交太慢,脚本批量提交是标配。下面这个脚本读取flag文件,按submit.conf的配置提交。

#!/usr/bin/env python3 # submit_flag.py - 批量提交flag import requests import sys import time def load_config(path='config/submit.conf'): cfg = {} with open(path) as f: for line in f: if '=' in line and not line.startswith('#'): k, v = line.strip().split('=', 1) cfg[k] = v.strip('"') return cfg def submit(url, token, flag): try: resp = requests.post(url, data={'token': token, 'flag': flag}, timeout=5) return resp.status_code, resp.text[:100] except Exception as e: return None, str(e) if __name__ == '__main__': cfg = load_config() flag_file = sys.argv[1] if len(sys.argv) > 1 else 'flags.txt' with open(flag_file) as f: for flag in f: flag = flag.strip() if not flag: continue code, msg = submit(cfg['SUBMIT_URL'], cfg['TOKEN'], flag) print(f"[{code}] {flag[:20]}... -> {msg}") time.sleep(0.5) # 避免请求过快被限流

逻辑说明:脚本从submit.conf读URL和token,从flags.txt逐行读flag提交。time.sleep(0.5)是防止请求过快被平台限流,具体间隔看比赛规则。参数方面,data里的字段名token和flag要按实际接口改,有的平台用team_token和flag_content。注意提交成功和失败的返回格式不同,脚本只打印前100字符,实际使用时可以加判断逻辑,成功的flag从文件里删掉避免重复提交。

4. 避坑与常见问题:那些年我们踩过的脚本坑

4.1 脚本跑通了但flag提交全是失败

现象:脚本显示提交成功,但平台分数没涨。原因:接口字段名不对或者token过期。解决:先手动提交一次,抓包看请求体格式,确认字段名和token有效性。很多平台token每轮刷新,脚本里要支持从环境变量或文件读取最新token。

4.2 改密码脚本把SSH连接搞断了

现象:改完密码后脚本自己连不上了,后续操作全失败。原因:脚本用旧密码连接,改密后连接断开,但脚本没有重新连接的逻辑。解决:改密和后续操作分开脚本,改密后确认新密码可用再执行其他任务。另外不要一次性改所有机器,先改一台验证。

4.3 备份脚本把磁盘写满了

现象:比赛后半段服务异常,检查发现磁盘100%。原因:备份文件没清理,或者mysqldump导出频率太高。解决:备份脚本里加保留数量限制,比如只留最近20个。另外mysqldump可以加--single-transaction减少锁表时间,但导出频率别太高,30秒一次足够。

4.4 文件监控脚本报inotify limit错误

现象:monitor_web.sh启动后报“Failed to watch, upper limit on inotify watches reached”。原因:Web目录文件太多,超过系统默认的inotify watch上限。解决:临时调大echo 524288 > /proc/sys/fs/inotify/max_user_watches,或者只监控关键子目录,不要递归整个大目录。

4.5 脚本依赖在比赛环境装不上

现象:pip3 install报网络错误,脚本跑不起来。原因:比赛环境没有外网或者pip源不可用。解决:赛前在本地把requests、paramiko等库打包成whl,用pip3 install --no-index --find-links=./whl requests离线安装。或者直接用系统自带的curl和bash实现功能,减少Python依赖。

5. 进阶技巧:把脚本集合变成真正的防守体系

脚本集合用熟了之后,可以往两个方向进阶。第一个方向是加日志聚合和告警,把文件监控、登录日志、提交流水统一到一个时间线上,方便赛后复盘。我一般会写一个简单的Python脚本,用pandas把logs目录下的日志按时间排序,输出成一张表。这样你能清楚看到对手什么时候进来、改了什么、你什么时候提交的flag。第二个方向是加简单的对抗逻辑,比如检测到某个IP频繁访问就自动加iptables规则封禁。但要注意,自动封禁有风险,可能误封裁判机的check请求,导致服务不可达扣分。我一般只封禁连续多次404或者明显扫描特征的IP,并且加白名单。

验证脚本是否有效,最直接的方法是在本地搭一个模拟环境。用Docker起两台容器,一台当靶机,一台当攻击机,跑一遍改密码、备份、监控、提交的完整流程。重点看三个指标:脚本执行时间、日志是否完整、异常情况是否被捕获。我自己的习惯是每次比赛前把脚本集合在本地跑一遍,确认没有语法错误和路径问题。比赛结束后把当场改过的参数和踩的坑记在一个markdown文件里,下次直接翻。这个习惯帮我省了很多重复调试的时间。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 7:09:44

跑在你电脑上的 AI 智能体:从写代码到做 PPT,TaoToken 一句话搞定

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/1 7:09:10

黑马程序员Java教程学习笔记(六)

File类 File类概述和创建&#xff0c; 代码中的变量&#xff0c;数组&#xff0c;对象&#xff0c;集合他们是存储内存中的数据容器。他们记住的数据&#xff0c;在断电&#xff0c;或者程序终止时数据会丢失。 有些数据想要长久保存&#xff0c;就需要把数据存储在文件中。…

作者头像 李华
网站建设 2026/10/1 7:08:56

Spring Boot @RequestBody 406异常根因与解决方案

1. 这个异常不是“406 Not Acceptable”&#xff0c;但比它更让人抓狂刚接手一个Spring Boot项目&#xff0c;前端发来一个POST请求&#xff0c;body里是标准的JSON字符串&#xff0c;Content-Type头也明明白白写着application/json&#xff0c;可后端日志里却冷不丁跳出一行红…

作者头像 李华