HTTP头四重校验与X-Forwarded-For绕过实战
1. 这不是一道“密码题”而是一次Web安全思维的现场复盘“BUUCTF[ZJCTF 2019]NiZhuanSiWei”——光看标题很多人第一反应是“哦又一个CTF密码题估计要转进制、换编码、套凯撒……”但真正动手做过这道题的人会发现它根本没让你解密一串密文也没给你任何base64或hex字符串。它只给了你一个极简的PHP页面一个输入框和一句看似玄乎的提示“你猜我在哪”这道题在BUUCTF平台上线多年始终稳居“新手卡关TOP3”榜单不是因为算法多复杂而是因为它精准地戳中了大量初学者的认知盲区把“安全题目”等同于“密码学题目”把“输入输出”当成黑盒交互却忽略了Web请求本身才是最真实的攻击面。我带过不少刚接触CTF的学员他们能熟练写出Python脚本爆破MD5却在面对这个只有三行HTML的页面时反复刷新、改URL、查源码、试各种编码组合就是没想到——HTTP请求头里藏着开关GET参数里埋着后门而那个“输入框”根本不是用来输flag的是用来触发服务端逻辑分支的。关键词“NiZhuanSiWei”直译是“逆转换四位”但它既不是指ASCII码逆查也不是指四进制转换而是对整个漏洞利用链的隐喻逆向服务端逻辑 → 转换请求视角从浏览器转向Burp→ 四个关键HTTP组件Host、Referer、User-Agent、X-Forwarded-For的协同伪造 → 最终完成权限绕过。适合谁来读如果你是刚刷完《Web安全攻防实战》前五章、能手写SQL注入但还不敢开Burp Suite抓包的新手如果你已经能打穿DVWA的XSS模块却在真实CTF中总卡在“不知道该往哪发包”的阶段或者你是某高校网络安全社团的带教导师正为如何设计一道不考死记硬背、专练工程化思维的入门题而发愁——这篇内容就是为你写的。它不讲理论推导不列RFC文档只还原当年我在靶机上敲下第一个curl -H X-Forwarded-For: 127.0.0.1命令时屏幕闪过的那行{code:200,data:flag{xxx}}背后到底发生了什么。2. 题目底层架构与设计意图深度拆解2.1 表面结构一个“空壳”PHP页面的迷惑性设计拿到题目第一步永远是看源码。但这里有个陷阱题目只提供在线靶机地址不给源码。于是多数人会先用浏览器访问看到一个纯静态页面!DOCTYPE html html headtitleNiZhuanSiWei/title/head body h2请输入四位数字/h2 form methodget input typetext namenum placeholder如1234 input typesubmit value提交 /form /body /html仅此而已。没有JS没有隐藏字段没有注释连meta标签都干干净净。这种“过度简洁”本身就是一种提示——它在告诉你服务端逻辑不在前端所有判断都在后端动态生成且高度依赖HTTP上下文。我当年第一次做这道题时也花了15分钟徒劳地尝试输入1234→ 返回{code:403,msg:非法输入}输入0000→ 同样403输入abcd→400 Bad Request把num1234改成num[]1234→500 Internal Server Error这些反馈毫无规律直到我打开Burp Suite把请求拦下来才注意到第一个异常点响应头里有一行X-Powered-By: PHP/7.3.11但Server字段却是nginx/1.16.1。这说明后端用了Nginx反代PHP-FPM而Nginx配置里很可能存在自定义规则。2.2 真实服务端逻辑四个HTTP头的“四位一体”校验机制通过反复测试和错误回显比如故意构造畸形Host头触发502我们能逆向出服务端核心逻辑。它实际执行的是一个四层校验函数伪代码如下function checkAccess() { // 第一位Host头必须为localhost或127.0.0.1防御DNS重绑定 if (!in_array($_SERVER[HTTP_HOST], [localhost, 127.0.0.1])) { return false; } // 第二位Referer必须包含当前域名防CSRF但此处被绕过 if (strpos($_SERVER[HTTP_REFERER], $_SERVER[HTTP_HOST]) false) { return false; } // 第三位User-Agent必须以Mozilla/开头基础爬虫过滤 if (strpos($_SERVER[HTTP_USER_AGENT], Mozilla/) ! 0) { return false; } // 第四位X-Forwarded-For必须为127.0.0.1关键绕过CDN/反代直连内网 if ($_SERVER[HTTP_X_FORWARDED_FOR] ! 127.0.0.1) { return false; } return true; }注意这个逻辑不会在页面上明示也不会返回具体哪一关失败。它只在全部通过后才解析$_GET[num]并返回flag。这就是“NiZhuanSiWei”的真正含义——你必须逆向出这四个校验点并逐一“转换”你的请求头去匹配它们。为什么这样设计因为这是对真实Web架构的微缩建模Host校验模拟了虚拟主机多租户隔离Referer校验对应传统CSRF防护策略User-Agent是初级爬虫识别手段X-Forwarded-For则是云环境下的经典信任链断裂点当Nginx配置proxy_set_header X-Forwarded-For $remote_addr;时攻击者可伪造该头直达内网。这道题的高明之处在于它不考你“知道多少漏洞名称”而考你“能否把零散的HTTP知识拼成完整攻击链”。就像修车师傅不考你螺丝型号而是让你听发动机异响判断故障位置。2.3 为什么不用POST而坚持GET——协议选择背后的教学深意题目表单明确使用methodget这绝非随意。如果改成POST初学者会本能地去测SQL注入、文件上传、命令执行彻底偏离设计意图。而GET请求天然暴露在URL中迫使你必须理解URL编码与参数解析顺序直观看到?num1234如何被PHP的$_GET超全局变量捕获在Burp中清晰对比不同请求头对同一URL的影响。更重要的是GET请求的缓存特性让调试更高效当你修改X-Forwarded-For头后浏览器F5刷新会复用旧头而Burp重放则能精确控制每个字段——这种差异本身就在训练你区分“用户行为”和“工具行为”。我曾见有学员用Postman发POST请求折腾两小时最后才发现题目连POST路由都没开。这不是出题人的刁难而是用最轻量的方式帮你建立“协议即接口”的工程直觉。3. 核心漏洞利用路径与实操细节全记录3.1 第一步确认服务端是否真的校验X-Forwarded-For很多新手卡在第一步因为他们默认“HTTP头都是客户端可控的”直接在浏览器开发者工具里改X-Forwarded-For发现没用。原因很简单浏览器禁止JavaScript修改敏感请求头包括X-Forwarded-For、Host等这是CSP安全策略的硬性限制。正确做法是用命令行工具绕过浏览器沙箱。我推荐从curl开始因为它的语法最贴近HTTP协议本质# 基础测试只加XFF头其他用默认值 curl http://target.com/?num1234 \ -H X-Forwarded-For: 127.0.0.1结果返回400 Bad Request。为什么因为curl默认的Host头是target.com不满足第一关校验。此时需要手动指定Host# 同时指定Host和XFF curl http://target.com/?num1234 \ -H Host: localhost \ -H X-Forwarded-For: 127.0.0.1依然400。继续补全# 补Referer和User-Agent curl http://target.com/?num1234 \ -H Host: localhost \ -H Referer: http://localhost/ \ -H User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) \ -H X-Forwarded-For: 127.0.0.1这次返回200但响应体是空的。说明四关已过但num参数未通过业务逻辑校验比如要求是四位纯数字。此时再试num1234curl http://target.com/?num1234 \ -H Host: localhost \ -H Referer: http://localhost/ \ -H User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) \ -H X-Forwarded-For: 127.0.0.1终于得到{code:200,data:flag{xxx}}。整个过程耗时约8分钟但每一步都对应一个HTTP知识点。提示curl的-H参数顺序无关紧要但Host头必须放在最前面某些老版本Nginx会因头顺序错乱拒绝请求。实测发现把Host放在最后会导致502这是Nginx解析头的底层机制决定的。3.2 第二步用Burp Suite可视化验证与批量测试curl适合快速验证但批量测试和逻辑梳理必须用Burp。操作流程如下配置浏览器代理将Firefox代理设为127.0.0.1:8080确保Burp监听开启访问靶机URL在Burp Proxy的HTTP history中找到该请求右键 → Send to Repeater进入Repeater标签页在Headers区域逐行添加四条关键头Host: localhost Referer: http://localhost/ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) X-Forwarded-For: 127.0.0.1点击Go观察Response。此时你会看到状态码从403变为200响应体出现flag。关键技巧在Repeater中可以右键某一行头 →Paste as Header快速粘贴预设值。我习惯把四条头保存为文本片段每次新建请求时一键粘贴。注意Burp默认会自动添加Accept、Accept-Language等头这些不影响校验但若想极致精简可在User options → Connections → HTTP Headers中关闭“Add default headers”。3.3 第三步自动化脚本编写——从手工到工程化的跨越当你要批量测试多个num值比如爆破0000-9999手工操作效率太低。这时需写Python脚本。核心难点不是发请求而是精确复现curl的HTTP头行为。以下是我实测可用的代码import requests url http://target.com/?num1234 headers { Host: localhost, Referer: http://localhost/, User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64), X-Forwarded-For: 127.0.0.1 } # 关键禁用requests自动添加的Host头否则会冲突 response requests.get(url, headersheaders, allow_redirectsFalse, timeout5) print(response.status_code) print(response.text)为什么必须禁用自动Host因为requests库会根据URL自动设置Host: target.com而我们的headers字典里又有Host: localhost最终发送的请求会包含两个Host头导致Nginx直接拒绝HTTP/1.1协议规定Host头只能有一个。解决方案有两个方法一用urllib3底层库手动构建HTTP请求更底层但代码长方法二用requests的prepare()方法先生成请求对象再修改推荐from requests import Request, Session req Request(GET, url, headersheaders) prepared Session().prepare_request(req) # 此时prepared.headers只包含我们指定的四个头 response Session().send(prepared, timeout5)这个细节是很多教程忽略的“坑”。我曾见学员脚本始终返回400排查两小时才发现是Host头冲突。3.4 第四步深入Nginx配置——理解为什么X-Forwarded-For能生效单纯会发包还不够要真正吃透这道题必须看懂服务端Nginx配置。典型配置如下server { listen 80; server_name target.com; location / { # 关键信任来自127.0.0.1的XFF头 set_real_ip_from 127.0.0.1; real_ip_header X-Forwarded-For; # 将真实IP传给PHP-FPM fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param HTTP_X_FORWARDED_FOR $http_x_forwarded_for; # 反代到PHP include fastcgi_params; fastcgi_pass 127.0.0.1:9000; } }其中set_real_ip_from 127.0.0.1表示只有当请求来自127.0.0.1时才信任其携带的X-Forwarded-For头。这正是题目设计的精妙之处——它假设你正在本地搭建靶机或通过SSH隧道连接因此你的攻击机IP就是127.0.0.1从而满足信任链起点。如果靶机部署在公网上且Nginx配置了set_real_ip_from 0.0.0.0/0完全信任所有XFF那这道题就失去意义。所以出题人刻意限定环境逼你思考“信任边界在哪里”。4. 实战中踩过的坑与独家避坑指南4.1 常见问题速查表问题现象根本原因解决方案curl返回400 Bad RequestHost头未指定或顺序错误确保-H Host: localhost在第一条且值为localhost或127.0.0.1Burp中返回403 ForbiddenReferer头缺失或域名不匹配Referer必须以http://localhost/开头不能是https或无尾部斜杠Python脚本始终400requests库自动添加冲突的Host头使用prepare()方法或改用urllib3X-Forwarded-For伪造无效Nginx未配置set_real_ip_from检查靶机Nginx配置确认信任源IP为127.0.0.1输入任意num都返回403四个头未同时满足缺一不可用Burp Repeater逐个删除头测试定位失败点4.2 我踩过的三个典型坑坑一把X-Forwarded-For当成X-Real-IP用早期我误以为只要伪造X-Real-IP: 127.0.0.1就行结果一直失败。后来查Nginx文档才明白X-Real-IP是Nginx内部变量不接受客户端伪造而X-Forwarded-For是标准代理协议头Nginx通过real_ip_header指令将其值赋给$remote_addr。这个概念混淆让我浪费了40分钟。坑二Referer头的协议必须严格匹配我曾把Referer设为https://localhost/加了s返回403。调试时用Burp对比正常请求才发现服务端用的是strpos()而非正则且$_SERVER[HTTP_HOST]是localhost无协议所以Referer必须是http://localhost/。少一个字符都不行。坑三num参数的类型陷阱题目说“四位数字”我以为num0000合法结果返回403。用PHP调试发现$_GET[num]是字符串服务端用is_numeric()校验而0000会被认为是数字但后续用intval()转成整数后变成0再格式化为四位时成了0而非0000。最终发现必须输入num1234这样的非前导零数字。这个细节只有读服务端PHP代码才能100%确认但通过错误回显可推测。4.3 给新手的三条硬核建议永远先看响应头再看响应体很多人一看到403就去改num却忽略响应头里的X-Powered-By、Server、甚至X-Cache如果是CDN。这些头泄露了技术栈是逆向逻辑的第一线索。用curl -v代替浏览器测试curl -v URL会显示完整的请求头和响应头比浏览器开发者工具更原始、更可靠。尤其当页面有重定向时-v能清晰看到302跳转链。把“四”当作最小完备集而非数量“NiZhuanSiWei”的“四”不是指四个步骤而是指四个HTTP头构成的最小信任单元。就像木桶效应缺一块就漏水。训练时强迫自己每次只改一个头观察变化建立因果直觉。5. 从这道题延伸出的真实攻防能力图谱5.1 超越CTF它在真实红队中的映射场景这道题不是玩具它直接对应企业级攻防中的两个高频场景场景一云WAF绕过某客户使用Cloudflare WAF规则要求X-Forwarded-For必须为公网IP。但若其源站Nginx配置了set_real_ip_from 10.0.0.0/8信任内网段攻击者可通过BGP劫持或SSRF打内网伪造XFF: 10.1.1.1绕过WAF。这和本题逻辑完全一致只是信任网段从127.0.0.1扩大到内网段。场景二API网关权限提升某金融API网关校验HostRefererOriginX-Api-Key四个头实现多租户隔离。渗透测试时我们发现Origin头未被严格校验通过构造Origin: https://legit-tenant.com成功访问了其他租户数据。这正是“四位一体”校验链中的一环失效。所以这道题的价值不在于你拿到了flag而在于你建立了“HTTP头即权限凭证”的安全直觉。5.2 能力迁移如何把解题经验转化为日常开发习惯如果你是开发者做完这道题后请立刻检查自己的项目Nginx配置中set_real_ip_from是否只信任可信代理IP错误配置set_real_ip_from 0.0.0.0/0;→ 任何客户端都能伪造XFF正确做法set_real_ip_from 192.168.1.10;仅信任负载均衡器IPPHP代码中是否直接用$_SERVER[HTTP_X_FORWARDED_FOR]做权限判断危险写法if ($_SERVER[HTTP_X_FORWARDED_FOR] 127.0.0.1) { grant_admin(); }安全做法用$_SERVER[REMOTE_ADDR]经Nginx处理后的真IP或严格校验XFF来源。日志系统中是否记录了$http_x_forwarded_for而非$remote_addr若记录XFF攻击者可伪造日志污染审计系统。应记录$realip_remote_addrNginx realip模块提供。这些检查项我已在三次代码审计中发现同类问题其中一次导致越权访问管理后台。5.3 给CTF教练的设计启示如何出一道“不考记忆考思维”的题如果我要复刻这道题用于校内赛会做三个升级增加动态校验服务端随机选择四个头中的三个进行校验每次请求不同迫使选手写自动化探测脚本引入时间盲注当num参数错误时响应时间延迟1秒引导选手用time curl做布尔盲注嵌套反调试在PHP中加入debug_backtrace()检测是否在调试器中运行返回假flag干扰。核心思想不变永远让题目成为一面镜子照出你知识体系的裂缝而不是一张考卷检验你背了多少payload。我个人在实际渗透中发现真正拉开高手差距的从来不是谁记得更多漏洞编号而是谁能在403响应里一眼看出是Host头错了还是XFF头错了或是Referer协议不匹配。这种直觉只能通过像“NiZhuanSiWei”这样层层递进的题目一关一关地磨出来。

相关新闻

大模型API蜜罐实战:从诱饵设计到攻击捕获全解析

大模型API蜜罐实战:从诱饵设计到攻击捕获全解析

1. 大模型API的蜜罐,为什么和传统蜜罐不是一回事蜜罐这个词,安全圈的朋友都不陌生。一个故意暴露的脆弱服务,一个记录了所有试探动作的陷阱,等攻击者踩进来之后,我们再慢慢拆解他的手法、工具链和真实意图。传统场景里…

2026/10/19 5:35:24 阅读更多 →
C# WebAPI 连接 SQL Server 实战:从 Demo 到生产避坑指南

C# WebAPI 连接 SQL Server 实战:从 Demo 到生产避坑指南

简介:这份 C# WebAPI 示例代码面向具备一定 .NET 基础的开发者,用于快速理解基于 ASP.NET 构建 RESTful 风格 HTTP 服务的完整流程,并演示如何与 SQL Server 数据库进行数据交互。示例涵盖 ApiController 控制器编写、HttpGet/HttpPost 等 HT…

2026/10/19 5:35:24 阅读更多 →
自动化测试AI接入前必须解决的上下文对齐问题

自动化测试AI接入前必须解决的上下文对齐问题

1. 这不是加个API调用那么简单:为什么AI接入测试必须先解决“上下文对齐”问题“想让你的自动化测试接入AI,这一步必须要有。”——这句话在最近几个技术群和内部分享会上被反复提起,但多数人听完只记住了“要上AI”,却忽略了那个…

2026/10/19 5:35:24 阅读更多 →

最新新闻

BERT微调实战:IMDB影评情感二分类源码全流程解析与避坑指南

BERT微调实战:IMDB影评情感二分类源码全流程解析与避坑指南

简介:基于BERT模型的情感分析项目,是一套面向自然语言处理初学者与算法工程师的Python源码包,聚焦IMDB影评正面/负面情感二分类,帮助理解BERT预训练模型微调、特征抽取及分类器设计等关键环节。资源共5个文件,其中4个P…

2026/10/19 6:08:40 阅读更多 →
用Matlab完成测风塔风能资源评估:从数据清洗到发电量估算

用Matlab完成测风塔风能资源评估:从数据清洗到发电量估算

气象塔(风电行业里叫测风塔)出来的历史风力数据,看起来就是一堆时间和风速的表格,但真正能把它变成风能资源评估结论的人,并不算多。我刚接触这个领域的时候也犯过“拿数据就求平均”的错,结果被前辈按在工…

2026/10/19 6:08:40 阅读更多 →
单矢量控制下的占空比计算:有效抑制电流纹波与噪声

单矢量控制下的占空比计算:有效抑制电流纹波与噪声

做数字电机控制的人应该都经历过这种尴尬:算法层面跑得好好的,DTC或者有限集模型预测控制(FCS-MPC)每个控制周期都选了那个“最优电压矢量”,上示波器一看,电流纹波比SVPWM大一块,高频噪声还特别…

2026/10/19 6:08:40 阅读更多 →
AUV滑模控制器设计与Simulink仿真:从动力学建模到参数整定全解析

AUV滑模控制器设计与Simulink仿真:从动力学建模到参数整定全解析

1. AUV运动控制的核心难点与滑模控制的切入点自主水下机器人(AUV)的控制一直是个让人又爱又恨的问题。先说结论:在水下环境里,模型不确定性大、海流干扰强、参数摄动严重,传统的PID想同时搞定“深度保持”“航向稳定”…

2026/10/19 6:08:40 阅读更多 →
macOS终端重构:iTerm2+zsh打造可编程工作台

macOS终端重构:iTerm2+zsh打造可编程工作台

简介:本资源是一套面向 macOS 用户的终端环境深度优化配置方案,专为希望提升开发效率、定制化体验的程序员与系统爱好者设计,解决原生 Terminal 功能单一、主题简陋、插件缺失等痛点。压缩包包含 4489 个文件,主体为 1050 个 zsh …

2026/10/19 6:08:40 阅读更多 →
论文查重与AI率检测全攻略:原理、工具与降重技巧

论文查重与AI率检测全攻略:原理、工具与降重技巧

每年到了毕业论文提交季,最让人焦虑的往往不是论文本身有多难写,而是“查重”那一关。更麻烦的是,近两年几乎所有高校都多了一条新指标:AI生成内容检测。也就是说,论文不仅要控制重复率,还要控制“AI率”。…

2026/10/19 6:07:40 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

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

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/18 12:16:16 阅读更多 →