在界面上,通过“Register”操作,随便提供了一个文件作为输入,界面提示:"The specified file is invalid.",
到软件的安装目录的lib中找到smartgit.jar文件,基本可以认定它是核心功能包,所以对它进行逆向分析。
从上面的提示找到的信息,基本上都是一个通用aqU字符返回类,里面有比较多的信息,但是提供不了处理逻辑,但是
返回字符中有关于版本的信息,通过对反编译的工程进行call调用查找,定位到aqT类(说明:windows不区分文件大小
写很坑,混淆过的文件中,很多不区分大小写就是重名的,通过luyten.exe导出可以解决)
虽然没有定位到关键处理点,但是上面的信息基本提供了证书文件的字段内容,仔细分析这个类后,可以基本确定证书文件格式:
当然上面的还不是证书文件的全部信息,需要继续分析,再次查找aqT类的创建点:
因为代码进行了混淆,看起来还是非常的低效,所 以想着能构建一个可调试工程,但是这个程序是从smartgit.exe进行运行的,它
是用的自己的加载器进行jar的加载,所以转到分析smartgit.exe,程序并没有加壳,直接找smartgit.jar字符串相关的信息,结果
什么也没有找到。但是在查看数据目录(C:\Users\<username>\AppData\Roaming\syntevo\SmartGit\18.2)时,有个logger.properties
配置文件,看着像可以配置日志级别,以为能收集数据,就改了下配置,结果启动程序的时候,直接出错了,而且提示有完整DUMP文件,
从文件中看到比较有意思的信息:
基本理清楚加载的过程:
smartgit.exe ---> (bootloader.jar + bootloader-config.jar) ---> smartgit.jar
好吧,现在可以不管smartgit.exe了,直接复制lib目录,在eclipse中创建新的工程,加载这些jar文件(创建过程不表了)
以bootloader.jar作为启动,确认可以加载运行起来,通过反编译插件就可以进行断点调试了,一大进步。
可以调试后,调试了几次感觉信息还是比较多的,可以有一次直接就走到了软件升级框,而且是强制的,升级完成了,再后来进行调试时,
smartgit的版本都变化了,这让我感觉比较奇怪,因为我构建的工程目录不在安装目录,它是怎么升级的?或者加载器加载了其它文件 ?
转到分析bootloader.jar文件,发现还真有不少信息:
首先bootloader.jar文件自身会被写入一些key=value信息:
buildNubmer=13205
buildDate=2018-12-06
smartboot.majorVersion=18.2
smartboot.productName=SmartGit
smartboot.productKey=SmartGit
smartboot.productCompany=syntevo
smartboot.additionalJars=org.eclipse.swt.$G.$P.jar
在bootloader.jar加载的时候,它会读取自己身的这些信息,同时和临时目录C:\Users\<username>\AppData\Roaming\syntevo\SmartGit\18.2\updates\18.2
中的current文件内容比较,判断版本是不是最新的,如果不是,则会根据contorl-<version number>文件的内容,进行加载,contorl-<version number>
记录了需要加载的文件和对应升级的文件路径信息。
搞清楚了这部分基本就可以调试升级部分功能了,修改current信息,然后进次启动,弹出了升级框,进行主线程暂停,得到栈信息:
查看代码中的http处理的API,重新设置断点,得到了请求远端服务器信息:
通过向升级服务器获取最新版本信息,再与本地版本进行比较确认是否需要升级。
这样比较简单的办法就是hosts文件,直接把www.syntevo.com 重定向到127.0.0.1.
解决升级问题,再次回到之前版本进行调试,从掌握的信息,先直接对aqT类的函数都设置了断点,看看有哪些有意思的栈信息,再逐个分析:
和上面的分析基本对应上了,在aqT的调用点之前,ake是证书文件信息,S1,S2是公钥信息。
通过对上面的调用逐个调试,定位到alV类函数:
进行文件解析处理
从上面的信息基本可以把调用过程都走一遍,不过依赖的信息太多了,每次调试都比较麻烦,所以通过staruml对相关的类进行了梳理,结果如
下图所示:
把这些相关的类反编译代码提取出来,再构建新的工程,就不再依赖smartgit.jar进行调试了,代码比较多,就不逐个函数说了,整理出来的
验证信息如下:
1, 证书文件是ZIP包,内部有一个证书文件,文件可以是UTF8格式;
2, 证书文件中包含了相关的证书字段,以Key = Value 方式写入(明文格式),其中以#表示该行注释。
3,对于证书的验证,软件提供了两个方式,要么是有一个Signature=XXX的内容,要么是在文件的最后有
有一个文件不包含“=”的签名,其中这个签名至少两行,第一行字符长度 != 80,内容不重要,后面的行长度 == 80 ,如果不足,可以补0.
整理出来的校验逻辑如下:
1, 提供的KEY 值格式(string1 , string2, bool1, bool2)
其中string1, string2均为JAVA BigInteger的对应结果。
bool1从分析,可以知道在验证中,如果为true, 那么校验时使用了 最后<key, value>中的value, 反之,使用key .
2, 具体算法:
string1 ---> SIGA (BigInteger)
string2 ---> SIGB (BigInteger)
fileSig ---> SIGC (BigInteger) # 说明,中间经过了一些从字符串到BigInteger转换。
encryptSourceStr =bool1 ? value : key # 说明:使用文件最后一组值对的内容。
关键函数:
可以看到只要验证结果不正确,就会抛出异常alS。
从上面的分析,由于对算法不熟悉,数据太大不能穷举,放弃,选择对alV类进行暴破,因为有混淆,不能构建
出可编译环境,直接对上面的函数进行字节码修改,验证删除抛出异常部分,进行return.将修改后的alV.class更新到smartgit.jar
中,再构建完整证书文件:
启动smartgit,提交压缩的证书文件,直接验证OK,分析成功,在IDA和OD之外,解析型语言的分析尝试了一波!!!
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2019-3-15 10:49
被nevinhappy编辑
,原因: