August CTF挑战:利用Next.js中间件中的SSRF漏洞
在Intigriti,我们每月举办基于网络的夺旗挑战赛,以此与安全研究社区互动。本月由@0xblackbird呈现的挑战展示了一个影响使用Next.js中间件的Web应用程序的服务器端请求伪造漏洞。
发现阶段
八月的挑战名为CatFlix AI,允许访客流式传输AI生成的猫咪视频。从第一眼看去,访客需要在观看平台上的任何视频之前登录。使用BuiltWith和Wappalyzer等工具,我们可以轻松确定Next.js用于应用程序的前端和后端。
NoSQL注入
在位于/src/app/api/auth/register/route.ts的注册API端点内,我们可以注意到第20行原始用户输入直接连接到MongoDB查询中。
从我们的NoSQL注入利用指南中,我们了解到这可以直接导致NoSQL注入。这有效地允许我们操纵查询,以便我们可以提取比需要更多的信息,甚至更改现有记录。
然而,经过进一步考虑,我们认为这个NoSQLi不会帮助我们获得对文件系统的访问权限。所以让我们进一步看看是否能发现其他异常情况。
NextJS中间件
我们的下一个主要关注点是middleware.ts文件。这个位于/src/middleware.ts的特殊文件允许开发人员在返回响应之前运行代码。用于基于逻辑执行服务器端重定向、身份验证和授权检查。在这种情况下,中间件用于在响应返回给客户端之前向每个响应添加安全头。
除了安全头之外,中间件似乎还执行一些分析,尽管从评论中我们可以推断这个添加仍在进行中。
以下代码片段检查是否存在UTM参数之一。当满足此条件时,将返回带有我们请求头的完整响应。但在那之前,Next.js中间件将首先评估所有头。
这个未记录的功能允许我们让NextResponse.next()处理某些头,包括Location响应头,这可能会触发内部重定向。在响应对象中传递此特定头将导致框架向该位置发出服务器端请求,并返回该请求的响应,即服务器端请求伪造。
理解这一含义,我们可以轻松尝试发送以下概念验证请求并观察响应:
|
|
发送上述请求将使Next.js应用程序返回example.com的响应。
利用NextJS中间件中的SSRF
服务器端请求伪造漏洞允许攻击者代表易受攻击的应用程序、服务或服务器请求外部资源。这为我们开辟了新的攻击向量,因为我们现在可以访问基于HTTP的内部服务。
由于没有验证存在,发送到localhost端口3000的基本请求可以确认我们可以轻松访问内部服务:
|
|
我们的下一个重点是找到一个允许我们利用本地文件读取的内部服务。使用Ffuf或Burp Suite等工具,我们可以暴力破解端口号并寻找任何命中。使用这种方法,我们可以轻松确定Jenkins CI/CD在端口8080上运行。对响应的进一步检查表明身份验证似乎被禁用。
将SSRF升级为RCE
从这一点开始的利用很简单,因为Jenkins具有内置的Groovy脚本控制台,允许开发人员评估代码,包括执行系统命令。由于身份验证被禁用,我们实际上可以在不提供会话令牌的情况下使用它,并且仍然设法执行我们的命令。
复制以下请求将在系统上执行whoami:
|
|
现在我们有了确认的远程代码执行,我们可以开始寻找flag。在大多数情况下,这将保存在系统的项目根目录中。
一个简单的ls确认了这一点:
使用前一个命令的信息,我们可以制作另一个请求来查看flag.txt文件的内容:
|
|
结论
在许多情况下,未经过滤的用户输入直接传递给评估函数调用,这是所有注入攻击的常见根本原因。通过仔细审查服务器端代码,我们能够识别、验证并武器化几个注入漏洞以实现命令执行。