资讯动态

BugkuCTF Web 1~10通关手记:从源码审计到SQL注入的完整链路

发布时间:2026/10/17 12:27:56 来源:尧图企业网站定制
第一次点开BugkuCTF的web入门题时我心里其实挺没底的。不是不会做题而是不知道这个平台前10道题到底想教会我什么——是单纯找flag还是真的有循序渐进的能力设计。等我把web 1~10整套走完才发现这一组题更像一个手工活训练场源码、响应头、请求改写、弱口令、SQL注入、伪协议、文件包含……每一道都在逼你用最基础的方式跟HTTP打交道而这恰恰是很多人学Web安全时最薄弱的一环。这篇writeup不会只报答案。我会把每一类题的判断思路、实际请求、踩坑点按顺序拆开重点讲“为什么这样做”。它适合刚接触CTF、准备刷BugkuCTF web方向的新手也适合学了一阵子却总觉得Web题没手感的朋友。1. web 1~3号题先把看这件事做到位1.1 前几题究竟在考什么很多新手刷这类平台第一题往往栽在最无聊的地方不知道flag就藏在页面源码里或者右键菜单被禁用后就没了办法。说实话这种题目放在CTF里更像开胃菜但它真正想传递的信息是——Web题第一步永远是信息收集而信息收集的起点不是扫描器是你的浏览器。我在刷web 1~3号这道区间时明显感觉到平台在教三件事查看页面源码、留意开发工具里的网络面板、识别响应头字段。听起来好像跟安全没什么关系但后面很多题的漏洞利用信息恰恰都得靠这些地方拿到手。比如某题在源码注释里留了半截字符串另一题把提示写在了响应头的自定义字段里还有一题只有在特定浏览器标志下才返回正常页面。这些不靠技巧靠的是“看”得仔细。1.2 响应包和源码里被忽略的细节我一般会按固定顺序做“信息收集”打开开发者工具先看Elements里的完整HTML尤其注意注释节点!-- ... --和隐藏表单域。切到Network面板刷新页面逐个点开JS、CSS、图片之外的文档请求查看Headers里的细字段。顺手试一下/robots.txt再访问/.git/这类常见路径。很多题不设防纯粹是大多数人连这一步都没做就放弃了。有一次我在响应头里看到一段base64字符解码之后就是下一步的路径提示。那题如果直接搜答案永远不会理解为什么别人能顺着链路走下去——他们只是比我更早养成了看响应头的习惯。1.3 一个小细节右键被禁止怎么办前几题里偶尔会遇到右键菜单被禁用的关卡。不要慌那只是前端的oncontextmenu事件在捣乱。最简单的办法是按F12打开开发者工具或者用CtrlU直接查看源码。如果连快捷键都被拦截还可以在开发者工具的Console里执行document.oncontextmenu null解除限制。这里插一句我的经验CTF平台里所有“禁用右键”都只是模拟目的就是让你学会绕开前端限制而不是真的跟你作对。相比硬记绕过代码更值得记住的思路是前端永远不可信所有限制只存在于展示层换个入口就能绕过去。2. web 4~6号题请求改写的第一次实战2.1 为什么这几题一定要开抓包工具从第4题左右开始单纯“看”已经不够了因为你开始得“改”。有的题目要求你把请求方法从GET改成POST有的要求伪造某一段请求头还有的会让你在登录框里撞一个预设的弱口令。这类题目必须借助抓包改包工具。我用的是Burp Suite Community版免费版本对于这种入门题目完全够用。基本流程是在Burp里打开Proxy开启拦截功能然后在浏览器访问目标页面Burp会截住请求我把它发到Repeater里反复修改重放。很多教程说这一步很简单但新手常见的卡点其实是原始包体看不到。这里提醒一下Burp默认只监听的监听端口需要在浏览器设置里配置好确认证书已导出并导入到系统信任列表不然HTTPS流量会显示成一堆乱码。2.2 从改User-Agent到伪造Referer的思考这一组题里比较典型的类是“只有某种浏览器才能访问”。比如页面提示需要用某个古老的浏览器标识用Burp把User-Agent改成指定字符串后返回内容就变了。我第一次改User-Agent时只改了值却忽略了末尾的换行。看起来影响不大但在后面写脚本发请求时会频繁踩坑——requests库的headers如果带多余空格有些服务端严格校验就会不认。这个细节我现在都会写成注释放在自己的自动脚本里。还有一类题目要求从指定来源页面跳转过来也就是检查Referer字段。在Burp里加一行Referer: http://xxx/重新发送即可。这类题本身不复杂但让我意识到一件事服务端信任请求头里的信息本来就是一种值得测试的弱点因为请求头是可以完全伪造的。2.3 一道弱口令题引发的字典思考这组区间通常还会有一道登录题。平台提示是“弱口令”那么它的考点就不是要你爆破而是锻炼你“用常识去试”的耐心。常见套路就是admin加一堆弱密码比如admin、password、123456、admin123。我实际测试时在第四个组合上通过了。建议大家先手工试三到五组再考虑上字典。因为模拟训练关卡的弱口令列表非常短直接上爆破反而慢还会错过题目里“提示语本身就暗示账号格式”的信息。使用字典跑的时候也不要顺便把“未授权扫描”的思路带进来——CTF平台是授权靶场一切操作都只针对题目给出的环境我在自己练习时也始终坚持这一点。3. 某道SQL注入题从单引号到完整手工排查链路3.1 注入点是怎么被发现的进入后半段有一道典型的SQL注入题会突然把难度拉高。先看参数URL里带?id1点击不同数字返回不同内容。这种动态查询十有八九是数据库拼接。我用单引号测试在id后追加一个页面开始报错说明单引号进入了SQL语句并且破坏了结构。这里要补充一个基础知识为什么单引号有用因为SQL字符串通常用单引号包裹。假如后台是select * from xxx where id$id传入1后语句变成where id1多出来的引号会导致语法错误。如果后台是数字型参数即where id$id那么传1也会报错但报错类型可能不同。判断注入类型有个快捷方式数字型直接写id1 and 11对比id1 and 12布尔结果不同就是数字型字符型则需要先闭合单引号加注释符再把后面的引号吃掉。3.2 联合查询猜列数与显示位在确定是注入点后我第一步不是查数据而是先搞清楚列数。用order by n逐个试当语句变成order by 3正常、order by 4报错就说明查询结果只有3列。这个做法的原理是order by后跟数字表示按第几列排序超出查询结果列数就会报错。列数确认后我把原id改成不存在的值比如id-1再构造联合查询?id-1 union select 1,2,3 --如果页面把第2、第3个数字直接回显说明那是可用的显示位接下来就可以把函数替换进去比如获取数据库名?id-1 union select 1,database(),3 --3.3 布尔盲注与脚本化尝试这道题的进阶形态是页面只显示“查询成功”和“查询失败”没有直接回显位那就要走布尔盲注构造一个逻辑条件根据页面真假逐字符猜解数据。一个常用的公式如下?id1 and substr((select database()),1,1)a --手动试太累我习惯用Python脚本跑。这段脚本思路很简单遍历字符集用条件判断拿结果。import requests url http://靶机地址/?id1 and substr((select database()),{pos},1){char} -- database_name chars abcdefghijklmnopqrstuvwxyz0123456789_ for pos in range(1, 20): for char in chars: r requests.get(url.format(pospos, charchar)) if 查询成功 in r.text: database_name char print(f第{pos}位: {char}) break脚本本身不复杂但要注意URL编码问题单引号和空格在部分场景下需要编码提交。另外平台如果对注释符有过滤--就是最稳妥的写法因为在URL中被解析成空格。这个细节我一开始没注意导致脚本始终跑不出正确结果后来才发现是请求头里的Content-Type没对上数据没有按预期提交。4. 伪协议、文件包含与一条利用链路4.1 php伪协议为什么是CTF常客到了web 8~9号左右就会出现一类“文件包含”题。选手可以通过一个参数控制include的文件路径。单纯包含一个已经存在的文件意义不大核心玩法是通过伪协议拿到源码或直接执行代码。我在这组题里遇到的是典型的php://filter链。URL大概是?fileshow.php改成?filephp://filter/readconvert.base64-encode/resourceshow.php页面会返回一坨base64解码后就是show.php的原始源码。我直到这一步才发现原来底下的代码里藏着对file参数的黑名单只允许某些前缀。拿到源码后才能继续想下一步怎么绕过过滤。4.2 文件包含题的利用链路当我看到源码里的过滤规则之后整道题的思路就变了。它不再是“读文件”而是“在限制条件下继续构造可利用的协议”。一个常见延伸是用data://伪协议来执行我们传入的内容?filedata://text/plain,?php system(ls);?但在实际题目里如果过滤了php关键字或括号这条路就走不通。我在刷这道题时重点不是背payload而是摸清一个链条输入点是否可控可利用的函数是哪一个对协议、关键字、符号有哪些过滤能否找到未过滤的旁路手法最终目标是读源码还是执行系统命令。这类题的另一个练习价值是把“读源代码”当成了逆向思路的训练。当你拿到源码后后续的每一处绕过都有依据而不是瞎试。4.3 代码审计视角的输入点定位文件包含题往往也会带出一点代码审计的影子。比如源码里除了include之外可能存在某个eval、system或assert的调用甚至会有和弱类型比较的考点。我之前刷某道关卡时它故意把关键判断写成了if ($_GET[key] CTF2024) {这里用的是松散比较意味着当我传一个数字0时某些情况下会与字符串比较相等。我试过?key0结果直接通过。这类知识单独看很冷门但放在题目里就是考察源码审计时对细节的敏感度。我建议把这类题目当作小的审计案例来复盘而不是刷完就忘。5. 最后一道题与整组题的能力闭环5.1 最后一道题常常是综合题web第10道题往往不会只考一个点而是把前面几种手法串起来。比如先通过源码注释拿到一个后台路径再发现后台存在命令执行点最后还要通过请求头伪造来满足某个条件。我做这道题时最喜欢的地方不是最终拿到flag而是它逼着我做了一次完整的“手动渗透小演练”信息收集找到隐藏入口访问入口观察请求与响应差异构造参数触发代码执行读取目录确认flag位置。这个流程和真实授权测试中的最小验证路径几乎一样。即便平台定期更换题目能力模型不会变。5.2 这10道题完成后我手上多了什么我复盘时列了一张清单觉得这10道题如果认真刷完至少会掌握以下能力通过开发者工具和Burp完成基本请求观察与改写理解GET、POST、Cookie、Referer、User-Agent等HTTP要素对SQL注入有手工判断和联合查询、布尔盲注的实操经验知道文件包含与伪协议的关系能读源码并以此为基础绕过能看懂简单PHP代码里的危险函数和弱类型比较养成先收集信息、再猜测逻辑、最后验证的思路习惯。这些内容杂而不乱互相之间是递进的。前几道题让你学会“动手”中间题让你理解“输入不可信”后面几道题让你体会“当服务端把输入拼进代码时会发生什么”。整组题刷完一个完整Web漏洞利用的最小思维链就建立了。5.3 刷题之外的三个习惯最后再分享几个我刷完这10道题后一直在用的习惯。第一个是写“结构化笔记”。我不只在writeup里记录payload也记录当时判断错了什么。比如某次我以为注入点是数字型试了半天才发现参数前有单引号。这种错误记录比正确解法更值钱。第二个是避免过度依赖工具。Burp、sqlmap都很好用但我在入门阶段坚持手工操作。你只有手工做一次联合查询才能真正明白为什么sqlmap要把payload分成那么多类型而不是直接输入命令看结果。第三个是保持耐心。有些题第一次解不出来不是因为不会而是因为省略了某个细节。比如有个题目我卡了很久最后发现只是没把请求中的Cookie带进去。这种小坑会在平台的公告里或者是题目描述中埋得很浅慢下来重新读题往往比换工具更有效。对我来说BugkuCTF web 1~10让我重新理解了什么叫入门不是背几个漏洞名字而是真的在一次一次改请求、看响应、读代码的过程中把HTTP和Web应用的关系装进脑子里。如果你也正在这个阶段不妨把这组题完完整整走一遍不跳题、不急着查答案。过程中那些“我明明改了为什么还不行”的瞬间才是能力真正增长的瞬间。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑