Articles

飞天信使企业版数据库分析

飞天信使企业版v4.0是一个多功能的电话、短信、名片管理系统。可以利用GSM MODEM在线接收发送短信, 还具有手机归属地查询功能,自带手机归属地信息59117条。 本文讲述的就是如何获取飞天信使企业版v4.0手机归属地数据库中的内容。

安装这个软件后,很明显目录里有一个7,106,560 bytes 的数据库文件dblsms.mdb。 是Microsoft Access DB格式,估计八成这些信息就在里面了。打开Microsoft Access 2003,调入这个文件, 不幸的是让我输入密码。

密码会是什么呢?试了几个比较弱的密码都不成功之后还是决定用现成的软件破解。 上网下了个Advanced Access Password Recovery v2.5,最经典的破Access密码的软件了,果然一下子就破出来了。 密码的确不复杂”xuntian”,真不知道为什么Office系列密码都这么脆弱。再次打开dblsms.mdb,输入密码,OK! 果然进去了,里面有很多表,挨个点点看吧。

发现城市邮编存放在CITY里,手机卡的类型存放在CARDTYPE里,所有手机号都存放在NumIndex里, 然后用一个共同的Index 把手机号与城市关联起来。可是问题又来了,所有的手机号码都是用21位数字表示的, 分析来分析去我也没看明白这 21 位数字与手机号的关系。哎,还是运行一下人家的软件瞧瞧吧。 于是打开飞天信使,点击号码查询,在查询旁边写着”至少输入前七位”,也就是说只判断手机的前七位号码了。 可数据库里表示的手机号却是21位,显然是经过某种运算的结果。这下可要使出咱们Cracker 的看家本领了,嘿嘿。 习惯性的用PEiD看了看加了什么壳,嘿嘿!又让我高兴了一次,什么壳都没有啊,是用Delphi写的。 下面开始该进入跟踪的正题了,打开 OllyDbg,调入文件,断点设什么好呢…

点击Searchfor Name in Current Modules,里面既没有MessageBox也没有StrCmp 之类的东西, 看来Delphi 编译出来的东西有点类似微软的 MFC,函数的调用都是 call 飞天信使.00484ACC 这样的, 比较麻烦,还是想其它的办法吧。于是我输入了一个错误的手机号,哈哈,有了。 ”对不起,没有找到这个卡号的归属地”,就拦截这个字符串的引用吧。 用Ultra Edit打开飞天信使企业版.exe,找到这个字符串的位置是163234H,转换成VA是563E34H, Break Point, Memory on Access。Go!程序停在:

77F7B484 |. 0FB602 MOVZX EAX,BYTE PTR DS:[EDX]

是ntdll模块中,一路Ctrl + F9,回到飞天信使企业版.exe中,经过一段时间的分析,终于发现了重要的函数调用:

00563BAC |. E8 07F8FFFF CALL 飞天信使.005633B8

这个调用就是将 7位手机号变为21位数字的地方,进去仔细瞧瞧:

00563424 |. BB DA000000 MOV EBX,0DA
00563429 |. BE 06020000 MOV ESI,206

;EDI = 396,参数1
0056342E |. BF 96030000 MOV EDI,396
00563433 |. 57 PUSH EDI
00563434 |. 8D45 E4 LEA EAX,DWORD PTR SS:[EBP-1C]
00563437 |. 50 PUSH EAX

;ECX = 206,参数2
00563438 |. 8BCE MOV ECX,ESI

;EDX = 0DA,参数3
0056343A |. 8BD3 MOV EDX,EBX

;EAX -> 输入的手机号
0056343C |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
0056343F |. E8 FCFBFFFF CALL 飞天信使.00563040

这个函数调用对手机号进行了变换,继续进取跟踪:

;求输入的手机号长度
00563071 |. E8 9618EAFF CALL 飞天信使.0040490C
00563076 |. 84C0 TEST AL,AL
00563078 |. 76 43 JBE SHORT 飞天信使.005630BD

;[EBP-9]保存输入的手机号长度
0056307A |. 8845 F7 MOV BYTE PTR SS:[EBP-9],AL

;初始化计数器,不妨计作:i = 1
0056307D |. B3 01 MOV BL,1
0056307F |> 8D45 F0 /LEA EAX,DWORD PTR SS:[EBP-10]
00563082 |. 33D2 |XOR EDX,EDX
00563084 |. 8AD3 |MOV DL,BL

;ECX -> 输入的手机号
00563086 |. 8B4D FC |MOV ECX,DWORD PTR SS:[EBP-4]

;str[i-1]
00563089 |. 8A5411 FF |MOV DL,BYTE PTR DS:[ECX+EDX-1]

;ESI = 0DA,上面提到的参数3用上了
0056308D |. 8BCE |MOV ECX,ESI
0056308F |. C1E9 08 |SHR ECX,8

;str[i-1] ^= (esi >> 8)
00563092 |. 32D1 |XOR DL,CL

;将计算出的字符考被
00563094 |. E8 9B17EAFF |CALL 飞天信使.00404834
00563099 |. 8B55 F0 |MOV EDX,DWORD PTR SS:[EBP-10]
0056309C |. 8BC7 |MOV EAX,EDI
0056309E |. E8 7118EAFF |CALL 飞天信使.00404914
005630A3 |. 33C0 |XOR EAX,EAX
005630A5 |. 8AC3 |MOV AL,BL
005630A7 |. 8B17 |MOV EDX,DWORD PTR DS:[EDI]
005630A9 |. 0FB64402 FF |MOVZX EAX,BYTE PTR DS:[EDX+EAX-1]

;ESI += str[i-1];
005630AE |. 03F0 |ADD ESI,EAX

;ESI *= 206,参数2也用上了
005630B0 |. 0FAF75 F8 |IMUL ESI,DWORD PTR SS:[EBP-8]

;ESI += 396,参数3!
005630B4 |. 0375 0C |ADD ESI,DWORD PTR SS:[EBP+C]

;i++
005630B7 |. 43 |INC EBX

;手机号长度 - 1
005630B8 |. FE4D F7 |DEC BYTE PTR SS:[EBP-9]
005630BB |.^75 C2 \JNZ SHORT 飞天信使.0056307F

以上的计算公式的 C语言描述就是:

UINT sum;
UCHAR in[7] = 输入的手机号;
UCHAR out[7];
sum = 0xDA;
for(int i = 0; i < 7; i++)
{
    out[i] = in[i] ^ ((sum >> 8) & 0xff);
    sum = (sum + str[i]) * 0x206 + 0x396;
}

这样,经过上面计算,就把输入的 7位手机号转换为另外的 7位字符串。 还需要继续跟踪,看看怎么把这转换出来的 7位变为21位。回到上面这个转换之前的函数,下面是:

;EAX -> 转换之后的字符
00563444 |. 8B45 E4 MOV EAX,DWORD PTR SS:[EBP-1C]
00563447 |. 8B55 F8 MOV EDX,DWORD PTR SS:[EBP-8]

;这个函数对刚刚转换出来的 7字节进行运算
0056344A |. E8 FDFDFFFF CALL 飞天信使.0056324C
进入函数内部看看:

;EAX = out[i],就是刚转换出来的字符
005632B2 |. 0FB64402 FF |MOVZX EAX,BYTE PTR DS:[EDX+EAX-1]

;一个指针
005632B7 |. 8D4D F4 |LEA ECX,DWORD PTR SS:[EBP-C]

;长度3
005632BA |. BA 03000000 |MOV EDX,3

;很明显是将out[i]转换为 3个字节
005632BF |. E8 C0FEFFFF |CALL 飞天信使.00563184

去EDX指向的地址看看算出来的数字,哈哈,竟然是将out[i] 转换为10进制,这段转换代码用 C语言表示如下:

UCHAR num21[22] = {0}; //存放算出来的21位数字
for(int i = 0; i < 7; i++)
{
  UCHAR buf[4] = {0};
  sprintf((char *)buf, "%03d", out[i]);
  strcat(num21, buf);
}

因为上面只用到了异或变换,所以再异或一次就可以将数据还原了。

encode(1364401) = 049044253017003094010
decode(049044248042195035000) = 1331212

哈哈,近六万条的手机数据终于搞到手了,加上昨天弄到的十五万条 IP 地址的数据, 哎!幸福啊,可以好好的睡一觉了,睡醒了好好学习!嘿嘿。