雨笋教育技术干货:漏洞分析,Docker CVE-2018-6552

本文深入探讨了Docker容器中的CVE-2018-6552安全漏洞,该漏洞可能导致条件竞争并允许容器逃逸到宿主机。分析了源码,揭示了如何通过操纵PID命名空间和核心转储机制来规避安全检查。同时,文章提供了利用条件竞争来绕过apport的两个判断,并讨论了如何通过大量进程占用PID来实现逃逸。最后,提到了利用logrotate进行进一步的攻击策略。
摘要由CSDN通过智能技术生成

本篇文章漏洞分析,目前还没有人分析过,唯一的参考就是滴滴安全大会中有做过简单的解析,一起来看看吧!

首先看看漏洞描述

我们借此可以了解到大概成因,以及影响的版本,看下diff文件

这是个条件竞争的洞,看diff可以看到差别就是多出了对the is_same_ns() function fails open (returning True) 的处理,也就是说,之前未修复漏洞时,在is_same_as()函数open失败时是不会引发将local pid更换为global pid的操作的,也就是说,我们可以通过特殊方法使其不走以上任何一个分支,继续往下走。

源码分析

贴上is_same_as的源码,以及更改前后版本的漏洞处源码

def is_same_ns(pid, ns):

if not os.path.exists('/proc/self/ns/%s' % ns) or \

not os.path.exists('/proc/%s/ns/%s' % (pid, ns)):

# If the namespace doesn't exist, then it's obviously shared

return True

try:

if os.readlink('/proc/%s/ns/%s' % (pid, ns)) == os.readlink('/proc/self/ns/%s' % ns):

# Check that the inode for both namespaces is the same

return True

except OSError as e:

if e.errno == errno.ENOENT:

return True

else:

raise

return False

未修复的源码

# Check if we received a valid global PID (kernel >= 3.12). If we do,

# then compare it with the local PID. If they don't match, it's an

# indication that the crash originated from another PID namespace.

# Simply log an entry in the host error log and exit 0.

if len(sys.argv) == 6:

host_pid = int(sys.argv[5])

if not is_same_ns(host_pid, "pid") and not is_same_ns(host_pid, "mnt"):

# If the crash came from a container, don't attempt to handle

# locally as that would just result in wrong system information.

# Instead, attempt to find apport inside the container and

# forward the process information there.

if not os.path.exists('/proc/%d/root/run/apport.socket' % host_pid):

error_log('host pid %s crashed in a container without apport support' %

sys.argv[5])

sys.exit(0)

[ ... ]

sys.exit(0)

elif not is_same_ns(host_pid, "pid") and is_same_ns(host_pid, "mnt"): #这里

# If it doesn't look like the crash originated from within a

# full container, then take the global pid and replace the local

# pid with it, then move on to normal handling.

# This bit is needed because some software like the chrome

# sandbox will use container namespaces as a security measure but are

# still otherwise host processes. When that's the case, we need to keep

# handling those crashes locally using the global pid.

sys.argv[1] = str(host_pid)

elif not is_same_ns(host_pid, "mnt"):

error_log('host pid %s crashed in a separate mount namespace, ignoring' % host_pid)

sys.exit(0)

修复之后的源码

elif not is_same_ns(host_pid, "mnt"):

error_log('host pid %s crashed in a separate mount namespace, ignoring' % host_pid)

sys.exit(0)

else:

# If it doesn't look like the crash originated from within a

# full container or if the is_same_ns() function fails open (returning

# True), then take the global pid and replace the local pid with it,

# then move on to no

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值