Below you will find pages that utilize the taxonomy term “Authentication”
Battle.net v2 登录协议分析 3
刚才再次动态跟踪了Wow.exe。程序先在offset 0x008EE000处断下(我所标记的“第三层错误处理程序1”),然后调用到0x008EDA30(“第二层错误处理程序3”),随后调用到0x008E9540(“最内层错误处理程序”)。这样看来,分层应该是正确的了。
对于第三层错误处理程序无法继续上溯的问题,我已经发现了原因。进入第三层错误处理程序后,取消所有断点,执行到返回,就返回到了调用者(offset 0x007B2864) ^_^ 。果然,调用者是使用的是call eax的形式,而eax是由上面数句计算出来的。正因为没有明显标记,反汇编器才无法得到调用来源。
随后的测试表明,我所谓的“错误处理程序”在受到challenge后会被反复调用,多达百次。加上ASCII码分析,我认为,这些程序处理的是服务器消息,而不仅仅是错误。其中 offset 0x007B2864 所在子程序开始于 offset 0x007B2810。这一子程序会被反复执行,内存中大约40字节的数据会被反复改写,差不多有近百次。有一部分数据变化是有规律的,有一部分则没有。这看起来在计算一些数据。难道是Challenge的hash计算或解码?我会进行进一步分析。
Battle.net v2 登录协议分析 2
花了整整两天时间反汇编wow.exe,略有成果。当然,在将来的分析中,这些资料很可能会是无用的,甚至错误的。但是我现在仍然将它们记录下来,以备以后需要。
简单的密码学扫描证明,Battlenet.dll有SHA1,MD5和DES的算法签名。wow.exe多了CRC和Tea。我在Battlenet.dll中看到了类似于AVRSAPublicKey的字符串,因此推断它也使用了RSA算法。
一下所有分析均采用美服9947客户端+大陆服10146 Wow.exe。
offset 0x00460FF0 处调用了W32库的send()函数。实验证明,在每一次向Battle.net认证服务器发报时,都会调用这一处。在此下断,ECX指向的内存地址即为即将发出的报文,EDI中为报文长度。
offset 0x004605B2 处调用了recv()函数。每一次Battle.net认证服务器向客户端发报时,这一处均会被调用。在此下断,EAX指向的内存地址即为收到的报文。
这两处内存地址是永远固定的。故在登录时dump WoW.exe内存,会在固定位置发现报文。
我尝试在收到服务器端AuthServerProof后,在AuthServerProof所在内存处下内存访问断点,成功在0x00411318处断下。但这会导致wow.exe崩溃。在后续测试中,我尝试在收到AuthServerProof后在该处下常规的int 3断点,程序依然会被断下,且没有发现任何问题。但是从此往后的分析却陷于停顿。程序似乎调用了大量MMX指令,疑为反调试。但因为WoW.exe本身是一个多媒体应用程序,具体这些指令是不是反调试代码,在进行进一步分析前也不好定论。
后来我尝试按照connection.log中的日志记录分析字符串。很快便在offset 08E979B找到了显示LOGON_BAD_SERVER_PROOF字符串的函数,它位于一个多达216种情况的switch…case语句中(offset 0x008E9776)。这个语句所在子程序开头处受到四处调用。这四处调用该函数的函数均为错误处理函数。我认为,这四处函数负责对错误代码进行大致处理,分出错误所属大类,offset 0x008E9776 处的函数是下一级错误处理,负责显示具体的错误信息。这四处调用中,Offset 008E9565处可以直接断下,该处函数开始自offset 008E9540。这里依然受到四处调用。依次上溯,大致可以找到3级错误处理。在最上一级错误处理函数的开头,反汇编程序就找不到调用来源了。我会对此进行更进一步的分析。
当然,这些函数调来调去,完全把我搞晕了…我不保证真的存在3层错误处理。很可能是互相调用造成的假象。
我的思路是继续上溯,直至找到导致LOGON_BAD_SERVER_PROOF的来源。报文中,这是一个长512字节的,一个字节都不能改的数据。这很可能会是一个散列,但我确实没见过如此长的散列。如果是散列,那么应该可以找到cmp。此时就可以看到正确的ServerProof了。继续上溯甚至可以找到算法。若不是散列(基本不可能),那么应该可以找到解码代码,分析之便可得到正确的制造该处报文的方法。
Battle.net v2 登录协议分析 1
网易开放魔兽世界内测后,我迫不及待地试图按照以前九城的老方法用美服/台服客户端连接大陆服务器。未想,网易竟然在登录服务器上进行了特殊限制,阻止了非大陆客户端的登录。我承认那天晚上我等到12:30却始终看到客户端报版本错误的时候十分郁闷…
第二天,在mop,nga等地陆续看到有人发帖子请教如何用非大陆服务器客户端登录大陆服务器。为此,我进行了一些研究。碰巧在mop上碰到一个和我做了同样初步分析的人(raptium,他的Blog:http://www.raptium.net/),隧联系之,一起分析这种情况。
我们当然可以认定,网易在服务器上做的设置是“特殊的”,“全球唯一的”。因为美服欧服台服之间完全可以互相登录。抓包分析表明,当前版本的魔兽世界(3.1.3.*)会使用两种登录协议。一种是传统魔兽世界认证协议,一种是Battle.net认证协议。前一种已经被分析得差不多了,甚至Wireshark都认得,后者基本还没有相关文档。当客户端发现所输入用户名符合email格式时,会启用Battle.net登录协议。此时,在realmlist.wtf中设置的realmlistbn会起到认证服务器的作用。反之,会使用传统魔兽世界认证协议,使用realmlist.wtf中设置的reamlist字段的服务器作为认证服务器。
目前,美服,欧服的Battle.net并不是强制绑定的,台服还没有Battle.net,只有大陆服务器是强制绑定。
经过分析,我们认为客户端首先向服务器发送的第一个报文中,包含版本信息。经过对大量实验结果的diff,我们得到如下结论:
第一个报文被称之为AuthChallenge(有一篇很好的文章,作者在我们之前对Battle.net新版认证协议进行了分析。虽然没有我们透彻,但他却为我们解释了一个十分重要的数据,这个数据可能是通过反汇编得到的,也可能是经过大量diff后得到。它为我们节省了大量时间。原文请见:http://www.deviange.net/wow-clients/login-protocol/。 注:大陆地区无法访问。再注:该文中称第一个报文为AuthRequest),其中包含了将要登录用户的名称,游戏的四个版本,可能还包含游戏平台信息。
offset 0x00处必然为0x00,应该是一个cmd,表示这是AuthChallenge。
offset 0x19和0x20处为wow.exe的版本。对应于connection.log中的 Component WoW.Win. 。值:9974:6D 01,10146:D1 00
offset 0x24和0x25处,为Data目录的版本,对应于connection.log中的 Component WoW.base. 。值:9947:6D 01,10146:D1 00
offset 0x31和0x21处,为Locale目录(如Data/enUS,Data/zhCN)的版本,对应于connection.log中的 Component WoW.enUS. / Component WoW.zhCN. 等。值:9947:6D 55,10146:D1 54
offset 0x2C,0x2D和0x2E应该表示客户端语言信息,对应于connection.log中的 locale= 。这一处仍存在疑问。
因为大陆客户端的特殊性(AuthChallenge报文比其它客户端要长),我们暂时无法解释多出来的数据。以上内容均以美服客户端为参照,欧服台服应该是一样的(台服已验证)。
报文最后是用户名,用户名前两个字节是用户名的长度。这里使用了特殊的计算方法。如果长度不对,登录报文将被拒绝。计算方法上面所提到的文章中有详细说明。感谢那篇文章的作者 David Liu 。没有他,我们是不会研究到这一步的。
这个报文中很可能还包括游戏的名称,游戏运行平台等信息。条件所限,我们暂时没有解析出它们。
登录第二步,服务器端发送给客户端一个很大的报文,称之为AuthServerProof(David Liu 的文章中称为AuthChallenge)。其中前6个字节是固定的,为 42 10 61 75 74 68 。这可能是用户名验证通过的意思。offset 0x08,0x09处是服务器语言代码,如US,CN等。offset 0xF3,0xF4处是同样的信息。offset 0x0A到0x2C处为固定字符。所有服务器均相同。0x2D到0x6C处的64字节,可能是某种散列。对于相同的服务器,它是相同的,不同的服务器则不同。
随后,offset 0x6D到0xEC处的128字节,每次登录均不同。可能是服务器发来用作加密密码的RSA Public Key。offset 0xED到0x116处,是一段固定数据。从0x117开始,直到报文结束的512字节,对于相同服务器来说它是相同的,不同的服务器则不同。
raptium试着把客户端的realmlist.wtf中realmlistbn的值改为127.0.0.1,在本地架设服务器。客户端发送AuthChallenge时,一切正常。但是当我们的服务程序把暴雪Battle.net认证服务器的AuthServerProof发送给客户端后,客户端却“礼貌地”用FIN中断了连接,并提示“invaild server”。raptium认为这可能是服务器端发送的AuthServerProof中存在某种校验的缘故。raptium把自己的IP改成官方认证服务器的IP,并发送暴雪Battle.net认证服务器的AuthServerProof,没有出现任何问题。这便印证了他的猜想。我们又尝试用无效数据填充第一个未知的64字节数据,依然可以通过认证。这说明最后的512字节数据中很可能存有某种服务器身份校验数据。这512字节,替换任何一个字节都会导致认证失败。
我们正在进行进一步研究分析。反汇编是必需的。希望有熟悉反汇编的朋友帮助我们。