From dd90e55cc1689d69c486c523993640be2efc4646 Mon Sep 17 00:00:00 2001 From: Drun1baby <2717763591@qq.com> Date: Thu, 12 Dec 2024 11:35:34 +0800 Subject: [PATCH 1/3] modify k8s service account functions --- pkg/evaluate/evaluate.go | 14 ++++++- pkg/evaluate/k8s_service_account.go | 59 +++++++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 6 deletions(-) diff --git a/pkg/evaluate/evaluate.go b/pkg/evaluate/evaluate.go index b2dd022..2cbb88f 100644 --- a/pkg/evaluate/evaluate.go +++ b/pkg/evaluate/evaluate.go @@ -17,8 +17,8 @@ limitations under the License. package evaluate import ( + "fmt" "github.com/cdk-team/CDK/pkg/util" - "github.com/cdk-team/CDK/conf" ) // CallBasics is a function to call basic functions @@ -51,7 +51,17 @@ func CallBasics() { CheckK8sAnonymousLogin() util.PrintH2("Discovery - K8s Service Account") - CheckPrivilegedK8sServiceAccount(conf.K8sSATokenDefaultPath) + + path := GetDefaultK8SAccountInfo() + address, err := GetKubernetesAddress() + + if err != nil { + fmt.Println("Error:", err) + } else { + fmt.Println("KUBERNETES_PORT_443_TCP_ADDR:", address) + } + + CheckPrivilegedK8sServiceAccount(path, address) util.PrintH2("Discovery - Cloud Provider Metadata API") CheckCloudMetadataAPI() diff --git a/pkg/evaluate/k8s_service_account.go b/pkg/evaluate/k8s_service_account.go index b8b68cf..d236130 100644 --- a/pkg/evaluate/k8s_service_account.go +++ b/pkg/evaluate/k8s_service_account.go @@ -1,4 +1,3 @@ - /* Copyright 2022 The Authors of https://github.com/CDK-TEAM/CDK . @@ -18,17 +17,19 @@ limitations under the License. package evaluate import ( + "bytes" "fmt" "github.com/cdk-team/CDK/pkg/tool/kubectl" "log" + "os/exec" "strings" ) -func CheckPrivilegedK8sServiceAccount(tokenPath string) bool { +func CheckPrivilegedK8sServiceAccount(tokenPath string, address string) bool { resp, err := kubectl.ServerAccountRequest( kubectl.K8sRequestOption{ - TokenPath: "", - Server: "", + TokenPath: tokenPath + "/token", + Server: address, Api: "/apis", Method: "get", PostData: "", @@ -71,3 +72,53 @@ func CheckPrivilegedK8sServiceAccount(tokenPath string) bool { return false } } + +func GetDefaultK8SAccountInfo() string { + // 执行 df -T 命令来看 serviceaccount 保存路径 + cmd := exec.Command("df", "-T") + var out bytes.Buffer + cmd.Stdout = &out + cmd.Stderr = &out + + err := cmd.Run() + if err != nil { + fmt.Printf("Command execution failed: %s\n", err) + return "" + } + + output := out.String() + lines := strings.Split(output, "\n") + + var serviceAccountLines []string + + for _, line := range lines { + if strings.Contains(line, "serviceaccount") { + fmt.Println("\tk8s account service path fetch success" + line) + serviceAccountLines = append(serviceAccountLines, line) + } + } + + return strings.Join(serviceAccountLines, "\n") +} + +func GetKubernetesAddress() (string, error) { + cmd := exec.Command("env") + var out bytes.Buffer + cmd.Stdout = &out + cmd.Stderr = &out + err := cmd.Run() + if err != nil { + return "", fmt.Errorf("command execution failed: %s", err) + } + + output := out.String() + lines := strings.Split(output, "\n") + + for _, line := range lines { + if strings.HasPrefix(line, "KUBERNETES_PORT_443_TCP_ADDR=") { + return strings.TrimPrefix(line, "KUBERNETES_PORT_443_TCP_ADDR="), nil + } + } + + return "", fmt.Errorf("KUBERNETES_PORT_443_TCP_ADDR not found") +} From 18a45fd0a7fd50f3dbdc47e6df9e73a645b5cc3c Mon Sep 17 00:00:00 2001 From: Drun1baby <2717763591@qq.com> Date: Thu, 12 Dec 2024 21:10:00 +0800 Subject: [PATCH 2/3] modify some codes --- pkg/evaluate/evaluate.go | 12 +----- pkg/evaluate/k8s_service_account.go | 58 +++++++++++------------------ 2 files changed, 23 insertions(+), 47 deletions(-) diff --git a/pkg/evaluate/evaluate.go b/pkg/evaluate/evaluate.go index 2cbb88f..ca4b26d 100644 --- a/pkg/evaluate/evaluate.go +++ b/pkg/evaluate/evaluate.go @@ -17,7 +17,6 @@ limitations under the License. package evaluate import ( - "fmt" "github.com/cdk-team/CDK/pkg/util" ) @@ -52,16 +51,7 @@ func CallBasics() { util.PrintH2("Discovery - K8s Service Account") - path := GetDefaultK8SAccountInfo() - address, err := GetKubernetesAddress() - - if err != nil { - fmt.Println("Error:", err) - } else { - fmt.Println("KUBERNETES_PORT_443_TCP_ADDR:", address) - } - - CheckPrivilegedK8sServiceAccount(path, address) + CheckPrivilegedK8sServiceAccount(GetDefaultK8SAccountInfo(), GetKubernetesAddress()) util.PrintH2("Discovery - Cloud Provider Metadata API") CheckCloudMetadataAPI() diff --git a/pkg/evaluate/k8s_service_account.go b/pkg/evaluate/k8s_service_account.go index d236130..e068b97 100644 --- a/pkg/evaluate/k8s_service_account.go +++ b/pkg/evaluate/k8s_service_account.go @@ -17,14 +17,16 @@ limitations under the License. package evaluate import ( - "bytes" + "bufio" "fmt" "github.com/cdk-team/CDK/pkg/tool/kubectl" "log" - "os/exec" + "os" "strings" ) +const mountInfoPath string = "/proc/self/mountinfo" + func CheckPrivilegedK8sServiceAccount(tokenPath string, address string) bool { resp, err := kubectl.ServerAccountRequest( kubectl.K8sRequestOption{ @@ -74,51 +76,35 @@ func CheckPrivilegedK8sServiceAccount(tokenPath string, address string) bool { } func GetDefaultK8SAccountInfo() string { - // 执行 df -T 命令来看 serviceaccount 保存路径 - cmd := exec.Command("df", "-T") - var out bytes.Buffer - cmd.Stdout = &out - cmd.Stderr = &out - - err := cmd.Run() + file, err := os.Open("/proc/self/mountinfo") if err != nil { - fmt.Printf("Command execution failed: %s\n", err) - return "" + fmt.Println("error opening /proc/self/mountinfo: %w", err) } + defer file.Close() - output := out.String() - lines := strings.Split(output, "\n") + scanner := bufio.NewScanner(file) - var serviceAccountLines []string - - for _, line := range lines { + for scanner.Scan() { + line := scanner.Text() if strings.Contains(line, "serviceaccount") { - fmt.Println("\tk8s account service path fetch success" + line) - serviceAccountLines = append(serviceAccountLines, line) + fmt.Println("find serviceaccount successfully") + return line } } - return strings.Join(serviceAccountLines, "\n") -} - -func GetKubernetesAddress() (string, error) { - cmd := exec.Command("env") - var out bytes.Buffer - cmd.Stdout = &out - cmd.Stderr = &out - err := cmd.Run() - if err != nil { - return "", fmt.Errorf("command execution failed: %s", err) + if err := scanner.Err(); err != nil { + fmt.Println("error reading /proc/self/mountinfo: %w", err) } - output := out.String() - lines := strings.Split(output, "\n") + return "" +} - for _, line := range lines { - if strings.HasPrefix(line, "KUBERNETES_PORT_443_TCP_ADDR=") { - return strings.TrimPrefix(line, "KUBERNETES_PORT_443_TCP_ADDR="), nil +func GetKubernetesAddress() string { + env := os.Environ() + for _, e := range env { + if strings.HasPrefix(e, "KUBERNETES_PORT_443_TCP_ADDR=") { + return strings.TrimPrefix(e, "KUBERNETES_PORT_443_TCP_ADDR=") } } - - return "", fmt.Errorf("KUBERNETES_PORT_443_TCP_ADDR not found") + return "KUBERNETES_PORT_443_TCP_ADDR not found" } From 6ecc0210c5261208dcea134761b01a156acdadec Mon Sep 17 00:00:00 2001 From: Drun1baby <2717763591@qq.com> Date: Thu, 12 Dec 2024 21:32:57 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20auto=5Fescape=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/task/auto_escape.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pkg/task/auto_escape.go b/pkg/task/auto_escape.go index 947c7a8..4cc72a8 100644 --- a/pkg/task/auto_escape.go +++ b/pkg/task/auto_escape.go @@ -25,7 +25,6 @@ import ( "github.com/cdk-team/CDK/pkg/exploit/persistence" "log" - "github.com/cdk-team/CDK/conf" "github.com/cdk-team/CDK/pkg/cli" "github.com/cdk-team/CDK/pkg/evaluate" "github.com/cdk-team/CDK/pkg/plugin" @@ -109,7 +108,13 @@ func autoEscape(shellCommand string) bool { // 4. check k8s anonymous login fmt.Printf("\n[Auto Escape - K8s API Server]\n") anonymousLogin := evaluate.CheckK8sAnonymousLogin() - privServiceAccount := evaluate.CheckPrivilegedK8sServiceAccount(conf.K8sSATokenDefaultPath) + defaultAccountInfo := GetDefaultK8SAccountInfo() + kubernetesAddress := GetKubernetesAddress() + + privServiceAccount := evaluate.CheckPrivilegedK8sServiceAccount( + CheckPrivilegedK8sServiceAccount(defaultAccountInfo, kubernetesAddress), + ) + k8sExploit = privServiceAccount || anonymousLogin if !k8sExploit {