• 标 题:翻译FLEXlm9.2的破解教学三
  • 作 者:newsearch
  • 时 间:2004-12-06,18:59
  • 链 接:http://bbs.pediy.com

翻译第三篇 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 */