juppytt commited on
Commit
e0c04c2
1 Parent(s): 444e806
Files changed (1) hide show
  1. container-escape-check.sh +463 -0
container-escape-check.sh ADDED
@@ -0,0 +1,463 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+
4
+ echo -e ""
5
+ echo -e "\033[34m=============================================================\033[0m"
6
+ echo -e "\033[34m Containers Escape Check v0.3 \033[0m"
7
+ echo -e "\033[34m-------------------------------------------------------------\033[0m"
8
+ echo -e "\033[34m Author: TeamsSix \033[0m"
9
+ echo -e "\033[34m Twitter: TeamsSix \033[0m"
10
+ echo -e "\033[34m Blog: teamssix.com \033[0m"
11
+ echo -e "\033[34m WeChat Official Accounts: TeamsSix \033[0m"
12
+ echo -e "\033[34m Project Address: github.com/teamssix/container-escape-check \033[0m"
13
+ echo -e "\033[34m=============================================================\033[0m"
14
+ echo -e ""
15
+
16
+ # Supported detection methods:
17
+ #
18
+ # 1. Privileged Mode
19
+ # 2. Mount Docker Socket
20
+ # 3. Mount Procfs
21
+ # 4. Mount Root Directory
22
+ # 5. Open Docker Remote API
23
+ # 6. CVE-2016-5195 DirtyCow
24
+ # 7. CVE-2020-14386
25
+ # 8. CVE-2022-0847 DirtyPipe
26
+ # 9. CVE-2017-1000112
27
+ # 10. CVE-2021-22555
28
+ # 11. Mount Host Var Log
29
+ # 12. CAP_DAC_READ_SEARCH
30
+ # 13. CAP_SYS_ADMIN
31
+ # 14. CAP_SYS_PTRACE
32
+ # 15. CVE-2022-0492
33
+
34
+
35
+ CheckCommandExists(){
36
+ $1 >/dev/null 2>&1
37
+ ret=$?
38
+ if [ "$ret" -eq 0 ]; then
39
+ return 1
40
+ fi
41
+ return 0
42
+ }
43
+
44
+
45
+ # Install command
46
+ InstallCommand(){
47
+ # install command if not present
48
+ CheckCommandExists $1
49
+ if [ $? -eq 0 ]; then
50
+ # Check network
51
+ timeout 3 bash -c "echo -e >/dev/tcp/baidu.com/80" > /dev/null 2>&1 && IsNetWork=1 || IsNetWork=0
52
+ if [ $IsNetWork -eq 1 ];then
53
+ echo -e "\033[93m[!] It is detected that the $1 command does not exist in the current system, and the command is being installed.\033[0m"
54
+
55
+ CheckCommandExists sudo
56
+ if [ $? -eq 0 ]; then
57
+ CheckCommandExists apt-get
58
+ if [ $? -eq 0 ];then
59
+ if [ "$1" = "capsh" ];then
60
+ apt-get -y update >/dev/null 2>&1 && apt-get install -y libcap2-bin >/dev/null 2>&1
61
+ else
62
+ apt-get -y update >/dev/null 2>&1 && apt-get install -y $1 >/dev/null 2>&1
63
+ fi
64
+ fi
65
+ CheckCommandExists yum
66
+ if [ $? -eq 0 ];then
67
+ if [ "$1" = "capsh" ];then
68
+ yum -y update >/dev/null 2>&1 && yum install -y libcap >/dev/null 2>&1
69
+ else
70
+ yum -y update >/dev/null 2>&1 && yum install -y $1 >/dev/null 2>&1
71
+ fi
72
+ fi
73
+ else
74
+ CheckCommandExists apt-get
75
+ if [ $? -eq 0 ];then
76
+ if [ "$1" = "capsh" ];then
77
+ sudo apt-get -y update >/dev/null 2>&1 && apt-get install -y libcap2-bin >/dev/null 2>&1
78
+ else
79
+ sudo apt-get -y update >/dev/null 2>&1 && apt-get install -y $1 >/dev/null 2>&1
80
+ fi
81
+ fi
82
+ CheckCommandExists yum
83
+ if [ $? -eq 0 ];then
84
+ if [ "$1" = "capsh" ];then
85
+ sudo yum -y update >/dev/null 2>&1 && yum install -y libcap >/dev/null 2>&1
86
+ else
87
+ sudo yum -y update >/dev/null 2>&1 && yum install -y $1 >/dev/null 2>&1
88
+ fi
89
+ fi
90
+ fi
91
+ CheckCommandExists $1
92
+ if [ $? -eq 0 ]; then
93
+ echo -e "\033[93m[!] $1 command installation failed.\033[0m"
94
+ else
95
+ echo -e "\033[93m[!] $1 command installation completed.\033[0m"
96
+ fi
97
+ fi
98
+ fi
99
+ }
100
+
101
+
102
+ # 0. Check The Current Environment
103
+ CheckTheCurrentEnvironment(){
104
+ if [ ! -f "/proc/1/cgroup" ];then
105
+ IsContainer=0
106
+ else
107
+ cat /proc/1/cgroup | grep -qi docker && IsContainer=1 || IsContainer=0
108
+ fi
109
+
110
+ if [ $IsContainer -eq 0 ];then
111
+ echo -e "\033[31m[-] Not currently a container environment.\033[0m"
112
+ exit 1
113
+ else
114
+ echo -e "\033[33m[!] Currently in a container, checking ......\033[0m"
115
+ VulnerabilityExists=0
116
+ fi
117
+ }
118
+
119
+
120
+ # 1. Check Privileged Mode
121
+ CheckPrivilegedMode(){
122
+ if [ ! -f "/proc/self/status" ];then
123
+ IsPrivilegedMode=0
124
+ else
125
+ cat /proc/self/status | grep -qi "0000003fffffffff" && IsPrivilegedMode=1 || IsPrivilegedMode=0
126
+ cat /proc/self/status | grep -qi "0000001fffffffff" && IsPrivilegedMode=1 || IsPrivilegedMode=0
127
+ fi
128
+
129
+ if [ $IsPrivilegedMode -eq 1 ];then
130
+ echo -e "\033[92m[+] The current container is in privileged mode.\033[0m"
131
+ VulnerabilityExists=1
132
+ fi
133
+
134
+ }
135
+
136
+
137
+ # 2. Check Docker Socket Mount
138
+ CheckDockerSocketMount(){
139
+ if [ ! -f "/var/run/docker.sock" ];then
140
+ IsDockerSocketMount=0
141
+ else
142
+ ls /var/run/ | grep -qi docker.sock && IsDockerSocketMount=1 || IsDockerSocketMount=0
143
+ fi
144
+
145
+ if [ $IsDockerSocketMount -eq 1 ];then
146
+ echo -e "\033[92m[+] The current container has docker socket mounted.\033[0m"
147
+ VulnerabilityExists=1
148
+ fi
149
+ }
150
+
151
+
152
+ # 3. Check Procfs Mount
153
+ CheckProcfsMount(){
154
+
155
+ find / -name core_pattern 2>/dev/null | wc -l | grep -q 2 && IsProcfsMount=1 || IsProcfsMount=0
156
+
157
+ if [ $IsProcfsMount -eq 1 ];then
158
+ echo -e "\033[92m[+] The current container has procfs mounted.\033[0m"
159
+ VulnerabilityExists=1
160
+ fi
161
+ }
162
+
163
+
164
+ # 4. Check Root Directory Mount
165
+ CheckRootDirectoryMount(){
166
+
167
+ find / -name passwd 2>/dev/null | grep /etc/passwd | wc -l | grep -q 7 && IsRootDirectoryMount=1 || IsRootDirectoryMount=0
168
+
169
+ if [ $IsRootDirectoryMount -eq 1 ];then
170
+ echo -e "\033[92m[+] The current container has root directory mounted.\033[0m"
171
+ VulnerabilityExists=1
172
+ fi
173
+ }
174
+
175
+
176
+ # 5. Check Docker Remote API
177
+ CheckDockerRemoteAPI(){
178
+ InstallCommand hostname
179
+ for PORT in "2375" "2376"
180
+ do
181
+ IP=`hostname -i | awk -F. '{print $1 "." $2 "." $3 ".1"}' ` && timeout 3 bash -c "echo -e >/dev/tcp/$IP/$PORT" > /dev/null 2>&1 && DockerRemoteAPIIsEnabled=1 || DockerRemoteAPIIsEnabled=0
182
+ if [ $DockerRemoteAPIIsEnabled -eq 1 ];then
183
+ echo -e "\033[92m[+] The Docker Remote API for the current container is enabled.\033[0m"
184
+ VulnerabilityExists=1
185
+ fi
186
+ done
187
+ }
188
+
189
+
190
+ LinuxKernelVersion=`uname -r | awk -F '-' '{print $1}'`
191
+ KernelVersion=`echo -e $LinuxKernelVersion | awk -F '.' '{print $1}'`
192
+ MajorRevision=`echo -e $LinuxKernelVersion | awk -F '.' '{print $2}'`
193
+ MinorRevision=`echo -e $LinuxKernelVersion | awk -F '.' '{print $3}'`
194
+
195
+
196
+ # 6. Check CVE-2016-5195 DirtyCow
197
+ # 2.6.22 <= ver <= 4.8.3
198
+ CheckCVE_2016_5195DirtyCow(){
199
+ # 2.6.22 <= ver <= 2.6.xx
200
+ if [[ "$KernelVersion" -eq 2 && "$MajorRevision" -eq 6 && "$MinorRevision" -ge 22 ]];then
201
+ echo -e "\033[92m[+] The current container has the CVE-2016-5195 DirtyCow vulnerability.\033[0m"
202
+ VulnerabilityExists=1
203
+ fi
204
+
205
+ # 2.7 <= ver <= 2.x
206
+ if [[ "$KernelVersion" -eq 2 && "$MajorRevision" -ge 7 ]];then
207
+ echo -e "\033[92m[+] The current container has the CVE-2016-5195 DirtyCow vulnerability.\033[0m"
208
+ VulnerabilityExists=1
209
+ fi
210
+
211
+ # ver = 3
212
+ if [[ "$KernelVersion" -eq 3 ]];then
213
+ echo -e "\033[92m[+] The current container has the CVE-2016-5195 DirtyCow vulnerability.\033[0m"
214
+ VulnerabilityExists=1
215
+ fi
216
+
217
+ # 4.x <= ver <= 4.8
218
+ if [[ "$KernelVersion" -eq 4 && "$MajorRevision" -lt 8 ]];then
219
+ echo -e "\033[92m[+] The current container has the CVE-2016-5195 DirtyCow vulnerability.\033[0m"
220
+ VulnerabilityExists=1
221
+ fi
222
+
223
+ # 4.8.x <= ver <= 4.8.3
224
+ if [[ "$KernelVersion" -eq 4 && "$MajorRevision" -eq 8 && "$MinorRevision" -le 3 ]];then
225
+ echo -e "\033[92m[+] The current container has the CVE-2016-5195 DirtyCow vulnerability.\033[0m"
226
+ VulnerabilityExists=1
227
+ fi
228
+ }
229
+
230
+
231
+ # 7. CVE-2020-14386
232
+ # 4.6 <= ver < 5.9
233
+ CheckCVE_2020_14386(){
234
+ # 4.6 <= ver < 4.x
235
+ if [[ "$KernelVersion" -eq 4 && "$MajorRevision" -ge 6 ]];then
236
+ echo -e "\033[92m[+] The current container has the CVE-2020-14386 vulnerability.\033[0m"
237
+ VulnerabilityExists=1
238
+ fi
239
+
240
+ # 5.x <= ver < 5.9
241
+ if [[ $KernelVersion -eq 5 && $MajorRevision -lt 9 ]];then
242
+ echo -e "\033[92m[+] The current container has the CVE-2020-14386 vulnerability.\033[0m"
243
+ VulnerabilityExists=1
244
+ fi
245
+ }
246
+
247
+
248
+ # 8. CVE-2022-0847 DirtyPipe
249
+ # 5.8 <= ver < 5.10.102 < ver < 5.15.25 < ver < 5.16.11
250
+ CheckCVE_2022_0847(){
251
+ if [ $KernelVersion -eq 5 ];then
252
+ # 5.8 <= ver < 5.10.x
253
+ if [[ "$MajorRevision" -ge 8 && "$MajorRevision" -lt 10 ]];then
254
+ echo -e "\033[92m[+] The current container has the CVE-2022-0847 DirtyPipe vulnerability.\033[0m"
255
+ VulnerabilityExists=1
256
+ fi
257
+ # 5.10.x <= ver < 5.10.102
258
+ if [[ "$MajorRevision" -eq 10 && "$MinorRevision" -lt 102 ]];then
259
+ echo -e "\033[92m[+] The current container has the CVE-2022-0847 DirtyPipe vulnerability.\033[0m"
260
+ VulnerabilityExists=1
261
+ fi
262
+ # 5.10.102 < ver <= 5.10.x
263
+ if [[ "$MajorRevision" -eq 10 && "$MinorRevision" -gt 102 ]];then
264
+ echo -e "\033[92m[+] The current container has the CVE-2022-0847 DirtyPipe vulnerability.\033[0m"
265
+ VulnerabilityExists=1
266
+ fi
267
+
268
+ # 5.10.x < ver < 5.15.x
269
+ if [[ "$MajorRevision" -gt 10 && "$MajorRevision" -lt 15 ]];then
270
+ echo -e "\033[92m[+] The current container has the CVE-2022-0847 DirtyPipe vulnerability.\033[0m"
271
+ VulnerabilityExists=1
272
+ fi
273
+
274
+ # 5.15.x <= ver < 5.15.25
275
+ if [[ "$MajorRevision" -eq 15 && "$MinorRevision" -lt 25 ]];then
276
+ echo -e "\033[92m[+] The current container has the CVE-2022-0847 DirtyPipe vulnerability.\033[0m"
277
+ VulnerabilityExists=1
278
+ fi
279
+ # 5.15.25 < ver <= 5.15.x
280
+ if [[ "$MajorRevision" -eq 15 && "$MinorRevision" -gt 25 ]];then
281
+ echo -e "\033[92m[+] The current container has the CVE-2022-0847 DirtyPipe vulnerability.\033[0m"
282
+ VulnerabilityExists=1
283
+ fi
284
+
285
+ # 5.16.x <= ver < 5.16.11
286
+ if [[ "$MajorRevision" -eq 16 && "$MinorRevision" -lt 11 ]];then
287
+ echo -e "\033[92m[+] The current container has the CVE-2022-0847 DirtyPipe vulnerability.\033[0m"
288
+ VulnerabilityExists=1
289
+ fi
290
+ fi
291
+ }
292
+
293
+
294
+ # 9. CVE-2017-1000112
295
+ # 4.4 <= ver<=4.13
296
+ CheckCVE_2017_1000112(){
297
+ # 4.4 <= ver <= 4.13
298
+ if [[ "$KernelVersion" -eq 4 && "$MajorRevision" -ge 4 && "$MajorRevision" -le 13 ]];then
299
+ echo -e "\033[92m[+] The current container has the CVE-2017-1000112 vulnerability.\033[0m"
300
+ VulnerabilityExists=1
301
+ fi
302
+ }
303
+
304
+
305
+ # 10. CVE-2021-22555
306
+ # 2.6.19 <= ver <= 5.12
307
+ CheckCVE_2021_22555(){
308
+ # 2.6.19 <= ver <= 2.6.xx
309
+ if [[ "$KernelVersion" -eq 2 && "$MajorRevision" -eq 6 && "$MinorRevision" -ge 19 ]];then
310
+ echo -e "\033[92m[+] The current container has the CVE-2021-22555 vulnerability.\033[0m"
311
+ VulnerabilityExists=1
312
+ fi
313
+ # 2.7 <= ver <= 2.x
314
+ if [[ "$KernelVersion" -eq 2 && "$MajorRevision" -ge 7 ]];then
315
+ echo -e "\033[92m[+] The current container has the CVE-2021-22555 vulnerability.\033[0m"
316
+ VulnerabilityExists=1
317
+ fi
318
+
319
+ # ver = 3 or ver = 4
320
+ if [[ "$KernelVersion" -eq 3 || "$KernelVersion" -eq 4 ]];then
321
+ echo -e "\033[92m[+] The current container has the CVE-2021-22555 vulnerability.\033[0m"
322
+ VulnerabilityExists=1
323
+ fi
324
+
325
+ # 5.x <= ver <= 5.12
326
+ if [[ $KernelVersion -eq 5 && $MajorRevision -le 12 ]];then
327
+ echo -e "\033[92m[+] The current container has the CVE-2021-22555 vulnerability.\033[0m"
328
+ VulnerabilityExists=1
329
+ fi
330
+ }
331
+
332
+
333
+ # 11. Mount Host Var Log
334
+ CheckVarLogMount(){
335
+ if [ ! -f "/var/run/secrets/kubernetes.io/serviceaccount/token" ];then
336
+ IsPodEnv=0
337
+ else
338
+ IsPodEnv=1
339
+ fi
340
+ if [ $IsPodEnv -eq 1 ];then
341
+ find / -name lastlog 2>/dev/null | wc -l | grep -q 3 && IsVarLogMount=1 || IsVarLogMount=0
342
+ if [ $IsVarLogMount -eq 1 ];then
343
+ echo -e "\033[92m[+] The current container has /var/log mounted.\033[0m"
344
+ VulnerabilityExists=1
345
+ fi
346
+ fi
347
+ }
348
+
349
+
350
+ # 12. Check CAP_DAC_READ_SEARCH
351
+ ChekckCAP_DAC_READ_SEARCH(){
352
+ if command -v capsh >/dev/null 2>&1; then
353
+ cap_dac_read_searchNum=`capsh --print | grep cap_dac_read_search | wc -l`
354
+ if [ $cap_dac_read_searchNum -gt 0 ];then
355
+ echo -e "\033[92m[+] The current container has the CAP_DAC_READ_SEARCH permission.\033[0m"
356
+ VulnerabilityExists=1
357
+ fi
358
+ fi
359
+ }
360
+
361
+
362
+ # 13. Check CAP_SYS_ADMIN
363
+ CheckCAP_SYS_ADMIN(){
364
+ if command -v capsh >/dev/null 2>&1; then
365
+ cap_sys_adminNum=`capsh --print | grep cap_sys_admin | wc -l`
366
+ if [ $cap_sys_adminNum -gt 0 ];then
367
+ echo -e "\033[92m[+] The current container has the CAP_SYS_ADMIN permission.\033[0m"
368
+ VulnerabilityExists=1
369
+ fi
370
+ fi
371
+ }
372
+
373
+
374
+ # 14. Check CAP_SYS_PTRACE
375
+ CheckCAP_SYS_PTRACE(){
376
+ if command -v capsh >/dev/null 2>&1; then
377
+ cap_sys_ptraceNum=`capsh --print | grep cap_sys_ptrace | wc -l`
378
+ if [ $cap_sys_ptraceNum -gt 0 ];then
379
+ echo -e "\033[92m[+] The current container has the CAP_SYS_PTRACE permission.\033[0m"
380
+ VulnerabilityExists=1
381
+ fi
382
+ fi
383
+ }
384
+
385
+
386
+ # 15. Check CVE-2022-0492, Code By https://github.com/PaloAltoNetworks/can-ctr-escape-cve-2022-0492/blob/main/can-ctr-escape-cve-2022-0492.sh
387
+ CheckCVE_2022_0492(){
388
+ # Setup test dir
389
+ test_dir=/tmp/.cve-2022-0492-test
390
+ if mkdir -p $test_dir ; then
391
+ # Test whether escape via user namespaces is possible
392
+ while read -r subsys
393
+ do
394
+ if unshare -UrmC --propagation=unchanged bash -c "mount -t cgroup -o $subsys cgroup $test_dir 2>&1 >/dev/null && test -w $test_dir/release_agent" >/dev/null 2>&1 ; then
395
+ echo -e "\033[92m[+] The current container has the CVE-2022-0492 vulnerability.\033[0m"
396
+ fi
397
+ done <<< $(cat /proc/$$/cgroup | grep -Eo '[0-9]+:[^:]+' | grep -Eo '[^:]+$')
398
+ umount $test_dir >/dev/null 2>&1 && rm -rf $test_dir >/dev/null 2>&1
399
+ fi
400
+ }
401
+
402
+
403
+ main()
404
+ {
405
+ # 0. Check the current environment
406
+ CheckTheCurrentEnvironment
407
+
408
+ # 1. Check Privileged Mode
409
+ CheckPrivilegedMode
410
+
411
+ # 2. Check Docker Socket Mount
412
+ CheckDockerSocketMount
413
+
414
+ # 3. Check Procfs Mount
415
+ CheckProcfsMount
416
+
417
+ # 4. Check Root Directory Mount
418
+ CheckRootDirectoryMount
419
+
420
+ # 5. Check Docker Remote API
421
+ CheckDockerRemoteAPI
422
+
423
+ # 6. Check CVE-2016-5195 DirtyCow
424
+ CheckCVE_2016_5195DirtyCow
425
+
426
+ # 7. CVE-2020-14386
427
+ CheckCVE_2020_14386
428
+
429
+ # 8. CVE-2022-0847 DirtyPipe
430
+ CheckCVE_2022_0847
431
+
432
+ # 9. CVE-2017-1000112
433
+ CheckCVE_2017_1000112
434
+
435
+ # 10. CVE-2021-22555
436
+ CheckCVE_2021_22555
437
+
438
+ # 11. Mount Host Var Log
439
+ CheckVarLogMount
440
+
441
+ InstallCommand capsh
442
+
443
+ # 12. Check CAP_DAC_READ_SEARCH
444
+ ChekckCAP_DAC_READ_SEARCH
445
+
446
+ # 13. Check CAP_SYS_ADMIN
447
+ CheckCAP_SYS_ADMIN
448
+
449
+ # 14. Check CAP_SYS_PTRACE
450
+ CheckCAP_SYS_PTRACE
451
+
452
+ # 15. Check CVE-2022-0492
453
+ CheckCVE_2022_0492
454
+
455
+
456
+ if [ $VulnerabilityExists -eq 0 ];then
457
+ echo -e "\033[33m[!] Check completed, no vulnerability found. \033[0m"
458
+ else
459
+ echo -e "\033[33m[!] Check completed.\033[0m"
460
+ fi
461
+ }
462
+
463
+ main