首页
社区
课程
招聘
[1月27日更新在49楼][软件自带加密算法分析]校园网那些事
发表于: 2013-1-19 17:12 37623

[1月27日更新在49楼][软件自带加密算法分析]校园网那些事

2013-1-19 17:12
37623
收藏
免费 6
支持
分享
最新回复 (64)
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
51
这两天忙 好几天没来了
2013-1-31 00:21
0
雪    币: 40
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
52
mark lz强人呀。
2013-2-22 15:29
0
雪    币: 49
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
53
向楼主学习,先收藏了,慢慢消化,才看完第一页的,赞!
2013-2-24 10:17
0
雪    币: 329
活跃值: (235)
能力值: ( LV13,RANK:320 )
在线值:
发帖
回帖
粉丝
54
谢谢支持,只是才回学校,后面几章必须要对应环境。所以就暂时没写了。
2013-2-24 18:38
0
雪    币: 49
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
55
嗯,不要紧,等有环境再咨询楼主。
2013-2-24 18:43
0
雪    币: 12
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
56
Thank you
2013-3-7 17:06
0
雪    币: 329
活跃值: (235)
能力值: ( LV13,RANK:320 )
在线值:
发帖
回帖
粉丝
57
好久没写了。没激情了~~~

大家伙儿还想看下去么?
2013-10-31 10:47
0
雪    币: 141
活跃值: (318)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
58
有空看看吧。。。。。
2013-11-1 13:14
0
雪    币: 329
活跃值: (235)
能力值: ( LV13,RANK:320 )
在线值:
发帖
回帖
粉丝
59
隔了那么十个月没写了,真的很抱歉了。最近又打起精神,还是想把它完成吧,也算是了了一桩心愿啊。不过可惜的是,这次是的确没环境了,很多实例不能用图片来展示了,那么,就只有靠文字和代码来给大家描绘。

       而且,后面都是分析一些算法的,可能看起来不是那么好理解了,望原谅~~~

Chapter 3——窗口弹出

       一直就用着自己的工具盗号、拨号上网。忽然有一天又对蝴蝶.exe感兴趣起来了。因为,在印象中,每次拨号成功后,都会在右下角弹出一个窗口,显示你账号的剩余时长之类的信息。然后,还会弹出校园网论坛。这事貌似有点猫腻。

      于是,很想知道它是如何弹出网页和窗口的。然而,用宽带连接拨上号之后,马上打开网站,无论你的网址是什么,都会跳转到校园网论坛。这事,的确有点蹊跷。而且,它是如何控制客户端弹出网页和窗口的呢?通过发送特定的数据包?那么,要是我知道了这一原理,自己写出这么一个数据包,那是不是说我也可以对别人发送数据,然后使他人的电脑弹出窗口,打开特定的网页呢?

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



     经过前面的讲解,我们可以看出1-27步都是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命令时,发现拨号客户端一直在监听UDP的4999和3852了。可后来仔细看了看,又觉得不对,因为我都不了解这数据包里某一位的作用分别是什么,又怎么去构造呢?

那么,还是祭出OD来进行分析,上次我们是对rasdiala下段,得到要发出的内容,这次,因为是收到网络数据包之后,客户端再对数据进行处理。显然,突破口是在接受UDP数据包这里。根据以前的方法,先看有没有recvfrom,然后再在OD中bp recvfrom下断。之后,拨号运行。程序成功中断在00408C85处,然后我们看看recvfrom的参数。

sockfd:标识一个已连接套接口的描述字。 

buf:接收数据缓冲区。 

len:缓冲区长度。 

flags:调用操作方式。是以下一个或者多个标志的组合体,可通过or操作连在一起:

那就是说,第二个参数就是我们接收到数据的存放处了。由于,调试的时候是在学校,写文是在家,所以不能一步一截图,只能凭记忆说说了。看看堆栈窗口,在第二个参数那右键,在数据窗口跟随,就可以看到我们的接受到的数据包了。再然后就是看程序对数据包做了些什么了。

首先,我们把在三个不同时刻用两个账号进行拨号,得到的数据包如下:

收到的数据包:

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

10 1B9C962AE65C0E 82 98 64 BC 3E 78 15 CC E7 B2 A0 11 80 00 00 00 20 D0 4948 C8 49 B8 C8 48 B8 C8 C9 08 49 48 69 D8 C869 C9 E8 2181 C8 A1 81 48 30 D9 28 166FFB A6 C7 87 27 CA7A1E 37 2B C8 48 D8 E8 39 49 E8 08 468A27 CA 8B3A567A58 58 36 3E A8 28 166FDA16 C7 0E 5B3F37 2B 48 39 48 48 08 56 2B A8 B0 602C5C5C4C69 B9 B9 C8 E8 4939 C8 59 6839 C8 C839 C8 59 68 B9 31 11 08 81 00 00 31 11 00 20 00 00 40 602C5C5C4C69 B9 B9 C8 E8 4939 C8 59 6839 C8 C839 C8 59 68 B9


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

109AE2 10 CE4CAB 06 CB0FCD 66 32 38 32 2B37 C0 A0 11 80 00 00 00 20 D0 4948 C8 49 B8 C8 48 B8 C8 D8 08 48 48 69 49 59 69 49 68 2181 C8 A1 81 48 30 59 28 166FFB A6 C7 87 27 CA7A1E 37 2B 59 48 D9 39 59 68 08 468A27 CA 8B3A567A49 D8 36 3E A8 28 166FDA16 C7 0E 5B3F37 2B 48 39 48 48 08 56 2B A8 B0 602C5C5C4C69 B9 B9 C8 E8 4939 C8 59 6839 C8 C839 C8 59 68 B9 31 11 5E 80 00 00 31 11 00 10 00 00 40 602C5C5C4C69 B9 B9 C8 E8 4939 C8 59 6839 C8 C839 C8 59 68 B9


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

109A89 FC B4 3E B0 B3 51 1D 84 77 4D 5685 A1 566CA0 11 80 00 00 00 20 D0 4948 C8 49 B8 C8 48 B8 C8 D8 08 48 4869 C9 D9 6958 C8 2181 C8 A1 81 48 30 59 28 166FFB A6 C7 87 27 CA7A1E 37 2B 59 48 D9 39 D8 48 08 468A27 CA 8B3A567A49 D8 36 3E A8 28 166FDA16 C7 0E 5B3F37 2B 48 39 48 48 08 56 2B A8 B0 602C5C5C4C69 B9 B9 C8 E8 4939 C8 59 6839 C8 C839 C8 59 68 B9 31 11 5E 80 00 00 31 11 00 10 00 00 40 602C5C5C4C69 B9 B9 C8 E8 4939 C8 59 6839 C8 C839 C8 59 68 B9


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

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

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

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

可以,发现,数据包中对应的变化的数字的位置的变化,居然就是我们前面的那套算法,也就是说,这个数据包是经过了自身加密算法加过密的。

那么,我们把上面的数据放到前一节中得到的解密算法中去还原出真实内容试试。



      上图为我们对第一个账号拨号后得到的数据包进行解密后得到的信息。

      可以看出我们收到了一些什么信息,能看得懂的第一个部分为时间,第二个部分为我们拨号窗口弹出的信息:“可用时间,余额”,第三部分为拨号器拨号成功后弹出的网站的网址。那么,是不是说我们对应改掉这些内容然后向其他电脑的相应的端口发送就能让让他们的电脑弹出我想要弹出的网址和对话框呢?如果是这样的话,那就真算是一个很大的漏洞了,而且,很具破坏力的。

      为了方便演示,我们的发出包和收到的包,都用今天刚获取的。

      首先我们还是看看发出去了一些什么信息(截图都是数据包进行解密后在winhex中看到的内容):

      我们截包得到下面的内容:



      再来看看收到的数据包里面的有些啥:



      可以看到,发出去的信息中的时间和收到的时间是相同的(这点很有用,在后面的数据包验证中,这也是判定之一)。发出去的数据包中,有一段是D0341901,也就是我们拨号的账号了,发出去,应该是为了查询这个账号的费用信息(YY出来的),(……中间隔了十个月没写,可能思路和风格会有些不同哈,后面的内容,也可能没有那么多图片去展示了,毕竟,现在没有当时的环境了,只能凭印象把文章写完了~……)1.2.9则是拨号器版本信息了。也就是说,客户端按照指定的规则发出一个带有账号信息的信息,将会返回一个带有账号费用信息的数据包。该数据包由客户端处理后,显示给用户。

      那,也就是说,实现的是一个查询功能咯,而且,是根据服务器发过来的数据包,弹出窗口显示相应的内容,并打开数据包中包含的网址。

      好,回到上一个问题,我们要做的是让他显示我们想要的让他显示的内容。为了确定是数据包控制的,我用BlackFeather大哥给的SocketTool,把收到的数据包再对自己发送。成功弹出消息框和网页,也就说明我们的推断没错。可是呢,我断开了一下网络,然后再次拨号时,用上次的接收到的数据包对本地发送,却毫无反应了。那么问题在哪呢?另外,数据包的控制位有哪些呢?且看下回分解。
2013-11-8 20:19
0
雪    币: 329
活跃值: (235)
能力值: ( LV13,RANK:320 )
在线值:
发帖
回帖
粉丝
60
Chapter4——数据包中的功能控制

        通过一次次各种截获数据包、发数据包、看是否弹出窗口的时候后,得出了如下结论:每次截获的数据包只对本次拨号在线的状态下起作用。那,问题也就随之而来了,我们得弄清楚数据包中的判定条件在哪。也就是,哪些是校验码?

      那?我们为什么要去弄清楚这个呢?因为,按照我们现在的分析,如果我们知道了数据包的整个生成原理,包括每一位相应的功能,那么是不是就可以构造出能够实现我们想要实现的功能的数据包呢?比如:弹出我们想要弹出的消息,打开我们指定的网站,等等……那么,这个就是我接下来的目的:做一个这样的数据包生成器!

       那么,首先,我们得对数据包进行分析。OD载入,对recvform下断点。直接Shift+F9运行起来,拨号。然后呢?因为我们是自己搭建的系统,所以,服务器不可能有数据包发过去,于是我们要自己发数据包过去。还记得上章节中的那些数据包么?直接拿过来用吧,反正我们也是想知道为什么上次截获的数据包这次不用了。

       复制一个截获到的数据包内容,UDP方式发送到客户端所在的ip的4999端口。然后,我们的od成功中断程序。     

      Alt+F9返回程序代码段。我看看堆栈情况。EAX中存放的就是接收到的数据包的总长度。现在单步运行,往后看看,你会发现,这是一个switch case 语句。我们看看反汇编的代码吧。(UDD文件丢失,以前所有的注释都没了,所以~~再敲上一点点吧)

00408C8C  |> \83FB 12       |cmp ebx,0x12 
00408C8F  |.  0F8E C9000000 |jle 1_2_9破?00408D5E     //当总长度小于0x12时,丢弃该数据包 
00408C95  |.  8D8424 380100>|lea eax,dword ptr ss:[esp+0x138]   //数据包存放地址放到eax中 
00408C9C  |.  53            |push ebx 
00408C9D  |.  50            |push eax 
00408C9E  |.  E8 FD99FFFF   |call 1_2_9破?004026A0    //这是一个解密call,我们在前面的章节破解的 
00408CA3  |.  8B8C24 400100>|mov ecx,dword ptr ss:[esp+0x140]        ;  将解密后数据包中前四个字符给ecx,其实也就用到第一个字符 
00408CAA  |.  83C4 08       |add esp,0x8 
00408CAD  |.  81E1 FF000000 |and ecx,0xFF            //得到数据包解密后的首个字符 
00408CB3  |.  8D41 FC       |lea eax,dword ptr ds:[ecx-0x4]          ;  Switch (cases 4..CA) 
…… 
00408CD0  |>  8D8424 380100>|lea eax,dword ptr ss:[esp+0x138]        ;  Case 4 of switch 00408CB3 
…… 
00408CD9  |.  E8 82030000   |call 1_2_9破?00409060        //这个call中将会出现数据包中各位对应的功能 
…… 
00408CEB  |>  8D8C24 380100>|lea ecx,dword ptr ss:[esp+0x138]        ;  Case 6 of switch 00408CB3 
…… 
00408D02  |>  8B4424 14     |mov eax,dword ptr ss:[esp+0x14]         ;  Case C8 of switch 00408CB3 
…… 
00408D2D  |>  8B4C24 14     |mov ecx,dword ptr ss:[esp+0x14]         ;  CaseCAof switch 00408CB3 
…… 
00408D5E  |>  8B35 98CE4300 |mov esi,dword ptr ds:[0x43CE98]         ;  Default case of switch 00408CB3 
…… 
00408D6A  |.^0F84 36FEFFFF \je 1_2_9破?00408BA6 


      从这里可以看出,首字符有“04,06,C8,CA”四个不同选项,大概是四种不同功能的数据包,由于我只收过04开头的数据包,所以,我们也只能够通过这个数据包来分析清楚数据包中数据的结构。当然,你如果有兴趣的话,也可以试着逆向来分析一下06,C8,CA得功能,我估计吧,应该有一个是调出在线升级程序,一个是进行消息提醒(相当于突然弹出一个对话框警告你啥啥啥的)。废话就不多说了,暂时先来分析下04中的功能吧,我们主要分析00408CD9处的那个call。代码如下(先去掉除call和case分支以外的代码):

…… 
004090F4  |.  897424 18     mov dword ptr ss:[esp+0x18],esi          ;  清空内存数据 
004090F8  |.  E8 D3190000   call 1_2_9破?0040AAD0 
004090FD  |.  83C4 08       add esp,0x8 
00409100  |.  84C0          test al,al 
00409102  |.  0F84 ED010000 je 1_2_9破?004092F5 
0040913B  |. |83C0 FC       |add eax,-0x4                            ;  Switch (cases 4..10) 
…… 
0040914E  |> |8D4C24 18     |lea ecx,dword ptr ss:[esp+0x18]         ;  Case 9 of switch 0040913B 
…… 
0040915F  |> |684C1A4400   |push 1_2_9破?00441A4C                    ;  Case 4 of switch 0040913B 
…… 
00409170  |> |68 90064400   |push 1_2_9破?00440690                    ;  Case A of switch 0040913B 
…… 
00409177  |> |688C064400   |push 1_2_9破?0044068C                    ;  Case B of switch 0040913B 
…… 
0040917E  |> |684C1E4400   |push 1_2_9破?00441E4C                    ;  Case C of switch 0040913B 
…… 
00409185  |> |684C124400   |push 1_2_9破?0044124C                    ;  Case D of switch 0040913B 
…… 
0040918C  |> |68 88064400   |push 1_2_9破?00440688                    ;  Case E of switch 0040913B 
…… 
00409193  |> |68 84064400   |push 1_2_9破?00440684                    ;  Case F of switch 0040913B 
……
0040919A  |> |684C164400   |push 1_2_9破?0044164C                    ;  Case 10 of switch 0040913B 
……
004091A9  |> |E8 A2030000   |call 1_2_9破?00409550    //对接收到数据的数据结构进行判定,若异常,则丢弃数据包,若正确,则保存数据到相应的位置 
…… 
004091BB  |> |8D5424 30     |lea edx,dword ptr ss:[esp+0x30]         ;  Case 8 of switch 0040913B 


      是不是发现看起来很舒服啊,从上面我们可以大概看出数据包中的控制字符有“09,04,0A,0B,0C,0D,0E,0F,10,08”,我们暂时先跟进大的分支选择:

0040912E  |. /0F8E C1010000 jle 1_2_9破?004092F5                      ;  循环开始 
00409134  |> |8B4424 10     /mov eax,dword ptr ss:[esp+0x10]         ;  剩余数据的第一个字符位置,即功能字符 
00409138  |. |0FBE00        |movsx eax,byte ptr ds:[eax]             ;  放入eax 
0040913B  |. |83C0 FC       |add eax,-0x4                            ;  Switch (cases 4..10) 
0040913E  |. |83F80C       |cmp eax,0xC                             ;  减4后再与0xC比较,也就是0x10以内的条件分支 
00409141  |. |0F87 D0000000 |ja 1_2_9破?00409217


      经过一轮后,我们会发现,在如下图红色框框的位置上,对应的是我们的功能代码。


      而粉红色的框框中的数值则是我们相应功能代码内容的长度-2。为什么-2?我也不知道。其中第一个字符是数据包类型代码(我们暂且这么称呼它吧),第二个字符则是我们的数据包总长度,地3-17中16个字符我们暂时不说(下章要进行分析~)。后面都是统一的格式了,一个功能代码+一个长度标识+内容。

      光凭眼睛看,我们大概也能确定这么几个性质:

      0C后面接的肯定是要输出的消息内容,而0D、10与弹出的网址有关,08是时间,那么这个时间在神马地方用到了呢?同时,我们还有很多诸如0A、、09、0B、0E等功能的字符没弄明白。为了弄清楚数据包中这些控制字符的相应功能,就得先把对数据包进行判定的判定条件去除掉。

      那么,哪些地方做了判定和限制呢?继续跟下去~跟到功能代码为08的case时我们发现,这地方有好多跳转,稍微分析后就知道了,程序通过拨号成功的时间保留起来,与接收到的数据包中的时间进行逐位对比,若有偏差则丢弃数据包(跳转),这也是为什么数据包中会包含时间的原因了。如下图:



所以,改动的地方应该时间判定处:



      将所有的跳转nop掉后,时间已经不构成限制了。

      F9运行后弹出消息提示框和网站。



      于是,我们就解决了先前的那个问题,为什么上次的数据包对这次拨号后发送没有效果,因为数据包中包含有拨号成功时间,会与保存在程序内存中的时间进行比对,若两个时间不相同,则丢弃数据包,于是自然也就没有效果了。

      好的,那照这么说我们就已经成功解开了限制问题了。我们就可以去分析其他的功能标识符的含义?我们再次把数据包发送到客户端,同样断下程序,解密后把0D(对应网址)的标识改为0C看看会发生什么?



      这次我们不单步了,直接F9跑起来,看是否会弹出两个对话框,来证实我们的猜想。

可结果却:



       这又是为什么呢?我又随意改了一些其他的功能表示符号,或则内容,都弹出上图提示。

       看来,做到这步还是不能完全去试验数据包的每一位是控制什么功能的,还是有些限制在其他地方。那么,在哪呢?且看下回分解~
2013-11-14 02:39
0
雪    币: 80
活跃值: (109)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
61
收藏,坐等下回分解。
非常感谢楼主——哪天还得学汇编啊,代码看着真头疼。。。

曾经捣鼓过极域电子教室,是老师上信息技术课用的,在虚拟机测试,安装好了教师端和学生端,就这么一点点的改配置、设置,捣鼓出了几种数据包的含义,并且成功利用此伪造数据包让学生机显示几行消息,可是到学校那几行消息就跑到老师电脑上了(老师电脑提示:“XX同学发来消息:XXXXXX“,很奇怪,不知为何。
2013-11-14 16:22
0
雪    币: 80
活跃值: (109)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
62
版本都是样的,极域电子教室V6 2007豪华版
2013-11-14 16:23
0
雪    币: 219
活跃值: (793)
能力值: (RANK:290 )
在线值:
发帖
回帖
粉丝
63
顶。。。。。。。。
2013-11-15 14:19
0
雪    币: 48
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
64
你们那拨号输入的密码不是真实密码???
2013-11-15 14:52
0
雪    币: 329
活跃值: (235)
能力值: ( LV13,RANK:320 )
在线值:
发帖
回帖
粉丝
65
现在的netkeeper输入的账号都不是真实帐号了
2013-12-23 10:34
0
游客
登录 | 注册 方可回帖
返回
//