XZ后门故事:初始分析

2024年3月29日,Openwall OSS安全邮件列表上的一条消息“炸醒”了整个信息安全、开源和Linux社区:XZ出现了一个CVSS评分10.0的恶意后门。

这个后门库的特殊危险在于OpenSSH服务器进程sshd使用它。在多个基于systemd的发行版上(包括Ubuntu、Debian和RedHat/Fedora Linux),OpenSSH会以一种方式与systemd通信,因此依赖于这个库(注意Arch Linux和Gentoo不受影响)。攻击者的最终目标很可能是为sshd引入其他人无法使用的远程代码执行功能。

不同于在Node.js、PyPI、FDroid和Linux内核中看到的其他供应链攻击,这次事件是一个多阶段的操作,几乎成功地在全球范围内破坏了SSH服务器。

Liblzma(XZ包的一部分)库中的后门分为两个阶段。构建基础架构的源代码被稍微修改了一下(通过引入一个额外的文件build-to-host.m4),以提取隐藏在测试用例文件(bad-3-corrupt_lzma2.xz)中的下一阶段脚本。这些脚本依次从另一个测试用例文件(good-large_compressed.lzma)中提取恶意二进制组件,该文件在编译过程中与合法库链接,并将其发送到Linux存储库。

 

事件时间轴

2024.01.19:XZ网站被新的维护者(jiaT75)移至GitHub页面;

2024.02.15:“build-to-host. m4”被添加到.gitignore;

2024.02.23:引入了两个包含恶意脚本阶段的“测试文件”;

2024.02.24:XZ 5.6.0版本发布;

2024.02.26:提交入CMakeLists.txt破坏Landlock安全特性;

2024.03.04:后门导致Valgrind出现问题;

2024.03.09:更新两个“测试文件”,修改CRC功能,Valgrind问题被“修复”;

2024.03.09:XZ 5.6.1版本发布;

2024.03.28:漏洞被发现,通知Debian和RedHat;

2024.03.28:Debian回退XZ 5.6.1到5.4.5-0.2版本;

2024.03.29:一封电子邮件在OSS-security邮件列表中发布;

2024.03.29:RedHat宣布发布的Fedora Rawhide和Fedora Linux 40测试版中有植入后门的XZ;

2024.03.30:Debian关闭构建并启动重建进程;

存在后门的发行版

xz-5.6.0

MD5

c518d573a716b2b2bc2413e6c9b5dbde

SHA1

e7bbec6f99b6b06c46420d4b6e5b6daa86948d3b

SHA256

0f5c81f14171b74fcc9777d302304d964e63ffc2d7b634ef023a7249d9b5d875

xz-5.6.1

MD5

5aeddab53ee2cbd694f901a080f84bf1

SHA1

675fd58f48dba5eceaf8bfc259d0ea1aab7ad0a7

SHA256

2398f4a8e53345325f44bdd9f0cc7401bd9025d736c6d43b372f4dea77bf75b8

初始感染分析

XZ git存储库包含一组测试文件,用于测试压缩/解压缩代码以验证其是否正常工作。这个名为“Jia Tan”或“jiaT75”的账户提交了两个初看起来无害的测试文件,但这些文件最终却成为了植入后门程序的引导程序。

两个相关文件分别为:

bad-3-corrupt_lzma2.xz (86fc2c94f8fa3938e3261d0b9eb4836be289f8ae)

good-large_compressed.lzma (50941ad9fd99db6fca5debc3c89b3e899a9527d7)

这些文件旨在包含shell脚本和后门二进制对象本身。但是,它们隐藏在格式不正确的数据中,只有攻击者知道如何在需要时正确地提取它们。

阶段1:修改的build-to-host脚本

当XZ版本准备好后,官方Github存储库会发布项目的源文件。最初,存储库上的这些版本除了包含恶意测试文件之外,是无害的,因为它们没有机会执行。然而,攻击者似乎只在发行版来自https://xz[.]tukaani.org(由Jia Tan控制)时,添加了引导感染的恶意代码。

不幸的是,大多数发行版都使用这个URL。如此一来,在下载时就会附带一个包含恶意代码的“build-to-host.m4”文件。

build-to-host.M4(c86c8f8a69c07fbec8dd650c6604bf0c9876261f)在构建过程中执行,并通过执行下述代码来修复并解压缩添加到测试文件夹的第一个文件。

1713316497_661f22912513c4265c74b.png!small?1713316497987

【build-to-host.m4中去混淆的一行代码】

这行代码使用tr命令替换了bad-3-corrupt_lzma2.xz中的“损坏”数据,并将输出传送到Xz -d命令,以便对数据进行解压缩。解压后的数据包含一个shell脚本,该脚本稍后将通过/bin/bash执行,并由这个.m4文件触发。

阶段2:shell脚本注入

恶意.m4文件注入的恶意脚本会验证它是否正在Linux机器上运行,并且是否正在预期的构建过程中运行。

1713316511_661f229f35afaeb234f4c.png!small?1713316511593

【注入的脚本内容】

为了执行下一阶段,它使用了good-large_compressed.lzma,该文件确实用XZ正确地压缩了,但在解压缩的数据中包含垃圾数据。

垃圾数据清除过程如下:eval函数执行head pipeline,每个head命令要么忽略下一个1024字节,要么提取下一个2048或724字节。

这些命令总共提取了33492字节(2048*16 + 724字节)。然后,tail命令保留文件的最后31265字节,并忽略其余字节。

之后,tr命令对输出应用一个基本替换来消除混淆。第二个XZ命令将转换后的字节解压缩为原始的lzma流,然后将结果传输到shell中。

第三阶段:后门提取

最后一个阶段的shell脚本会执行许多检查,以确保它在预期的环境中运行,例如是否将项目配置为使用IFUNC(这将在下一节中讨论)。此阶段执行的许多其他检查包括确定GCC是否用于编译,或者项目是否包含稍后脚本将使用的特定文件。

1713316615_661f23072fc93960fdb0d.png!small?1713316621641

在这个阶段,它会提取后门二进制代码本身——一个对象文件,当前隐藏在相同的good-large_compressed.Lzma文件但不同的offset函数中。

下述代码处理的就是这个问题:

1713316626_661f2312556c5adef83cd.png!small?1713316626987

【最后一个脚本阶段使用的部分命令】

提取过程通过一系列命令进行操作,每个命令的结果作为下一个命令的输入。格式化后的一行代码如下所示:

1713316636_661f231caaa0d3af3625b.png!small?1713316637282

【格式化后的一行代码】

最初,文件good-large_compressed.lzma是使用XZ工具本身提取的。接下来的步骤包括使用“eval $i”函数调用一连串的head calls(与阶段3提取相同)。

然后使用自定义的类RC4算法来解密二进制数据,其中包含另一个压缩文件。这个压缩文件也可以使用XZ实用程序提取。随后,该脚本使用预定义的值从解压缩数据的开头删除一些字节,并将结果保存为liblzma_la-crc64-fast.O(这是链接过程中使用的后门文件)至磁盘。

最后,该脚本修改liblzma中crc_x86_clmull .h文件的is_arch_extension_supported函数,用_get_cpuid替换对__get_cpuid函数的调用(去掉了一个下划线字符)。这个修改允许将它链接到库中(我们将在下一节中更详细地讨论这个问题)。整个构建感染链可以总结为以下方案:

1713316639_661f231f4837889f41708.png!small?1713316640070

二进制后门分析

隐蔽加载场景

在原始的XZ代码中,有两个特殊的函数用于计算给定数据的CRC:lzma_crc32和lzma_crc64。这两个函数都以IFUNC类型存储在ELF符号表中,这是GNU C库(GLIBC)提供的一个特性。IFUNC允许开发人员动态选择要使用的正确函数。此选择发生在动态链接器加载共享库时。

XZ使用这种方法的原因是,它允许确定是否应该使用lzma_crcX函数的优化版本。优化的版本需要来自现代处理器(CLMUL、SSSE3、SSE4.1)的特殊功能。这些特殊功能需要通过发出cpuid指令来验证,这是使用GLIBC提供的__get_cpuid wrapper/intrinsic来调用的,在这一点上后门利用了加载自身的优势。

该后门程序被存储为一个对象文件,它的主要目标是在编译期间链接到主可执行文件。对象文件包含_get_cpuid符号,因为注入的shell脚本从原始源代码中删除了一个下划线符号,这意味着当代码调用_get_cpuid时,它实际上调用了它的后门版本。

1713316670_661f233e3895acc08d847.png!small?1713316673205

【后门代码入口点】

后门代码分析

初始后门代码被调用了两次,因为lzma_crc32和lzma_crc64都使用相同的修改函数(_get_cpuid)。为了确保对此进行控制,开发人员又创建了一个简单的计数器来验证代码是否已经执行。当lzma_crc64 IFUNC调用_get_cpuid,看到指示函数已被访问的计数器值为1,并启动最后一步重定向到此恶意软件的真正入口点时,实际的恶意活动就开始了。

1713316681_661f2349a090a7ac4a4d0.png!small?1713316682302

【后门构造过程】

要构造恶意代码,后门程序首先需要构造两个结构,这些结构包含有关当前运行进程的核心信息。首先,它使用硬编码的偏移量来定位全局偏移表(GOT)地址,并使用该信息来查找其中的cpuid指针。

1713316723_661f2373063f2f7873f66.png!small?1713316724222

【GOT修改代码】

GOT包含cpuid wrapper等的偏移量。然后,后门会交换指向主恶意软件函数的指针,并像调用cpuid一样调用它。

核心行为分析

该后门程序的主要目标是成功地钩住(hook)特定的功能,使其能够监视到受感染机器的每个连接。目标函数如下所示:

目标函数

描述

RSA_public_decrypt

被libcrypto用于解密由私钥签名的密文

EVP_PKEY_set1_RSA

被libcrypto用于设置给定上下文的RSA密钥

RSA_get0_key

被libcrypto用于检索RSA密钥

然而,对于后门程序来说,钩住所有这些函数并不是一项简单直接的任务。它涉及访问许多内部结构并操纵特定于进程的结构,直至达到目标,并且它还需要尽可能地隐蔽,这意味着恶意代码包含多个检查以避免被分析。

执行环境检查

它首先解析ld-linux(动态链接器),其主要负责动态解析内存中的符号地址。它还提取有关环境的各种信息,并验证后门正在运行的当前进程是否符合下述执行标准:

  • 当前进程为/usr/bin/sshd;
  • 检查终止开关是否存在;

它从argv[0]中提取当前进程的名称,并解析所有进程环境变量,以查看其内部字符串表中是否存在这些变量。如果找到匹配项,或者进程不是sshd,恶意软件就会停止执行。

1713316780_661f23ac429d64c8c8a51.png!small?1713316781039

【流程环境检查】

它自身的表中唯一的变量是yolAbejyiejuvnup=Evjtgvsh5okmkAvj,它在此上下文中充当终止开关。

trie结构

该后门的一个显著特征是使用单一的trie结构进行字符串操作。代码没有直接比较字符串或使用字符串散列来匹配特定的常量(例如,库函数的名称),而是执行一个trie查找,并检查结果是否等于某个常量。例如,ELF文件头的magic value导致trie返回0x300,而系统函数的名称与返回值0x9F8匹配。Trie不仅用于比较:某些使用指向字符串的指针的函数(例如,ssh-2.0)也使用Trie在主机二进制文件中搜索这些字符串,因此在后门的主体中不会有可疑的数据。

trie的实现使用16字节的位掩码,每一半对应于字节输入范围0x00-0x3F和0x40-0x7F,以及2字节的trie叶子节点(leaf node),其中3 bits是标志(方向,终止),其余的留作值(或下一个节点的位置)。

1713316811_661f23cb142b3e14ebd01.png!small?1713316812105

【执行位图(bitmap)匹配的trie查找函数的一部分】

符号解析器

至少有三个与符号解析器相关的例程被该后门用于定位ELF符号结构,后者保存着诸如符号名称及其偏移量之类的信息。所有符号解析器函数都接收要在trie中搜索的密钥。

1713316825_661f23d959d943a81097a.png!small?1713316825782

【符号解析器示例】

其中一个后门解析器函数遍历所有符号并验证哪个符号具有所需的密钥。如果找到了,它将返回Elf64_Sym结构体,该结构体稍后将用于填充保存所有必要函数指针的后门的内部结构。这个过程类似于在带有API散列例程的Windows威胁中常见的过程。

该后门从libcrypto(OpenSSL)库中搜索许多函数,并将其用于后续加密例程。它还会跟踪它能够找到和解决多少函数;这决定了它是正确执行还是应该停止。

另一个有趣的符号解析器滥用lzma_alloc函数,该函数是liblzma库本身的一部分。这个函数可以帮助开发人员使用默认分配器(malloc)或自定义分配器有效地分配内存。在XZ后门的情况下,这个函数被滥用来利用一个假的分配器。实际上,它是另一个符号解析器。用于“分配大小”的参数实际上是trie中的符号键。这个技巧是为了使后门分析复杂化。

1713316856_661f23f8c40e12bdab247.png!small?1713316857293

【使用假分配器结构的符号解析器】

该后门程序会在执行时动态解析其符号;它不一定要一次完成这些操作,或者只在需要使用它们时才这样做。解析的符号/函数范围从合法的OpenSSL函数到用于在机器上执行命令的system等函数。

Symbind钩子

如前所述,后门初始化的主要目标是成功地挂钩函数。为此,该后门程序使用了rtdl-audit,这是动态链接器的一个特性,它允许在链接器中发生某些事件(如符号解析)时通知自定义共享库的创建。在一个典型的场景中,开发人员将按照rddl -audit手册创建一个共享库。但是,XZ后门选择对加载在内存中的已注册(默认)接口执行运行时补丁,从而劫持符号解析例程。

1713316884_661f2414cef43b44d123c.png!small?1713316886195

【Dl-audit运行时补丁】

该恶意构造的结构audit_iface存储在动态链接器内存区域内的dl_audit全局变量中,它包含由动态链接器调用的symbind64回调地址。它将所有符号信息发送给后门控件,后门控件随后会被用于获取目标函数的恶意地址,从而实现hook。

1713316897_661f2421415ec64ef4c75.png!small?1713316897731

【已修改的Symbind回调中的钩子位置】

通过反汇编dl_main和dl_audit_symbind_alt函数,可以获得dl_audit和dl_naudit的地址(其中保存了可用的审计接口数量)。该后门还包含一个用于指令解码的内部极简反汇编器。它广泛使用它,特别是在寻找特定值(如 *audit地址)时。

1713316908_661f242c0a6b018dbbba3.png!small?1713316908561

【Dl_naudit搜索代码】

dl_naudit地址由访问它的dl_main函数代码中的mov指令之一找到。有了这些信息,后门程序就会寻找对内存地址的访问并保存它。

它还会验证获取的内存地址是否与dl_audit_symbind_alt函数在给定偏移量中访问的地址相同。这允许它安全地假设它确实找到了正确的地址。在找到dl_naudit地址之后,它可以很轻松地计算出dl_audit在哪里,因为这两个地址在内存中是紧挨着存储的。

黑客&网络安全如何学习

今天只要你给我的文章点赞,我私藏的网安学习资料一样免费共享给你们,来看看有哪些东西。

 1.学习路线图 

 攻击和防守要学的东西也不少,具体要学的东西我都写在了上面的路线图,如果你能学完它们,你去就业和接私活完全没有问题。

2.视频教程

网上虽然也有很多的学习资源,但基本上都残缺不全的,这是我自己录的网安视频教程,上面路线图的每一个知识点,我都有配套的视频讲解。

内容涵盖了网络安全法学习、网络安全运营等保测评、渗透测试基础、漏洞详解、计算机基础知识等,都是网络安全入门必知必会的学习内容。

 

 (都打包成一块的了,不能一一展开,总共300多集)

因篇幅有限,仅展示部分资料,需要保存下方图片,微信扫码即可前往获取

3.技术文档和电子书

技术文档也是我自己整理的,包括我参加大型网安行动、CTF和挖SRC漏洞的经验和技术要点,电子书也有200多本,由于内容的敏感性,我就不一一展示了。 

 因篇幅有限,仅展示部分资料,需要保存下方图片,微信扫码即可前往获取

4.工具包、面试题和源码

“工欲善其事必先利其器”我为大家总结出了最受欢迎的几十款款黑客工具。涉及范围主要集中在 信息收集、Android黑客工具、自动化工具、网络钓鱼等,感兴趣的同学不容错过。 

还有我视频里讲的案例源码和对应的工具包,需要的话也可以拿走。

 因篇幅有限,仅展示部分资料,需要保存下方图片,微信扫码即可前往获取

 最后就是我这几年整理的网安方面的面试题,如果你是要找网安方面的工作,它们绝对能帮你大忙。

这些题目都是大家在面试深信服、奇安信、腾讯或者其它大厂面试时经常遇到的,如果大家有好的题目或者好的见解欢迎分享。

参考解析:深信服官网、奇安信官网、Freebuf、csdn等

内容特点:条理清晰,含图像化表示更加易懂。

内容概要:包括 内网、操作系统、协议、渗透测试、安服、漏洞、注入、XSS、CSRF、SSRF、文件上传、文件下载、文件包含、XXE、逻辑漏洞、工具、SQLmap、NMAP、BP、MSF…

 因篇幅有限,仅展示部分资料,需要保存下方图片,微信扫码即可前往获取 

  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/28682.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从根源解决问题:构建体系化BOM管理机制与解决方案

BOM(物料清单)是设计与生产间的纽带,其准确及时对企业的竞争力至关重要。然而,维护BOM数据时,常遇到录入错误、信息孤岛及跨部门沟通障碍等难题,直接影响生产效率和成本。为此,道合顺将探讨确保…

Hi3861 OpenHarmony嵌入式应用入门--点灯

本篇实现对gpio的控制,通过控制输出进行gpio的点灯操作。 硬件 我们来操作IO2,控制绿色的灯。 软件 GPIO API API名称 说明 hi_u32 hi_gpio_deinit(hi_void); GPIO模块初始化 hi_u32 hi_io_set_pull(hi_io_name id, hi_io_pull val); 设置某个IO…

如何使用xurlfind3r查找目标域名的已知URL地址

关于xurlfind3r xurlfind3r是一款功能强大的URL地址查询工具,该工具本质上是一个CLI命令行工具,可以帮助广大研究人员从多种在线源来查询目标域名的已知URL地址。 功能介绍 1、从被动在线源获取URL地址以实现最大数量结果获取; 2、支持从Way…

遗传算法浅理解

1. 什么是遗传算法? ​ 遗传算法,又称为 Genetic algorithm(GA)Genetic algorithm(GA)。其主要思想就是模拟生物的遗传与变异。它的用途非常广泛,可以用于加速某些求最大或者最小值的算法(换句话说就是加速算法收敛,最…

移动端专业视频剪辑解决方案,深度编辑,专业级体验

面对众多繁杂的移动端视频编辑软件,如何挑选一款既高效又专业的解决方案,成为众多企业关注的焦点。美摄科技凭借其卓越的技术实力,推出了面向企业的移动端专业视频剪辑解决方案,助力企业轻松打造高质量视频内容。 一、深度编辑&a…

OAuth 2.0:现代应用程序的授权标准

前言 随着互联网和移动应用的发展,应用程序之间的交互变得越来越普遍。用户希望通过单一的身份认证在多个平台上无缝体验,这就要求不同的应用程序能够安全地共享用户数据。而 OAuth 2.0 正是为了解决这一问题而设计的,它提供了一种标准机制&…

Golang 百题(实战快速掌握语法)_1

整形转字符串类型 实验介绍 本实验将展示三种方法来实现整形类型转字符串类型。 知识点 strconvfmt Itoa 函数 代码实例 Go 语言中 strconv 包的 itoa 函数输入一个 int 类型,返回转换后的字符串。下面是一个例子。 package mainimport ("fmt"&qu…

wps 二维数据转转一维度数据

HSTACK(TOCOL(C2:H2&A3:A8),TOCOL(B3:B8&C1:H1),TOCOL(C3:H8))

网络编程(三)UDP TFTP协议

文章目录 一、 UDP(一)概述(二)流程 二、收发函数(一)recvfrom(二)sendto 三、实现一个简单的udp服务端和客户端四、实现tftp客户端协议 一、 UDP (一)概述 …

Spring-事件

Java 事件/监听器编程模型 设计模式-观察者模式的拓展 可观察者对象(消息发送者) Java.util.Observalbe观察者 java.util.Observer 标准化接口(标记接口) 事件对象 java.util.EventObject事件监听器 java.util.EventListener public class ObserverDemo {public static vo…

Spring IoC【控制反转】DI【依赖注入】

文章目录 控制反转(IoC)依赖注入(DI)IoC原理及解耦IoC 容器的两种实现BeanFactoryApplicationContext IoC 是 Inversion of Control 的简写,译为“控制反转”,它不是一门技术,而是一种设计思想&…

解放双手 免费AI编程工具---Fitten Code

前言 相信大家在2023年后听说了不少的关于人工智能的话题,对于这种全新的科技又好奇又恐惧,今天我们来见识下一个在VS中的AI代码工具吧。 配置环境 安装 首先我们找到管理扩展,然后再搜索Fitten Code下载安装。 我这里已经下好过了&#xff…

MacOS系统搭建Appium自动化测试环境

一、Appium简介 1.1 什么是APPium APPium是一个开源测试自动化框架,适用于原生、混合或移动Web应用程序的自动化测试工具。 APPium使用WebDriver协议驱动iOS、Android等应用程序。 APPium具有如下特点: 支持多平台(Android、iOS等)。支持多语言(python、java、ruby、js…

【每日刷题】Day67

【每日刷题】Day67 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 23. 合并 K 个升序链表 - 力扣(LeetCode) 2. 1189. “气球” 的最大数量 - …

网络安全 - kali 安装

文章目录 Kali 安装教程下载镜像 Kali 安装教程 下载镜像 kali-images安装包下载_开源镜像站-阿里云 (aliyun.com) 下载对应镜像(自己挑) 打开本机 cmd 并输入一下命令 ipconfig找到 NAT 模式的 IP 地址并从虚拟机中 ping

6月15号作业

使用手动连接,将登录框中的取消按钮使用第二中连接方式,右击转到槽,在该槽函数中,调用关闭函数 将登录按钮使用qt4版本的连接到自定义的槽函数中,在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0…

一键掌控,4G红外插座引领智能生活新潮流!

随着科技的进步,市场上出现大量带语音、手机APP可控制的智能插座产品,由此可看出客户对产品的功能要求也越来越高,追求舒适的体验感,特别是对操控性的要求越来越高。但是目前大部分红外遥控插座均为WiFi插座类型,WiFi红…

gitlab仓库中用git bash生成不是默认路径的ssh秘钥

使用命令 ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 会在默认路径生成秘钥,(C:\Users\用户\.ssh\) 想要修改默认路径使用如下命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com"…

【吉林大学Java程序设计】第11章:网络编程技术

第11章:网络编程技术 1.网络协议概述2.网络类及应用(1)InetAddress类(2)ServerSocket类(3)Socket类基于TCP的点对点通信基于TCP的点对面通信(一个服务器,多个客户端&…

如何通过数据库与AI实现以图搜图?OceanBase向量功能详解

OceanBase支持向量数据库的基础能力 当前,数据库存储系统与人工智能技术的结合,可以体现在两个主要的应用方向上。 一、近似搜索。它利用大语言模型(LLM,简称大模型)的嵌入(embedding)技术&am…