diff --git a/pkg/evaluate/evaluate.go b/pkg/evaluate/evaluate.go index b2dd022..ca4b26d 100644 --- a/pkg/evaluate/evaluate.go +++ b/pkg/evaluate/evaluate.go @@ -18,7 +18,6 @@ package evaluate import ( "github.com/cdk-team/CDK/pkg/util" - "github.com/cdk-team/CDK/conf" ) // CallBasics is a function to call basic functions @@ -51,7 +50,8 @@ func CallBasics() { CheckK8sAnonymousLogin() util.PrintH2("Discovery - K8s Service Account") - CheckPrivilegedK8sServiceAccount(conf.K8sSATokenDefaultPath) + + 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 b8b68cf..e068b97 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,21 @@ limitations under the License. package evaluate import ( + "bufio" "fmt" "github.com/cdk-team/CDK/pkg/tool/kubectl" "log" + "os" "strings" ) -func CheckPrivilegedK8sServiceAccount(tokenPath string) bool { +const mountInfoPath string = "/proc/self/mountinfo" + +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 +74,37 @@ func CheckPrivilegedK8sServiceAccount(tokenPath string) bool { return false } } + +func GetDefaultK8SAccountInfo() string { + file, err := os.Open("/proc/self/mountinfo") + if err != nil { + fmt.Println("error opening /proc/self/mountinfo: %w", err) + } + defer file.Close() + + scanner := bufio.NewScanner(file) + + for scanner.Scan() { + line := scanner.Text() + if strings.Contains(line, "serviceaccount") { + fmt.Println("find serviceaccount successfully") + return line + } + } + + if err := scanner.Err(); err != nil { + fmt.Println("error reading /proc/self/mountinfo: %w", err) + } + + return "" +} + +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 "KUBERNETES_PORT_443_TCP_ADDR not found" +} 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 {