Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pkg/evaluate/evaluate.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down
45 changes: 41 additions & 4 deletions pkg/evaluate/k8s_service_account.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

/*
Copyright 2022 The Authors of https://github.com/CDK-TEAM/CDK .

Expand All @@ -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: "",
Expand Down Expand Up @@ -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"
}
9 changes: 7 additions & 2 deletions pkg/task/auto_escape.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
"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"
Expand Down Expand Up @@ -109,7 +108,13 @@
// 4. check k8s anonymous login
fmt.Printf("\n[Auto Escape - K8s API Server]\n")
anonymousLogin := evaluate.CheckK8sAnonymousLogin()
privServiceAccount := evaluate.CheckPrivilegedK8sServiceAccount(conf.K8sSATokenDefaultPath)
defaultAccountInfo := GetDefaultK8SAccountInfo()

Check failure on line 111 in pkg/task/auto_escape.go

View workflow job for this annotation

GitHub Actions / Buildable and Runable

undefined: GetDefaultK8SAccountInfo
kubernetesAddress := GetKubernetesAddress()

Check failure on line 112 in pkg/task/auto_escape.go

View workflow job for this annotation

GitHub Actions / Buildable and Runable

undefined: GetKubernetesAddress

privServiceAccount := evaluate.CheckPrivilegedK8sServiceAccount(
CheckPrivilegedK8sServiceAccount(defaultAccountInfo, kubernetesAddress),

Check failure on line 115 in pkg/task/auto_escape.go

View workflow job for this annotation

GitHub Actions / Buildable and Runable

undefined: CheckPrivilegedK8sServiceAccount
)

k8sExploit = privServiceAccount || anonymousLogin

if !k8sExploit {
Expand Down
Loading