ARTICLE DETAIL

资讯详情

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

CTF Web安全入门:Bugku源码题套路与代码审计实战

CTF Web安全入门:Bugku源码题套路与代码审计实战 做CTF的Web题我见过太多人一上来就对着页面乱点或者直接掏出扫描器乱扫。其实很多入门题答案就明晃晃摆在“源码”里只是大家没养成先看源码的习惯。Bugku上凡是跟source沾边的题从最基础的查看网页源代码到备份文件泄露再到AWD比赛里直接审计整站源码本质上考的都是“信息收集”和“代码审计”这两项基本功。这篇文章我就结合自己刷Bugku的经验把source题的常见套路、实操方法、踩坑记录一次说清楚适合刚入门Web安全、想系统搞懂源码类题型的读者。1. 为什么Bugku里的“source”题总是绕不开1.1 source题的本质信息收集是第一生产力很多人以为搞Web安全就是直接打漏洞实际上真正的实战过程一大半时间都花在信息收集上。source题就是把“信息收集”这件事单独拎出来考你你能不能从页面源代码、注释、响应头、备份文件、版本控制目录这些地方把开发者无意间暴露出来的信息挖出来再顺着这些信息拿到flag。Bugku上的source类题目形态非常多有的是直接在HTML注释里塞flag有的是把flag藏在一个备份压缩包里有的是让你审计一套完整的CMS源码找漏洞还有的干脆就是个套娃题源码看完一层还有一层。这些题目表面上看是“碰运气”实际上考察的是系统性的信息收集能力以及拿到源码之后的代码审计能力。1.2 别把source理解成Source Insight我先插一句题外话因为看到不少人搜“Bugku source”的时候会搜到很多无关内容。source这个词在中文技术圈里太容易被联想了一搜source出来的可能全是Source InsightWindows上的代码阅读工具、Source Insight序列号、Source Insight使用教程之类的。但Bugku里的source指的是source code也就是源代码、源码。不是让你拿Source Insight去打开网页而是让你去“找源码、看源码、审源码”。如果你在练习的时候习惯用搜索引擎辅助记得过滤掉这些工具类的干扰信息不然很容易被带偏。之前我就见过有人拿着Source Insight到处找地方打开Bugku的题目页面折腾半天没结果其实方向完全错了。2. 基础形态从查看网页源代码开始2.1 四种打开源码的姿势最基础的source题就是让你直接查看网页源代码。这个操作听起来简单但很多人只会一种方式一旦被禁就卡住了。我常用的方式有四种第一种鼠标右键选择“查看网页源代码”或“显示网页源代码”这是最直观的但不少CTF题会禁用右键菜单甚至通过JavaScript覆盖右键事件这个方法就失效了。第二种浏览器快捷键。在Chrome或Edge里按CtrlU可以快速查看源码按F12或者CtrlShiftI可以打开开发者工具切到Elements或Sources标签页看DOM结构和资源文件。F12基本不会失效而且能看到网络请求、控制台报错比单纯看源码有用得多。第三种地址栏手工输入view-source:前缀把完整的URL加到view-source:后面浏览器就会直接以源码形式渲染页面。比如view-source:http://example.com。第四种命令行工具最常用的是curl。curl -s http://目标地址能拿到原始响应体配合-v参数还能看到完整的HTTP响应头。这个方法不依赖浏览器右键被禁用、JavaScript被禁用都不影响而且对后续分析响应头信息特别关键。我自己的习惯是拿到一个题目先F12看一眼再curl -v看一遍响应头。两道工序下来基本不会漏掉明面上的线索。2.2 HTML注释与响应头里的隐藏线索HTML源码里最常见的隐藏信息就是注释。有些出题人比较直接flag就在注释里写着唯恐你看不见有些则会在注释里放提示比如“去看xxx文件”、“密码是xxx的base64编码”之类的话。除了HTML注释还要注意JS代码里的变量、meta标签里的content属性、隐藏的input标签甚至data-*自定义属性里都可能藏着东西。我举个实际场景某次遇到一个题目整个页面上只有一个按钮点了没反应。我打开源码发现按钮绑了一个click事件对应的JS函数里有段被注释掉的URL访问这个URL返回的是一段base64编码的字符串。这种事在Bugku里特别常见源码本身不复杂但你必须耐心看。响应头也很重要。有些题目把flag直接放在自定义响应头里比如X-Flag、Flag、Custom-Header等。浏览器地址栏看不到这些信息只有通过开发者工具的Network面板或者curl -v、Burp Suite抓包才能看到。所以我说看响应头一定要用工具别只盯着页面显示出来的内容。2.3 实战练手Bugku里的“小试牛刀”以Bugku里比较经典的“网站被黑”这类题为例页面打开可能就是一个静态页面你翻遍源码发现没有flag但注释里可能写着“shell.php.bak”或者“admin.zip”之类的提示。顺着这个提示去访问备份文件就能拿到Webshell源码或者后台登录逻辑再继续往里渗透。这种题其实已经超出“纯看源码”的范畴了但又没有脱离source这个大框架本质上是让你意识到源码泄露的入口不只是前端文件还可能是任意一个残留的备份文件、编辑器临时文件、压缩包。这也就引出了本文的下一部分进阶的源码泄露姿势。3. 进阶形态源码不会主动送到你面前3.1 备份文件与临时文件最常用的泄露入口很多初学者看完页面源码没发现东西就以为题目做完了这是最大的误区。source题的进阶形态需要你主动去“找”源码最常见的方式之一就是猜备份文件和临时文件。开发者在修改代码之前经常会把原文件备份一份比如index.php.bak、index.php~、index.php.swp或者把整个目录打包成www.zip、web.zip、backup.rar、site.tar.gz。这些文件一旦残留在服务器上又没有做访问控制任何人都能直接下载。CTF出题人特别喜欢用这个套路故意留一个看似不起眼的后缀文件考的就是你有没有尝试去访问。我之前刷题总结过一份常用备份文件字典包括.bak / .old / .save / .orig / .temp编辑器临时文件.swp、.swo、~、.vim打包压缩文件.zip、.rar、.tar.gz、.7z、.sql常见文件名index.php.bak、config.php.bak、flag.txt、admin.php.save、www.zip、website.zip访问路径的套路也很多比如/index.php.bak、/config.php.bak、/flag.php.txt、/backup/www.zip。做这类题手动试几个常见的再用目录扫描工具跑一遍字典基本就能扫出来。3.2 版本控制目录.git/.svn的利用思路比备份文件更“高级”一点的源码泄露是残留的版本控制目录。很多项目使用Git或SVN管理部署的时候直接把整个项目文件拷贝到服务器上却忘了删除.git或.svn目录。这时候攻击者可以直接通过.git/目录还原出整个项目的源代码甚至包括历史提交记录里的敏感信息。Bugku上这类题也不少我第一次遇到的时候访问/.git/HEAD发现返回了200里面内容类似“ref: refs/heads/master”当时我就知道稳了。还原.git目录可以用GitHack或者git_dumper这类工具它们是专门干这个的会在本地把Git对象逐个拉取下来拼出完整源码。.svn目录也有对应的利用工具比如Seay SVN漏洞利用工具。这里要提醒一句版本控制目录泄露的危害不只是暴露当前源码更危险的是历史提交记录。很多开发者会把数据库密码、API密钥、后台地址提交到Git里后来虽然删了但历史记录还在。CTF题目里也出现过flag就藏在某一次commit的diff里。3.3 搜索引擎与目录扫描的好搭档除了手工猜路径目录扫描也是找隐藏源码文件的利器。我常用的工具是dirsearch和dirmap前者速度快、字典全后者支持递归扫描和自定义规则。扫描的时候字典选择很关键如果默认字典扫不出来可以试试专门针对备份文件的字典或者自己把上面提到的备份文件命名规则组合起来加进去。另外robots.txt也是一个很经典的入口。很多网站都会在robots.txt里声明disallow路径目的是不让搜索引擎爬某些目录但这反而等于给攻击者画了一张藏宝图。Bugku的一些题目会在robots.txt里写上/admin、/flag、/source之类的内容等于明示了入口。所以拿到题目顺手访问一下/robots.txt应该变成肌肉记忆。还有一点扫描的时候要注意频率和线程数。CTF平台一般比较抗造但也不要一上来就开几百线程容易把自己IP封了也可能影响平台体验。我一般先用50线程扫一波发现目标明确后再针对路径做细扫。4. 拿到源码之后代码审计的关键路线4.1 第一步先看文件和路由源码拿到手之后很多新手会陷入“不知道看哪里”的茫然状态。我的建议是先看整个项目的文件结构快速判断这是什么类型的项目再找入口文件。通常入口文件就是index.php、api.php、admin.php或者框架的路由配置文件。如果是ThinkPHP、Laravel这类框架代码审计的切入点会和原生PHP不太一样要先找路由规则、控制器、模型层。如果是原生PHP就直接从index.php开始顺着include、require、$_GET、$_POST这些关键点往下追。还有一个优先级比较高的点就是配置文件比如config.php、database.php、.env这些文件里面经常写数据库账号密码、加密密钥、调试开关CTF题目也经常把flag或者关键提示藏在配置里。4.2 盯着危险函数和比较逻辑代码审计的核心是找出可控输入到达危险函数的路径。对CTF source题来说最常见的几类危险点包括文件包含include、require、include_once、require_once如果参数可控就可能包含本地文件或者远程文件。代码执行eval、assert、call_user_func这类函数一旦参数可控基本就等于直接给了shell。命令执行system、exec、shell_exec、passthru配合管道符、分号、反引号就能执行任意命令。反序列化unserialize配合魔术方法比如__destruct、__wakeup可能触发RCE。弱类型比较和的差异md5比较绕过in_array函数宽松模式绕过这些都是PHP审计的高频考点。举一个经典的弱类型比较例子代码里面写着if ($_GET[a] ! $_GET[b] md5($_GET[a]) md5($_GET[b])) { echo $flag; }一看就知道考的是MD5弱比较。解题方法有两个一个是传数组比如?a[]1b[]2两个数组的md5值都是nullnull null成立另一个是找0e开头的MD5值比如s878926199a和s155964671a它们在弱比较下会被当作科学计数法值都是0同样能绕过。这类代码在Bugku里出现的频率非常高我用它来提醒大家拿到源码后先搜关键词比一行行读更高效。4.3 用“层层剥洋葱”的思路拆套娃题Bugku里有一类题叫“套娃”题名字就很直白。这类题的流程通常是查看页面源码看到一段base64或者URL编码的字符串解码后得到一个文件名访问这个文件又在注释里发现另一段加密字符串以此类推。我有一个写脚本的习惯遇到反复复制的解码步骤直接用Python脚本跑一遍。比如一段字符串先base64编码再反转再URL编码手算很容易出错脚本几秒钟就能出来。下面是我常用的解码小模板import base64 from urllib.parse import unquote s 这里放原始字符串 s base64.b64decode(s).decode() s s[::-1] # 反转 s unquote(s) # URL解码 print(s)当然实际题目不会每次都按这个顺序可能是AES、可能是MD5拼接也可能是凯撒移位。但思路是一致的先识别编码类型再逆向还原循环往复直到拿到flag。4.4 工具辅助审计但别当甩手掌柜代码审计可以借助工具提高效率比如Seay源代码审计系统、Fortify SCA甚至直接用IDE的搜索功能全局搜危险函数。我自己的习惯是先全局搜一遍正则eval、assert、system、exec、unserialize、include、$_GET、$_POST把命中点列出来再逐个分析。但工具永远只是辅助真正的洞还是要靠人去看。比如同一个include函数放在白名单路径里就是安全的放在拼接变量后面就可能被利用。工具能帮你缩小范围但判断不了业务逻辑。所以我的建议是工具用来定位人脑用来思考两者结合才有效率。5. AWD里的source源码审计决定攻防上限5.1 为什么AWD里审源码要“快、准、狠”如果你打的是AWDAttack With Defense模式的比赛那source的意义就更大了。AWD里所有队伍会拿到一套相同的CMS源码主办方会提前埋好几个漏洞你需要做的就是在最短时间内完成两件事找出漏洞攻击别人修好漏洞防止被打。这时候源码审计就是核心竞争力。AWD的限时压力下不可能像平时刷CTF那样慢慢看必须快准狠。我常用的顺序是先把整个源码看一遍接着用diff工具和原始CMS官方源码对比找出被改动过的文件这些地方大概率就是漏洞点。如果没有官方源码可比就直接全局搜危险函数结合入口文件推断可以被打通的链路。5.2 几类高价值利用点的快速定位方式AWD里比较常见的漏洞类型包括SQL注入、文件上传、任意文件包含、反序列化、命令执行、变量覆盖。快速定位这些漏洞点我有几个优先排查方向SQL注入搜索mysql_query、mysqli_query、PDO再回溯变量是否来自$_GET、$_POST或$_COOKIE看有没有过滤。文件上传搜upload、move_uploaded_file重点看上传目录是否可访问、文件类型校验是否严格、文件名是否可控。命令执行搜system、exec、shell_exec查看参数有没有经过escapeshellarg或白名单过滤。反序列化搜unserialize结合__destruct、__wakeup、__toString这些魔术方法判断利用链。每发现一个点都要立刻验证然后写成一个可直接使用的攻击脚本比如用Python的requests库构造payload。AWD里时间紧张payload要越短越好最好能复制粘贴直接打。5.3 拿到漏洞后如何止血与反打AWD不仅是攻也是防。找到漏洞之后第一时间要做的不是急着打别人而是先修自己的洞。常见的防守操作包括给危险函数加上过滤规则删除后门文件修改默认后台密码禁用危险配置项。如果平台允许还可以在源码层面加一个简单的WAF比如在index.php开头统一拦截union select、eval、system这些关键词。反打是AWD另一个有趣的地方。对手如果打进来通常会在服务器上留一个Webshell文件文件名往往比较随机比如x.php、1.php、shell.php。这时候要养成用diff脚本比对文件系统的习惯发现新增文件就立刻删除同时分析这个Webshell的代码看它是用什么漏洞打进来的再顺着这个思路加固其他地方。需要强调一下AWD所有操作都发生在比赛平台内部属于授权的攻防环境。但养成在授权范围内测试的习惯对今后的安全从业者是底线要求。6. 常见问题与排查技巧实录6.1 我踩过的三个坑第一个坑右键菜单被禁用就以为看不了源码。刚接触CTF时遇到一个网页鼠标右键没反应我就傻眼了好一阵后来才知道按F12和CtrlU就能绕过去。这个坑属于对浏览器工具不熟多刷几道题就能克服。第二个坑拿到源码不按入口读直接到处乱翻。有一道题我花了半小时翻遍所有PHP文件就是没找到flag最后冷静下来从index.php开始逐行读才发现flag藏在include进来的一个不显眼的配置文件里。从那以后我养成了“先入口、再配置、后业务”的阅读顺序。第三个坑只看GET参数忽略了POST和Cookie。有的源码审计题关键参数根本不是来自URL而是藏在POST请求体或者Cookie里光盯着地址栏看永远不会发现入口。用Burp Suite或者Postman把请求包完整放出来看才是正道。6.2 source题问题速查表我在刷题过程中整理过一份问题速查表虽然不一定覆盖所有场景但遇到卡壳的时候可以先对着排查一遍现象可能原因排查方法页面源码里没有flag线索藏在备份文件或子目录访问robots.txt扫描备份文件、.git等目录右键被禁用网页通过JavaScript拦截了菜单使用CtrlU、F12、view-source:或curl源码里发现编码字符串需要解密或解码识别base64、URL编码、Hex、Unicode并还原扫不到任何隐藏目录字典不够全换大字典尝试常见备份文件和压缩包命名拿到源码但找不出漏洞危险函数被封装在框架底层从入口文件追踪所有变量再全局搜危险函数响应头里有可疑字段flag可能藏在响应头使用curl -v或Burp Suite查看原始响应头页面报错却看不到详细路径调试模式未开启尝试触发异常、访问错误日志或改配置开启debug另外标题里有人搜到“no source”或者“cannot open embedded assembler output”这类报错那其实多半是嵌入式开发工具链的编译问题和CTF的source题没有关系不要被这些搜索噪音干扰。还有一个小技巧不管遇到什么source题拿到目标URL后第一时间把以下地址都试一遍/robots.txt、/.git/HEAD、/www.zip、/index.php.bak、/flag.php。这些路径不耗时间但经常能直接中奖。我见过不少题目就这么简单几分钟就能出flag只是很多人根本没有挨个试过的习惯。关于工具链准备我自己平时常备的是Burp Suite用于抓包改包dirsearch用于目录扫描GitHack用于还原.git源码泄露Python的requests库用于快速编写验证脚本。这些工具组合起来已经能覆盖绝大多数source类题目的需求。回头再看source题它既是Web安全里最入门的一类又是最考验基本功的一类。很多看似玄乎的漏洞利用最开始都只是比旁人多看了几行源码而已。我个人的体会是刷题别急着上工具先老老实实把源码读完把每条线索记下来这个过程看似枯燥却是提升最快的时候。而且这个习惯不只对CTF有用平时自己开发写代码的时候也会下意识注意别在注释里留敏感信息、别把备份文件传到服务器上算是刷题意外的收获。
返回列表