注:本博文仅供学习参考,请不要用户其他非法用途。
版本:安腾校园网客户端3.3.0
操作系统:windowsXP
背景:
相信很大一部分的高校校园网客户端用的都是安腾校园网客户端,同学无意中发现了一个漏洞,那就是免费上网!真是爽啊。具体是这样的,由于学校对校园网的服务器端进行了升级,说简单点就是网关更改了,如果把电脑网关地址改为新地址,IP随便改(保证在同一网段内),学号随便输入,密码用原始密码,如果这个IP没有被绑定,那恭喜你,可以免费上网了。
大家都知道客户端是通过IP,MAC,学号,密码来验证的,其中一个IP只能被一个MAC绑定,如果这个IP之前被使用过,肯定有一个MAC与之绑定,再按上述步骤肯定通不过。但是由于学校换了服务器,新的服务器上的数据和原先的并不同步,这就造成,没有被使用的IP与之绑定的MAC是空的,与之绑定的学号也是空的,密码当然是默认的。这样也就出现了上述的漏洞。
IP MAC 用户名 密码 余额
1 a.b.c.d1 ee-ff-gg-hh1 xxxxxx2 yyyy4 20
2 a.b.c.d2 ee-ff-gg-hh2 xxxxxx1 yyyy5 0
3 a.b.c.d3 ee-ff-gg-hh3 xxxxxx3 yyyy1 30
4 a.b.c.d4 yyyy 40
5 …
数据库的表结构应该可以简化如上,注意第四条,如果这个时候有用户来用a.b.c.d4 IP来验证的话是不是会通过呢?肯定会的,至于余额为什么不是默认的0值,我一直都没有想明白。
破解第一步:
破解的第一步当然是找出客户端将验证信息发往了哪个服务器以及使用的端口,这可以通过抓包来实现,当然也可以通过调试程序来实现,但这里并不那样做。下载一个网络抓包工具,sniffer或者EtherDetect Packet Sniffer,我用的是后者,只是抓个包而已后者就足够用了。详细步骤如下:
1、关闭一切可能访问网络的软件,这是为了减少干扰,因为如果有多个程序访问网络,就不容易看出哪个数据包是客户端发出的。
2、打开EtherDetect Packet Sniffer开始抓包,启动客户端,点击按钮进行验证。
3、由于我用的是正确的账号和密码,可以看到有两条信息,一个是验证信息,由客户端发出,一个是验证结果信息,是服务器发回。
4、可以看到这次通信的端口是A,服务器的IP地址是B,居然还是UDP通信,这个破解带来不少好处啊。
5、好了再看一下数据包,都是乱码。不过很正常,这些通信数据一般都会加密的
到此为止破解第一步就算完成了,就这么简单,对,就这么简单。最重要的部分是下面的内容
破解第二部:
找出客户端究竟向服务器发送了什么,当然 IP地址,MAC地址,用户名,密码肯定会以某种格式发给服务器的,具体是什么格式,用什么算法加密的,是这一步骤需要解决的问题。
好久没有用OD了,不过这可是我的得力助手,搞破解的想必都是非常熟悉的。
1、OD加载。加载后OD提示软件被加壳了,稍微一分析其实是加了一个压缩壳,非常容易脱壳的那种,三下五除二搞定。
2、观察入口点是C++写的,这也正常。这就可以断定通信用的是socketAPI,查看引用的Dll也可以看得出,这就好办多了。
先复习一下SOCKET API通信的过程:用WSAStartup初始化,然后创建socket,sendto,recvfrom ,closesocket,WSACleanup。
其实在创建socket的时候也可以看出通信的端口,服务器的地址,以及通信类型(UDP),但是这样比较麻烦。
3、关键点是sendto这个函数,通过它可以知道发送的数据是什么了,那就把它给bp了吧。哈勒,F9运行。
00C5F75C 00417227 /CALL 到 sendto
00C5F760 000001AC |Socket = 1AC
00C5F764 00C5F790 |Data = 00C5F790
00C5F768 0000000D |DataSize = D (13.)
00C5F76C 00000000 |Flags = 0
00C5F770 00C5F780 |pTo = 00C5F780
00C5F774 00000010 /ToLength = 10 (16.)
这次的数据指针是00C5F790那就转过去看看吧,
00C5F790 69 6E 66 6F 20 73 6F 63 6B 20 69 6E 69 info sock ini
居然是这样一个简单的字符串,估计是先发送一个简单的数据给服务器告诉服务器我要发送验证信息了,让服务器做好准备,毕竟是UDP通信,如果立即发送数据,则可能发送不成功,引起超时。当然这只是猜测,也有可能是进城之间的通信,因为这次的数据并没有被抓包工具抓到,说明数据并没有发送到网络,而且发送的也是明文(这是破解成功之后想到的)
再次F9
00C5F104 00418F54 /CALL 到 sendto
00C5F108 0000013C |Socket = 13C
00C5F10C 00C5F214 |Data = 00C5F214
00C5F110 0000004B |DataSize = 4B (75.)
00C5F114 00000000 |Flags = 0
00C5F118 00C5F120 |pTo = 00C5F120
00C5F11C 00000010 /ToLength = 10 (16.)
转到00C5F214,发现是一堆乱码
00C5F214 80 A5 DE A5 0E 22 C6 45 FE 1D 5E 83 0F EC 93 37 €マ?"艵?^?鞊7
00C5F224 5B 09 91 20 00 A1 B9 08 1C C2 80 21 48 E8 48 C8 [.?.」聙!H鐷
00C5F234 C8 48 C9 58 01 11 68 68 68 68 A0 B0 D8 E8 39 59 菻蒟hhhh牥罔9Y
00C5F244 68 39 C8 39 49 48 49 21 21 AC 3D 5C 9C 4D 3D 9C h9?IHI!!?/淢=
00C5F254 5C 31 81 00 F1 91 C9 39 C9 39 48 /1?駪??H....
不过让人欣慰的是和抓包得到的数据是一样的,我们离成功不远了!偶也!
数据指针是00C5F21,那么哪个函数对其进行了加密呢?也就是说那个函数更改了它指向的内存呢?
好吧,那就让我们下内存写入断点吧。其实这并不是个明智之举,因为通过这个断点很难找到关键点。
那就ALT+F9吧,
00418F10 /$ 83EC 10 SUB ESP,10
00418F13 |. 8B4424 20 MOV EAX,DWORD PTR SS:[ESP+20]
00418F17 |. 66:C74424 00 >MOV WORD PTR SS:[ESP],2
00418F1E |. 50 PUSH EAX ; /pAddr
00418F1F |. E8 DA2D0000 CALL <JMP.&WS2_32.#11> ; /inet_addr
00418F24 |. 8B4C24 24 MOV ECX,DWORD PTR SS:[ESP+24]
00418F28 |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX
00418F2C |. 51 PUSH ECX ; /NetShort
00418F2D |. E8 1A2E0000 CALL <JMP.&WS2_32.#9> ; /ntohs
00418F32 |. 8B4C24 18 MOV ECX,DWORD PTR SS:[ESP+18]
00418F36 |. 8D5424 00 LEA EDX,DWORD PTR SS:[ESP]
00418F3A |. 66:894424 02 MOV WORD PTR SS:[ESP+2],AX
00418F3F |. 8B4424 1C MOV EAX,DWORD PTR SS:[ESP+1C]
00418F43 |. 6A 10 PUSH 10 ; /ToLength = 10 (16.)
00418F45 |. 52 PUSH EDX ; |pTo
00418F46 |. 8B5424 1C MOV EDX,DWORD PTR SS:[ESP+1C] ; |
00418F4A |. 6A 00 PUSH 0 ; |Flags = 0
00418F4C |. 50 PUSH EAX ; |DataSize
00418F4D |. 51 PUSH ECX ; |Data
00418F4E |. 52 PUSH EDX ; |Socket
00418F4F |. E8 D42D0000 CALL <JMP.&WS2_32.#20> ; /sendto
00418F54 |. 83C4 10 ADD ESP,10
00418F57 /. C3 RETN
来到了这个函数,可以看出数据由这个函数发出,那么再调用这个函数之前肯定对 ECX指向的数据进行了加密。退出这个函数之后
00416828 |. 8B5424 48 MOV EDX,DWORD PTR SS:[ESP+48]
0041682C |. 8B0D C43C5200 MOV ECX,DWORD PTR DS:[523CC4]
00416832 |. 68 080F0000 PUSH 0F08
00416837 |. 68 7C924500 PUSH upplican.0045927C ; ASCII "192.168.4.2"
0041683C |. 8D8424 D40000>LEA EAX,DWORD PTR SS:[ESP+D4]
00416843 |. 52 PUSH EDX
00416844 |. 50 PUSH EAX
00416845 |. 51 PUSH ECX
00416846 |. E8 C5260000 CALL upplican.00418F10
0041684B |. 83C4 50 ADD ESP,50
上面代码处于一大段函数体之内,这个函数很长,而且幸运的是,OD把其中一些指针表示的数据注释了出来,什么?我看到了自己的学号输入的密码IP地址甚至服务器IP地址!这样就好办多了,那就对这个函数进行重点跟踪吧。
不知不觉到了中午,好了先去吃饭,剩下的回来再说。