Ps:多少参杂了一些逆向,LPC通信Handler处理用windbg附加SbieSvc服务,利用Start.exe挂调试,IDA定位分析/源码辅助学习,调试过程有些问题拿捏不准,感谢前辈的帮助。
SandBoxie循序渐进耳(进程篇)
序
关于沙箱,工作之外断断续续学习走过不少坑,去年部署Cuckoo用来个人学习优化Monitor。也尝试过开发轻量级沙盘,逆向Sandboxie连皮毛都没学到,幸好今年SandBoxie开源给学习者带来了更多的思路。
作者推荐了代码审计重点,个人喜欢从界面开始熟悉,交互是响应各功能模块第一步,相对比较友好,较快的理解软件流程的来龙去脉。
推荐一个活跃的sandboxie生态论坛分支,也许你会找到想要的答案:
https://www.wilderssecurity.com/forums/sandboxing-virtualization.98/
SandBoxie:
源码编译:
1. 如果系统已有wdk7600环境,vs2015配置7600,请参考下述文章:
https://www.cnblogs.com/iBinary/p/8290595.html
2. 解决error LNK2001: 无法解析的外部符号 _memcmp/_wcsnicmp等被引用原因:这个过程浪费了大量的业余时间,引入各类函数lib无济于事,修复skd环境,大量的obj报错最终参考msdn文档解决,在Sandboxie的论坛上也发现了解决方案。
https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=vs-2019
https://community.sophos.com/products/sandboxie/f/forum/119641/important-sandboxie-open-source-code-is-available-for-download
3. 解决MinFilter编译被引用,属性-->链接器-->输入-->附加依赖项目:fltMgr.lib
4. 编译成功,不错的开端(vs2017同样编译成功,v141)。
安装沙盘:
这个步骤该阶段不太重要,不影响源码学习。Install/ReadMe按照步骤来做,NSIS已经更新到了v3,按照步骤安装和替换文件。Sandbox.sln同级目录下创建tools/iconv,解压拷贝,这些工作一次性便适用,不需要重复工。
DavidXanatos推出了SandBoxie-Plush,使用了QT,如果不加入其它操作系统分析引擎(可移植),Win下面向界面便捷开发更倾向于使用Libuidk实现(基于MFC商用框架已开源-国外人可能也不知道),容易重构。
https://github.com/sandboxie-plus/Sandboxie
源码学习:
可以下载发行版Sandboxie安装到主机,如果熟悉MFC这将是好的开端,能快速定位代码,控件响应和功能模块,代码重在理解和应用,汲取自己需要的知识。
创建沙盘(r3)
Create New SandBox找到对应的类
1. 输入沙盘名称做规则检测,如下所示:
2.调用SbieApi_IsBoxEnabled()判断沙盘名称是否已创建,发送API_SBIEDRV_CTLCODEDLL查询,封装了两个重要的参数:
1. API_IS_BOX_ENABLED(Driver API Codes)
2. Name_Address
3. Drv驱动 --> api.c(370行开始),对分发进行校验和处理:
3. 校验API_SBIEDRV_CTLCODEDLL
4. 分发api,回调查询code-->API_IS_BOX_ENABLED
Api_functions通过SetFunction初始化(conf_user.c-->106行),初始化分发函数.
Api_SetFunction(API_IS_BOX_ENABLED, Conf_Api_IsBoxEnabled)回调函数处理,如果不存在添加到链中,返回状态码标识是否成功,详细请见代码。
沙盘进程运行:
1. 选中沙盘点击运行,也可以直接拖到Dlg中,如下所示:
2. 思路有很多种,最简单直接的办法搜索函数,这里拖拽文件响应使用OnDropFiles,该工程也只有这一处拖拽使用,如下所示:
3. 沙盘如何将可执行文件加载,这是一个漫长的过程,RunStartExe.cpp --> 35行Common_RunStartExe,如下所示:
4. SbieDll_RunFromHome被定义在了proc.c进程模块,最终会通过CreateProcessW来启动文件,如下所示:
参数:"E:\Program Files\Sandboxie\Start.exe" /box:__ask__ "C:\Users\Administrator\Downloads\powershell.txt"
5. Start.exe,可以选择x64跟踪,也可以选择参数带入源码,解析格式box和_,查询进程信息,box:__ask__,如下所示:
针对一些指令会进行处理,Parse_Command_Line()返回执行文件路径。
Validate_Box_Name选择使用沙盘,代码如下:
6. 通过return die(RestartInSandbox())完成进程启动,RestartInSandbox函数:
7. 调用Callsvc.c(dll模块)处理req,req结构体下文会介绍,数据如下:
SandBoxie-LPC通信
LPC参考:https://bbs.pediy.com/thread-144492.htm
8. 本地通信模块需要熟悉LPC,推荐如下:
https://bbs.pediy.com/thread-144492.htm
https://bbs.pediy.com/thread-162365.htm
Client-Server调试方式,每个人都有自己的学习习惯,文章使用的第二种方式:
1. vs执行start源码,vs执行SbieSvc源码,编译好全部工程,输出目录同一个文件夹下,安装驱动,然后进行调试。(未尝试,理论可行)
2. vs执行start源码,windbg附加SbieSvc服务,IDA+源码辅助学习。
Client:
SbieDll_RunSandboxed()
负责tagPROCESS_RUN_SANDBOXED_REQ结构数据填充,前8bit数据MSG_HEADER结构体。
tagPROCESS_RUN_SANDBOXED_REQ结构,后面尾随的是消息块包括执行cmd和dir,env环境,内存数据如下所示:
SbieDll_CallServer()
负责将客户端结构数据分发至服务端处理。
Service:
Sandboxie客户端循环发送MSG消息到服Svc.Pipserver.cpp(SbieSvcPort),服务端由NtReplyWaitReceivePort循环等待客户端数据,源码中封装如下:
NtReplyWaitReceivePort():
构造PORT_MESSAGE数据包,data->MaxDataLen数值是288bit,TotalLength总大小是328bit,包含结构体本身大小,LPC传输超过256bit进行内存共享传输。
windbg下断SbieSvc.exe-->NtReplyWaitReceivePort,客户端发送MSG至服务端消息队列,也可以直接审计源码,如下所示:
Sbiesvc.exe拖入ida,定位代码段:
LPC处理LPC_CONNECTION_REQUEST,LPC_REQUEST,LPC_PORT_CLOSED,LPC_CLIENT_DIED类型。
客户端client->replying标志,客户端在循环传输过程中调用PortRequest。
PortRequest():
CallTarget():
负责LPC Handler函数分发,LPC Handler根据Msgid执行功能函数。
定位分发函数,断点0x1205观察,通过搜索定位函数代码,如下所示:
*ProcessServer::Handler()
IDA-Windbg对比源码无误,下断g运行,如下所示:
运行后会触发LPC回调分发,MSGID_PROCESS_RUN_SANDBOXED调用号断下1205,ProcessServer.cpp(line:428),启动新进程主模块。
*ProcessServer::RunSandboxedHandler()
获取cmd,dir,env数据
*cmd参数如下:
如果调用方是沙盒,pid号将确定API_START_PROCESS调用的BoxNameOrModel Pid参数,如果是沙箱外部的呼叫者则指定了一个框名。
SbieApi_QueryProcessInfo()
复制和初始化,调用Ioctl来进行数据初始化
SbieApi_Ioctl()
1. 初始化 "\\Device\\" SANDBOXIE L"DriverApi"对象
2. NtOpenFile-->DriverApi
3. 发送API_SBIEDRV_CTLCODE控制码
RunSandboxedGetToken()
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2020-7-16 15:03
被一半人生编辑
,原因: