好友
阅读权限20
听众
最后登录1970-1-1
|
本帖最后由 loudy 于 2017-10-17 08:35 编辑
最近新开了一个微信公众号:风云处(fyc1687),欢迎大家多多交流。其中我会逐步把我学习逆向的经验、实例、技巧分享出来。
一、整体流程IDA载入,简单分析发现,主要处理流程在sub_403B70处,如下图,函数不长,但是很复杂。
进阶版引进了RSA思想。上图sub_4033A0检查userName的合法性;sub_4034E0从userName生成4个64位整数,具体算法后面分析;sub_403860和sub_405FB0两个函数从输入的userName生成了RSA的N和E;sub_405CA0对输入的RegCode进行处理,得到16字节长数组(得不到则失败),即2个64位整数;接着sub_403160检测之前生成的6个64位整数是否满足其中公式。
二、关键函数剖析
(1)sub_4033A0如下图,IDA中已经标注,key长度为0x27,其中连接符“-”共7个,有效位0x20个,分成8段,每段4byte,每个有效byte均为0-9或a-f或A-F(转化为a-f)。
(2)sub_4034E0该函数经过调试化简,可以与以下函数等价,key为输入,param为a1、a2、a3、a6。
[C] 纯文本查看 复制代码 int get_formula_param(unsigned __int64 * param,char * key)
{
if(strlen(key)!=0x27)
{
return -1;
}
if(key[4]!='-' ||key[9]!='-' ||key[14]!='-' ||key[19]!='-' ||key[24]!='-' ||key[29]!='-' ||key[34]!='-')
{
return -2;
}
for(int i=0;i<0x27;i++)
{
if(i!=4 && i!=9 && i!=14 && i!=19 && i!=24 && i!=29 && i!=34)
{
if(!(key>='0'&&key<='9'||key>='a'&&key<='f'))
{
return -3;
}
}
}
unsigned int s0[4],s1[4],s2[4],s3[4],s4[4],s5[4],s6[4],s7[4];
for(int i=0;i<4;i++)
{
s0 = (unsigned int)key;
s1 = (unsigned int)key[5+i];
s2 = (unsigned int)key[10+i];
s3 = (unsigned int)key[15+i];
s7 = (unsigned int)key[20+i];
s6 = (unsigned int)key[25+i];
s5 = (unsigned int)key[30+i];
s4 = (unsigned int)key[35+i];
}
unsigned x0 = s0[0]*s4[0];
x0 = x0<<0x10;
param[0] = x0 + s0[1]^s4[1] + s0[2]%(s4[2]+1)+1 + s0[3]/(s4[3]+1);
x0 = s1[0]^s5[0];
x0 = x0<<0x10;
param[1] = x0 + s1[1]%(s5[1]+3)+s1[2]/(s5[2]+1)+5 +s1[3]+s5[3];
x0 = s2[0]/(s6[0]+3);
x0 = x0<<0x10;
param[2] = x0^(s2[1]*s6[1])+s2[2]%(s6[2]+7)+ 5 + s2[3]+s6[3];
x0 = s3[0]+s7[0];
x0 = x0<<0x10;
param[3] = x0*(s3[1]/(s7[1]+2)) + (s3[2]%(s7[2]+5))+7 + s3[3]*s7[3];
}
(3)sub_403860和sub_405FB0涉及到大数的运算以及随机值生成算法,过程比较复杂,应该用到了某大数库,但没找到对应的,解题过程中,直接调用了原程序,得到RSA的N和E(附件程序中使用了Miracl库)。
(4)sub_405CA0该函数比较复杂,首先是对RegCode进行base64解码,如下图:
此base64解码做了变形,首先常量从“ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/”变成了“OPWvYny#Nopz0$HI34QRSG@dJKq7fghD9Zi*kAB8rsFu56L&Ca^2tTUVEewxlm+/”,如下图。
其次,下图红线处在基本base64上加了异或操作。
因此将base64编解码做变形如下:
[C] 纯文本查看 复制代码 const char * base64char = "OPWvYny#Nopz0$HI34QRSG@dJKq7fghD9Zi*kAB8rsFu56L&Ca^2tTUVEewxlm+/";
char * base64_encode( const unsigned char * bindata, char * base64, int binlength )
{
int i, j;
unsigned char current;
unsigned char k;
for ( i = 0, j = 0 ; i < binlength ; i += 3 )
{
current = (bindata >> 2) ;
current &= (unsigned char)0x3F;
for(k=0;k<64;k++)
{
unsigned h = k>>4;
h = k^h;
if(h == current)
{
current = k;
break;
}
}
base64[j++] = base64char[(int)current];
current = ( (unsigned char)(bindata << 4 ) ) & ( (unsigned char)0x30 ) ;
if ( i + 1 >= binlength )
{
for(k=0;k<64;k++)
{
unsigned h = k>>4;
h = k^h;
if(h == current)
{
current = k;
break;
}
}
base64[j++] = base64char[(int)current];
base64[j++] = '=';
base64[j++] = '=';
break;
}
current |= ( (unsigned char)(bindata[i+1] >> 4) ) & ( (unsigned char) 0x0F );
for(k=0;k<64;k++)
{
unsigned h = k>>4;
h = k^h;
if(h == current)
{
current = k;
break;
}
}
base64[j++] = base64char[(int)current];
current = ( (unsigned char)(bindata[i+1] << 2) ) & ( (unsigned char)0x3C ) ;
if ( i + 2 >= binlength )
{
for(k=0;k<64;k++)
{
unsigned h = k>>4;
h = k^h;
if(h == current)
{
current = k;
break;
}
}
base64[j++] = base64char[(int)current];
base64[j++] = '=';
break;
}
current |= ( (unsigned char)(bindata[i+2] >> 6) ) & ( (unsigned char) 0x03 );
for(k=0;k<64;k++)
{
unsigned h = k>>4;
h = k^h;
if(h == current)
{
current = k;
break;
}
}
base64[j++] = base64char[(int)current];
current = ( (unsigned char)bindata[i+2] ) & ( (unsigned char)0x3F ) ;
for(k=0;k<64;k++)
{
unsigned h = k>>4;
h = k^h;
if(h == current)
{
current = k;
break;
}
}
base64[j++] = base64char[(int)current];
}
base64[j] = '\0';
return base64;
}
int base64_decode( const char * base64, unsigned char * bindata )
{
int i, j;
unsigned char k;
unsigned char temp[4];
for ( i = 0, j = 0; base64 != '\0' ; i += 4 )
{
memset( temp, 0xFF, sizeof(temp) );
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64 )
temp[0]= k ^ (k>>4);
}
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i+1] )
temp[1]= k ^ (k>>4);
}
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i+2] )
temp[2]= k ^ (k>>4);
}
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i+3] )
temp[3]= k ^ (k>>4);
}
bindata[j++] = ((unsigned char)(((unsigned char)(temp[0] << 2))&0xFC)) |
((unsigned char)((unsigned char)(temp[1]>>4)&0x03));
if ( base64[i+2] == '=' )
break;
bindata[j++] = ((unsigned char)(((unsigned char)(temp[1] << 4))&0xF0)) |
((unsigned char)((unsigned char)(temp[2]>>2)&0x0F));
if ( base64[i+3] == '=' )
break;
bindata[j++] = ((unsigned char)(((unsigned char)(temp[2] << 6))&0xF0)) |
((unsigned char)(temp[3]&0x3F));
}
return j;
}
此变形base64对RegCode解码后,每个byte都不能大于0x31,如下:
然后转化为16段,每段分别转化为一个大数(十进制),共16个大数,转化方式为:X(1byte,不相关) | 大小y(2byte) | 数据(y字节) |
其中每段第一个字节不参与运算,可以任意,故同一个userName可以有很多RegCode。然后利用之前生成的D和N对每个大数进行RSA加密(幂模运算),取运算结果16进制的低2位作为一字节。
共16字节,前8byte作为a4,后8byte为a5。
(5)sub_403160该函数看起来简单,但因为在32位下实现64位计算,分析起来也难。
经过分析可以发现,前一个if比较(a6 * a1 + a2) * a6 + a3和a4*a6 + a5,后一个if比较(a2-a4)*(a2-a4)和4*a1*(a3-a5),均相等则注册成功。由于a1、a2、a3、a6和key有关,相当于已知量,a4、a5和code有关相当于未知量,则由
三、注册机编写
(1)从UserName得到a1、a2、a3、a6(编码实现),和大数E、N(直接从原程序CrackMe.exe中提取)。
(2)从a1、a2、a3、a6计算a4、a5。
(3)从a4、a5得到RSA加密运算结果(本文认为解密结果就是2位16进制,当然可以在满足低位不变得情况下,任意扩展加密结果,得到不同的RegCode)。
(4)将大整数N分解为P和Q(修改ppsiqs.exe程序进行)。
(5)从P、Q得到私钥D。
(6)用D和N对第(3)步的结果解密,得到16个不同的大数。
(7)对大数按如下规则编排,得到base64解码结果。
X(1byte,不相关) | 大小y(2byte) | 数据(y字节) |
(8)进行base64编码,得到RegCode。
四、使用说明
(1)CrackMe.exe、ppsiqs2.exe、dbg.exe三个文件放在同一目录运行。
(2)CrackMe.exe(在偏移0x403c88手动加了断点,方便提取内存数据,且决定标准还是进阶的跳转改为只有进阶版)和ppsiqs2.exe(删除了循环,输入从控制台改为文件)均经过手动修改。
(3)dbg.exe是附件代码生成的的程序。
(4)使用时,运行dbg.exe,在跟随运行起来的CrackMe.exe的UserName处填上正确的userName,点击按钮“go”,在dbg.exe的控制台界面可以看到正确的RegCode(另外在当前目录下还会生成out.txt文件,内容即为RegCode)。
输入该RegCode,成功注册。
结束,代码见附件中main.cpp。该版本利用了调试器原理,没有完全编码。
后来把生成RSA参数的过程看了一下,得到另一版见附件2,其中有源码和可执行文件,分析过程免去,无太多价值。
附件(http://bbs.pediy.com/attach-download-128525.htm) |
-
-
附件2.zip
26.05 KB, 下载次数: 17, 下载积分: 吾爱币 -1 CB
免费评分
-
查看全部评分
本帖被以下淘专辑推荐:
- · 杂七杂八|主题: 1074, 订阅: 320
- · 优秀逆向文|主题: 238, 订阅: 93
- · 教程类|主题: 265, 订阅: 43
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|