---
tags: Kubernetes,SecurityContext
description: Kubernetes Security Context Issue
robots: index, follow
---
# misconfig - II: Security Context
相信很多人由容器環境轉到Kubernetes時,最常做的一件事就是上傳好image後,就很直覺的把服務開到叢集中,非常直覺、快速、幫自己挖了坑。
例如:
```yaml=
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: mycontainer
name: mycontainer
spec:
containers:
- args:
- client
image: nginx
name: mycontainer
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
```
前一篇文章我們有提到一些需要補充的東西,就讓我們來看看會發生什麼事。
## 1.1. 環境資訊
**K8S: v1.20.12**
**NAME STATUS ROLES**
g1-master1 Ready controlplane,etcd
g1-master2 Ready controlplane,etcd
g1-master3 Ready controlplane,etcd
g1-worker1 Ready worker
g1-worker2 Ready worker
g1-worker3 Ready worker
## 1.2. Lab操作
1. 建立一個pod,快速的把他對外服務、確認狀態。
```shell=
└[~]> kubectl run mycontainer
pod/mycontainer created
└[~]> kubectl expose pod mycontainer --type=NodePort --target-port 80 --port 80
service/mycontainer exposed
└[~]> kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 74d
mycontainer NodePort 10.43.194.42 <none> 80:31065/TCP 1m
└[~]> curl 172.24.2.16:31065
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
...
(略)
```
2. 然後我們就可以幫他安裝套件了,前後不用5分鐘完成。(擦汗
```shell=
└[~]> kubectl exec -it mycontainer -- /bin/bash
root@mycontainer:/# apt update
Get:1 http://deb.debian.org/debian bullseye InRelease [116 kB]
Get:2 http://security.debian.org/debian-security bullseye-security InRelease [44.1 kB]
Get:3 http://deb.debian.org/debian bullseye-updates InRelease [39.4 kB]
Get:4 http://deb.debian.org/debian bullseye/main amd64 Packages [8183 kB]
...
root@mycontainer:/# apt install recon-ng
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
javascript-common libgpm2 libjs-jquery libjs-skeleton libjs-sphinxdoc
(略)
```
:::info
1. [recon-ng](https://www.kali.org/tools/recon-ng/ "recon-ng"): Recon-ng is a full-featured Web Reconnaissance framework.
:::

沒有模組可以用,就安裝或enable自己想要的囉。
3. 用一個沒有安裝任何服務的nginx來做範例似乎說不過去,我們用一個可以執行系統指令的網頁服務來看看。
[1. 小網頁程式-github、dockerfile](https://github.com/yansheng133/securitycontext "security context")
[2. 已經build好的docker image](https://hub.docker.com/r/yansheng133/securitycontext "")
:::danger
1. 上述兩個連結,僅用於本文展示透過網頁執行系統指令所產生的可能問題,不負責任何濫用後產生的任何損失。
:::
**source code**
```go=
package main
import (
"os/exec"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/ping/:exec", func(c *gin.Context) {
exe := c.Params.ByName("exec")
out, err := exec.Command(exe).Output()
if err != nil {
c.JSON(200, gin.H{
"message": err,
})
}
output := string(out[:])
c.JSON(200, gin.H{
"CLI return message": output,
"Warning: ": "This is training sample, DO NOT USE IT FOR BAD!",
})
})
r.Run()
}
```
4. 能夠執行指令的web服務:testweb.yaml。
```yaml=
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: testweb
name: testweb
spec:
replicas: 1
selector:
matchLabels:
app: testweb
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: testweb
spec:
containers:
- image: yansheng133/securitycontext:0.3
name: securitycontext
resources: {}
status: {}
---
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: testweb
name: testweb
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
app: testweb
type: NodePort
status:
loadBalancer: {}
```
5. 建立相關的服務。
```shell=
└[~]> kubectl create -f testgo.yaml
deployment.apps/testweb created
service/testweb created
└[~]> kubectl get svc,deploy,pod
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 73d
service/mycontainer NodePort 10.43.194.42 <none> 80:31065/TCP 23h
service/testweb NodePort 10.43.91.239 <none> 80:30344/TCP 12m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/testweb 1/1 1 1 12m
NAME READY STATUS RESTARTS AGE
pod/mycontainer 1/1 Running 0 23h
pod/testweb-5f8f8bcb9f-pq5sk 1/1 Running 0 12m
```
6. 傳指令進去,確認回應是什麼,也可用瀏覽器打開,透過網址輸入一樣的內容就可以了。
```shell=
└[~]> curl 172.24.2.15:30344/ping/ls
{"CLI return message":"go.mod\ngo.sum\nmain.go\n","Warning: ":"This is training sample, DO NOT USE IT FOR BAD!"}%
└[~]> curl 172.24.2.15:30344/ping/whoami
{"CLI return message":"root\n","Warning: ":"This is training sample, DO NOT USE IT FOR BAD!"}%
└[~]> curl 172.24.2.15:30344/ping/'%20check%20ascii.'
{"message":{"Name":" check ascii.","Err":{}}}{"CLI return message":"","Warning: ":"This is training sample, DO NOT USE IT FOR BAD!"}%
└[~]> curl 172.24.2.15:30344/ping/id
{"CLI return message":"uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)\n","Warning: ":"This is training sample, DO NOT USE IT FOR BAD!"}%
```
7. 從回應我們可以觀察到以下狀況:
:::info
1. 可以列出當前的資料夾。
2. 自己的權限是root。
3. 有些ascii碼會做轉換。
:::
撇除ASCII碼會做轉換這個網頁程式面的問題,發現可以進行一些基本指令的呼叫,這個問題一樣會發生在登入容器或透過特定的指令、程式反向連結到想要的IP位置。
不過我們可以在服務建立的時候,就把系統權限全部拔掉。
例如拔掉所有的系統權限(capabilities)、拿掉切換到root的權限(allowPrivilegeEscalation)、把權限切換到指定的使用者(runAsUser)等。
```yaml=
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: dropall
name: dropall
spec:
containers:
- args:
- /bin/sleep
- "3600"
image: busybox
name: dropall
resources: {}
securityContext:
runAsUser: 2000
capabilities:
drop:
- all
allowPrivilegeEscalation: false
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
```
8. 確認一下id, whoami, ping與系統能夠執行哪些東西。
```shell=
└[~]> kubectl exec -it dropall -- /bin/sh
/ $ id
uid=2000 gid=0(root)
/ $ whoami
whoami: unknown uid 2000
/ $ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
ping: permission denied (are you root?)
/ $ cat /proc/1/status |grep Cap
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000000000000000
CapAmb: 0000000000000000
##想確認可以操作哪些東西可以透過capsh --decode=值來做檢查,整排0就是無任何權限。
```
經過調整之後,就可以把非必要的權限等都移除,能夠有效的縮小被攻擊面,另外搭配一些network policy能夠更加明確的指定容器與容器間相互存取的方式,建議讀者可以參考先前的calico network policy,強化網路活動可視性,避免惡意人士對整體環境的偵查作業。
## 1.3. 參考資料
[1. official - security contex](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ "")
[2. Open Policy Agent](https://www.openpolicyagent.org/ "OPA")
[3. kubesec](https://kubesec.io/ "kubesec")