翻译第三篇 On Software Reverse Engineering - 3
Reverse Engineering, FLEXlm, IMSL
揭示加密钥和加密种子
从实际的观点出发我们现在可以止步不前了,因为有了许可的拷贝我们可以自由的使用目标程序了。但是,软件破解的最终目的是反向(逆向)工程的所有相关算法并重新创建它们,那就好像我们是原始作者一样。在我们的实例中,最低限度的要求是揭示VNI的5个vendor密钥和3个随机种子。不用说,这要求我们更仔细的阅读FLEXLM SDK源代码,因此我们简单的回顾一下它是怎样组织的。下面的列表显示了包含最关键文件的文件夹。
src lmgr.lib或lmgr9a.dll的源文件
app lmgras.lib的源文件
server lmgrs.lib的源文件
master lmgrd.exe的源文件
utils 实用工具的源文件
machind 机器独立文件(源 & 头)
i86_n3 对于x86 平台的最终的二进制文件
h 头文件
certicom 来自Certicom公司的库和头文件
ulite FLEXLM的ultralite版本
此外,文件和函数根据其角色被指定了不同的前缀。例如,目录app, server和master以ls_开始,而在utils中是以lm为前缀。
l_ 许可证, 用于内部函数
lc_ 许可证客户端, 用于客户端API
ls_ 许可证服务器, 用于服务器API
lm_ 许可证管理器, 用于实用工具和一般的程序(原为材料)
现在,我们回到文献[2]和[3]中关于Vendor怎样实用FLEXLM SDK的指导中。基本地,Vendor需要将许多FLEXLM二进制与其自己的产品结合并创建若干实用工具-一些作为内部使用,一些用于最终用户发布。在这些Vendor-所产生的文件之间有很亲密的联系,下面是其关系表:
文件 由...产生 #include
lmrand1.exe lmrand1.c + lmgr.lib
lmcode.c, lsrvend.c lmrand1.exe + lsvendor.c lm_code.h
lmappfil.c, lmkeyfil.c lmrand1.exe
lmnewgen.exe lmnewgen.c + lmcode.c + lmgr.lib lm_code.h
lm_new.c lmnewgen.exe seeds & pubkey
lmseeds.h lmnewgen.exe
lmprikey.h, lmpubkey.h lmnewgen.exe
lmcrypt.exe lmcrypt.c + lmgr.lib lm_code.h,
lmseeds.h,
lmprikey.h
makekey.exe makekey.c + lmgr.lib lm_code.h,
lmseeds.h,
lmprikey.h
vendor application vendor code + lm_new.obj + lmgr.lib + seeds & pubkey
libsb.lib + libcrvs.lib
vendor daemon lsvendor.obj + lm_new.obj + lmgr.lib + lm_code.h,
lsserver.h,
lmgras.lib + lmgrs.lib + libsb.lib + seeds & pubkey
libcrvs.lib
注意,并非上述的所有文件都对我们是重要的。lmappfil.c和lmkeyfil.c是Vendor确定的滤波器,它们是附加的安全测试但通常未用。类似的,lmprikey.h 和lmpubkey.h仅用于CRO密钥,在我们的例子中可以忽略。通过编辑lsrvend.c 或lsvendor.c,Vendor可定制后台程序,但很少有人那样做。
有一件值得讨论的事情是Certicom产品,也即libsb.lib和libcrvs.lib 。它们几乎涵盖了从SHA到DSA的整个加密领域,而且FLEXLM采用的API几乎为ECC(椭圆曲线加密技术)和RGN(随机数字产生)。ECC用于在CRO中的公开/专用密钥对,但在我们的目标程序中关闭了;而RGN用于Vendor种子的转换,我们不可忽略。
正如先前声明的,Vendor选择了3个随机种子(LM_SEED1, LM_SEED2, LM_SEED3),但并不直接使用它们。实际上,基于前3个,lmnewgen.c!main()®l_prikey.c!l_genrand()®libsb.lib!sb_rngFIPS186Session()产生了4个新种子[8](ENCRYPTION_SEED1, … ENCRYPTION_SEED4)输出到lmseeds.h。种子3和4专门用于公开/专用密钥对,因此我们仅需要考虑种子1和2。
尽管FLEXLM在l_rand.h和lm_rand3.c中有其自己的RGN,但它在此仍然使用了在DSS标准中确定的算法(c.f. [8])。该算法是决定性的(没有读取时间、寄存器值等),因此对给定的LM_SEED,那么ENCRYTION_SEED(的值)将是固定的。它也是一个单向的函数,这意味着在实践中不可能从已知的ENCRYPTION_SEED来解决LM_SEED。因为是ENCRYPTION_SEED被编程到Vendor发布版本中,而LM_SEED除了在l_genrand()中出现外别处都不出现,因此我们最好恢复前者。但是,恰巧出于相同的原因,我们假定恢复LM_SEED是同样的好。
在FLEXLM的内部基本上是C/S模型,结合Vendor应用程序的是客户端,Vendor后台程序(这里是vni.exe )是服务器。注意,Vendor后台程序不同于FLEXLM许可证管理器lmgrd.exe,后者仅重定向客户端请求到相应的做实际工作的Vendor后台程序。令一个因素是许可证文件格式。FLEXLM提供了丰富的许可选项,在计数与不计数上是很重要的。不计数的许可证对于(用户)数量的检查没有限制并且不需要Vendor后台程序-其有效性仅在Vendor软件同时作为客户端和服务器时发生。计数的许可证通常用于网络(浮点许可证必须被计数),在大公司通常可以看到这样的情景:中心节点运行服务器,所有工作站连接到它上面进行许可证的输入输出检查。因此,我们可以推断Vendor后台程序的主要任务是计数、管理和调节受限许可证的使用。
看我们的许可证,它是 “permanent uncounted HOSTID=ANY”, 它表明没有任何条件限制。这一定是每个破解者的梦想(无后台程序处理也使追踪更容易)。实际上在许可证文件中,“SERVER"和"DAEMON"行是不必要的,两个“FEATURE"足以保证cmath.exe能无限制的运行。后面我们将有主题讨论许可证类型。
现在,我们已有了具有Vendor密钥和加密种子的cmath.exe作为客户段和服务器。有个好消息是CRO不起作用,因此仅要一套密钥。如果我们挖掘出它们,我们将可以用lmcrypt.exe或makekey.exe制作任何许可证文件,与Visual Numerics的方式一样。在我们着手进行时,我们总结了在密钥文件中的一些密钥。
lm_code.h: /* \machind\lm_code.h and \h\lm_code.h must be identical */
VENDOR_KEY1, VENDOR_KEY2, VENDOR_KEY3, VENDOR_KEY4, VENDOR_KEY5
LM_SEED1, LM_SEED2, LM_SEED3
lmcode.c:
#include "lm_code.h"
#include "lmclient.h"
VENDORCODE vendorkeys[] = { /* 错误的名字,需使用vendorcodes[]代替*/
{ VENDORCODE_7,
ENCRYPTION_SEED1 ^ VENDOR_KEY5, ENCRYPTION_SEED2 ^ VENDOR_KEY5,
VENDOR_KEY1, VENDOR_KEY2, VENDOR_KEY3, VENDOR_KEY4,
FLEXLM_VERSION, FLEXLM_REVISION, FLEXLM_PATCH,
LM_BEHAVIOR_CURRENT, {CRO_KEY1, CRO_KEY2},
LM_STRENGTH, LM_SIGN_LEVEL, 0
},
};
lmseeds.h:
ENCRYPTION_SEED1, ENCRYPTION_SEED2, ENCRYPTION_SEED3, ENCRYPTION_SEED4
lm_new.c:
x = 0x3d73db2e; /* 在lmnewgen.c中产生的随机数key5_uniqx */
VENDORCODE.data /* 由key5()模糊 */
VENDORCODE.keys /* 由l_xorname()模糊 */
l_getattr.c:
#define VENDORMAGIC_V7 0x08BC0EF8 /* 不重要, 仅用于xor(与或)取消*/
lmclient.h:
#define L_NEW_JOB l_n36_buf
l_privat.h:
#define L_UNIQ_KEY5_FUNC l_n36_buff
#define L_SET_KEY5_FUNC l_x77_buf
#define SEEDS_XOR mem_ptr2_bytes /* 这里seeds 隐藏在job */
#define SEEDS_XOR_NUM 12
此外,这里有三个数字被嵌入到二进制中(比如VENDORMAGIC_V7),但好像从来没有使用(至少在cmath.exe)中。也许它们仅用于某个版本或某个许可证类型,当我们访问这些函数时,我们将会看到它们。
Besides, there are three numbers that are hard-coded into the binaries (just like VENDORMAGIC_V7) but seems never used (at least in the case of cmath.exe). Maybe they are solely for certain versions or license types, we’ll see that when we visit those functions.
lm_ckout.c!l_sg():
x = 0x6f7330b8; /* v8.x */
lmnewgen.c!VKEY5():
x = 0x6f7330b8; /* v8.x */
l_key.c!l_zinit():
z = crokey_flag ? 0x62586954 : 0x72346B53; /* v9.x */
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)