token
, error
_安全_报告
kubeadm
的delete
命令将引导令牌 ID 或完整令牌作为输入。 在确定输入是 id 还是完整标记之前, kubeadm
使用klog
记录输入。 如果删除失败,令牌将保持有效。 有权访问日志的攻击者可以使用它来执行需要引导令牌的操作,例如创建集群或将节点加入现有集群。
易受攻击的代码存在于 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 :
kubeadm 的 delete 命令将引导令牌 ID 或完整令牌作为输入。 在确定输入是 id 还是完整令牌之前,kubeadm 使用 klog 记录输入。 如果删除失败,令牌将保持有效。 有权访问日志的攻击者可以使用它来执行需要引导令牌的操作,例如创建集群或将节点加入现有集群。
您好,感谢您记录问题。 为了能够读取这样的日志,一个人需要拥有正确的权限,我假设日志要么处于 root 访问权限下,要么提供给具有比引导令牌更高访问权限的特定组。
还:
kubeadm token delete
执行期间启用--v=>1
我认为 PR 的改进大部分都很好,但我认为我们不应该由于这种攻击的复杂性而向后移植到旧版本(<1.20)。
我同意@neolit123不向后移植(除非确实有特定需求)
WRT 修复,我 +1 从日志中删除 TokenID