从Sandboxie源码分析软件注册机制及逆向思路
本帖最后由 jc021227 于 2023-6-3 18:02 编辑## 一、简介
Sandboxie是Windows上的虚拟环境,可以用来测试不受信任的软件,类似轻量级的虚拟机,用于隔离安装流氓软件也十分方便
Sandboxie最初是收费的商业软件,后来停止开发并开源,现在由github的开发者David Xanatos维护,添加了许多新功能,称为Sandboxie Plus,但这些新功能需要向作者赞助获取激活码才能使用
既然有源代码,不妨以此为例分析软件的注册机制,以及逆向思路
## 二、分析
首先下载Sandboxie Plus的安装包,安装后打开设置,看到以下捐赠界面:
先随便输入,弹出错误提示:
意思是格式不对,那么接下来就去源码中找到对应的部分。可以git clone到本地然后用Visual Studio打开,也可以用github自带的搜索,结果如图:
注意到`location`标签包含了调用处的文件和行号,于是找到对应位置:
分析`ApplyCertificate`函数的逻辑,参数`Certificate`是一个字节数组,首先判断许可证是否为空,然后通过`GetArguments`函数解析为指定格式。下面是两个判断,`NAME`和`SIGNATURE`不能为空,否则就弹出刚才的错误提示。如果格式正确,就把许可证写入文件。
继续看,发现下面调用了`theAPI->ReloadCert()`然后进行条件判断,意识到`ApplyCertificate`函数的作用只是对许可证的初步处理,验证逻辑并不在这里。
那么继续看`theAPI`是什么,然而文件中找不到定义,头文件也没有,最后发现在`stdafx.h`中(这一步用VS就方便的多)
原来它是`CSbiePlusAPI*`类型,但在这个类中没有`ReloadCert()`函数,于是到父类`CSbieAPI`中查找。在`SbieAPI.cpp`找到定义,只有一行,调用了`ReloadConf(SBIE_CONF_FLAG_RELOAD_CERT)`,紧接着就是它的定义:
大概是对参数进行处理,然后调用`IoControl`,继续跟进:
发现处理后的参数最终传入Windows的系统函数`NtDeviceIoControlFile`,这个函数有些陌生,上网查找它的用法,其中`API_SBIEDRV_CTLCODE`是关键,这是设备IO控制代码,用于指定要执行的具体操作。于是全局搜索这个名称,最后在驱动中找到了处理位置:
继续往下看,这里首先把参数`buf`赋值到`user_args`,第一个元素就是函数的编号,`Api_Functions`是存放函数指针的数组,然后计算出下标,取出对应的函数指针。
继续搜索,发现`Api_Functions`由`Api_SetFunction`函数初始化:
寻找调用处,原来在另一个文件中:
这个`API_RELOAD_CONF`就是传给驱动的参数,它对应的函数指针是`Conf_Api_Reload`,发现它很长,但关键的地方在前几行:
看到调用了`MyValidateCertificate()`,最后返回`status`,这很可能就是验证函数。紧接着搜索它的定义,发现它又调用了`KphValidateCertificate()`:
继续跟进,终于来到了真正的验证函数:
这个函数特别长,但是还得仔细看,因为它修改了一些全局变量,也就是有副作用,如果直接写`return 0`可能导致意外状况。看到它首先调用了`MyInitHash`,转到它的定义,分析一下,它的作用是初始化`pHashObj`的成员,其实都是指向算法函数的指针:
接着往下看,下一处验证在这里,功能是验证许可证有效期和类型,格式错误则验证失败:
至于许可证类型到底有哪些,别急,先往下分析。
这里又出现了两个函数`MyFinishHash`和`KphVerifySignature`,分别查看定义:
经过分析,它的作用是计算许可证的hash,如果成功则返回`STATUS_SUCCESS`。但它只是完成了计算,校验不在这里,不需要修改。
而`KphVerifySignature`就是真正的验证函数了,分析这段代码,发现它是个纯算法函数,仅仅判断hash是否有效,而不创建或者修改外部资源,因此可以放心修改,方法是在第一行直接返回`STATUS_SUCCESS`:
经过这么多判断之后,终于来到了`Verify_CertInfo.valid = 1;`这一行。经过以上分析,发现它就是除了返回值以外验证许可证的条件之一。如果只关注返回值,却没发现函数对外部变量的修改,验证依然会失败。在商业软件中,会用到更复杂的多个变量验证的方法,就是所谓的“暗桩”。
接下来是确定许可证的类型和有效期,代码逻辑很清晰,这时发现一个隐藏属性`CONTRIBUTOR`,能直接跳过有效期判断。去官网看了一下价格,相当于赞助1000欧获得的Huge Supporter Certificate,果然内鬼比土豪更可怕……
所以许可证的`TYPE`可以写`CONTRIBUTOR`或者`PERSONAL-HUGE`,`DATE`都可以省略了。
回顾一下,实际上修改的只有一个函数。因为重点是分析和理解验证的流程,如果要实现任意输入都能通过验证,需要在多处进行修改,不利于初学者理解。
接下来就要验证是否破解成功,这里有个简便的方法,因为代码库在github上,而且配置了CI/CD,因此只要fork原仓库,提交自己的修改,等待自动构建完成,下载生成的Artifacts就可以了。这样就无需在本机花费大量时间和空间安装Qt,VS和WDK。如果想在本机编译,装好环境后用VS打开工程编译即可,可以参考readme,这里不详细讲述了。
## 三、验证
前面说过,为了让修改尽可能简洁,并不是随便输入都能通过验证。根据前面的分析,构造出如下许可证:
```
NAME: 52pojie//任意
DATE: 01.04.2099//非必需
TYPE: CONTRIBUTOR//或PERSONAL-HUGE
SOFTWARE: Sandboxie-Plus
UPDATEKEY: 123456789//非必需
SIGNATURE: www.52pojie.cn//任意
```
最后还有一个问题,Windows内核驱动必须签名才能加载,签名是需要花钱从微软买的。这个问题确实没有什么好办法,所以可以猜到,作者为什么要把验证放到驱动层了吧。
一个临时方案是暂时关闭Windows的驱动签名验证,方法是以管理员身份打开命令行,输入`bcdedit /set testsigning on`,重启即可。但这带来一些问题,比如游戏反作弊系统检测到禁止驱动签名则不能启动,桌面右下角会有测试模式的水印,安全性下降等等。
先不管那么多,看看修改后的效果如何吧:
验证成功,所有功能都正常使用
备注一下,在`verify.c`中还发现两个名称相近的函数`KphVerifyFile`和`KphVerifyCurrentProcess`,逻辑与`KphVerifySignature`相似,暂时没发现具体作用,不过也进行了修改。许可证的`SIGNATURE`属性少于6个字符会验证失败,猜测与hash函数的计算方式有关,暂时没做进一步分析。
## 四、总结
这次分析的软件虽然验证方式简单,但从中能总结出常见的验证流程以及破解方法。通常,破解从验证提示处入手,一步步跟踪找到验证函数的位置,大体是这样的流程:
```
提示窗口 -> 验证函数1 -> ... -> 验证函数n -> 算法函数
```
而某个需要验证的功能函数是:
```
功能函数 -> 验证函数1 -> ... -> 验证函数n -> 算法函数
```
很多时候,输入许可证和调用功能,验证时中间过程是不一样的,但如果能找到并修改最底层的算法函数,那么无论验证的中间过程是什么样的,最后进行计算时总能得到我们想要的结果。就像能控制一加一等于几,那么再复杂的算法结果也能操纵,比起修改中间过程更加彻底。
假如不修改算法函数,那就必须逐一分析验证过程中调用链的每个函数。修改返回值有时候是不行的,因为它们常常有副作用,创建或修改了一些外部变量,然后在另一个隐蔽的地方进行验证导致失败。另外,输入许可证时和调用功能时的验证函数可能是不同的,但大多数时候默认两者相同或部分相同。而遇到防护严密或者验证过程不寻常的软件,这个假设就不成立了。
在实际应用中,分析反编译的代码比源代码困难的多,需要经验和技巧的积累。而Sandboxie Plus作为开源的付费软件,很适合新手用来学习和练手,了解常见验证机制的流程。
## 版权信息
本文涉及的源代码使用GPLv3授权,在以GPLv3发布的前提下可以任意修改,来自`SandboxiePlus/LICENSE`:
```
Sandboxie-Plus is made up of the following components, governed under various licenses:
* MiscHelpers a generic Qt based helper library, license under the LGPL.
* The Qt Framework which is license under the LGPL.
* SandMan the primary Sandboxie-Plus UI component, provided under a custom license.
* QSbieAPI a stand alone re implementation of sandboxie’s API using IPC mechanisms to. communicate with sandboxie’s core components, license under the LGPL.
* Sandboxie core components, licensed under the GPL v3.
* UglobalHotkey is an extension for Qt framework, which implements global hotkeys functionality and is in the Public Domain.
* QtSingleApp a Qt Solutions Component that provides support for applications that can be only started once per user, BSD licensed.
ALL THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
``` 根据作者的方法在 GitHub 上编译了一下: https://github.com/lyc8503/Sandboxie-crack/actions/runs/5170029087
感谢作者~ cxl 发表于 2023-6-3 18:36
这个不是有免费的么
plus版本有试用限制 其实功能上普通版本就够用了 本帖最后由 suhetao 于 2023-6-16 23:04 编辑
感谢楼主分享,近期刚好在挣扎要不要购买赞助者凭证。主要win11自带的沙盘也不错。
尝试用不可描述的天上掉下来的过期证书驱动签名后,无需打开驱动测试或者关闭驱动签名模式的Win环境就可以运行。然而。。。
”开源“软件的第二作者明显不想那么轻松的让人跳过付费环节,依旧有暗桩。会提示缺少SandMan.exe的有效SandMan.exe.sig签名文件,导致沙盘无法创建。
省事的话简单粗暴编译一个新的驱动替换原版安装包安装后的驱动即可 {:1_921:}算法部分要是可以具体分析就更好了 厉害呀!赞 这个不是有免费的么 这思路,学到了{:1_918:}{:1_918:} 学习学习 支持支持 谢谢{:1_893:}学习了 多谢大佬的详细分析
多谢大佬的详细分析