KDE4/5 命令执行漏洞 (CVE-2019-14744) 简析

发布时间:2020-08-10 13:41:12 作者:酷酷的晓得哥
来源:ITPUB博客 阅读:195

作者:   HACHp1@知道创宇404实验室  
日期: 2019/08/08

原文链接: https://paper.seebug.org/1006/


漏洞简介

KDE Frameworks是一套由KDE社群所编写的库及软件框架,是KDE Plasma 5及KDE Applications 5的基础,并使用GNU通用公共许可证进行发布。其中所包含的多个独立框架提供了各种常用的功能,包括了硬件集成、文件格式支持、控件、绘图功能、拼写检查等。KDE框架目前被几个Linux发行版所采用,包括了Kubuntu、OpenMandriva、openSUSE和OpenMandriva。

2019年7月28日Dominik Penner(@zer0pwn)发现了KDE framework版本<=5.60.0时存在命令执行漏洞。

2019年8月5日Dominik Penner在Twitter上披露了该漏洞,而此时该漏洞还是0day漏洞。此漏洞由KDesktopFile类处理.desktop或.directory文件的方式引起。如果受害者下载了恶意构造的.desktop或.directory文件,恶意文件中注入的bash代码就会被执行。

2019年8月8日,KDE社区终于在发布的更新中修复了该漏洞;在此之前的三天内,此漏洞是没有官方补丁的。

一些八卦

影响版本

漏洞复现

环境搭建

KDE4/5 命令执行漏洞 (CVE-2019-14744) 简析

复现过程及结果

PoC有多种形式,此处使用三种方式进行复现,第1、2种为验证性复现,第3种为接近真实情况下攻击者可能使用的攻击方式。

1.PoC1: 
创建一个文件名为”payload.desktop”的文件:

KDE4/5 命令执行漏洞 (CVE-2019-14744) 简析

在文件中写入payload:

KDE4/5 命令执行漏洞 (CVE-2019-14744) 简析

保存后打开文件管理器,写入的payload被执行:

KDE4/5 命令执行漏洞 (CVE-2019-14744) 简析

文件内容如下:

KDE4/5 命令执行漏洞 (CVE-2019-14744) 简析

2.PoC2:

创建一个文件名为” .directory”的文件:

KDE4/5 命令执行漏洞 (CVE-2019-14744) 简析

使用vi写入内容(此处有坑,KDE的vi输入backspace键会出现奇怪的反应,很不好用):

KDE4/5 命令执行漏洞 (CVE-2019-14744) 简析

写入payload:

KDE4/5 命令执行漏洞 (CVE-2019-14744) 简析

保存后打开文件管理器,payload被成功执行:

KDE4/5 命令执行漏洞 (CVE-2019-14744) 简析

3.PoC3: 
攻击者在本机启动NC监听:

KDE4/5 命令执行漏洞 (CVE-2019-14744) 简析

攻击者将payload文件打包挂载至Web服务器中,诱导受害者下载:

KDE4/5 命令执行漏洞 (CVE-2019-14744) 简析

受害者解压文件:

KDE4/5 命令执行漏洞 (CVE-2019-14744) 简析

解压后,payload会被执行,攻击者接收到反连的Shell:

KDE4/5 命令执行漏洞 (CVE-2019-14744) 简析

漏洞原理简析

desktop entry

详见: https://wiki.archlinux.org/index.php/Desktop_entries_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)

漏洞的产生

KDE的桌面配置解析参考了XDG的方式,但是包含了KDE自己实现的功能;并且其实现与XDG官方定义的功能也有出入,正是此出入导致了漏洞。

在KDE文档中有如下的话( https://userbase.kde.org/KDE_System_Administration/Configuration_Files#Shell_Expansion ):

Shell ExpansionSo called Shell Expansion can be used to provide more dynamic default values. With shell expansion the value of a configuration key can be constructed from the value of an environment variable.To enable shell expansion for a configuration entry, the key must be followed by [$e]. Normally the expanded form is written into the users configuration file after first use. To prevent that, it is recommend to lock the configuration entry down by using [$ie].Example: Dynamic EntriesThe value for the "Email" entry is determined by filling in the values of the $USER and $HOST environment variables. When joe is logged in on joes_host this will result in a value equal to "joe@joes_host". The setting is not locked down.[Mail Settings]Email[$e]=${USER}@${HOST}
payload.desktop[Desktop Entry]Icon[$e]=$(echo hello>~/POC.txt)

进入文件管理器,此时系统会对.desktop文件进行解析;进入解析Icon的流程,根据文档中的说明,参数中带有[$e]时会调用shell动态解析命令:

kdesktopfile.cpp:

QString KDesktopFile::readIcon() const{
    Q_D(const KDesktopFile);
    return d->desktopGroup.readEntry("Icon", QString()); }

跟进,发现调用了KConfigPrivate::expandString(aValue): 
kconfiggroup.cpp:

QString KConfigGroup::readEntry(const char *key, const QString &aDefault) const{
    Q_ASSERT_X(isValid(), "KConfigGroup::readEntry", "accessing an invalid group");
    bool expand = false;
    // read value from the entry map
    QString aValue = config()->d_func()->lookupData(d->fullName(), key, KEntryMap::SearchLocalized,
                     &expand);
    if (aValue.isNull()) {
        aValue = aDefault;
    }
    if (expand) {
        return KConfigPrivate::expandString(aValue);
    }
    return aValue;}

再跟进,结合之前对KDE官方文档的解读,此处是对动态命令的解析过程,程序会把字符串中第一个出现的$(与第一个出现的)之间的部分截取出来,作为命令,然后调用popen执行: 
kconfig.cpp

QString KConfigPrivate::expandString(const QString &value){
    QString aValue = value;
    // check for environment variables and make necessary translations
    int nDollarPos = aValue.indexOf(QLatin1Char('$'));
    while (nDollarPos != -1 && nDollarPos + 1 < aValue.length()) {
        // there is at least one $
        if (aValue[nDollarPos + 1] == QLatin1Char('(')) {
            int nEndPos = nDollarPos + 1;
            // the next character is not $
            while ((nEndPos <= aValue.length()) && (aValue[nEndPos] != QLatin1Char(')'))) {
                nEndPos++;
            }
            nEndPos++;
            QString cmd = aValue.mid(nDollarPos + 2, nEndPos - nDollarPos - 3);
            QString result;// FIXME: wince does not have pipes#ifndef _WIN32_WCE
            FILE *fs = popen(QFile::encodeName(cmd).data(), "r");
            if (fs) {
                QTextStream ts(fs, QIODevice::ReadOnly);
                result = ts.readAll().trimmed();
                pclose(fs);
            }#endif

自此,漏洞利用过程中的代码执行流程分析完毕;可以看到KDE在解析桌面设置时,以直接使用执行系统命令获取返回值的方式动态获得操作系统的一些参数值;为了获得诸如${USER}这样的系统变量直接调用系统命令,这个做法是不太妥当的。

官方修补方案分析

KDE4/5 命令执行漏洞 (CVE-2019-14744) 简析

Summary:It is very unclear at this point what a valid use case for this featurewould possibly be. The old documentation only mentions $(hostname) asan example, which can be done with $HOSTNAME instead.

总结

参考资料

[1] 漏洞细节: 

https://gist.github.com/zeropwn/630832df151029cb8f22d5b6b9efaefb



[2] 发现者推特: 

https://twitter.com/zer0pwn/status/1158167374799020039



[3] 演示视频: 

https://www.youtube.com/watch?v=l4z7EOQQs84



[4] 官方修复细节: 

https://mail.kde.org/pipermail/kde-announce/2019-August/000047.html



[5] 修复补丁: 

https://cgit.kde.org/kconfig.git/commit/?id=5d3e71b1d2ecd2cb2f910036e614ffdfc895aa22



推荐阅读:
  1. 安装react脚手架失败的解决方法
  2. CSS实现居中的方法有哪些

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

cve-2019-14744 kde4 命令

上一篇:python处理图片的方法

下一篇:在python idel终止python程序运行的方法

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》