ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CTF Web入门:从easy_html看HTML源码审计与信息泄露

CTF Web入门:从easy_html看HTML源码审计与信息泄露 拿到[HNCTF 2022 Week1]easy_html这个题目的时候我第一反应就是这应该是一道Web方向的签到题名字里带着“easy”还特意点出了HTML。但很多刚接触CTF的朋友恰恰是栽在这种看似简单的题上。不是不会HTML而是不知道在CTF里HTML题到底要你做什么——是看源代码是改请求还是找隐藏的注释这篇文章我就以这道题为核心把一整套Web入门题的解题思路、相关知识点和踩坑经验完整拆开讲一遍。无论你是刚注册HNCTF账号的萌新还是想带新人的老手这篇都能给你一些可复用的东西。1. 题目背景与考察点拆解1.1 HNCTF Week1的题目定位HNCTF是面向高校新生的CTF联赛Week1专门给零基础选手热身。这类题有一个共同特征不考复杂算法不考底层逆向只考你“有没有摸到Web安全的大门”。easy_html作为第一周的Web题它的存在意义不是让你写一个漂亮的网页而是让你学会用“攻击者”的视角去审视一个普通页面。HTML是Web的骨架所有浏览器展示的内容最终都归结为一段HTML标记而安全问题往往就隐藏在这些标记的边角料里。我记得当时打开题目看到的是一个再普通不过的页面白底黑字写着欢迎语没有任何交互功能。如果你只是像平时浏览网页一样看两眼那flag永远也找不到。这类题的核心考察点只有一个你是否知道网页源码里可能藏着东西以及你有没有能力把它翻出来。说白了easy_html考的不是HTML写得好不好而是会不会看HTML。1.2 为什么用HTML作为CTF入口很多人觉得HTML太基础有什么好考的但恰恰是这种“基础”最能筛掉一批人。CTF比赛中Web题的第一步永远是信息搜集而HTML源码是最直接的信息来源。开发者注释、临时调试代码、隐藏表单字段、外部引入的脚本路径都可能直接或间接泄露flag。从出题人的角度HTML题目非常适合做Week1的“开胃菜”。它不依赖复杂环境一个静态页面就能承载考点同时又能在源码审计、参数传递、数据编码等方向上延伸出丰富的变体。easy_html就是这样一个“引子”它是为了让你熟悉后续Web题的基本操作流程打开页面、看源码、分析请求、尝试提交。1.3 我需要提前准备什么做这种题不需要虚拟机不需要扫描器一个浏览器加一个简单的命令行工具就够了。浏览器方面我推荐Chrome或Firefox因为它们内置的开发者工具最顺手。命令行工具可以用curlWindows用户也可以考虑在Git Bash或PowerShell里跑功能不受影响。如果你完全没接触过curl也没关系后面我会把每一步命令都解释清楚。除了工具你还需要一个思维转换把网页当作一段可以被任意查看和修改的数据而不是“最终渲染出来的漂亮画面”。这个思维贯穿整个Web安全学习过程早晚要建立不如从这道easy题开始。2. 实操过程与解题思路2.1 第一次访问页面表面什么都没有我在浏览器里打开题目给的地址页面上显示的内容大概是“Welcome to HNCTF! 祝你玩得开心”。没有输入框没有按钮也没有跳转链接。这时候直接去看渲染效果是找不到任何线索的。我习惯性地按了一下F12打开开发者工具切到“元素”或者“查看器”标签开始逐行扫页面结构。果不其然页面结构非常简单没有复杂的脚本和样式。但如果你只盯着可视区域很容易忽略一个细节HTML注释。很多Web入门题喜欢把flag放在!-- --注释里因为注释不会显示在页面上但会完整地出现在源码中。我随手往下翻就在注释里看到了一串形如flag{...}的字符串。整个过程不到两分钟。这一步听起来简单但确实有相当一部分人卡在这里。原因很可笑——他们用的是手机浏览器或者不会打开“查看源代码”功能。所以我一般建议做CTF Web题最好在电脑上操作并且第一时间学会三种看源码的方式CtrlU查看源代码、F12开发者工具、以及命令行curl拉取原始响应。2.2 右键菜单与源码查看的细节在页面空白处右键选择“查看页面源代码”不同浏览器叫法略有差异Chrome叫“查看网页源代码”Firefox叫“查看页面源代码”浏览器会打开一个新的标签页显示服务器返回的原始HTML。这个操作和F12开发者工具里的“元素”面板有一个关键区别源码页面显示的是未经浏览器解析的原始文本而“元素”面板可能会帮你补全HTML标签、调整样式结构甚至经过JavaScript修改后的DOM。对于easy_html这种静态页面两种方式看到的东西基本一致但我还是推荐养成看“源代码”的习惯因为遇到动态页面时“元素”面板展示的可能是JS运行后改变过的内容容易误导你。真正的flag如果写在注释或隐藏属性里多半能在原始源码里找到。2.3 如果注释里没有flag怎么办我在这道题里直接通过注释拿到了flag但你要知道easy_html不代表每次都直接在注释里放flag。按我的经验HTML题目常见的藏flag方式至少有五种我列个表给你参考位置特征查找方式HTML注释!-- flag{...} --查看源代码隐藏输入框input typehidden valueflag{...}查看源代码/表单分析标签属性div>curl -v http://target.com/这个命令会把服务器返回的HTTP头和页面正文全部打印出来-v参数还能显示请求和响应的详细过程。如果flag藏在某个不常被浏览器渲染的位置比如响应头里的自定义字段或者某个隐蔽的cookie用curl很容易发现。虽然easy_html不需要这么复杂但提前把curl用熟对后面的Web题只有好处。3. 核心知识点HTML与Web基础3.1 HTML注释为什么是信息泄露高发区在开发阶段程序员经常用注释来临时标记代码、记录TODO、或者临时禁用一些代码块。上线时如果忘记清理这些注释就会变成信息泄露点。在CTF中出题人模拟的就是这种“失误”。!--和--之间的内容浏览器不会渲染但服务器仍然会完整发送给客户端。你要理解浏览器和服务器之间交互的是文本所有过滤和隐藏都只是“表现层”的并不代表数据不存在。我自己做开发时也犯过这种错习惯把接口地址、测试账号、甚至内网IP写在HTML注释里。后来被一个做安全的朋友提醒才意识到这种习惯有多危险。CTF题目中的注释flag本质上就是对这种真实威胁的缩影。所以看源码的时候我总会下意识扫一眼注释块别小看这个习惯它帮我拿过好几次“意外的flag”。3.2 表单、隐藏域与HTTP请求方法easy_html虽然可能没有表单但顺带讲讲隐藏域因为它在Web入门题里太常见了。HTML表单里有这么一类标签input typehidden nametoken valueflag{...}它不会在页面上显示任何可见控件但提交表单时这个键值会被原样发送到服务器。出题人有时候会把flag放在hidden字段里或者要求你通过提交某个特定参数来触发flag返回。识别隐藏域的方法还是看源码看到typehidden时多留个心眼。再扩展一点表单提交有两种方式GET和POST。GET会把参数拼在URL后面比如?tokenflagPOST则是把参数放在请求体里。CTF题目经常会要求你用某种特定方式提交不能想当然。判断方式很简单——看题面给的提示或者看页面表单的method属性。没提示的时候用curl分别试一下两种方式代价很低。3.3 开发者工具与“查看源代码”的异同我经常被初学者问F12打开的“元素”面板不就是源码吗其实不是。浏览器开发者工具里的“元素”Elements面板展示的是当前DOM树的实时状态。假设页面用JavaScript动态生成了新节点或者删除了某些节点你在Elements里看到的就是变化后的结果而“查看源代码”看到的是服务器返回的原始字节。为什么这个区别很重要因为CTF中有些题会故意用JavaScript在运行时把flag写进页面或者反过来用JS把flag从页面中“藏”起来。如果你只依赖Elements可能看到假象如果你只依赖源代码又可能错过JS执行后的真实内容。两者结合才能拼出完整信息。easy_html用不到这么深的区分但这是我推荐所有人尽早养成的操作习惯。3.4 了解一点HTTP头与响应内容除了页面正文HTTP响应头里也可能有信息。标准HTTP响应头包括Server、Content-Type、Set-Cookie等。有些题目会把flag拆开一部分放在响应头里一部分放在正文里。用浏览器开发者工具的“网络”Network标签页刷新页面后选中主文档请求就能看到请求头和响应头的完整内容。如果标题里带了eheasy html大概率用不到但以防万一。curl也能直接看到这些信息-i参数可以显示响应头。比如curl -i http://target.com/这个命令会先输出HTTP状态行和所有头部字段然后输出正文。建议你拿到任何一道Web题时都先用curl -i把所有内容拉一遍好过只凭浏览器“肉眼观察”。4. 常见问题与排查技巧实录4.1 为什么我在页面上看不到任何东西这是easy_html遇到最多的困惑。因为flag不会明文显示在渲染后的页面上你需要跳出“用户视角”进入“开发者视角”。具体操作就三步右键查看源代码、搜索flag或{、翻看注释。如果页面没有任何交互元素也别忘了看地址栏——有些参数是通过URL传的比如?filexxx。这类参数在浏览器地址栏里能看到但在页面内容里看不到。我还见过有人把页面下载到本地用记事本打开找flag这种方法虽然可行但效率太低。更专业的做法是直接用curl把HTML源码输出配合grep搜索关键字curl http://target.com/ | grep -i flag只要flag以普通文本形式存在这条命令基本能一击命中。4.2 提交flag时提示格式错误HNCTF平台通常会在题目描述里说明提交格式。常见的坑有两种一是flag外壳的大小写不对比如实际是flag{...}你提交成了FLAG{...}二是题目要求提交hnctf{...}而不是flag{...}但页面源码里的注释写的是后者。解决方法是仔细读题面说明不要盲目相信源码里看到的那串字符的完整格式。有些出题人会很坏地把假flag放在注释里真flag却在某个JS文件里这时提交假flag就会提示错误逼你继续深挖。如果真的遇到“注释里有个flag但提交不对”的情况大概率是题目不止一关。我建议你重新完整地看一遍源码尤其是外部脚本和CSS文件。easy_html可能没有这么复杂但养成完整审计的习惯是必要的。4.3 缓存导致的旧页面问题浏览器缓存是个隐蔽的坑。有时候题目更新过或者你多次访问同一个URL浏览器会直接加载本地缓存导致你看到的页面和服务器实际返回的页面不一致。我遇到过好几次明明题目提示说flag已经改了我刷新还是旧的最后用CtrlShiftR强制刷新才看到新内容。在CTF中正确的做法是先用curl绕过缓存验证一遍因为curl默认不会保存缓存每次请求都是“诚实”的。如果你用命令行访问发现响应里带了一些奇怪的时间戳或者随机字符串那就更要留意这可能说明页面输出每次都在变化或者有服务端模板注入的迹象。但这些都是后话了easy_html阶段你只需要知道curl是Debug利器是CTFer的基础装备。4.4 题目做出来之后还能学点什么拿到flag只是第一步。我强烈建议你做完easy_html之后再给自己加两个小任务第一用Python的requests库写一个小脚本模拟curl的过程打印出页面的状态码、响应头和正文第二尝试把页面中出现的所有链接和引用的文件全部下载到本地逐个打开看看确认没有遗漏信息。这两个小任务能帮你形成“完整信息搜集”的肌肉记忆。这里给一段简单的示例代码适合刚接触Python的朋友import requests url http://target.com/ resp requests.get(url) print(resp.status_code) print(resp.headers) print(resp.text)把target.com换成你实际的目标地址在本地跑一遍输出结果和浏览器查看源代码有什么区别你会发现requests拿到的是最原汁原味的服务器响应没有任何浏览器美化。这个“原汁原味”恰恰是做题时最需要的。4.5 一张速查表Web入门题的通用解题顺序为了方便你以后做其他类似题目我把自己的排查顺序整理成了一个表每一步都对应不同的信息源步骤目标工具/方法1收集页面基本信息curl -i 查看HEAD与正文2审查HTML源码CtrlU 查看源代码3审查网络请求F12 Network / curl -v4检查外部引用文件打开js/css路径5尝试常见参数参考题面提示GET/POST6搜索flag关键字grep / CtrlF不要小看这六步至少能解掉80%的Web签到题。easy_html大概率只需要走到第2步但如果以后遇到披着“easy”外衣的难缠题目这个流程能保证你不至于手足无措。5. 从easy_html延伸到其他HTML相关考点5.1 HTML实体编码与XSS的雏形HTML实体编码是Web安全里一个绕不开的概念它把特殊字符用...;的形式表示比如写成lt;写成gt;。在HTML源码中这些实体最终会被浏览器解析回原始字符。有些题目会把部分flag字符进行实体编码肉眼看起来是一堆#x66;这样的数字实际上解码后就是字母。如果你在源码里看到一堆实体编码却辨识不出来可以在线解码一遍或者直接用Python的html.unescape()处理。进一步说实体编码和XSS跨站脚本攻击也有关联。当开发者对用户输入进行HTML实体编码后浏览器就不会把输入当作标签执行。easy_html不考XSS但你在源码审计时一定要理解浏览器解析HTML的过程先是解析HTML标签再是解析实体最后执行脚本。出题人可以利用这个过程制造信息差。5.2 HTML文件上传题的基本思路如果你在Week1后面还撞见“easy_upload”之类的题不难发现上传题的第一步也是看HTML源码。页面可能有一个文件上传表单源码里写了accept属性或者限制条件。CTF常见的做法是上传一个含有脚本的HTML文件再利用浏览器解析它来获取cookie或执行操作。所以easy_html虽然简单但它教会了你观察表单、观察限制这些在后续题目中都通用。我再提醒一点当页面中有文件上传功能时一定要留意它是否校验了文件内容、文件后缀、MIME类型以及上传后文件的访问路径。这部分内容比HTML本身要复杂得多但对于Web题来说起点永远是“看这个HTML是怎么写的”。5.3 有趣的HTML小玩意与CTF的区别平时你可能会在网上搜到“爱心代码html”“烟花代码html”“表白html”之类的现成网页模板它们用纯HTML、CSS、JavaScript实现酷炫效果。这类东西和CTF里的HTML题目有一个本质区别前者是“展示”后者是“隐藏”。但反过来玩过这些特效代码的人对HTML的语法结构和JavaScript的引入方式会有天然的熟悉感看CTF源码时不会发怵。所以如果你是从“网页制作”这个方向转来打CTF的别觉得自己基础薄弱你对DOM、事件、脚本的理解说不定比纯安全方向的学生还要好。我个人很推荐在学习Web安全之余自己动手写几个小页面比如把中秋祝福、烟花动画做成一个HTML文件然后在里面故意藏一个注释让朋友来找。这种“攻防游戏”能让你同时体验出题人和做题人的视角对理解题目帮助很大。6. 写在最后一点个人的实操体会easy_html这道题我前后用了不到三分钟但我在比赛结束后依然会反思它带给我的方法论价值。这些年带新人打CTF我发现真正卡住新人的从来不是技巧而是“浏览器里的页面究竟怎么来的”这个基础问题。很多人不会看源码不理解HTML注释不明白隐藏域也不清楚开发者工具和源代码之间的差别。这些问题恰恰是easy_html想提醒你的。以我个人的经验做这类题最顺手的流程是拿到URL先开一个终端跑一遍curl -i同时留一个浏览器窗口做直观检查。两边对照着看既不遗漏响应头信息又能快速浏览渲染后的页面。等到你把这个流程练成本能再回头看easy_html就会觉得它远不止“签到题”三个字那么简单。它是你Web安全之路的第一块垫脚石踩着它后面还有更多更有趣的题目在等你。
返回列表