token
, error
_SECURITY_ LAPORAN
Perintah kubeadm
's delete
mengambil sebagai input baik ID token bootstrap, atau token lengkap. Sebelum menentukan apakah input hanya id atau token lengkap, kubeadm
mencatat input menggunakan klog
. Jika penghapusan gagal, token akan tetap valid. Penyerang yang memiliki akses ke log dapat menggunakannya untuk melakukan tindakan yang memerlukan token bootstrap, seperti membuat cluster atau menggabungkan node ke cluster yang ada.
Kode rentan ada di kubernetes 1.19. Baris khusus yang berisi panggilan ke klog
terakhir diedit pada 24-03-2019.
Kode yang rentan ada di repositori github.com/kubernetes
, di file kubernetes/cmd/kubeadm/app/cmd/token.go
, pada baris 423. Berikut adalah keseluruhan fungsinya:
// 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
}
Dan inilah definisi dari perintah kubeadm yang memanggil fungsi tersebut (dalam file yang sama):
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)
},
}
Penyerang yang memperoleh token bootstrap dari log dapat menggunakannya untuk mengautentikasi dengan kubeadm
dan membuat cluster baru atau menggabungkan node ke cluster yang ada, misalnya untuk menggunakan sumber daya komputasi. Penyerang juga dapat melakukan tindakan lain menggunakan kubeadm
, misalnya membuat daftar atau menghapus token lain.
Saya telah melaporkan kerentanan ini ke HackerOne dan mereka telah memberi tahu saya bahwa berdasarkan kompleksitas serangan yang tinggi dan tingkat keparahan yang rendah, mereka pikir ini dapat dilaporkan dan diperbaiki secara publik.
Saya telah membuka PR di kubernetes yang menerapkan perbaikan: https://github.com/kubernetes/kubernetes/pull/94727
perintah delete kubeadm mengambil sebagai input ID token bootstrap, atau token lengkap. Sebelum menentukan apakah input hanya id atau token lengkap, kubeadm mencatat input menggunakan klog. Jika penghapusan gagal, token akan tetap valid. Penyerang yang memiliki akses ke log dapat menggunakannya untuk melakukan tindakan yang memerlukan token bootstrap, seperti membuat cluster atau menggabungkan node ke cluster yang ada.
hai, dan terima kasih telah mencatat masalah ini. untuk dapat membaca log seperti itu, seseorang harus memiliki hak istimewa yang tepat dan saya akan menganggap log tersebut berada di bawah akses root atau diberikan kepada grup tertentu yang memiliki akses lebih tinggi daripada token bootstrap.
juga:
--v=>1
harus diaktifkan selama eksekusi kubeadm token delete
jika token dalam format yang validsaya pikir peningkatan dalam PR sebagian besar baik-baik saja, tetapi saya tidak berpikir kita harus melakukan backport ke rilis yang lebih lama (<1.20) karena kompleksitas serangan semacam itu.
Saya setuju dengan @neolit123 untuk tidak melakukan backport (kecuali benar-benar ada kebutuhan khusus)
WRT untuk memperbaikinya, saya memberi +1 untuk menghapus TokenID dari log
ditutup saat https://github.com/kubernetes/kubernetes/pull/94727 digabungkan.
Terima kasih