360漏洞研究院:xz-utils后门漏洞 CVE-2024-3094 深度分析)

1

事件背景

3月29日,微软PostgreSQL开发人员Andres Freund在oss-security上公告[1]他发现开源项目xz-utils存在后门漏洞。该项目遭到供应链攻击,项目维护者jiaT75(jia Tan)通过上传二进制测试文件和篡改编译脚本,使得编译过程中恶意二进制文件会替换原有文件,导致编译输出与公开的源码不匹配。

其中liblzma库会通过IFUNC劫持sshd,添加后门以实现远程代码执行。该漏洞CVSS评分10分,受到影响的liblzma版本包括:5.6.0和5.6.1。

2

后门漏洞样本分析

本文对该后门漏洞进行了动静态分析,分享了我们整个漏洞的复现和分析的过程,有以下新进展:

1.定位了两处RCE点(调用system())。

2.恢复了部分关键对象,可以确定后门程序调用了哪些系统库函数。

样本获取  

目前xz-utils项目仓库已经无法访问,你可以通过以下方式获取样本:

1. Andres Freund在邮件列表中提供了二进制文件样本liblzma_la-crc64-fast.o.gz;

2. 从Debian仓库[2]下载xz源代码;    

样本分析  

此次攻击流程如下:

1.在编译阶段插入恶意代码;

2.执行阶段构造后门,通过IFUNC劫持sshd进程;

3.触发后门阶段,在特定条件下,通过system实现RCE;

1. 编译阶段注入恶意代码   

攻击者将看似测试的混淆代码推送到数据压缩库liblzma的构建过程中。

在XZ构建过程中,会调用关键脚本build-to-host.m4。在其中会嵌入一个混淆的脚本,与配置的脚本在一起执行。这个注入的脚本在模块xz-utils和liblzma生成MakeFiles过程中发挥着重要作用[3]

另外,liblzma的符号会在许多其他库之前得到解析,包括sshd二进制文件中的符号。在解析符号后,由于编译标志的GOT将被重新映射为只读页面权限-Wl,-z,relro。所以,为了使得恶意代码能够解析尚未加载的库中的符号,后门会在动态链接器中安装挂钩。这个钩子函数从_dl_audit_symbind中被调用,后门将RSA_public_decrypt@….plt的值更改为指向其自己的代码。

编译分为三个阶段[4]

(1)通过M4编译宏,还原恢复恶意数据:

m4/build-to-host.m4文件里有一些相关的代码片段:    

从tests/files/bad-3-corrupt_lzma2.xz文件中读取的字节被输出到标准输入输出。在读取完所有内容后,还会添加一个新行(\\\\n)。

第二步是运行tr(转换,就像是“将字符映射到其他字符”,或者“将字符替换为目标字符”),基本上是将选定的字符(或字节值)更改为其他字符(其他字节值)。于是,我们有tr \\”\\\\t -\\” \\” \\\\t-\\”, 它在从tests/files/bad-3-corrupt_lzma2.xz文件流式传输的字节中进行以下替换:

360漏洞研究院:xz-utils后门漏洞 CVE-2024-3094 深度分析)

这实际上是“修复”了bad-3-corrupt_lzma2.xz,使其再次形成一个正确的xz流。在这个阶段的最后一步中,修复后的xz字节流被提取。

(2)通过Bash脚本,提取和合并恶意数据:

该过程包括从一个压缩文件读取字节,通过一系列操作(如字符转换和筛选)来修正和提取数据。    

360漏洞研究院:xz-utils后门漏洞 CVE-2024-3094 深度分析)

第二阶段的提取代码,这包括一个复杂的导出语句export i=…。这个命令基本上定义了一个函数,它会在后面的步骤中被调用。

第二阶段提取的第一步是解压缩一个压缩文件,然后这个解压的输出会作为下一步的输入。接下来,执行一个由多个步骤组成的函数i,通过eval $i调用。这个函数主要是一系列的命令,用来处理数据流,要么提取(输出)数据的特定部分,要么跳过(忽略)数据的特定部分。在数据处理的开始,我们会跳过一些数据,比如忽略文件的前1024字节。这个过程反复进行,交替跳过和提取数据直到文件结束。如果文件的开始部分是由重复的字符构成,之后是一些二进制数据。我们通过这种方式去除空白区域,仅合并包含实际数据的区域。    

简而言之,这个过程涉及解压缩数据,逐步处理和提取重要部分,最终得到准备好的数据以进行下一步的操作。

(3)修改编译过程,插入恶意代码:

360漏洞研究院:xz-utils后门漏洞 CVE-2024-3094 深度分析)

以上脚本,通过在项目的测试文件夹中搜索包含特定签名的文件,脚本可以定位并执行隐藏于这些文件中的额外脚本或代码。这允许攻击者在不直接修改原始有效payload携带文件的情况下,增加新的恶意功能。    

360漏洞研究院:xz-utils后门漏洞 CVE-2024-3094 深度分析)

通过一系列精心设计的命令,在一个特定的.o文件(liblzma_la-crc64-fast.o)中嵌入恶意代码。

2. 执行阶段构造后门  

liblzma_la_crc64_fast.o中get_cpuid()非常可疑。正常情况下,该函数会内联到代码中,GCC源码如下:

 360漏洞研究院:xz-utils后门漏洞 CVE-2024-3094 深度分析)

而后门程序实现如下:

 360漏洞研究院:xz-utils后门漏洞 CVE-2024-3094 深度分析)

看上去sub_A750()应该是_get_cpuid_max(),但实际上它的逻辑不止如此:    

 360漏洞研究院:xz-utils后门漏洞 CVE-2024-3094 深度分析)

当dword_CB60为1时,会调用Llzma_block_param_encoder_0(),该函数是攻击的入口。这里使用了IFUNC技术,liblzma库在加载时,加载器会调用resolver函数,crc32_resolve()和crc64_resolve()这两个函数均会调用get_cpuid()。crc32_resolve()调用时,dword_CB60由0变为1。crc64_resolve()调用时,由于dword_CB60已经为1,后门程序会执行Llzma_block_param_encoder_0()。该函数最终会调用sub_3A10(),后者会检查当前进程是否为sshd,如果是sshd且环境变量符合要求,才会进行攻击:

360漏洞研究院:xz-utils后门漏洞 CVE-2024-3094 深度分析)    

Lsimple_coder_update_0()的功能是通过一个状态自动机来识别字符串,如果是已知字符串,返回该字符串的ID,如果没有则返回0。sub_3A10()先将当前进程的argv[0](/usr/sbin/sshd)传入,然后将结果与0x108进行比较。如果不是0x108,则当前进程不是sshd,后门程序直接返回。

对Lsimple_coder_update_0()下断点可以看到,rdi第一个参数为“/usr/sbin/sshd”的情况。

360漏洞研究院:xz-utils后门漏洞 CVE-2024-3094 深度分析)

返回值为0x108时,sub_3A10()会继续调用Lsimple_coder_update_0()进行环境变量的检查:

360漏洞研究院:xz-utils后门漏洞 CVE-2024-3094 深度分析)可以看到此处对env指针列表进行遍历,将每个环境变量字符串传入进Lsimple_coder_update_0(),并检查其返回值,如果返回值不为0则校验不通过,直到env指针列表结束:    

360漏洞研究院:xz-utils后门漏洞 CVE-2024-3094 深度分析)

360漏洞研究院:xz-utils后门漏洞 CVE-2024-3094 深度分析)

后门程序需要LANG环境变量,如果存在LD_DEBUG变量或者LD_PROFILE变量,后门程序直接返回。满足要求时,后门程序会劫持sshd进程的RSA_public_decrypt()的GOT表:

              

360漏洞研究院:xz-utils后门漏洞 CVE-2024-3094 深度分析)

3. 触发后门  

前面发现Lsimple_coder_update_0()会根据字符串返回对应的ID,通过对该函数下断点,发现system字符串对应的ID为0x9f8。通过搜索0x9f8,发现lzma_alloc函数,该函数能够通过ID找到库函数的地址:

360漏洞研究院:xz-utils后门漏洞 CVE-2024-3094 深度分析)

实际上libc_ctx对象保存了libc库相关的函数地址, system函数地址保存在该对象的0x30偏移处:    

360漏洞研究院:xz-utils后门漏洞 CVE-2024-3094 深度分析)

libc_ctx位于global_ctx全局对象中,后者保存了多个库的ctx对象,例如libcrypto等:

360漏洞研究院:xz-utils后门漏洞 CVE-2024-3094 深度分析)

最后我们根据system_ptr的引用,找到两处RCE点,一处是在RSA_public_decrypt()的HOOK函数调用过程中:

360漏洞研究院:xz-utils后门漏洞 CVE-2024-3094 深度分析)

另外一处如下:    

360漏洞研究院:xz-utils后门漏洞 CVE-2024-3094 深度分析)

该函数do_RCE()在以下地方被引用:

从而确认该后门漏洞存在RCE。

3

后续工作

如何构造出合法的公钥触发system函数的执行?目前看来该公钥难以构造,后续可能可以对公钥校验的逻辑进行patch,从而对载荷的逻辑进行分析。    

(补充说明:复现环境的liblzma.so.5.4.1为带有后门漏洞的自行编译的so,原本的版本是5.6.1,为了方便调试更改名称为liblzma.so.5.4.1)

4

参考文献

[1].https://openwall.com/lists/oss-security/2024/03/29/4

[2].https://salsa.debian.org/debian/xz-utils/-/tree/debian/unstable?ref_type=heads

[3].https://gynvael.coldwind.pl/?lang=en&id=782

[4].https://www.armosec.io/blog/cve-2024-3094-kubernetes/

[5].https://github.com/karcherm/xz-malware

[6].https://gist.github.com/smx-smx/a6112d54777845d389bd7126d6e9f504    

原创文章,作者:小技术君,如若转载,请注明出处:https://www.sudun.com/ask/34074.html

Like (0)
小技术君的头像小技术君
Previous 2024年4月6日
Next 2024年4月6日

相关推荐

  • 如何使用adobe experience design进行界面设计?

    你是否曾经为界面设计而烦恼?是否想要拥有一个更加便捷高效的设计工具?那么,让我来向你介绍一款名为Adobe Experience Design的软件吧!这款软件不仅可以帮助你轻松完…

    问答 2024年3月30日
    0
  • 如何利用在线课堂教学提高学生的学习效率?

    如何利用在线课堂教学提高学生的学习效率?这是一个备受关注的话题。随着网络技术的不断发展,越来越多的教育机构开始采用在线课堂教学模式,以期提高学生的学习效率。那么什么是在线课堂教学?…

    问答 2024年4月18日
    0
  • 118kj.com是什么网站?(详细介绍)

    你是否曾经听说过这个网站?它是一个备受瞩目的网络平台,拥有着令人惊叹的功能和特点。它的用户群体广泛,使用情况也非常丰富多彩。那么,究竟是什么呢?它又有着怎样的发展历史和公司背景?让…

    问答 2024年4月17日
    0
  • 企业微信服务商怎么选择?

    随着企业微信的普及,越来越多的企业开始意识到选择一家合适的企业微信服务商的重要性。但是,如何选择一家适合自己的企业微信服务商却是让众多企业困惑不解的问题。今天,我们将带您一探究竟,…

    问答 2024年4月13日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注