ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

从BUUCTF签到题看CTF Web入门:源码注释与GET参数构造

从BUUCTF签到题看CTF Web入门:源码注释与GET参数构造 刚刷完BUUCTF的Web模块有个现象特别有意思真正让我觉得“CTF Web入门也就这么回事”的不是那些需要各种骚操作的难题反而是[极客大挑战 2019]Havefun这道签到题。题目名就叫Havefun一眼看去页面也特别简单但就是有新手在这卡住。这篇文章我会顺着完整解题过程把从查看源码到构造GET参数这条链路讲透。无论你是第一次接触CTF还是刚入Web安全想补基础都可以把这道题当作镜子看看自己有没有养成最基本的做题习惯。这道题的答案网上已经有很多无非就是查看页面源码发现注释里有一段PHP代码提示然后拼接/?catdog就能拿到flag。但我要聊的不只是这个答案而是为什么答案长这样、源码注释里的逻辑怎么读、GET参数到底怎么构造、以及我刷题过程中亲眼见过别人踩进去的坑。把这些东西串起来你才算真正“Havefun”了。1. 题目背景与解题思路整体拆解1.1 这题到底在考什么信息收集才是Web第一课[极客大挑战 2019]Havefun是极客大挑战2019比赛里的Web签到题后来被BUUCTF平台收录成了很多人的入坑第一题。题目本身没有任何难度但它的出题思路非常典型考的是“你会不会去看网页源码”。我刚拿到这道题的时候页面就是一个非常干净的入口没有登录框没有上传点没有明显的注入参数乍一看好像什么都做不了。如果这时候只会盯着页面发呆那大概率是要卡住的。Web题和传统逆向题不一样逆向题至少给你一个二进制文件让你逆而Web题很多时候连攻击面都要自己找。题目不会主动告诉你“你去翻源码”但所有线索其实都藏在你看得到的地方。HTML源码、注释、隐藏的input标签、响应头里的自定义字段、JS文件里的接口地址这些都是Web信息收集的基础。Havefun这道题把这些基本功浓缩成了一个最简单的场景查看页面源代码找到藏在HTML注释里的PHP代码提示再用URL传参满足条件。所以我说它是“信息收集参数控制”的组合题。用一个生活类比就是门根本没锁钥匙就放在门口地垫下面出题人甚至在地垫上画了个箭头但你必须养成“翻地垫”的习惯才会发现。Web安全里最怕的不是不知道高深技术而是连送分的信息收集都没做全。1.2 为什么很多新手卡在第一步路径依赖和信息遗漏我在不少CTF交流群里看到有人卡在这道题上第一个反应是“这也太简单了”第二个反应是想不通为什么有人会卡住。但后来我发现卡住的人往往不是因为笨而是因为之前的做题习惯太糟糕。他们拿到题目以后第一反应是去扫目录、去测SQL注入、去试各种工具唯独没有老老实实按F12看源码。工具用多了以后很多人会形成路径依赖总觉得所有题目都需要复杂攻击反而把最基础的信息收集漏掉了。另一个典型问题是不知道“源代码里的注释也能是提示”。很多新手看源码只看标签结构和文字内容遇到!-- ... --这种HTML注释直接跳过觉得注释只是给开发人员看的。但在CTF里注释就是出题人的小纸条有时候是路径有时候是参数名有时候干脆就是半个flag。从那以后我养成了一个习惯无论页面多简单先按CtrlU看完整源码再按F12看网络请求最后才考虑用什么工具去打。这个顺序放到今天依然管用。还有一类新手卡住是因为对HTTP的GET参数没有概念。看到?catdog不知道这是什么也不知道往哪里填。这恰恰说明基础还不牢固后面我把GET参数单独拿出来讲。2. 核心细节解析从源码注释到参数传递2.1 源码注释里的PHP代码到底在说什么这题的突破口在页面源码底部有一行HTML注释里面封装了一段PHP代码。不同版本的环境下代码可能略微不同但核心逻辑基本是下面这个样子!-- $cat $_GET[cat]; echo $cat; if ($cat dog) { echo flag{...}; } --首先要明确一点这段代码写在HTML注释里浏览器只会把它当成普通注释显示并不会执行真正的服务端逻辑其实藏在另一个PHP文件里。出题人是故意把这个代码片段放在源码注释中相当于给你递了一张纸条告诉你后端大概是怎么判断的。所以我们看这段代码看的不是它的语法而是它透露出来的“判定条件”。逐行解读一下。$cat $_GET[cat];意思是后端脚本会从URL的查询字符串中读取一个名为cat的参数。echo $cat;会把接收到的参数值原样回显到页面上这既方便调试也让选手能看到自己传了什么。if ($cat dog)是关键条件只要参数cat的值等于字符串dog就会执行echo输出flag。所以这题的目标非常清晰向脚本发送一个GET请求让cat等于dog。这里也顺带提一个PHP比较的小细节代码用的是不是。在PHP里是宽松比较是严格比较。如果一边是数字一边是字符串可能产生弱类型绕过问题。但这道题里$cat通过$_GET取到的是字符串和字符串dog做比较逻辑上仍然需要传入dog这个值才能触发flag。至于弱类型比较的更多玩法我会在后面的常见问题部分展开。2.2 GET参数的本质URL上的钥匙怎么拼看到$_GET[cat]以后接下来要解决的问题就是“怎么传这个参数”。GET参数是HTTP请求中很基础的一部分它直接拼在URL的路径后面用?起始多个参数之间用分隔。比如http://example.com/index.php?catdogpage2这个URL表示向example.com的index.php发起GET请求同时传递了两个参数cat的值是dogpage的值是2。在Havefun这道题里我们只需要一个参数所以构造出来的URL就是http://目标地址/?catdog如果目标站点本身有路径比如http://xxx/yyy/index.php那就把参数拼接在原有路径之后变成http://xxx/yyy/index.php?catdog。需要注意参数值dog不需要加引号因为URL查询字符串本身没有引号概念加引号反而会让后端收到一个带引号的字符串导致比较失败。有些新手会问为什么不用POST因为源码里用的是$_GET这是PHP专门用来接收URL查询字符串参数的超全局变量。如果你改成POST提交把catdog放进请求体里后端根本拿不到这个值。所以做题之前看清楚代码用的是$_GET还是$_POST是非常关键的一步。这也能解释为什么很多人在Burp里把请求体改了却没反应因为根本没改对地方。3. 实操过程完整复现拿到flag3.1 第一步查看源码找到代码注释实际操作的时候第一步永远是打开题目页面然后查看页面源代码。浏览器里查看源码的快捷方式一般是CtrlU或者右键点击页面空白处选择“查看页面源代码”。如果你习惯用开发者工具按F12以后切换到Elements面板也能看到同样的HTML结构但我更推荐CtrlU直接看原始源码因为原始源码不会因为DOM动态变化而干扰你的视线。打开源码以后不要急着从上往下扫先按CtrlF搜索几个关键词flag、cat、dog、php、comment。这道题的注释一般在页面底部搜索cat或者dog能很快定位到那段PHP代码。查看源码的时候一定要把所有注释都看完尤其是!--开头的内容。很多CTF题都会把提示放在注释里有的是URL路径有的是备份文件名有的是直接给出一段代码逻辑。就算这次没用到养成这个习惯也能让后面刷题少走弯路。找到那段PHP注释以后不要激动得直接复制粘贴去提交先冷静读一遍代码确认参数名是cat判定值是dog再继续下一步。我见过有选手把参数名记反了以为要传?dogcat结果怎么试都不出flag回头重新看源码才发现自己看反了。3.2 第二步构造catdog并验证结果确认了代码逻辑接下来就是最快乐的一步拼参数。假设当前浏览器地址栏是http://目标/直接在后面添加?catdog完整地址变成http://目标/?catdog回车以后页面会先把你传入的dog回显出来紧接着就能看到一串flag字符串。如果BUUCTF环境做了动态flag那生成的flag可能就是类似flag{一串随机字符}的格式。看到这个结果这道题就算打通了。整个过程不到十秒钟但就是这十秒把“查看源码→理解逻辑→构造参数→验证结果”的完整链路走了一遍。如果直接拼在地址栏里没有反应先检查一下URL有没有拼错尤其要注意是不是把参数拼到了错误的路径上。有些题目页面是一个二级路径比如http://xxx/note/index.php?mshow这时候应该保留原有路径只在后面加上catdog变成http://xxx/note/index.php?mshowcatdog而不是重新拼成http://xxx/?catdog。另外还要注意浏览器可能会因为HTTPS或HTTP混合内容拦截请求但这类题目环境一般不会出现这种问题。3.3 第三步用Burp和curl做交叉验证浏览器地址栏直接传参虽然直观但不能只依赖这一种方式。实战中我更推荐用Burp Suite或者curl再验证一次一方面能确认响应内容另一方面也能加深对HTTP请求结构的理解。用curl的话命令很简单curl -v http://目标/?catdog-v参数会输出完整的请求和响应头响应正文里就能看到flag。如果用Burp Suite先打开Proxy拦截浏览器访问题目页面时抓到请求这时候把请求行改成GET /?catdog HTTP/1.1然后放行在HTTP响应里就能看到flag。用Burp的好处是你能清清楚楚看到请求被发送到了哪里、响应里带上了什么内容还能直接在Repeater里反复修改参数测试不用在浏览器和Burp之间来回切换。对于这道题虽然浏览器就够用了但拿它当练习Burp的基础案例非常合适。交叉验证还有一个隐蔽的好处避免浏览器缓存骗你。有时候你改了URL参数但浏览器显示的还是上一次缓存的页面导致你以为没成功实际上请求早就发了。用curl或者Burp发出的请求是全新请求不存在缓存问题结果更可信。3.4 为什么这题叫Havefun从解出flag反推设计意图解出flag以后我反而会回头想想题目名为什么叫Havefun。极客大挑战2019是一场面向新人的CTF比赛出题人把它放在Web签到题的位置用一个轻松的标题告诉你“Web题也可以很好玩别紧张先来热个身。”这题的考点没有超出任何一本Web安全入门教程的范畴但它非常精准地考察了选手面对一个陌生Web应用时的第一反应。很多人刷题喜欢直接看writeup但我更建议自己先做一遍因为只有亲自卡过、急过、再解决掉才能真正理解题目背后的考点。Havefun这道题最好的打开方式就是抱着“玩一玩”的心态把页面翻个底朝天看看出题人到底把flag藏在了哪里。等你习惯了这个流程再往后刷难度更高的Web题时你会发现很多复杂攻击链的第一步依然是信息收集。4. 常见问题与排查技巧实录4.1 传参没反应先对照这四件事我见过不少人在Havefun上翻车翻车点翻来覆去就那么几个。第一参数名写错了。有人以为题目是“猫和狗”所以理所当然地传dogcat但源码里写的是$_GET[cat]参数名必须是cat值是dog。第二拼接位置错了。没有保留原有的路径直接拿根域名加参数导致请求到了错误的路由。第三浏览器缓存。修改URL以后页面显示的还是旧内容这种情况按CtrlF5强制刷新即可。第四看错源码提示。有些选手找到的是页面里其他无关的注释没有定位到真正的PHP提示代码就开始盲猜参数。可以列一个简单的排查顺序确认当前URL路径是否正确保留原有路径。确认参数名是cat值是小写的dog。用Burp Repeater重新发送请求绕过浏览器缓存。检查响应中是否有flag而不是只看页面是否变化。按照这个顺序走下来百分之九十九的情况都能解决。如果还是不行那就要怀疑是不是题目环境本身出问题了可以重新开启一道新的实例再试。4.2 浏览器只会打开页面不会做请求分析怎么办很多新手没有用过抓包工具打开浏览器只看到最终渲染后的页面不知道请求是怎么构造的、响应里有什么东西。这个问题在Havefun上不致命但会成为后面刷题的大障碍。我建议从今天开始至少学会看浏览器开发者工具里的Network面板。按F12打开面板切到Network刷新题目页面你会看到浏览器发出的每一个请求。点击请求可以看到请求方法、URL、请求头、还有服务器返回的响应体。如果浏览器开发者工具不够用再上Burp Suite。Burp是CTF Web题最常用的工具之一开启代理以后浏览器的所有请求都会经过Burp你可以在Proxy的HTTP history里看到完整的请求包用Repeater可以手动修改请求包并反复发送。Havefun这道题非常适合用来练习Repeater把请求行改成GET /?catdog HTTP/1.1点Send就能看到flag。这个动作学会了后面做任何Web题都离不开。抓包这块我多说一句抓包不是“黑客专属技能”它的本质就是“看清你和服务器之间到底说了什么”。Web安全里最忌讳盲打连请求包长什么样都不知道就乱猜参数那和闭着眼睛投篮没什么区别。只要能把请求看懂哪怕不会高深攻击排查问题的效率也能翻一倍。4.3 从Havefun延伸到PHP弱类型比较漏洞Havefun本身很简单但PHP的比较这行代码在CTF里可以延伸出非常多的考法。PHP是弱类型语言在比较时会自动进行类型转换导致很多看起来不相等的东西最终会被判定为相等。最典型的例子是0e开头的字符串。在PHP里如果一个字符串形如0e123它会被当作科学计数法解释数值等于0。于是两个完全不同的字符串0e123和0e456用比较时结果居然是true。这个特性常被用在MD5绕过题里比如要求传两个不同的参数但它们的MD5值相等就可以拿0e开头的两个字符串直接绕过。再看另一个例子在PHP 7的环境下字符串admin和数字0用比较时admin会被转换成整数0结果admin 0为true。如果某个登录逻辑写的是if ($user 0)那传入user0可能就能绕过身份校验。这些弱类型比较的坑在真实代码里是安全隐患在CTF题里就是出题人喜欢埋的考点。回到Havefun它用的是$cat dog两边都是字符串PHP不会把dog转换成数字所以不存在弱类型绕过的问题老老实实传dog就行。但理解了的特性以后看到类似代码就不会只盯着“怎么传普通值”这一个角度而是会多问一句有没有可能通过类型转换绕过这个思路上的转变比多刷十道简单题更有价值。4.4 我给新手的三条刷题建议最后分享三条我自己刷题以来一直坚持的习惯都是踩过坑换来的经验。第一条信息收集永远从看源码开始。任何Web题拿到手先按CtrlU看完整源码再看Network面板里的请求最后才考虑用什么扫描器。很多题目的突破口就藏在注释、JS文件、响应头里不看源码直接上工具等于放弃最便宜的线索。第二条参数测试要有记录。Havefun只测一个参数但后面有些题可能要测十几个参数手动乱试很容易把自己搞晕。我习惯用一个表格记录每次测试的参数名、值、响应特征哪怕只是简单的“有变化/没变化”也能帮你快速定位逻辑。第三条多写自己的writeup。每做完一道题花十分钟把过程整理成笔记不用很华丽写清楚“题目考点是什么、我怎么想到的、卡在哪里”就够了。人脑的记忆是会骗人的今天能做的题下周可能就忘了关键步骤。笔记不是为了发出去炫耀而是为了在下次遇到类似考点时能一秒想起当年的坑。这个习惯我从刷BUUCTF第一天开始坚持后来回头看那本笔记就是最值钱的财富。说到底Havefun这道题就是一道开胃菜它不会让你变成Web安全大师但它能帮你把最基础、最容易被忽略的习惯建立起来。字符串比较、GET参数、源码注释每一个概念单独拎出来都不难难的是在遇到陌生题目时能条件反射地想到“先去看源码再去找参数”。这个条件反射才是这道题真正想送给你的礼物。
返回列表