WPS Office 的 Product.dat 与 Oem.ini 配置文件哈希校验的逆向分析
本文简介
WPS 的默认配置使用 Product.dat 存储,而 Oem.ini 则存储一些用户自定义的设置,但这两个文件的配置信息都是加密且经过数字签名的,所以本文尝试通过逆向分析了解 WPS 对这两个文件数字签名的校验过程。
逆向分析
首先,我们尝试修改 office6\cfgs
目录中的 product.dat
,比如这里将结尾的数字签名随便改掉一位,然后启动 WPS 后发现弹出了对话框提示 “WPS Office 启动文件损坏”,那我们就从这里入手,给 MessageBox
系列函数打上断点。
|
|
这里使用的是 64 位版本的 WPS,所以用 x64dbg 来调试,运行直到断点,发现断在了 MessageBoxW
函数上,查看寄存器,rdx 中正是我们之前看到的错误提示。
运行到返回,看到调用消息框的函数在 kprometheus.dll 中,那么复制文件偏移,去 IDA 看看。
在 IDA 中跳转到文件偏移,发现这个动态库居然包含一部分符号信息,这就简单太多了。此时位于 KPromeApplication::configsTamperingError
函数中,大概看一下整个函数的结构,发现主要就是两部分,先调用 krt::configs::getOemIniValid
,如果通过则调用 krt::configs::getProductDatValid
,如果都验证没问题就直接退出函数,否则会进行一些验证失败的操作。
这两个函数是从 krt.dll 中引入的,这里分析 krt::configs::getProductDatValid
,用 IDA 打开并搜索这个函数,看到 productReader_0
从全局变量中获取 krt::configs
类的地址,看得出这似乎是个全局单例类,而 sub_180016310
是这个类中标志 Product.dat 是否合法的成员变量的 Get 函数。
接下来我们要找到程序在哪里设置了这个标志位的值,所以回到 x64dbg,跟踪到 krt::configs::getProductDatValid
函数中,执行到 call productReader_0
结束以得到常量的地址,将 rax 中的地址转到内存窗口查看,然后将 0x30
处打上内存写入断点。
重新运行,看到内存断点断了下来,复制文件偏移到 IDA,发现这里甚至有字符串 krt::anonymous-namespace::ensureValidProductFile
。(大意了,早知道应该先查查字符串的 >_<)
到处看看,运气很好,校验函数就是krt::configs
类初始化附近的 sub_7FFDAA09ECD0
函数(上图第 67 行),这个函数从配置文件结尾读取了 512 个字符作为数字签名,并将文件剩余的部分做 MD5 后与其进行校验。
翻到 sub_7FFDAA09D960
的时候,发现这里面很蹊跷,有一大串的硬编码,这很可能就是密钥之类的东西。
在函数的结尾,发现了一个大宝贝!居然有符号名。这个函数的第一个参数是前面算出来的,后两个参数就是 sub_7FFDAA09D960
的两个参数。
查看 krt::kcodec::KRSAVerifyFile
函数,这里就是 RSA 校验的地方,是用了 CryptoPP 库。
后记
又是对 WPS 下手的一天~
这次,内置的很多符号让逆向轻松了不少。
下一章写写怎么做一个过校验的补丁吧。