您现在的位置: Tracy‘Blog > 博客 > 一些破文 > 正文
拨号客户端弹窗原理追踪

在实践中学习~

       跟踪校园网拨号客户端的数据传输这事也是去年写下《破解pppoe拨号客户端,实现mac、linux、安卓等各平台拨号上网》后就想去做的事了,也因各种原因一直拖着。这两天好好的把系统环境全部搭建了一遍,便开始跟踪检测了起来。

       事情是这样的,大家都很想知道这个PPPOE客户端到底对我们的电脑做了些什么,是不是仅仅我上次所说的一个数据加密功能?还有没有控制或者监控的功能?……

       其实,其他的我暂时没去关注,到是对每次通过客户端拨号时弹出的一个显示自己还有多少时长可供使用这事挺感兴趣的,因为校园网也有时会用它向用户发送一些公告。这激发了我想知道它原理的动力。因为,要是我知道了这一原理,然后我在按它的格式向网络广播一个特定的数据包,是不是就可以让所有上网的同志都弹出一个窗口显示我想显示的东西呢?所以,我决定,看看它到底做了些什么。

       首先想到的就是抓包了,看它有哪些数据流通。这里我先用的是ethereal,还算是比较专业的一款工具了。虽然比不上sinffer pro,但还是可以满足我们的需要了。下面是我在用客户端拨号抓到的一些数据。我们来看看:

拨号客户端弹窗原理追踪

从这里我们可以分析一下。我们可以看出1-27步都是pppoe拨号所产生的纪录。等下我们再来分析这些吧。先不管这些,因为pppoe协议中就包含有这些步骤,所以28就是DHCP动态主机设置协议了。不出意外的话下面两个UDP数据包就是我们要找的东西了。为了确定,我再用wpe pro试下,发现直接忽略了前面的步骤直接显示有两个包,内容如下:

Ethereal中发出的数据包:

拨号客户端弹窗原理追踪

Ethereal中接收的数据包:

拨号客户端弹窗原理追踪

我们先把这些数据保存起来,发现与wpe pro所截获的数据十分相似,我们暂且相信在客户端报上号后,它只向服务器发送了一个数据包,然后得到了服务器的一个回复数据包。那么,如果它们之间进行了通信,它们都交流了些什么呢?就像前面说的它弹出了一个显示我们还有多长时间可以使用。所以,我们猜测,客户端说:“请问我这个账号还有多少天可用啊?”,然后服务器查了一下账本说“哦,你还可以用……。”当然,这也只是个人YY而已。还缺少实践去证明。

那么,怎么证明这些数据就是我们要找的数据呢?那就是伪装服务器向自己发送数据,或者向寝室里的其他电脑发送我截获的数据包。从上面可以清楚的看到源地址和目的地址、源端口和目的端口。

发送:

源地址:10.0.176.143   目的地址:172.31.15.2   发送端口:4999   接收端端口:3855

接收:

源地址:1.1.1.9   目的地址: 10.0.176.143   发送端口:3855   接收端端口:4999

这也就解释了,为什么我们在用netstat命令时,发现拨号客户端一直在监听UDP49993852了。可后来仔细看了看,又觉得不对,因为我都不了解这数据包里某一位的作用分别是什么,又怎么去构造呢?再者,我也不会些这么一个程序,尽管看了蛮多源程序。

于是,我想通过另一种方法再试试。想到的还是用OD,因为我们可以确定它进行了数据的传输,所以用C32_ASM打开客户端,在输入函数中找到了ws2_32.dll中的sendtorecvfrom,于是我们对其下断。补充一下ws2_32.dll相关知识:

 

ws2_32.dll是Windows Sockets应用程序接口, 用于支持Internet和网络应用程序。(Ps:如果不想让别人使用某个软件只要在其安装目录下新建一个文件名为ws2_32.dll的文件,这样系统就会以文件出错误而禁止运行(可以新建一个内容为空的文件夹,然后改名为ws2_32.dll))

ws2_32.dll包含有以下常用函数:

WSACleanup()是中止Winsock 2 DLL (Ws2_32.dll) 的使用。

WSAStartup()即WSA(Windows SocKNDs Asynchronous,Windows异步套接字)的启动命令。是Windows下的网络编程接口软件Winsock1 或 Winsock2 里面的一个命令(Ps:Winsock 是由Unix下的BSD Socket发展而来,是一个与网络协议无关的编程接口)。

Recvfrom()函数说明:recvfrom()用来接收远程主机经指定的socket传来的数据,并把数据传到由参数buf指向的内存空间,参数len为可接收数据的最大长度.参数flags一般设0,其他数值定义参考recv().参数from用来指定欲传送的网络地址,结构sockaddr请参考bind()函数.参数fromlen为sockaddr的结构长度.成功则返回接收到的字符数,失败返回-1.

sendto() 用来将数据由指定的socket传给对方主机。参数s为已建好连线的socket,如果利用UDP协议则不需经过连线操作。参数msg指向欲连线的数据内容,参数flags 一般设0,详细描述请参考send()。参数to用来指定欲传送的网络地址,结构sockaddr请参考bind()。参数tolen为sockaddr的结构长度。int sendto ( socket s , const void * msg, int len, unsigned int flags, const struct sockaddr * to , int tolen ) ;

 

OD加载,命令行输入:bp sendto,发现没反应。再输入bp Recvfrom也没反应。于是,直接找到函数地址,F2下断。F9运行后,发现虽然停了几次,但没得到想要的东西,也不知道是不是自己电脑的问题。只好再想其他的办法了。

换了一个账号,继续抓包,又得到了一些数据。我们把这几次的数据整合起来放在下面进行比较。

收到的数据报:

第一个账号拨号后截获的收到的数据包:

10 1B 9C 96 2A E6 5C 0E 82 98 64 BC 3E 78 15 CC E7 B2 A0 11 80 00 00 00 20 D0 49 48 C8 49 B8 C8 48 B8 C8 C9 08 49 48 69 D8 C8 69 C9 E8 21 81 C8 A1 81 48 30 D9 28 16 6F FB A6 C7 87 27 CA 7A 1E 37 2B C8 48 D8 E8 39 49 E8 08 46 8A 27 CA 8B 3A 56 7A 58 58 36 3E A8 28 16 6F DA 16 C7 0E 5B 3F 37 2B 48 39 48 48 08 56 2B A8 B0 60 2C 5C 5C 4C 69 B9 B9 C8 E8 49 39 C8 59 68 39 C8 C8 39 C8 59 68 B9 31 11 08 81 00 00 31 11 00 20 00 00 40 60 2C 5C 5C 4C 69 B9 B9 C8 E8 49 39 C8 59 68 39 C8 C8 39 C8 59 68 B9

 

第二个账号第一次拨号后截获的收到的数据包:

10 9A E2 10 CE 4C AB 06 CB 0F CD 66 32 38 32 2B 37 C0 A0 11 80 00 00 00 20 D0 49 48 C8 49 B8 C8 48 B8 C8 D8 08 48 48 69 49 59 69 49 68 21 81 C8 A1 81 48 30 59 28 16 6F FB A6 C7 87 27 CA 7A 1E 37 2B 59 48 D9 39 59 68 08 46 8A 27 CA 8B 3A 56 7A 49 D8 36 3E A8 28 16 6F DA 16 C7 0E 5B 3F 37 2B 48 39 48 48 08 56 2B A8 B0 60 2C 5C 5C 4C 69 B9 B9 C8 E8 49 39 C8 59 68 39 C8 C8 39 C8 59 68 B9 31 11 5E 80 00 00 31 11 00 10 00 00 40 60 2C 5C 5C 4C 69 B9 B9 C8 E8 49 39 C8 59 68 39 C8 C8 39 C8 59 68 B9

 

第二个账号相隔一会儿后拨号截获的收到的数据包:

10 9A 89 FC B4 3E B0 B3 51 1D 84 77 4D 56 85 A1 56 6C A0 11 80 00 00 00 20 D0 49 48 C8 49 B8 C8 48 B8 C8 D8 08 48 48 69 C9 D9 69 58 C8 21 81 C8 A1 81 48 30 59 28 16 6F FB A6 C7 87 27 CA 7A 1E 37 2B 59 48 D9 39 D8 48 08 46 8A 27 CA 8B 3A 56 7A 49 D8 36 3E A8 28 16 6F DA 16 C7 0E 5B 3F 37 2B 48 39 48 48 08 56 2B A8 B0 60 2C 5C 5C 4C 69 B9 B9 C8 E8 49 39 C8 59 68 39 C8 C8 39 C8 59 68 B9 31 11 5E 80 00 00 31 11 00 10 00 00 40 60 2C 5C 5C 4C 69 B9 B9 C8 E8 49 39 C8 59 68 39 C8 C8 39 C8 59 68 B9

 

我们把中间那个作为中间量进行比较。不同的部分用彩色显示出来。一和二三的账号是不同的。二和三的账号相同,但报号时间不同,一二三弹出窗口的内容分别如下:

第一次:(您可用时间为1059.29 小时,约44)(您的余额为0.00 )

第二次:(您可用时间为607.68 小时,约25)(您的余额为0.00 )

第三次:(您可用时间为607.50 小时,约25)(您的余额为0.00 )

      可以看出,二和三只有两个字符不同,而在收到的数据包中,也刚好有两位数字不一样,在第二个数据包中是59 68在第三个中是D8 48,很莫名其妙的四个字符让我想起了在破解客户端拨号真实密码时得到的一个转换表。0481c82493c94585d86597d98689e8。往里面一放,还真是6850。于是我们也不难知道59 48 D9 39 59 681059.29的意思了。

根据其规律,推出了如下的一部分对应转换,但却始终不知道汉字在其中的转换过程,有看出来的同学还请指教。

   后 D H

 →08 32 20

(→28 40 28

)→A8 41 29

.→39 46 2E

0→48 48 30

1→c8 49 31

2→49 50 32

3→c9 51 33

4→58 52 34

5→d8 53 35

6→59 54 36

7→d9 55 37

8→68 56 38

9→e8 57 39

 

       目测其大概是根据acsii码排序来的,个位始终为89交替,而十位则从0-F循环。同可表示16*2=32个字符。为acsii32-63号字符。那么,字母和汉字在其中又是怎么表示的呢?不得而知也。

我们随机选取上面的一段数据:

28 166FFB A6 C7 87 27 CA7A1E 37 2B 59 48 D9 39 D8 48 08 468A27 CA 8B3A567A49 D8 36 3E A8

对应:

(                         6  0  7  .  5  0               2  5     )

 

能说的大概也就这么多了吧,就是客户端在拨号之后会通过4999端口以UDP形式向服务器发送一个请求查询的数据包,然后得到服务器的回复,并通过客户端弹出窗口显示出来,不过,还有个问题不解,就是,它想利用本地的3852端口干嘛呢?

嗯,有点想睡了。大家自己去钻研一下吧,有了成果记得告诉我一声哈。

最后,通过抓包实例跟大家说说PPPOE协议吧。还是前面那张图:

拨号客户端弹窗原理追踪

首先,PPPoE协议的工作流程包含发现和会话两个阶段,发现阶段是无状态的,目的是获得PPPoE服务器的以太网MAC地址,并建立一个唯一的PPPoESESSION-ID,在发现阶段,基于网络的拓扑,主机可以发现多个接入集中器,然后允许用户选择一个。发现阶段结束后,就进入标准的PPP会话阶段。

发现阶段有4个步骤:

1.       PADI图示步骤1,主机发送广播包PADI寻找接入服务器。主机→服务器。

2.       PADO图示步骤24,服务器收到包后如果可以提供主机要求则回复一个PADO包。为什么有两个呢?有时,网络上有不止一个服务器。服务器→主机。

3.       PADR图示步骤3,主机在回应PADO的接入服务器中选择一个合适的,并发送PADR告知接入服务器,PADR中必须声明向接入服务器请求的服务种类。主机→服务器。

4.       PADS图示步骤5接入服务器收到PADR包后开始为用户分配一个唯一的会话标识符Session ID,启动PPP状态机以准备开始PPP会话,并发送一个会话确认包PADS。服务器→主机。

主机收到PADS后,双方进入PPP会话阶段。在会话阶段,PPPoE的以太网类域设置为0x8864CODE0x00Session ID必须是Discovery阶段所分配的值。

PPP会话阶段主要是LCP、认证、NCP 3个协议的协商过程,LCP阶段(图示步骤6-12)主要完成建立、配置和检测数据链路连接,认证(图示步骤13-19)协议类型由LCP协商(CHAP或者PAP)NCP(图示步骤20-27)是一个协议族,用于配置不同的网络层协议,常用的是IP控制协议(IPCP),它负责配置用户的IPDNS等工作。

其中,CHAP是一种加密的验证方式,能够避免建立连接时传送用户的真实密码。NAS向远程用户发送一个挑战口令(challenge),其中包括会话ID和一个任意生成的挑战字串(arbitrary challengestring)。远程客户必须使用MD5单向哈希算法(one-way hashing algorithm)返回用户名和加密的挑战口令,会话ID以及用户口令,其中用户名以非哈希方式发送。所以,我们通常抓到的VALUE值是没什么用的。

好了,就到这了,晚安~~

无意间听到了一句话,送大家了。

快乐也是一天,不快乐也是一天,你为什么要拿自己的不快乐去惩罚身边的人呢?

~~

 

 ——Tracy                                      201210152:08:50

发表评论(5)
1楼 小宠  发表于  2013-5-31 15:23:50
你这个抓取的是握手包和数据转换包 没意义啊
[博主回复]  抓的包是为了讲解pppoe验证的整个过程,并没有想告诉你,这里面的密码和用户名在哪
2楼 houjoutan  发表于  2013-3-1 18:09:00
补充一下,172.31.15.2的MAC地址和 PPPOE服务器的MAC地址一模一样,所以断定172.31.15.2是PPPOE服务器,同时兼拨号成功后的验证服务器和弹窗服务器。
[博主回复]  好久没看过了,也不知道现在改动了没?一般PPPOE服务器是一个服务器群,不止一台服务器的。
3楼 houjoutan  发表于  2013-3-1 18:04:28
又有一些新发现,一共截取了4组完整的数据包,然后用回放软件发现了一些问题。 172_31_15_2_Packets.cscpkt 以前截取的发往172.31.15.2的完整UDP数据包组,如果重新拨号后完整回放得到来自1.1.1.9的回复,但是客户端没有任何反应。 172_31_15_2_mod.cscpkt 以前发往172.31.15.2的完整UDP数据包组,修改原地之后,重新回放,得到1.1.1.9回复,但是软件没有响应。 172-31-15-2.cscpkt 拨号后新截取发往172.31.15.2的完整UDP数据包组,回放后,收到了1.1.1.9的回复,软件同时弹窗. 1-1-1-9.cscpkt 拨号后收到的来自1.1.1.9的数据包,回放后,软件弹窗,这是必须的。。。。不然不合情理了。。。 数据包通过Colasoft Capsa 7 Enterprise截取。 提及数据包下载http://www.fcsys.tk/data/sw-schoolnet/
4楼 houjoutan  发表于  2013-3-1 16:11:55
发现了为什么用真实密码会挂的问题了,客户端会在%windir%中建立一个pauthip.txt文件,打开里面就是一个ip地址和一个分号组成,ip就是172.31.15.2。确实把这个ip改了后不会弹窗,但是会挂死。通过抓包,客户端一直会向这个ip(被我改成了错误ip后)发送udp数据包,而且每个数据包只有中间一小部分不同,报头报尾一模一样。现在由于挂住了,没法进行下一步测试,晚上睡觉时准备把正确的报文截取下来,然后用windows pppoe拨上去,然后用科莱数据包回放工具发送这段报文,看看能不能骗取验证。学长真厉害!博客回帖有问题,刷新几次验证码才能,不然有点乱码。
[博主回复]  恩,那个文件里的ip我到没注意过,因为没注意过程序读取这个文件。挂上去的原因现在也还没摸索清楚,也没激情去弄这个了。欺骗验证那啥我搞定了,也是写这篇文的主要原因。博客回帖嘛,是因为我给的session存活期不高,所以,一般看完文章后估计就到期了。。。
5楼 heihuar  发表于  2012-11-27 21:55:30
 用实际密码通过win7自带pppoe上网正常下线不挂死 但安卓端pppoe上网一登上(可上网)不管直接断wifi还是点下线都必挂死  学长能分析下 或给出个解决方案吗
[博主回复]  等有时间吧,应该是服务器端的问题。或者,看看断开的时候有些什么信息的发送吧。
姓名 *
电子邮件
QQ
评论内容 *
验证码 *图片看不清?点击重新得到验证码请输入图片后链接字符‘a’