1、申 请 I D:willydong
2、个人邮箱:willydong@qq.com
3、原创技术文章:
全文纯手打,好累。。。。。。
0x 文章简介及其心路历程
阳光网驿-企业信息化交流平台-通达OA2017 10.12.180305版破解方法初探(含代码)V1.3 - Powered by Discuz!
http://bbs.sunwy.org/forum.php?mod=viewthread&tid=238816&extra=&page=1
该贴最后发表了对52的感谢。
第174楼还有备注内容。
0x01 第一部分,主要集中在php文件的破解
1、php文件解密。通达OA属于一款windows服务+php文件配合的OA系统,首先查看其php文件,发现为标准zend加密,所以,用SeayDzend或DeZend_Tool解密之。
2、找到注册文件,分析核心思想。走读代码,发现所有的验证都通过inc/td_core.php文件来完成,尤其是其中的核心注册信息函数:
[Java] 纯文本查看 复制代码 function get_reg_info($REG_CODE, &$REG_INFO)
{
if (256 <= strlen($REG_CODE)) {
$KEY_FILE = MYOA_ROOT_PATH . "inc/tech.dat";
}
else {
return _("注册文件无效");
}
$KEY = "";
$RESULT = tdrsa_get_public_key_from_file($KEY_FILE, "e7309293ede93aa43d23d93f6b6df350", $KEY);
if (($RESULT !== true) || !is_resource($KEY)) {
return $RESULT;
}
$REG_CODE = pack("H*", $REG_CODE);
$RESULT = tdrsa_public_decrypt($REG_CODE, $REG_INFO, $KEY);
if (($RESULT !== true) || ($REG_INFO == "")) {
return _("注册文件无效,请重新获取注册文件");
}
return true;
}
从代码不难发现,系统要从inc/tech.dat文件中读取内容,然后利用tdrsa_get_public_key_from_file函数将其还原为$KEY。
$KEY是什么呢?走读tdrsa_get_public_key_from_file发现,$KEY是一个RSA验证过程的“公钥”。
接下来的过程就比较好猜了,利用公钥,解析$REG_CODE这个加密文本,解密得到注册信息文本$REG_INFO。
接下来,可以从2个方面来进行破解。
3、破解方法一,直接改写get_reg_info函数,无论加密文本和公钥是什么都不管,直接返回需要的注册字符串。
在php中return true;之前增加echo语句,打印$REG_INFO的内容,发现其格式大致为:
北京NB总公司*TD20G-20180305-9999**0*0*999*123456789abcdefghijk*999*999*B44F9FFA72*999*999*999*999*999*999*999*999*999
其中的数字就代表了不同的权限限制,如果没注册,数值比较小,那么,我们直接将其赋值为需要的值返回即可。
[Asm] 纯文本查看 复制代码 function get_reg_info($REG_CODE, &$REG_INFO)
{
$REG_INFO="北京NB总公司*TD20G-20180305-9999**0*0*999*123456789abcdefghijk*999*999*B44F9FFA72*999*999*999*999*999*999*999*999*999";
return true;
}
4、破解方法二,考虑到破解php文件后难免会存在对某些代码的破坏,所以最安全的方法还是研究注册码,从公钥和$REG_CODE这个加密文本的角度入手。
跑了一圈发现系统注册思路为:
a)从注册文件tech.dat获取“公钥”加密串,用tdrsa_get_public_key_from_file函数将其解密为rsa算法可识别的公钥。
b) 从数据库version表“CODE”字段获取upnack后的权限字符串,用pack算法将其还原。
c) 在tdrsa_public_decrypt函数中,用openssl_public_decrypt算法,利用a步获得的公钥解密b步获得的权限字符串,得到形如"***0*0*999*123456789abcdefghijk*999*999*999*0*999*999*999*999*999*999*999"的明文权限串。
所以,如果不修改代码,就需要做一个注册机,来生成满足要求的权限字符串。
但是我们没有私钥(关于私钥和公钥,请自学RSA加解密算法),怎么办?
只好曲线救国,自制私钥和公钥,开始。
a)下一个openssl软件(请自学参数设置过程),得到一组公钥和私钥。
b)利用公钥和php自带的openssl_public_encrypt算法,将我们需要的明文权限串进行加密,相当于逆向上面的c步。
c)将加密后的字串利用unpack算法进一步处理,将其结果拷贝到数据库version表“CODE”字段,相当于逆向上面的b步。
d)分析tdrsa_get_public_key_from_file算法,用php写一个逆向算法,命名为tdrsa_set_public_key_to_file,将a步得到的私钥进行加密处理,将结果存储为tech.dat,相当于逆向上面的b步。
上述步骤涉及到许多参数和细节,估计够写几个版面的了,此处不再赘述,有兴趣的再详细交流。
OK,基本上不影响使用了,对于新安装的最新版通达OA(目前为20180305版本),使用方法如下:
1、防止注册码验证不通过:将tech.dat文件复制到inc文件夹下,里面包含了公钥信息。
2、防止注册文件信息与数据库中信息不一致:将version表中的SN字段改写为:TD20G-20180305-9999;将unit表中的UNIT_NAME字段改写为:北京NB总公司
3、取消itask验证:修改inc/reg_submit.php文件,注释掉itask返回的验证(第140/141行)
//message_reg("", _("注册失败"), $result[0], $BUTTON_BACK);
//exit();
4、将c步得到的加密字串存入文件tdkey10.dat,在软件注册页面导入注册文件tdkey10.dat,正常注册通过。
到这里,实现的效果为:
a.软件名称会显示为集团版,
b.软件注册会显示为已注册,
c.已注册可选组件会显示所有组件。
但其余的还是和未注册的显示一样,主要原因是“系统信息”页面中的信息除了上面abc3项外,其余的来自OfficeTask服务的端口返回值(之前还不会破解exe文件),但目前经测试发现已经不影响使用了。
5、为了更加美观,直接修改general/system/reg_view/index.php,只需要在$REG_ARRAY = explode("*", $REG_INFO);(第161行)前加一句:
$REG_INFO ="北京NB总公司*TD20G-20180305-9999**0*0*999*123456789abcdefghijk*999*999*B44F9FFA72*999*999*999*999*999*999*999*999*999";
这主要是替换掉OfficeTask服务的返回值为我们需要的值。
6、为了修改移动Office编辑点数限制的显示,在sys_para表中找到PARA_NAME为NTKO_ACTIVITION_CODE的字段,将其PARA_VALUE修改为:W3siQU5EUk9JRF9DT1VOVCI6OTk5OSwiSU9TX0NPVU5UIjo5OTk5LCJFWFBJUkVEX0RBVEUiOiIwMDAwLTAwLTAwIn1d
这一个加密串的由来?分析注册信息显示页面对应的index.php,发现移动Office编辑点数限制信息来自于NTKO_ACTIVITION_CODE字段,对其进行了base64_decode和json_decode解密,那么反过来,我们将需要的字符串”Android:9999,iOS:9999 (永久)“先后进行json_encode和base64_encode即可得到,这里也不赘述了。
OK,大功告成。
总结一下:
1、如果不需要体验注册过程,第3、4步可以不做,直接将tdkey10.dat中的注册信息复制到version表中的CODE字段即可。
2、对系统文件只修改了用于显示系统信息的1个php文件,如果不介意显示问题,甚至可以不修改。
但是,但是,不会破解exe文件的话,始终算不上完美?!!!!!
但苦于不会exe文件破解,卡住了。
0x02 第二部分,主要是在52pojie的帮助下破解exe服务程序(因为不熟悉,这部分之前走了很多弯路,最后简化如下,原来思路正确才是最关键的)
1、利用OD加载OfficeTask.exe,搜索,找到核心注册字符串,形如%s*%s*%d....的格式化字符串,有过VC编程经验的话,不难猜测系统会通过该串利用strformat函数来生成注册字符串,有2个办法进行处理,一是修改每一个参数的值为需要的值,但是总共19个参数,比较麻烦,之前长时间卡在这里了。第二个办法,不管参数是什么,直接改写”格式化字符串“,令其不匹配参数,直接写成需要的权限字符串。
2、新增区段(这一步要感谢52pojie入门教程第三课中关于“弹窗”方法给我的启发),直接利用ascII码写入字符串,其目的是无论什么情况下,都返回最大注册权限的字符串,形如"北京NB总公司*TD20G-20180305-9999**0*0*999*123456789abcdefghijk*999*999*B44F9FFA72*999*999*999*999*999*999*999*999*999"
3、将push格式化字符串的位置,修改为push第2步新增的区段地址。
4、生成新的文件,利用小程序检测注册信息反馈情况,完美,具体如下图。
5、检查软件注册情况,完美:
6、发帖,吃水不忘挖井人,感谢52。
0x02 自荐
本人长期从事软件编程工作,对asp/php/vc/java等语言有较多的感悟,通过此次破解,对破解和逆向工作兴趣倍增,希望能在52向大师们深入学习,与大家共同进步。
|