<p>kubeadm 可能会在尝试删除引导令牌之前记录引导令牌</p>

创建于 2020-09-11  ·  3评论  ·  资料来源: kubernetes/kubeadm

在提交这个问题之前,您在 kubeadm issues 中搜索了哪些关键字?

token , error

这是错误报告还是功能请求?

_安全_报告

概括:

kubeadmdelete命令将引导令牌 ID 或完整令牌作为输入。 在确定输入是 id 还是完整标记之前, kubeadm使用klog记录输入。 如果删除失败,令牌将保持有效。 有权访问日志的攻击者可以使用它来执行需要引导令牌的操作,例如创建集群或将节点加入现有集群。

Kubernetes 版本:

易受攻击的代码存在于 kubernetes 1.19 中。 包含对klog调用的特定行最后编辑于 2019 年 3 月 24 日。

细节:

易受攻击的代码位于github.com/kubernetes存储库中的kubernetes/cmd/kubeadm/app/cmd/token.go ,位于第 423 行。这是整个函数:

// RunDeleteTokens removes a bootstrap tokens from the server.
func RunDeleteTokens(out io.Writer, client clientset.Interface, tokenIDsOrTokens []string) error {
    for _, tokenIDOrToken := range tokenIDsOrTokens {
        // Assume this is a token id and try to parse it
        tokenID := tokenIDOrToken
        klog.V(1).Infof("[token] parsing token %q", tokenIDOrToken) // POTENTIAL LEAK HERE
        if !bootstraputil.IsValidBootstrapTokenID(tokenIDOrToken) {
            // Okay, the full token with both id and secret was probably passed. Parse it and extract the ID only
            bts, err := kubeadmapiv1beta2.NewBootstrapTokenString(tokenIDOrToken)
            if err != nil {
                return errors.Errorf("given token %q didn't match pattern %q or %q",
                    tokenIDOrToken, bootstrapapi.BootstrapTokenIDPattern, bootstrapapi.BootstrapTokenIDPattern)
            }
            tokenID = bts.ID
        }

        tokenSecretName := bootstraputil.BootstrapTokenSecretName(tokenID)
        klog.V(1).Infof("[token] deleting token %q", tokenID)
        if err := client.CoreV1().Secrets(metav1.NamespaceSystem).Delete(context.TODO(), tokenSecretName, metav1.DeleteOptions{}); err != nil {
            return errors.Wrapf(err, "failed to delete bootstrap token %q", tokenID)
        }
        fmt.Fprintf(out, "bootstrap token %q deleted\n", tokenID)
    }
    return nil
}

这是调用该函数的 kubeadm 命令的定义(在同一文件中):

    deleteCmd := &cobra.Command{
        Use:                   "delete [token-value] ...",
        DisableFlagsInUseLine: true,
        Short:                 "Delete bootstrap tokens on the server",
        Long: dedent.Dedent(`
            This command will delete a list of bootstrap tokens for you.

            The [token-value] is the full Token of the form "[a-z0-9]{6}.[a-z0-9]{16}" or the
            Token ID of the form "[a-z0-9]{6}" to delete.
        `),
        RunE: func(tokenCmd *cobra.Command, args []string) error {
            if len(args) < 1 {
                return errors.Errorf("missing subcommand; 'token delete' is missing token of form %q", bootstrapapi.BootstrapTokenIDPattern)
            }
            kubeConfigFile = cmdutil.GetKubeConfigPath(kubeConfigFile)
            client, err := getClientset(kubeConfigFile, dryRun)
            if err != nil {
                return err
            }

            return RunDeleteTokens(out, client, args)
        },
    }

影响:

从日志中获取引导令牌的攻击者可以使用它来验证kubeadm并创建新集群或将节点加入现有集群,例如使用计算资源。 攻击者还可以使用kubeadm执行其他操作,例如列出或删除其他令牌。

附加信息:

我已经向HackerOne报告了这个漏洞,他们告诉我,基于高攻击复杂性和低严重性,他们认为可以公开报告和修复。

我已经在 kubernetes 上打开了一个 PR 实施修复: https :

aresecurity kincleanup prioritbacklog

所有3条评论

kubeadm 的 delete 命令将引导令牌 ID 或完整令牌作为输入。 在确定输入是 id 还是完整令牌之前,kubeadm 使用 klog 记录输入。 如果删除失败,令牌将保持有效。 有权访问日志的攻击者可以使用它来执行需要引导令牌的操作,例如创建集群或将节点加入现有集群。

您好,感谢您记录问题。 为了能够读取这样的日志,一个人需要拥有正确的权限,我假设日志要么处于 root 访问权限下,要么提供给具有比引导令牌更高访问权限的特定组。

还:

  • 如果令牌格式有效,则必须在kubeadm token delete执行期间启用--v=>1
  • 默认情况下,令牌会在 24 小时后过期

我认为 PR 的改进大部分都很好,但我认为我们不应该由于这种攻击的复杂性而向后移植到旧版本(<1.20)。

我同意@neolit123不向后移植(除非确实有特定需求)
WRT 修复,我 +1 从日志中删除 TokenID

此页面是否有帮助?
0 / 5 - 0 等级