首页 网络安全 正文
  • 本文约6691字,阅读需33分钟
  • 321
  • 0

qBittorrent中的远程代码执行漏洞CVE-2024-51774

摘要

栋科技漏洞库此前对qBittorrent远程代码执行漏洞进行简单分析,但彼时该漏洞未获得CVE漏洞编号,现对CVE-2024-51774漏洞重新整理。

qBittorrent 是一款轻量级 BitTorrent 客户端,可运行于Linux、windows及其他系统,被视为一个良好的替代其他 BitTorrent 软件的客户端。

一、基本情况

qBittorrent 是一款跨平台的自由 BitTorrent 客户端,,用于下载和分享资源文件,图形用户接口由Qt4所写成,使用 libtorrent 作为后端。

栋科技漏洞库关注到qBittorrent 中存在一个超14年的时间未被修复的严重的远程代码执行(RCE)漏洞,现已被追踪为CVE-2024-51774。

该漏洞是由于其DownloadManager类中缺乏SSL证书验证导致的,由网络安全公司Sharp Security的网络安全研究员J. Sharp发现并报告。

该漏洞于2010年04月通过提交引入,可能允许攻击者利用应用程序使用的硬编码 URL 进行 RCE 攻击,并通过中间人 (MITM)发起攻击。

该漏洞于2024年10月12日时得以修复,但2024年10月28日发布的 qBittorrent 5.0.1 版本是包括该修复CVE-2024-51774补丁的最早版本。

栋科技漏洞库此前已就此漏洞进行简单分析,彼时漏洞暂未获得CVE漏洞编号,通过 CVE 官网 Program可看到编号分配时间2024-11-02。

今天栋科技漏洞库关注到 Sharp Security 对CVE-2024-51774的详尽解读,由于此前分析不够细致,因此决定结合官网更新日志重新整理。

二、漏洞分析

漏洞源于qBittorrent中DownloadManager类,该类绕过跨多个功能(包括 torrent 下载、RSS 源和搜索引擎功能)任何下载文件SSL验证。

这样的漏洞存在意味着 qBittorrent 跨多个关键功能信任任何SSL证书(无论是过期的、自签名的还是恶意的),从而产生了大量攻击媒介。

qBittorrent 中的 DownloadManager 在整个程序中的使用非常广泛,并且会影响导搜索、.torrent 下载、RSS 源以及favicon下载等等功能。

漏洞必须通过 MITM 访问或 DNS 欺骗才能利用,所有代码路径都接受任何证书,无论过期、自签名还是两者兼而有,按严重性降序排列:

(1)具有隐形功能的恶意可执行加载程序

如果您运行的是Windows且未安装足够新的Python版本, qBittorrent启动时将提示从硬编码 URL 安装/更新 Python便于使用搜索插件:

1、源代码

#ifdef Q_OS_WIN
            const QMessageBox::StandardButton buttonPressed = QMessageBox::question(this, tr("Missing Python Runtime")
                , tr("Python is required to use the search engine but it does not seem to be installed.\nDo you want to install it now?")
                , (QMessageBox::Yes | QMessageBox::No), QMessageBox::Yes);
            if (buttonPressed == QMessageBox::Yes)
                installPython();
...

#ifdef Q_OS_WIN
void MainWindow::installPython()
{
    setCursor(QCursor(Qt::WaitCursor));
    // Download python
    const auto installerURL = u"https://www.python.org/ftp/python/3.12.4/python-3.12.4-amd64.exe"_s;
    Net::DownloadManager::instance()->download(
            Net::DownloadRequest(installerURL).saveToFile(true)
            , Preferences::instance()->useProxyForGeneralPurposes()
            , this, &MainWindow::pythonDownloadFinished);
}

2、代码来源

https://github.com/qbittorrent/qBittorrent/blob/2d185dc1c7932e775ecf5f2b0a7b7639ed8228f7/src/gui/mainwindow.cpp#L1579

如果在自动选择的“是”的选项上单击或者是按下回车键而选择允许,那么qBittorrent 将**下载、执行,然后删除 .exe**

1、源代码

void MainWindow::pythonDownloadFinished(const Net::DownloadResult &result)
{
    if (result.status != Net::DownloadStatus::Success)
    {
        ...
    }

    setCursor(QCursor(Qt::ArrowCursor));
    QProcess installer;
    qDebug("Launching Python installer in passive mode...");

    const Path exePath = result.filePath + u".exe";
    Utils::Fs::renameFile(result.filePath, exePath);
    installer.start(exePath.toString(), {u"/passive"_s});

    // Wait for setup to complete
    installer.waitForFinished(10 * 60 * 1000);

    qDebug("Installer stdout: %s", installer.readAllStandardOutput().data());
    qDebug("Installer stderr: %s", installer.readAllStandardError().data());
    qDebug("Setup should be complete!");

    // Delete temp file
    Utils::Fs::removeFile(exePath);

    // Reload search engine
    if ...
}
#endif // Q_OS_WIN

2、源文件链接

https://github.com/qbittorrent/qBittorrent/blob/2d185dc1c7932e775ecf5f2b0a7b7639ed8228f7/src/gui/mainwindow.cpp#L1889

qBittorrent 从2015年06月至今的版本中一直存在此行为,影响版本包括 v3.2.1 到 v5.0.0(含),其他操作系统变体似乎不会复制该行为。

但其他操作系统只是在未找到 Python 或 Python 不够新的情况下禁用搜索小部件,而当可执行文件下载完成后,它将存储在例如:

C:\Users\_user_\AppData\Local\Temp\\ is-G61QK.tmp

这可能是由于“QProcess”实例的行为方式,exe 的两个线程正在运行,并且只有其中一个在执行后被杀死,而另一个则持续处于睡眠状态。

使用 mitmproxy 注入的 calc.exe 的强制屏幕截图:

qBittorrent中的远程代码执行漏洞CVE-2024-51774

(2)任意URL注入+可执行下载(软件升级上下文)

如果在 Windows 或 Linux 上运行已安装的 qBittorrent 版本,而不是“appImage”文件,那么它在启动时默认执行更新检查,这需要提取文档

具体来说,就是需要以 XML 形式的硬编码 URL下载 RSS 提要,并解析程序发布信息的文档:

    void ProgramUpdater::checkForUpdates() const
{
    const auto RSS_URL = u"https://www.fosshub.com/feed/5b8793a7f9ee5a5c3e97a3b2.xml"_s;
    // Don't change this User-Agent. In case our updater goes haywire,
    // the filehost can identify it and contact us.
    Net::DownloadManager::instance()->download(
            Net::DownloadRequest(RSS_URL).userAgent(QStringLiteral("qBittorrent/" QBT_VERSION_2 " ProgramUpdater (www.qbittorrent.org)"))
            , Preferences::instance()->useProxyForGeneralPurposes(), this, &ProgramUpdater::rssDownloadFinished);
}

然后,它将解析 XML,如果版本高于当前运行的版本,则提取 URL,并提示用户访问此 URL,而不进行任何过滤或验证:

...
    if (type.compare(variant, Qt::CaseInsensitive) == 0)
            {
                qDebug("The last update available is %s", qUtf8Printable(version));
                if (!version.isEmpty())
                {
                    qDebug("Detected version is %s", qUtf8Printable(version));
                    if (isVersionMoreRecent(version))
                    {
                        m_newVersion = version;
                        m_updateURL = updateLink;
                    }
                }
                break;
            }
...

如果用户接受提示,则在默认浏览器中打开此URL。用户期望收到一个exe文件且上下文是信任之一,因为链接/下载来自他们运行的软件:

bool ProgramUpdater::updateProgram() const
{
    return QDesktopServices::openUrl(m_updateURL);
}

因此,如果用户被定向到任何指定文件共享站点(例如 mediafire 等),他们就可以下载攻击者控制的 exe,他们希望其功能类似于升级。

由于该项目是 OSS,因此可以轻松通过附加后门功能重新编译最新版本,此过程中开发人员提供了一个密钥用于检查二进制文件的签名。

这是一项十分必要的工作,必须对其进行检查,并且必须考虑验证失败以保护用户。

(3)RSS Feeds(任意URL注入)

应用程序解析的所有 RSS 提要都会经过 DownloadManager,因此它们可能会被劫持。

受害者访问的 URL 可以被观察和编目,并且本质上它们是静态的、长期存在的 URL。

每个条目中的“link”元素会被直接解析,双击就会下载。

即使没有 MITM 篡改,这也适用 - 只需双击即可插入您关注的任何 RSS 提要中的任何 URL,无论是作者还是毒害该提要的攻击者。

            else if (name == u"link")
            {
                const QString link = (xml.attributes().isEmpty()
                                ? xml.readElementText().trimmed()
                                : xml.attributes().value(u"href"_s).toString());

                if (link.startsWith(u"magnet:", Qt::CaseInsensitive))
                {
                    article[Article::KeyTorrentURL] = link; // magnet link instead of a news URL
                }
                else
                {
                    // Atom feeds can have relative links, work around this and
                    // take the stress of figuring article full URI from UI
                    // Assemble full URI
                    article[Article::KeyLink] = (m_baseUrl.isEmpty() ? link : m_baseUrl + link);
                }
            }

让该漏洞更具破坏性的是CVE-2019-13640,因为CVE-2019-13640允许通过 torrent 名称或当跟踪器参数中的 shell 元字符执行远程命令。

这种漏洞叠加组合使用,意味着真正的 RSS 作者不需要发送恶意数据,因为 MITM 攻击者也可以这样做。

(4)解压库攻击面(0-click)

启动时,默认情况下,程序会自动从硬编码 URL 下载 .gz 扩展名二进制 MaxMind GeopIP 数据库,然后将其解压缩。

如果 zlib 解压中存在任何漏洞,例如CVE-2022-37434 the CVSS 9.8 Critical buffer Overflow from 2022,

由于未调用“inflateGetHeader()”函数,因此此处不适用,

攻击者可使用以下方法来瞄准此攻击面最大 64MB 的任意文件,记录并在出现任何错误后返回;

    ...

    bool ok = false;
    const QByteArray data = Utils::Gzip::decompress(result.data, &ok);
    if (!ok)
    {
        LogMsg(tr("Could not decompress IP geolocation database file."), Log::WARNING);
        return;
    }

截至 2024 年,解压后解析二进制 MaxMind 数据库的代码受到严格保护,但过去看起来有所不同,可能会提供更多的攻击面。

还有一个有趣的提交,其中贡献者对“gzip::decompress()”函数进行了调整,这暗示了堆栈溢出,

目标缓冲区从堆栈上的静态分配更改为堆上的动态分配,尽管它由于在写入之前进行了检查,因此无法利用:

-105           char tmpBuf[BUFSIZE] = {0};
+107           std::vector<char> tmpBuf(BUFSIZE);

三、漏洞影响

所有Python安装程序exe URL和更新RSS源URL都是硬编码,因此可轻松枚举且MITM上下文中的恶意脚本可以攻击每个易受攻击的版本。

而好消息是,RSS源URL为软件提供了指纹,因为除非 qBittorrent 正处于运行状态,否则没有其他理由访问这些URL之一。

这意味着 PRISM 等大规模监控程序可以通过被动流量监控轻松检测 qBittorrent 用户。

但由于没有证书验证,因此不需要像QUANTUM这样昂贵且复杂的部署来执行Man-On-The-Side攻击 - 而只需欺骗目标服务器即可。

URL 被硬编码的另一个方面,是攻击者可以有选择地仅拦截来自 qBittorrent 的不验证连接的请求,

而不是在受害者的浏览器/其他应用程序无法安全连接到互联网时提醒受害者。

由于该软件是开源的,因此添加后门并重新编译是微不足道的,因此可以为受害者提供功能齐全的软件,从而可以避免引起受害者的怀疑。

脚本编写的可能性,当与 mitmproxy 结合使用时,使用 `-s` 来提供 python 脚本:

1、用任意 exe 自动替换所有 Python exe:只需单击一下即可进行 RCE

2、自动替换 RSS 源中的所有 qBittorrent 更新 URL:浏览器劫持/RCE,具有适度的用户交互

3、自动替换 qBittorrent RSS 查看器中的所有/特定链接:RCE 直至 2019 年,下载劫持

人们将需要 MITM 访问权限的攻击视为理论,忘记近代历史上的教训,但显然这一攻击在中国、阿联酋和哈萨克斯坦等国家已变成现实。

四、修复建议

使用浏览器手动下载升级到 v5.0.1 ,而并非通过应用内更新提示。或者使用其他客户端,因为 Deluge 和 Transmission 等没有这个漏洞。

五、参考链接

https://www.qbittorrent.org/news

https://news.ycombinator.com/item?id=42004219 

https://sharpsec.run/rce-vulnerability-in-qbittorrent/ 

https://bugzilla.redhat.com/show_bug.cgi?id=2323594

https://access.redhat.com/security/cve/CVE-2024-51774



扫描二维码,在手机上阅读
评论
更换验证码
友情链接