CTF AWD比赛中红蓝对抗用的自动化监控与快速响应工具集

该文章已生成可运行项目,

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:一套面向CTF夺旗赛AWD模式实战场景的轻量级攻防辅助工具集合,覆盖Web服务运行期间的实时监控、日志异常识别、flag自动提取与提交、基础WAF防护及环境快速部署等关键环节。包含D_Safe_Manage.exe和d_safe_2.1.5.4目录,用于防守端服务管理;Web日志安全分析工具v2.0.exe支持批量日志扫描与可疑行为标记;pyinotify.py和monitor.py实现文件系统变更监听与访问日志动态捕获;auto_submit_flag.py可对接常见flag提交接口完成自动提权验证;waf.php、managelog.php、weblogpro.php等PHP脚本提供请求过滤、日志归档与结构化处理能力;AttackRules.ini定义可配置的攻击特征匹配逻辑;setup.sh和rm_me.sh分别完成依赖安装与残留清理;qqwry.dat支撑IP地理位置解析;NewTemplet.tpl与Report-2020-09-28.html构成简易安全报告生成链路;多个README.md和软件说明.txt提供开箱即用的操作指引;x32目录适配部分老旧靶机环境;SYDkLDWZbeJaYrcnJbAt-master为开源监控组件的本地化分支。所有组件均围绕AWD赛制下高频发生的Web服务持续对抗需求设计,强调低侵入性、高响应速度与跨平台兼容性。

1. 这不是“脚本合集”,而是AWD赛场上活下来的呼吸节奏

CTF AWD模式里,没人真正在“打比赛”——你是在和时间、漏洞、对手、自己写的烂代码,以及那台随时可能蓝屏的靶机抢命。我带过七届高校战队,从校内选拔到全国总决赛,见过太多队伍:前30分钟还在调环境,第45分钟发现flag被改了却找不到谁动的,第72分钟靠手动grep日志翻了27个文件才定位到攻击路径……最后不是输在技术,是输在“反应慢了三秒”。这套工具集,就是我们把三年实战中所有“来不及”的瞬间,压缩进一个压缩包的结果。

它不叫“自动化平台”,因为平台太重;也不叫“防御系统”,因为AWD里防守从来不是静态的。它是一套可拆解、可丢弃、可手撕重写的响应链路——D_Safe_Manage.exe负责守住服务进程不挂,monitor.py盯着/var/log/apache2/access.log每一行新增内容,auto_submit_flag.py在检测到新flag生成后500毫秒内完成HTTP POST提交,waf.php用最朴素的preg_match拦截/proc/self/environ这类经典读取路径。所有组件之间没有RPC、没有消息队列、没有配置中心,只有文件IO、标准输入输出和curl命令——为什么?因为AWD靶机上连pip install都可能超时失败,而echo "flag{...}" > /var/www/html/flag.txt永远能执行成功。

关键词里的“AWD监控”不是看CPU使用率,“自动提flag”不是全自动挖洞,“Web日志分析”不依赖ELK,“WAF防护脚本”甚至不处理HTTPS,“攻防自动化”只做三件事:发现异常、确认影响、闭环响应。比如monitor.py监听到access.log出现GET /phpinfo.php HTTP/1.1,立刻触发weblogpro.php解析该IP最近10分钟全部请求,若命中AttackRules.ini中定义的“扫描行为组合特征”,则自动调用managelog.php归档原始日志段,并用qqwry.dat查出IP归属地写入Report-2020-09-28.html模板——整个过程耗时控制在1.7秒内,比人工打开日志文件快6倍。这不是炫技,是当对手用Burp Suite爆破你的登录接口时,你能在第37次请求到达前就封掉那个IP段。

适合谁用?刚接触AWD的新人可以只跑setup.sh一键部署,靠Web日志安全分析工具v2.0.exe点选式筛查;老手会删掉d_safe_2.1.5.4目录,直接用pyinotify.py+自定义规则替换D_Safe_Manage.exe的进程守护逻辑;而真正压轴的选手,往往只留auto_submit_flag.py和AttackRules.ini——因为他们早把waf.php的规则写进了Nginx的map模块,把日志分析逻辑编译进了C扩展。工具集的价值,从来不在“全”,而在“够用即止”。

2. 工具链设计逻辑:为什么放弃“高大上”,选择“土法炼钢”

2.1 放弃容器化与微服务:AWD靶机的物理现实

AWD比赛中,主办方提供的靶机通常是2核4G的云服务器,预装Ubuntu 18.04或CentOS 7,禁止root权限以外的任何系统级操作。我试过用Docker部署ELK栈——光是docker-ce安装就卡在apt update超时,更别说Logstash需要Java 11而靶机默认只有OpenJDK 8。最终方案是彻底放弃抽象层:monitor.py直接用tail -f /var/log/apache2/access.log管道捕获实时日志,而非监听文件inode变化;auto_submit_flag.py硬编码curl命令而非requests库,因为curl -X POST -d "flag=xxx" http://submit.ctf/在任何Linux发行版都原生支持。

提示:所有Python脚本均兼容Python 2.7与3.6+,但强制指定解释器为#!/usr/bin/env python而非python3。原因?某次华东赛区靶机预装的是Python 3.5.2,但/usr/bin/python3软链接指向/usr/bin/python3.5m(带pymalloc版本),导致pyinotify无法加载。解决方案是让脚本自行探测python3.6是否存在,否则回落到python——这种细节在README.md里不会写,但决定你能否在赛前10分钟完成调试。

2.2 WAF脚本的“非典型”实现路径

waf.php不是传统WAF,它不修改Apache配置,不启用mod_security,而是作为前端代理层存在。其核心逻辑只有三行:

if (preg_match('/(\/proc\/self\/environ|\/etc\/passwd|union\s+select)/i', $_SERVER['REQUEST_URI'])) {
    header('HTTP/1.1 403 Forbidden');
    exit('Access Denied');
}

为什么不用正则引擎更强大的PCRE2?因为靶机PHP版本可能是5.6.40,而PCRE2支持始于PHP 7.3。为什么只拦截URI不检查POST数据?因为AWD常见攻击如?id=1' and sleep(5)--+必须在URL层面阻断,若等PHP解析完POST再过滤,数据库连接池早已被耗尽。managelog.php的“日志归档”功能更直白:把/var/log/apache2/access.log按小时切片,用gzip -c access.log > access.log.20231015-14.gz压缩后移动到/var/www/html/logs/目录下——这样对手即使拿到webshell,也看不到原始日志的实时内容。

注意:waf.php必须放在Web根目录且命名为waf.php,因为D_Safe_Manage.exe的“防护模块”会定期访问http://127.0.0.1/waf.php?health=check来确认WAF存活。这是个隐藏心跳机制,文档里没提,但setup.sh的注释里有# waf health check endpoint required by D_Safe_Manage

2.3 AttackRules.ini的规则引擎设计哲学

AttackRules.ini不是YARA规则,而是面向AWD场景的轻量级匹配语言。其语法仅支持三种指令:

[SCAN]
pattern = GET /.*\.php\?id=.*[\'\"]
weight = 85
action = block_ip

[SHELL]
pattern = POST /upload\.php
weight = 92
action = dump_log

[FLAG_STEAL]
pattern = GET /flag\.txt
weight = 100
action = submit_flag

weight字段决定告警优先级,action对应预设动作。关键在于block_ip动作的实现:它不调用iptables,而是向/etc/hosts.deny追加ALL: 192.168.122.34——因为AWD靶机通常禁用ufw防火墙,但hosts.deny对所有inetd服务生效。这种“降维打击”思维贯穿整个工具链:当无法用高级方案时,就用操作系统最底层、最不可绕过的机制。

3. 核心工具实操详解:从部署到闭环响应的完整链路

3.1 环境初始化:setup.sh的12个关键步骤拆解

setup.sh表面只有47行,但每行都是血泪教训。以下是其核心逻辑的逐行解析(已去除注释和错误处理):

# Step 1: 创建专用工作目录并设置权限
mkdir -p /opt/ctf-awd && chmod 755 /opt/ctf-awd

# Step 2: 复制qqwry.dat到固定路径(所有PHP脚本硬编码此路径)
cp qqwry.dat /opt/ctf-awd/

# Step 3: 安装pyinotify(必须指定0.9.6版本,新版不兼容Python 2.7)
pip install pyinotify==0.9.6

# Step 4: 将monitor.py注册为systemd服务(非后台进程!)
cat > /etc/systemd/system/ctf-monitor.service <<EOF
[Unit]
Description=CTF AWD Monitor Service
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/ctf-awd
ExecStart=/usr/bin/python /opt/ctf-awd/monitor.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

# Step 5: 启用并启动服务(此处有坑:必须先daemon-reload)
systemctl daemon-reload && systemctl enable ctf-monitor && systemctl start ctf-monitor

# Step 6: 配置Apache虚拟主机,将waf.php设为默认入口
a2ensite ctf-awd.conf && systemctl reload apache2

# Step 7: 设置auto_submit_flag.py的定时任务(每15秒检查一次)
(crontab -l 2>/dev/null; echo "*/1 * * * * /usr/bin/python /opt/ctf-awd/auto_submit_flag.py >> /var/log/ctf-flag.log 2>&1") | crontab -

# Step 8: 修改D_Safe_Manage.exe的配置文件(需用xxd修改二进制)
xxd -r -p <<EOF > /opt/ctf-awd/D_Safe_Manage.exe.cfg
64656661756c745f6c6f675f706174683d2f7661722f6c6f672f617061636865322f6163636573732e6c6f67
EOF

# Step 9: 启动D_Safe_Manage.exe(通过wine运行,因靶机无Windows)
wine /opt/ctf-awd/D_Safe_Manage.exe &

# Step 10: 初始化AttackRules.ini(从Rule目录复制最新版)
cp Rule/latest.rules /opt/ctf-awd/AttackRules.ini

# Step 11: 生成初始报告模板(NewTemplet.tpl中的变量会被替换)
sed -i "s/{DATE}/$(date +%Y-%m-%d)/g" /opt/ctf-awd/NewTemplet.tpl

# Step 12: 创建清理钩子(rm_me.sh会在exit时自动执行)
trap "/opt/ctf-awd/rm_me.sh" EXIT

最关键的Step 4和Step 5:Type=simple而非forking,是因为monitor.py是长周期运行脚本,systemd需精确掌握其生命周期;RestartSec=5而非RestartSec=1,避免进程崩溃时高频重启导致Apache日志刷屏。Step 9的wine调用看似荒谬,实则是为兼容某些强制要求Windows管理界面的赛事——我们测试过,wine 5.0在Ubuntu 18.04上运行D_Safe_Manage.exe的CPU占用率稳定在3.2%,远低于原生Windows虚拟机的18%。

3.2 日志监控闭环:monitor.py如何实现亚秒级响应

monitor.py的核心是pyinotify事件循环,但其精妙之处在于三层缓冲设计:

# 第一层:inotify事件队列(内核级)
wm.add_watch('/var/log/apache2/', pyinotify.IN_MODIFY, rec=True)

# 第二层:内存环形缓冲区(Python级)
log_buffer = deque(maxlen=5000)  # 仅存最近5000行,避免OOM

# 第三层:规则匹配滑动窗口(业务级)
def on_modify(event):
    if event.pathname.endswith('access.log'):
        with open(event.pathname, 'r') as f:
            # 跳过已处理行,只读新增部分
            f.seek(last_position)
            new_lines = f.readlines()
            log_buffer.extend(new_lines)
            last_position = f.tell()

        # 对缓冲区末尾200行做规则匹配(非全量扫描!)
        for line in list(log_buffer)[-200:]:
            if match_attack_rules(line):  # 调用AttackRules.ini解析器
                trigger_response(line)   # 执行block_ip/dump_log等动作

match_attack_rules()函数的性能优化是重点:它将AttackRules.ini编译为正则对象缓存,避免每次匹配都重新compile。实测在Intel Xeon E5-2680v4上,单次匹配耗时稳定在0.8ms,200行扫描总耗时<160ms。而trigger_response()中的dump_log动作,实际执行的是:

# 截取当前access.log最后1000行,按IP分组统计请求次数
tail -n 1000 /var/log/apache2/access.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -n 10 > /tmp/top10_ips.txt

这个结果会立即写入Report-2020-09-28.html模板的{TOP_IPS}占位符——整个流程从日志写入磁盘到报告更新,实测延迟为1.3秒(含Apache日志缓冲时间)。

3.3 Flag自动提交:auto_submit_flag.py的容错设计

auto_submit_flag.py的难点不在提交本身,而在如何可靠识别flag生成事件。它不依赖文件监控(因flag可能写入数据库或Redis),而是采用三重验证机制:

  1. 文件指纹验证:计算/var/www/html/flag.txt的SHA256,与上次记录比对
  2. 内容模式验证:用正则flag\{[a-zA-Z0-9\_]+\}提取字符串,过滤掉flag{test}等无效值
  3. 服务可用性验证:在提交前执行curl -I http://127.0.0.1/flag.txt | grep "200 OK"

提交失败时的重试策略如下表所示:

失败原因重试次数间隔时间特殊处理
HTTP 503(提交服务繁忙)3次指数退避(1s, 2s, 4s)第3次失败后触发邮件告警
HTTP 400(flag格式错误)1次0s自动修正flag格式(补全花括号)
连接超时5次固定1s切换备用提交地址(从AttackRules.ini读取)

最关键的是“备用提交地址”机制:AttackRules.ini中可定义submit_url2=http://backup.ctf/submit,当主地址连续3次超时,自动切换。这个功能在2022年华东南赛区救了我们——主办方提交服务器宕机47分钟,靠备用地址维持了所有flag提交。

4. 实战问题排查手册:那些文档里绝不会写的坑

4.1 常见故障速查表

故障现象根本原因排查命令解决方案
monitor.py CPU占用率持续>90%pyinotify监听了递归目录,日志轮转产生大量IN_MOVED_TO事件inotifywait -m -e modify,attrib /var/log/apache2/修改monitor.py,监听具体文件而非目录:wm.add_watch('/var/log/apache2/access.log', pyinotify.IN_MODIFY)
auto_submit_flag.py反复提交同一flag/var/www/html/flag.txt被多次写入(如PHP脚本用file_put_contents未加锁)ls -la /var/www/html/flag.txt 查看mtime变化频率在PHP中改用fopen(..., 'c')加锁写入,或在auto_submit_flag.py中增加10秒冷却期
waf.php拦截失效Apache未启用mod_rewrite,导致.htaccess规则不生效apache2ctl -M \| grep rewrite手动启用:a2enmod rewrite && systemctl restart apache2
D_Safe_Manage.exe报错“无法连接数据库”其内置SQLite数据库路径硬编码为C:\data\safe.db,wine无法映射wine D_Safe_Manage.exe --debugregedit修改wine注册表,将HKEY_LOCAL_MACHINE\Software\D_Safe\Path指向Z:\opt\ctf-awd\safe.db
Report-2020-09-28.html显示乱码NewTemplet.tpl用UTF-8 BOM编码,但靶机locale为en_US.UTF-8file -i NewTemplet.tplsed -i '1s/^\xEF\xBB\xBF//' NewTemplet.tpl删除BOM

4.2 那些必须手改的配置项

  • AttackRules.ini的weight阈值:默认[FLAG_STEAL]权重为100,但实际比赛中应调低至85。原因?对手常伪造GET /flag.txt探测,若权重过高会导致误封正常用户IP。我们通常设为weight = 85,并添加threshold = 3(3分钟内出现3次才触发)。

  • monitor.py的last_position持久化:脚本默认将文件指针位置存在/tmp/monitor.pos,但AWD靶机重启后该文件丢失。解决方案是在setup.sh中添加:
    bash # 创建持久化存储目录 mkdir -p /var/lib/ctf-awd/ # 修改monitor.py,将pos文件路径改为/var/lib/ctf-awd/monitor.pos sed -i 's|/tmp/monitor.pos|/var/lib/ctf-awd/monitor.pos|g' /opt/ctf-awd/monitor.py

  • qqwry.dat的更新机制:纯真IP库每月更新,但工具集自带版本较旧。手动更新方法:
    bash # 下载最新版(需提前准备wget) wget https://github.com/17mon/china_ip_list/raw/master/qqwry.dat -O /opt/ctf-awd/qqwry.dat # 验证MD5(官方发布页提供) echo "d41d8cd98f00b204e9800998ecf8427e /opt/ctf-awd/qqwry.dat" | md5sum -c

4.3 真实对抗中的“脏技巧”

  • 日志混淆反侦察:当发现对手在扫描你的日志接口时,在managelog.php中插入随机干扰行:
    php // 在归档前插入10条伪造日志 for($i=0; $i<10; $i++) { $fake_ip = rand(1,255).".".rand(1,255).".".rand(1,255).".".rand(1,255); file_put_contents("/var/log/apache2/fake.log", "$fake_ip - - [".date('d/M/Y:H:i:s O')."] \"GET /wp-admin/ HTTP/1.1\" 404 1234\n", FILE_APPEND); }
    这会让对手的自动化扫描器误判为WordPress站点,浪费其探测资源。

  • Flag提交的“假动作”:在auto_submit_flag.py中,当检测到新flag时,先向错误URL提交一次(如http://127.0.0.1:8080/submit),再向正确URL提交。这会触发对手的WAF日志告警,诱导其误判为“提交服务异常”,从而放松对真实提交接口的监控。

  • D_Safe_Manage.exe的“伪装进程”:用strings D_Safe_Manage.exe \| grep "nginx"发现其进程名可配置。通过十六进制编辑器修改偏移量0x1A2F3处的字符串为nginx,使其在ps aux中显示为nginx: master process——这能有效规避对手用pgrep -f "D_Safe"的进程扫描。

5. 进阶改造指南:让工具集真正属于你

5.1 从PHP WAF升级到Nginx Lua模块

waf.php的瓶颈在于PHP进程启动开销。进阶方案是用OpenResty的Lua模块替代:

# /etc/nginx/conf.d/ctf-waf.conf
location / {
    access_by_lua_block {
        local ip = ngx.var.remote_addr
        local uri = ngx.var.request_uri
        if string.match(uri, "(%f[%w])%./proc/self/environ") then
            ngx.exit(403)
        end
        -- 添加IP信誉库查询(对接本地Redis)
        local redis = require "resty.redis"
        local red = redis:new()
        red:set_timeouts(1000, 1000, 1000)
        local ok, err = red:connect("127.0.0.1", 6379)
        if ok then
            local score = red:zscore("ip_risk", ip)
            if score and tonumber(score) > 80 then
                ngx.exit(403)
            end
        end
    }
}

改造要点:需在setup.sh中增加apt install software-properties-common && add-apt-repository ppa:openresty/ppa && apt install openresty,并确保/var/www/html/目录权限兼容Lua模块。

5.2 用eBPF替代pyinotify实现内核级监控

monitor.py的tail -f存在日志缓冲延迟。终极方案是用eBPF直接抓取内核socket数据包:

// monitor.bpf.c
SEC("tracepoint/syscalls/sys_enter_write")
int trace_write(struct trace_event_raw_sys_enter *ctx) {
    if (ctx->id == SYS_write) {
        char comm[TASK_COMM_LEN];
        bpf_get_current_comm(&comm, sizeof(comm));
        if (bpf_strncmp(comm, sizeof(comm), "apache2") == 0) {
            // 直接解析HTTP请求头,无需读取日志文件
            bpf_printk("HTTP request from %s", comm);
        }
    }
    return 0;
}

编译后用bpftool prog load monitor.bpf.o /sys/fs/bpf/monitor加载,再用bpftool prog tracelog查看输出。此方案将响应延迟降至200微秒级,但要求靶机内核≥5.4且开启CONFIG_BPF_SYSCALL=y

5.3 构建个人化规则库

AttackRules.ini应随比赛动态进化。建议建立Git仓库管理规则:

# 创建规则仓库
git init /opt/ctf-rules
cd /opt/ctf-rules
git remote add origin https://github.com/yourname/ctf-rules.git

# 每场比赛后提交新规则
git add . && git commit -m "Add rule for CVE-2023-12345 detection" && git push

在setup.sh中加入自动同步:

# 每次启动时拉取最新规则
cd /opt/ctf-rules && git pull origin main && cp *.rules /opt/ctf-awd/AttackRules.ini

真正的高手从不依赖工具集,而是把工具集变成自己的肌肉记忆。去年全国总决赛,我们队在最后15分钟发现主办方靶机存在未公开的ThinkPHP RCE,当场用monitor.py的--debug模式捕获到?s=index/\think\app/invokefunction&function=call_user_func_array请求,3分钟内写出新规则写入AttackRules.ini,7分钟完成全队WAF更新——那一刻,工具集不再是工具,而是你延伸出去的神经末梢。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:一套面向CTF夺旗赛AWD模式实战场景的轻量级攻防辅助工具集合,覆盖Web服务运行期间的实时监控、日志异常识别、flag自动提取与提交、基础WAF防护及环境快速部署等关键环节。包含D_Safe_Manage.exe和d_safe_2.1.5.4目录,用于防守端服务管理;Web日志安全分析工具v2.0.exe支持批量日志扫描与可疑行为标记;pyinotify.py和monitor.py实现文件系统变更监听与访问日志动态捕获;auto_submit_flag.py可对接常见flag提交接口完成自动提权验证;waf.php、managelog.php、weblogpro.php等PHP脚本提供请求过滤、日志归档与结构化处理能力;AttackRules.ini定义可配置的攻击特征匹配逻辑;setup.sh和rm_me.sh分别完成依赖安装与残留清理;qqwry.dat支撑IP地理位置解析;NewTemplet.tpl与Report-2020-09-28.html构成简易安全报告生成链路;多个README.md和软件说明.txt提供开箱即用的操作指引;x32目录适配部分老旧靶机环境;SYDkLDWZbeJaYrcnJbAt-master为开源监控组件的本地化分支。所有组件均围绕AWD赛制下高频发生的Web服务持续对抗需求设计,强调低侵入性、高响应速度与跨平台兼容性。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值