V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
anhkgg
V2EX  ›  程序员

沙箱:概述

  •  1
     
  •   anhkgg ·
    anhkgg · 2019-10-08 11:09:06 +08:00 · 1871 次点击
    这是一个创建于 1884 天前的主题,其中的信息可能已经有所发展或是发生改变。

    作者:anhkgg 日期:2019 年 10 月 4 日

    最早接触沙箱,对它的印象就是:sandboxie

    因为学的是安全相关专业,在网上下载东西非常谨慎,就算通过了杀毒软件扫描,但是也怕有后门或者其他东西,毕竟我也可以静态过掉杀软。

    很多软件没有官网,各种下载站的东西真的是让人不放心。

    所以在下载某些软件后,只要不影响功能,基本都会用 sandboxie 来运行软件。如果不行,则放到虚拟机里。

    所以我对沙箱最初的概念就是:sandboxie,它是一个轻量级虚拟机,软件的操作都不会影响真正的系统,包括文件、注册表等等资源,可以放肆地想干嘛干嘛。

    那时当然是不怎么知道 sanboxie 是怎么做的。

    题外话:最近因为微软的关系,sanboxie 已选宣布免费,后续还可能开源,感兴趣的可以关注关注。

    沙箱

    注:沙箱现在的概念非常杂,某些分析平台后端也叫沙箱,主要关注的行为获取,我这里说的不一样。

    那么沙箱究竟是怎么做的呢?

    一句话概括的话就是:沙箱内万物基于重定向

    重定向,顾名思义,就是重新指定方向,也就是说沙箱能够做到让沙箱内软件操作的文件、注册表等路径重定向到其他位置(沙箱指定位置),这样软件本来想操作的资源就不会被访问或者操作,保证资源的安全性。

    这也就是我使用沙箱跑一些不明软件的原因,万一软件被恶意修改过,存在病毒,想破坏系统关键文件,也就不可能了。

    言归正传。

    重定向我们还有个高级的词叫做“虚拟化”,也可以称作"隔离",说到底沙箱就是为程序提供一个虚拟化环境,也就是隔离环境,并保证程序所有操作都在这个隔离环境内。

    再举一个简单的例子理解一下重定向。如果程序要删除 c:\boot.ini ,沙箱如何做到隔离,保证文件不被删除呢。

    1. 沙箱 hook ZwDeleteFile,函数是 HOOK_ZwDeleteFile。
    2. 在 HOOK_ZwDeleteFile 中,讲路径 c:\boot.ini 加上一个前缀 c:\sandbox\boot.ini ,转到沙箱内文件路径。
    3. c:\sandbox\boot.ini 不存在,会先把 c:\boot.ini 拷贝到沙箱内。
    4. 然后调用原始 ZwDeleteFile,删除 c:\sandbox\boot.ini 。
    NTSTATUS HOOK_ZwDeleteFile(
      POBJECT_ATTRIBUTES ObjectAttributes
    ) {
       AddPrefix(ObjectAttributes->ObjectName, L"sandbox");//路径加上沙箱前缀
       if(!PathFileExists(ObjectAttributes->ObjectName.Buffer)) {
          CopyFile();//拷贝进来
       }
       return OrigZwDeleteFile(ObjectAttributes);
    }
    

    如此就完成了一个简单的删除文件的隔离。

    一个完备的沙箱一般需要虚拟化(隔离)处理这些东西:

    1. 文件
    2. 注册表
    3. DCOM(RPCSS)
    4. 服务
    5. 其他如:窗口、类名、消息、token 等。
    6. 进程、线程安全
    7. 全局钩子、注入等防护
    8. 驱动加载
    9. ...

    下面对比较重要的几个内容进行一下阐述。

    文件重定向

    保证沙箱内程序创建、修改、删除、读取等文件操作都在沙箱内,不会影响系统中真实的文件。

    功能实现方式由很多,主要可以按下面分为:

    1. 用户态实现,hook ntdll.dll 文件相关函数,然后路径重定向
    2. 内核态实现,ssdt hook 文件相关函数,或者 minifilter 等技术

    用户态实现较为简单,语义更清晰,但是强度不够,有很多方式穿透 ntdll.dll 这层的文件操作函数,导致文件重定向(隔离)失败,比如用户态通过直接扇区读写来修改文件。

    内核态如果使用 minifilter 来实现,强度基本就够了。

    不过 sandboxie 是在用户态实现的。

    注册表重定向

    保证沙箱内程序创建、修改、删除、读取等注册表操作都在沙箱内,不会影响系统中真实的注册表信息。

    同样,和文件重定向一样,也可以在用户态或内核态使用不同的技术完成,先不细说。

    DCOM 虚拟化

    其实做 DCOM 虚拟化,最主要是为了防止沙箱内程序逃逸。

    所谓逃逸,就是沙箱无法控制沙箱内程序行为,程序可以绕过沙箱,对系统造成破坏。

    逃逸的方式有很多,对于支持 DCOM 的程序,就是其中一种。

    举个例子,在 wordpad.exe(写字板)插入对象-画笔图片,会启动 mspaint,可以看到 mspaint 是 svchost.exe -k DcomLaunch 的子进程。

    dcom.png

    什么意思呢?

    一般来说,如果在沙箱中启动 wordpad.exe ,wordpad.exe 的子进程默认也会进入沙箱,但通过 DCOM 启动的 mspaint 就没法拉入沙箱了,它不是 wordpad.exe 子进程。

    所以,此时需要虚拟化 DCOM,让沙箱内启动一个 DCOM 服务,这样 wordpad.exe 直接和沙箱内 DCOM 通信,启动子进程 mspaint.exe ,作为沙箱内 DCOM 服务的子进程,自然也被拉入沙箱内。

    如此做到组织逃逸。

    这里面涉及到很多技术细节,如 RPC,后面细说。

    服务虚拟化

    其实服务也是逃逸沙箱的一种方式,但是也可以说如果沙箱不支持服务虚拟化,某些程序就不能在沙箱内正常工作。

    所以不管出于那种原因考虑,沙箱都得实现服务虚拟化。

    至于说服务也能逃逸是怎么回事呢?

    很简单,程序通过服务 API 创建一个服务,然后启动服务,对应服务程序就没法被沙箱接管,逃出沙箱控制。

    实现就是接管服务相关 API 了。

    其他

    剩下的其他内容,暂时也不分析了,如果有时间,后面继续分享。

    最后

    前面说的内容都是如何完成虚拟化的东西,一个成熟的沙箱肯定还包括其他很多东西,比如多沙箱的支持、沙箱清理、安全浏览器等等,不过这些都不在我们重点讨论范围,毕竟这些只有在实际产品才会考虑的问题,我们这里只是研究沙箱核心相关的技术。

    另外,针对每种重定向技术细节后续会慢慢详细分享,敬请关注。

    最后,再来一张简单的沙箱框图。

    sandbox.png

    如果觉得内容还不错,欢迎关注公众号:汉客儿

    第 1 条附言  ·  2019-10-10 23:39:38 +08:00
    salamanderMH
        1
    salamanderMH  
       2019-10-08 12:38:12 +08:00
    跟 namespace 类似的原理吗?
    locoz
        2
    locoz  
       2019-10-08 18:58:43 +08:00
    咦,原来你有公众号的啊,关注了。
    (图片裂了
    locoz
        3
    locoz  
       2019-10-08 19:00:35 +08:00
    沙箱的原理介绍的挺清晰的,赞👍,我以前一直以为沙箱是直接套了一个轻量级的虚拟机
    Cloutain
        4
    Cloutain  
       2019-10-09 09:42:50 +08:00
    赞!实现一个好用且强度高的沙箱是十分困难的,期待后面的文章
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5856 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 02:41 · PVG 10:41 · LAX 18:41 · JFK 21:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.