KDE框架漏洞的原因及研究过程中的一系列思路

gejigeji Web安全 2019年11月25日发布
Favorite收藏

导语:5.61.0版本以下的KDE框架(kf5/kdelibs)容易受到KConfig类中的命令注入漏洞的攻击,远程用户可以通过该漏洞查看经特殊设计的配置文件,直接利用此功能。

5.61.0版本以下的KDE框架(kf5/kdelibs)容易受到KConfig类中的命令注入漏洞的攻击,远程用户可以通过该漏洞查看经特殊设计的配置文件,直接利用此功能。唯一需要进行的交互是在文件浏览器或桌面上查看文件。当然,这需要用户下载一个文件,但是隐藏这个文件一点也不难。

以下是一个演示动图:

1.gif

KDE框架漏洞的发现过

我发现使用Origin的客户端是使用Qt框架编写的,而KDE也是使用Qt框架构建的,我可能会尝试研究一下,而这又促使我去查看KDE。

另一个可能在整个发现过程中起到一定作用的因素是,我一直在我的一台笔记本电脑上使用KDE,对它足够熟悉,所以我可以相当容易地找到攻击面。

因为我了解KDE,所以我决定首先查看它们的默认图像查看器(gwenview)。这背后的想法是,“如果我能在默认图像查看器中找到一个漏洞,那应该是一个相当可靠的漏洞”。当然,如果我们能够将有效载荷驻留在一个图像中,并在有人查看或在浏览器中打开它时触发它,那么事情就会变得非常简单。

当我意识到gwenview实际上编译了一个最近查看的文件列表,并使用KConfig配置语法来设置这些目录时,我才恍然大悟。

2.png

让我印象深刻的是shell变量,根据这些变量的解释方式,我们可能能够实现命令执行。很明显,在File1中它调用了$HOME/Pictures/kdelol.gif并解析了变量,否则gwenview怎么知道文件在哪里呢?

为了查看这些配置目录是否解释了shell变量/命令,我在Name2中添加了一些自己的输入。

3.png

在gwenview中查看之后,并没有什么不同?这很糟糕,所以我返回到配置文件以查看是否有任何更改。事实证明,gwenview在启动时会解释shell变量,因此为了解释这些最新文件,gwenview必须在配置文件更新后重新启动。

一旦发生这种情况,命令就会执行。

4.png

可以看到,Name2目录中的命令得到了解释,并解析了$(whoami)的输出。它之所以返回到Name1是因为我用File复制了目录。目前这对我们来说没有太大的区别,只要我们的命令在执行,就足以运行。

最初,我不知道$e应该是什么意思,所以我进行了必要的挖掘,找到了KDE系统配置文件的文档。

原来$e是用来告诉KDE允许shell扩展的,不过,这根本不是一个漏洞或一个突出的问题。但它确实看起来很危险,我相信滥用它还能有更多的办法。在发现KDE允许在配置文件中扩展shell之后。

5.png

于是,我在想也许可以通过文件名实现内容注入类型的有效载荷。我尝试了这个方法,不幸的是,KDE似乎可以正确地解析新目录并通过添加额外的$来转义它们。不管怎样,如果你要给某人发送一个包含了有效载荷的文件,那显然是可疑的。

最后,我还是回到了KDE,正在浏览一个需要查看隐藏文件(dotfiles)的目录。我转到“控制”>“显示隐藏的文件”,突然意识到它在当前工作目录中创建了一个.directory文件。

由于不确定这个.directory文件是什么,我查看了其中的内容。

[Dolphin]
Timestamp=2019,8,11,23,42,5
Version=4

[Settings]
HiddenFilesShown=true

我注意到,它似乎与KDE用于所有配置文件的语法一致。所以,我想知道是否可以用shell命令注入这些目录,因为在打开目录时,KConfig正在读取和处理.directory文件。

我尝试用shell命令注入版本目录,但是它一直被覆盖。也许KDE有一些现有的。也许KDE有一些现有的.directory文件可以告诉我一些信息,所以我开始寻找它们。

[email protected]$ locate *.directory
/usr/share/desktop-directories/kf5-development-translation.directory
/usr/share/desktop-directories/kf5-development-webdevelopment.directory
/usr/share/desktop-directories/kf5-development.directory
/usr/share/desktop-directories/kf5-editors.directory
/usr/share/desktop-directories/kf5-edu-languages.directory
/usr/share/desktop-directories/kf5-edu-mathematics.directory
/usr/share/desktop-directories/kf5-edu-miscellaneous.directory
[...]

例如,让我们看一下kf5-development-translation.directory并查看其中的内容。

kf5-development-translation.directory:

[Desktop Entry]
Type=Directory
Name=Translation
Name[af]=Vertaling
[...]
Icon=applications-development-translation

我注意到在[Desktop Entry]标签中,某些具有键的目录被调用。例如,名称项上的af键:

Name[af]=Vertaling

由于KConfig确实在检查键的目录,让我们尝试使用$e选项添加一个键,就像前面提到的配置文档一样。

此时,真正让我感兴趣的事情是图标入口。在这里,它提供了设置当前目录或文件本身的图标的选项。如果文件只是简单地命名为.directory,它将为其所在的目录设置属性。如果该文件命名为有效载荷.directory,则仅有效载荷.directory文件具有图标,而不是父目录。为什么会这样工作?我们将在稍后讨论。

这意味着即使不打开文件也可以调用我们的图标目录,它可以被简单地导航到一个特定的目录。如果在这里使用$e键注入命令是可行的,那这也有点太简单了,不是吗?

使用以下有效载荷:

payload.directory
[Desktop Entry]
Type=Directory
Icon[$e]=$(echo${IFS}0>~/Desktop/zero.lol&)

9.png

实际测试

与任何漏洞一样,访问代码可以使我们的测试变得容易得多。实际测试中,我发现了几件事:

1. 漏洞实际上是KDE配置中的一个设计缺陷;

2. 可以通过查看一个文件或文件夹来触发漏洞。

显然漏洞存在于KConfig中,但是如果我们不能获得配置目录,就没有办法触发它。有了这些信息,我决定浏览KConfig和KConfigGroup的代码。此时,我会发现了一个名为readEntry()的函数。

kconfiggroup.cpp

10.png

我们可以看到它在做一些事情:

1. 检查密钥输入;

2. 如果存在expand ($e)键,则expandString()的值会被读取。

显然,现在我们需要找出expandString()在做什么。浏览文档时,我们发现kconfig.cpp中有这个功能。

kconfig.cpp

11.png

我们可以看到它在做一些事情:

1. 检查$字符;

2. 检查是否后缀();

3. 运行popen的值;

4. 返回值(必须删除该部分)。

基本上它的大部分工作原理就清楚了,但是我想根据代码找到readEntry(),然后再调用expandString(),并执行命令。

在github上搜索了很长一段时间后,我确定有一个特定于桌面文件的函数,这个函数名为readIcon(),位于KDesktopFile类中。

kdesktopfile.cpp

12.png

基本上,它只使用readEntry()函数并从配置文件中获取图标。知道了这个函数的存在后,我们就可以返回源代码并搜索readIcon()。

到目前为止,我只是在利用.directory文件,但是在阅读了更多的代码之后,我发现这个KDesktopFile类不仅仅用于.directory文件,它也用于.desktop文件。

因为KDE将.directory和.desktop文件视为KDesktopFile的文件,而且由于图标是从这个类中调用的,所以如果在其中注入命令,则将执行我们的命令。

触发触发过程

SMB分享方法

我们知道,如果我们可以让某人查看.directory或.desktop文件,就会调用readEntry(),从而执行我们的代码。我认为必须有更多的方法来触发readEntry。理想情况下,是完全远程的,交互较少,且不下载文件。

我想到的解决这个问题的方法是使用iframe中的smb:// URI来服务用户将连接到的远程共享,最终在他们连接时执行我们的.directory文件。

非常不幸的是,KDE与GNOME的不同之处在于,它不会自动挂载远程共享,而且如果文件系统上不存在.desktop/.directory文件,KDE也不会信任它们。

这实际上违背了让用户意外浏览远程共享并执行任意代码的目的,这很有趣,因为自动加载远程共享是KDE用户一直要求的功能。如果运行正常,这次攻击可能会更加危险。

不管怎样,我们不能自动挂载远程共享,但是KDE确实有一个客户端,它可以方便地处理在KDE用户中很常见的SMB共享,这个应用程序称为SMB4k。

使用SMB4k挂载共享后,就可以在Dolphin中对其进行访问。

如果我们可以对公共SMB共享进行写入访问(通过smb4k进行浏览),就可以植入一个恶意配置文件,当在Dolphin中查看时,该配置文件将显示如下内容,最终实现远程执行代码。

13.png

ZIP方法(嵌套配置)

当向某人发送.directory或.desktop文件显然会引起很多问题,对吗? 我会这样想。这就是大多数有关该主题的评论所建议的。为什么没关系?因为嵌套这些文件并伪造其文件扩展名是你可能想到的最简单的事情。

我们在这里有很多选择,第一个选择是创建一个嵌套目录,一旦打开父目录,它的图标就会被加载。这将执行代码,甚至不需要查看或知道目录的内容。例如,从Apache网站下载httpd。

14.png

网络安全小白用户不可能识别出其中一个目录中嵌套了一个恶意.directory文件,所以攻击就很容易发生。

嵌套目录有效载荷如下所示:

$ mkdir httpd-2.4.39
$ cd httpd-2.4.39
$ mkdir test; cd test
$ vi .directory

[Desktop Entry]
Type=Directory
Icon[$e]=$(echo${IFS}0>~/Desktop/zer0.lol&)

将档案文件压缩并发送出去,在文件管理器中打开httpd-2.4.39文件夹时,测试目录将尝试加载图标,从而执行命令。

ZIP方法(单独配置文件)

第二个选项是伪造文件扩展名,事实证明,当KDE不识别文件扩展名时,它会尝试自动分配一个mimetype。如果文件开头包含[Desktop Entry],则为该文件分配了application / x-desktop模仿类型,最终允许文件在加载时由KConfig处理。

知道了这一点,我们可以制作一个假冒的TXT文件,其字符非常类似于“ t”。为了演示隐藏文件的简便性,我再次使用了httpd包。

16.png

显然,伪造的图标出现了,但是,与拥有一个随机的.desktop / .directory文件相比,它更加谨慎。同样,一旦打开此文件夹,代码就会被执行。

拖放方法(单独配置文件)

说实话,这种方法没用,但我认为它在演示中会很酷,并为这个有效载荷的传播添加了一个潜在的社会工程载体。

在我分析KDE时,我意识到,实际上可以拖放远程资源,并具有文件传输触发器,这都是由KIO (kde输入/输出模块)实现的,这基本上允许用户拖放远程文件并将它们传输到本地文件系统。

简而言之,如果我们可以让用户拖放一个链接,文件传输将在文件加载到系统上的那一刻触发并最终执行任意代码。

本文翻译自:https://zero.lol/2019-08-11-the-year-of-linux-on-the-desktop/如若转载,请注明原文地址: https://www.4hou.com/web/20882.html
点赞 5
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论