0×01 简介
OZ系统是通过把Linux的桌面程序运行在隔离的安全沙盒中来保护程序的安全,从而避免攻击者可以轻易的利用应用程序的漏洞进一步攻击系统。
任何大型复杂的桌面程序都无法保证完全没有安全漏洞的存在,只要软件可以处理不可信的或者恶意的数据,那么这个程序可能就会成为攻击者的目标。
连接到网络服务中的应用通过网络协议从网络中获取数据,无意间就很可能暴露在恶意数据中。
比如以下3类应用就很容易暴露在恶意数据中:
1.浏览器 2.邮件客户端 3.即时通讯软件
即使一款应用从不连接网络,只要它处理了来自不可信源的数据,就有可能被攻击,例如:
1.文档阅读器 2.视频播放软件 3.文件管理软件
在一个系统中,尤其是单用户系统,应用被破坏是一个极大的问题。如果攻击者想要监视一个目标并且获取到他的数据,进一步获取到目标终端的用户权限,这些漏洞足够达到这样的目的。而通过这些,攻击者将能够获取到数据,获取到登录其他系统的证书以及本地加密密钥,而如果是一个现代化的操作系统和外围硬件中,那么情况就更可怕了。
终端上的一个应用程序的危害意味着攻击者可以做以下几件事:
1.不用提升权限就能获取到用户数据,例如:文档、邮件信息 2.获取到已保存的信息,例如:邮箱/即时通讯/网站密码,加密密钥,系统认证文件 3.修改用户的登陆属性,使用户在不知不觉中运行已修改过的客户端 4.获取并且操控用户使用的硬件设备,例如:移动硬盘,系统的录音和录像设备
此外,通过本地用户的权限,攻击者还能有许多条途径提升自己的权限:
1.利用在二进制文件中的内核漏洞或者普通漏洞 2.用非特权后门给系统装上后门
而逐步上升到管理员权限将对以后的攻击产生提供的帮助:可以经一步获取整个系统的控制权限,维护稳定的远程访问,获取长期的监控并且可以避免被某些高度安全的系统侦察到(尽管在实际环境中,大多数目标并没有这么高的安全等级,并且经常出现攻击者可以长时间的控制目标而不被发现的情况,尽管攻击者的权限并不怎么高)。
0×02 Oz是如何工作的?
Oz会将高危的应用隔离在一个隔离层中,这样就能有条不紊的切断提升权限的途径并且隔离程序和程序运行的数据。这样设计的目的是为了更细致更灵活的控制这些。
Oz的关键特性
沙盒中应用程序的访问控制参数在Oz的策略文件里面进行了预先定义。Oz为特殊的应用设计了很多需要预先配置的策略。
当Oz被安装之后:
1.沙盒中的应用程序将会被Oz改名,然后在文件系统中原始的二进制位置处就会创建一个链接,该链接指向Oz二进制文件。 2.当用户在应用程序原始位置运行的时候,Oz就开始工作了。Oz先会检查应用程序的名称,然后打开相关的策略文件。策略文件中包含了各种参数,用来控制应用的运行时间和运行环境,以及如何启动该程序。 3.然后Oz守护进程将会创建一个隔离的环境并且把实际的程序放入沙盒中根据定义好的安全策略设置并运行应用程序。 4.程序在运行的时候,用户还可以使用Oz CLI工具打开沙盒容器运行的shell进行操作。
具体的运行过程如下:
1)用户运行应用程序时
应用程序的二进制文件(图上图中的/usr/bin/evince)是一个指向oz命令行工具的符号链接
2)Oz程序向Oz后台进程发送一个信号,告诉后台进程把程序放入沙盒中
Oz程序读取运行命令时的argv[0]参数,oz就能知道要运行程序的路径,并且通过socket向oz后台进程发送一个信息,将要运行的程序放入沙盒中启动。
3)oz后台进程加载应用程序的策略配置文件
应用程序的配置文件详细记录了如何为该应用程序建立沙盒
4)应用程序的沙盒开始运行
沙盒具体怎么运行将在后面的文章中讲到
5)一个新的PID命名空间将oz-init进程被创建,例如pid 1
Oz-init进程用于管理沙盒中的子进程。如上插图,Oz-init开始运行Xpra服务端并且运行经过seccomp-bpf封装的应用软件的二进制文件,seccomp-bpf封装可以对应用程序调用的系统命令进行约束。
6)在沙盒外面有Xpra客户端与沙盒内的pra服务端进行连接
Xpra把应用程序和图形接口服务器(X server)隔离开了,因此,沙盒无法捕获键盘记录或者干扰其他桌面程序的运行。
7) Xpra 连接真正的图形接口服务器
Xpra客户端将应用程序窗口呈现在X server中
0×03 安全目标
防止访问超出程序所需要的数据
Oz会新创建一个与物理机文件系统隔离的空间,把要运行的应用程序放入隔离区的根目录下运行。Oz应用程序策略配置文件中定义了白名单和黑名单来控制程序运行时能访问和不能访问的文件和目录。
例如,在Oz中的一个应用程序可能不能访问以下文件,除非需要的时候:
1.用户的SSH密钥 2.用户的邮件内容 3.用户的加密密钥 4.用户的文档信息 5.用户的下载文件 6.系统的用户标识文件
很多静态访问控制权限系统,例如 AppArmor或者SELinux都无法完全解决这种问题,因为单个策略需要被定义得足够许可,这样的话程序才能在复杂的环境中正常的运行。
一个最有说明性的例子:文档阅读软件evince,通常都需要文件系统的任意目录的读/写权限。用户就能通过运行evince然后从菜单里加载任意他们想要查看的文件。
然而,当我们用evince打开一个不可信的文档的时候,这种策略就显得不那么恰当,因为该文档可能含有恶意代码可以攻击阅读器本身。我们需要的是即使用户打开了具有威胁性的文档,阅读器也不能允许攻击者读取或者擦除其他不属于该用户的数据。
在Oz中,当你用evince阅读一篇文档的时候,沙盒文件系统除了属于文档的数据外不会加载任何其他用户的数据。这样的访问权限(沙盒中只有单一的需要阅读的文档)动态的从用户行为中决定该加载那些数据。
防止攻击者有执行任意代码的能力
能达到什么样的攻击效果取决于最开始利用的漏洞是什么样的,如果利用的内存破坏型的漏洞,攻击者就能利用该漏洞执行任意机器代码(系统会被攻击者进行注入攻击,或者被清空内存地址空间,)那么,唯一可以限制这种行为的就是拒绝访问内核设施。
另一种任意执行漏洞可以让攻击者运行文件系统中的可执行文件,然后提升自己的权限进而控制整个操作系统。为了阻止攻击者执行任意代码,文件系统必须设置成无法从任何可写目录中执行任何代码。此外,脚本语言解释器也应该在被限制的范围内。
减少暴露操作系统的内核导致被提权
攻击者可能通过调用系统命令,设备或者内核文件系统(比如/proc)等方式攻击操作系统内核来绕过沙盒环境。
应用程序在运行的时候必须经过Seccomp-BPF的过滤。这些过滤器通过限制进程的系统调用次数来减少内核层面的攻击。Linux内核漏洞可以导致权限的提升,这通常可以在系统命令调用的时候看出来。 减少暴露出来的系统命令数将会减少推算出代码路径,并且发现内核漏洞。
防止攻击者逐步提升系统权限
Oz系统中使用到的命名空间隔离各种与系统后台进程交互的操作,因为这些可能会被黑客利用。
通过设置用户标记符或者增强二进制文件性能避免被攻击
程序被运行在沙盒中的时候会有一个标记PR_SET_NO_NEW_PRIVS用于避免获取任何功能。此外,所有运行在沙盒中的文件系统都被安装上MS_NOSUID并且已有的带有用户标识符的二进制文件将会被列入黑名单。
限制网络访问避免用户数据泄漏
Oz会在每个Oz容器中创建一个网络命名空间,这包括Oz自身的虚拟界面。通过策略可以规定Oz如何与外部的网络通讯。如果应用程序不需要连接网络,那么程序将可以完全被拒绝连接网络。
例如说,图像显示软件不需要进行连接网络,它在沙盒中运行的命名空间就不带任何网络设备,而其他的应用,例如IM客户端就只需要简单的访问地址和端口,这样的就要限制成最小的网络访问。
隔离X window应用程序
X Windows系统的结构对Linux桌面程序的沙盒安全提出了挑战。任何连接到X服务器上的进程都可以捕获用户的键盘输入和任何在桌面窗口上处理的屏幕。Oz隔离程序通过Xpra将每个沙盒私有的X服务器连接到真实的X服务器。
最小化沙箱外露设备
每个应用程序的容器环境都有一个/dev,配备了程序运行所需要的最小化设备。
在沙盒环境中已安装的设备(例如移动硬盘)将尽量少的暴露出来,音频和视频存储也将被Oz 策略控制。
0×04 具体操作
文件系统
以下介绍沙盒文件系统中具体的操作流程
1.新建一个rootfs目录
rootfs = "/srv/oz/rootfs" mkdir(rootfs)
2.递归的设置MS_PRIVATE的值
mount("", "/", "", MS_PRIVATE | MS_REC, "")
由于这个是在一个新的安装空间里,它只影响到oz-daemon进程
3.将tmpfs添加进rootfs目录
mount("", rootfs, "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV, "mode=755,gid=0")
4.捆绑安装/bin /lib /lib64 /usr /etc
mount("/bin", "/srv/oz/rootfs/bin", "", MS_BIND, "") mount("", "/srv/oz/rootfs/bin", "", MS_REMOUNT | MS_RDONLY) // repeat for remaining directories
5.创建一个空目录
var basicEmptyDirs = []string{ "/sbin", "/var", "/var/lib", "/var/cache", "/home", "/boot", "/tmp", "/run", "/run/user", "/run/lock", "/root", "/opt", "/srv", "/dev", "/proc", "/sys", "/mnt", "/media", }
6./srv/oz/rootfs/dev中安装上tmpfs
mount("", "/srv/oz/rootfs/dev", "tmpfs", MS_NOSUID | MS_NOEXEC, "mode=755")
7.创建设备
crw-------. 1 root root 5, 1 Jun 28 17:18 console crw-rw-rw-. 1 root root 1, 7 Jun 28 17:18 full crw-rw-rw-. 1 root root 1, 3 Jun 28 17:18 null crw-rw-rw-. 1 root root 1, 8 Jun 28 17:18 random crw-rw-rw-. 1 root root 5, 0 Jun 28 17:18 tty -rw-r-----. 1 root root 0 Jun 28 17:18 tty1 -rw-r-----. 1 root root 0 Jun 28 17:18 tty2 -rw-r-----. 1 root root 0 Jun 28 17:18 tty3 -rw-r-----. 1 root root 0 Jun 28 17:18 tty4 crw-rw-rw-. 1 root root 1, 9 Jun 28 17:18 urandom crw-rw-rw-. 1 root root 1, 5 Jun 28 17:18 zero
8.创建符号连接
var basicSymlinks = [][2]string{ {"/run", "/var/run"}, {"/tmp", "/var/tmp"}, {"/run/lock", "/var/lock"}, {"/dev/shm", "/run/shm"}, } var deviceSymlinks = [][2]string{ {"/proc/self/fd", "/dev/fd"}, {"/proc/self/fd/2", "/dev/stderr"}, {"/proc/self/fd/0", "/dev/stdin"}, {"/proc/self/fd/1", "/dev/stdout"}, {"/dev/pts/ptmx", "/dev/ptmx"}, }
9.创建黑名单文件或者目录
dr-x------. 2 root root 40 Jun 28 17:18 oz.ro.dir -r--------. 1 root root 0 Jun 28 17:18 oz.ro.file
10.特定的目录加入黑名单
var basicBlacklist = []string{ "${PATH}/sudo", "${PATH}/su", "${PATH}/xinput", "${PATH}/strace", "${PATH}/mount", "${PATH}/umount", "${PATH}/fusermount", }
11.从界面绑定白名单
界面白名单选项是通过鼠标点击文件或者目录事件添加到沙盒中的。
12.如果Xpra被使用,在用户目录下创建Xpra套接字目录并且捆绑在沙盒中
[evince] $ ls -n $HOME/.Xoz/evince/evince-0 srw-------. 1 1000 1000 0 Jun 28 17:18 /home/x/.Xoz/evince/evince-0
1.进入chroot
chroot("/srv/oz/rootfs") chdir("/")
2.在沙盒中添加内核文件系统
mount("", "/dev/shm", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV) mount("", "/tmp", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV) mount("", "/dev/pts", "devpts", MS_NOSUID | MS_NOEXEC "newinstance,ptmxmode=0666") mount("", "/proc", "proc", MS_NOSUID | MS_NOEXEC) mount("", "/sys", "sysfs", MS_NOSUID | MS_NOEXEC | MS_RDONLY)
网络图
桥接网络(Bridged Networking)
如果你的应用程序需要和网络进行通讯,沙盒将会给应用创建一个私有的网络,并且这个网络是通过桥接的方式连接到外部网络。
无网络连接(No network)
如果一个应用软件不需要访问网络,No network借口将会在沙盒的网络命名空间中被创建。
代理网络连接(Proxy networking)
如果事先已经知道了一个应用软件在启动的时候只需要连接一些特殊的服务,本地的代理监听就会被配置起来,用于在程序与远程地址和端口连接时候进行监听。这种情况下,除了特定服务外,其他的联网服务不需要被配置并运行。
Seccomp
如果攻击者拥有本地权限或者一些非特权权限,那么内核漏洞将会是提权的一个很有效的途径。很多内核漏洞通过系统调用把程序运行的整个流程暴露给了攻击者,往往有漏洞的系统调用了太多不是程序运行必须的系统调用,攻击者就能利用这些调用进行漏洞攻击。
Seccomp过滤是Oz提供的可以减少内核层面攻击的Linux内核调用机制,通过限制系统调用的进程数和控制确定的系统调用的使用来实现过滤。在Oz中,每一个应用程序都有Seccomp规则。这些规则规定了白名单内的系统调用和黑名单内的系统调用,这些调用在程序运行前将会被立即运行。这样的话,如果程序有内核漏洞,这样的机制就能限制攻击者进一步提取系统权限。
相关视频
以下是两个Oz沙盒具体的操作视频:
Demo vid 1: https://support.subgraph.com/videos/oz_evince_01.webm
Demo vid 2: https://support.subgraph.com/videos/ozshell_evince_01.webm
X server是Linux系统里面图形接口服务器的简称,总结一下linux图形界面层次关系:linux本身–>X服务器<-[通过X协议交谈]->窗口管理器(综合桌面环境)–>X应用程序。
* 参考来源: github ,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)