1、申 请 I D:changblade
2、个人邮箱:photoshopcc@qq.com
3、原创技术文章:OD跟踪快速找到某网游客户端登录程序用到的PFX证书导入私钥
需要用到的工具:OD、PEID、Ethereal
最近接触到一个客户端登录程序,发现是使用SSL连接服务端,想自己编写一个登录器,
1、用PEID查壳,结果如下
PEID查壳结果
查看目录下除了.dll文件外,还有.bpl文件,确定应该是Delphi开发的,不过有一个[Overlay]附加数据。
2、打开客户端运行,用Ethereal抓包结果显示,是连接服务器的443端口(SSL协议),
既然是SSL协议,就必须有证书,查看该程序文件夹中,有一个client.pfx文件,将其改名,再运行客户端登录程序,提示“连接不到后台服务器”。
将client.pfx改名回来,又能正常登录,这就让我更加肯定就是应用该证书文件登录服务器的。
3、问题来了,我想自己写一个登录客户端程序,就必须用到pfx文件中的密钥,可是导入该PFX文件中的私钥需要密码,
这样如何得到这密码呢?
4、分析该客户端的运行流程,应该就是直接读取这client.pfx,然后在程序中通过密码得到私钥,然后与服务器建立SSL连接。
5、撸起袖子,我们开始用OD载入跟踪一下看看能否得到PFX文件的私钥密码
OD载入后,程序停在入口点
[Asm] 纯文本查看 复制代码 00518C00 > 55 push ebp
00518C01 . 8BEC mov ebp,esp
00518C03 . 83C4 E0 add esp,-0x20
00518C06 . 53 push ebx
00518C07 . 56 push esi
00518C08 . 57 push edi
00518C09 . 33C0 xor eax,eax ; kernel32.BaseThreadInitThunk
00518C0B . 8945 E0 mov dword ptr ss:[ebp-0x20],eax ; kernel32.BaseThreadInitThunk
00518C0E . 8945 E4 mov dword ptr ss:[ebp-0x1C],eax ; kernel32.BaseThreadInitThunk
00518C11 . 8945 EC mov dword ptr ss:[ebp-0x14],eax ; kernel32.BaseThreadInitThunk
00518C14 . 8945 E8 mov dword ptr ss:[ebp-0x18],eax ; kernel32.BaseThreadInitThunk
00518C17 . B8 787A5100 mov eax,p.00517A78
00518C1C . E8 638AEEFF call p.00401684
00518C21 . 33C0 xor eax,eax ; kernel32.BaseThreadInitThunk
00518C23 . 55 push ebp
00518C24 . 68 2A8F5100 push p.00518F2A
00518C29 . 64:FF30 push dword ptr fs:[eax]
00518C2C . 64:8920 mov dword ptr fs:[eax],esp
00518C2F . BA 448F5100 mov edx,p.00518F44 ; ASCII "程序开始启动"
00518C34 . 33C0 xor eax,eax ; kernel32.BaseThreadInitThunk
00518C36 . E8 0916F7FF call <jmp.&baseimpcls.Hscomm::hsWriteLog>
6、按ALT+M,再CTRL+B,在内存中查找“client.pfx",发现有5处,经过测试,在下图处下内存访问断点最快到达关键代码处
7、按SHIFT+F9执行,断在下图处,
可以看到EDI指向”client.pfx"字符串,因为有10个字符,按Shift+F9 19次,然后按CTRL+F9到达下面的retn处
[Asm] 纯文本查看 复制代码 77180CA7 8B45 EC mov eax,dword ptr ss:[ebp-0x14]
77180CAA EB 09 jmp short KernelBa.77180CB5
77180CAC 6A 57 push 0x57
77180CAE E8 CE6BFDFF call KernelBa.77157881
77180CB3 33C0 xor eax,eax
77180CB5 8B4D FC mov ecx,dword ptr ss:[ebp-0x4]
77180CB8 5F pop edi ; rtl60.40006977
77180CB9 5E pop esi ; rtl60.40006977
77180CBA 33CD xor ecx,ebp
77180CBC 5B pop ebx ; rtl60.40006977
77180CBD E8 BAE5FEFF call KernelBa.7716F27C
77180CC2 C9 leave
77180CC3 C2 1800 retn 0x18 ;<==Ctrl+F9到达此处
然后按F8,单步跟踪执行,达到下面代码处,发现注释那边有"ssl_certfile“和"ssl_certpass",
[Asm] 纯文本查看 复制代码 005152B7 . 50 push eax
005152B8 . 8D85 20FEFFFF lea eax,dword ptr ss:[ebp-0x1E0]
005152BE . 50 push eax
005152BF . B9 A4585100 mov ecx,pbrc.005158A4 ; ASCII "ssl_certfile"
005152C4 . 8B55 F0 mov edx,dword ptr ss:[ebp-0x10]
005152C7 . 8B45 FC mov eax,dword ptr ss:[ebp-0x4]
005152CA . E8 3D090000 call pbrc.00515C0C
005152CF . 8D95 20FEFFFF lea edx,dword ptr ss:[ebp-0x1E0]
005152D5 . 8B45 FC mov eax,dword ptr ss:[ebp-0x4]
005152D8 . 05 4C010000 add eax,0x14C
005152DD . E8 4EC1EEFF call <jmp.&rtl60.System::VarToLStr>
005152E2 . 8D85 F0FDFFFF lea eax,dword ptr ss:[ebp-0x210]
005152E8 . BA BC585100 mov edx,pbrc.005158BC ; ASCII "hundsun@0915"
005152ED . E8 9EC1EEFF call <jmp.&rtl60.System::OleVarFromLStr>
005152F2 . 8D85 F0FDFFFF lea eax,dword ptr ss:[ebp-0x210]
005152F8 . 50 push eax
005152F9 . 8D85 00FEFFFF lea eax,dword ptr ss:[ebp-0x200]
005152FF . 50 push eax
00515300 . B9 D4585100 mov ecx,pbrc.005158D4 ; ASCII "ssl_certpass"
00515305 . 8B55 F0 mov edx,dword ptr ss:[ebp-0x10]
00515308 . 8B45 FC mov eax,dword ptr ss:[ebp-0x4]
0051530B . E8 FC080000 call pbrc.00515C0C
8、在00515300 处按F2下断,再按F4执行到该处,再继续按F8单步执行到下图处。
发现ds处是指向如下的ASCII字符串,应该就是密码的加密串32位,先复制保存下来,查MD5,发现解密需要时间。
ds:[045BE8EC]=045F1598, (ASCII "93772BD903FE6A6441473E70D9316C9D")
eax=045BE7A4
9、继续F8单步执行,来到下图处
发现字符串”xscli-666“字符串,并看到代码区的上一行代码是
00515356 . E8 9568F7FF call <jmp.&baseimpcls.Encryptpublic::hsDecryptEx>
基本上可以断定该字符串就是client.pfx的私钥密码。
10、到资源管理器中,双击导入client.pfx,密码处输入刚才获取的字符串”xscli-666“,导入成功!
总结:该客户端登录程序仅通过附加数据方式稍作加密,但是未将证书文件附加混淆到可执行文件中,相对来说还是比较容易找到证书密码。该程序的新版本中,已经将证书文件附加混淆到可执行文件中,笔者经过OD动态调试,将证书pfx文件从内存数据中dump出来,并获得证书密码,也可以自己写一个登录器。具体的下次再发。
虽然此篇解密难度并不大,也希望管理员能同意ID申请,谢谢。
|