大学的那点事~XX高校数字登录系统浅析

  • A+
所属分类:WEB安全

标 题: 【原创】大学的那点事~XX高校数字登录系统浅析
作 者: 習生
时 间: 2014-03-22,23:47:10
链 接: http://bbs.pediy.com/showthread.php?t=185874



关于XX高校数字登录系统,我的几点看法



  正如孔子所说,“逝者如斯夫,不舍昼夜!”时间如流水落花般逝去,二十二的年龄,毕业的季节。大四下,我会好好欣赏XX高校的各式风景。

*************************************************************

  好了,感慨不多发了,我们进入正题。写这篇文章的主要目的是分析一下数字XX高校的不足之处,好让这个系统能够更加完美。当然,有则改之,无则加勉。

  其实,在刚发这个校园卡上网的时候,见着6位数字的默认密码,我就曾大胆的猜测过,用穷举法不就能登录别人的帐号吗?对,就是一个一个试,当然不是靠我们人来手工操作,

6位数字的密码,共100万个,人工输入尝试当然是不可取的。但是写程序呢?那又会怎么样呢?

************************************************************

一、暴力密码拆解程序的实现。

名称:  图片1.png
查看次数: 1
文件大小:  10.3 KB

这是登录界面,校内网的同学就能看到,地址:http://61.137.86.87:8080/portalNat444/index.jsp



  我们平常登录是输入帐号密码,点击登陆按钮进行登录,这就是说明我们给服务端发送了一个数据,服务端接收到我们的数据然后判断帐号密码的正确性,最后给我们正确的响应。

  我们要用的是:

网页封包抓取---->即我们要知道计算机向服务端到底发送了什么样的数据包,便能依瓢画葫芦,直接实现数据包尝试登录。

抓包的工具很多,如果你还在用Httpwatch的话,我可以告诉你,你没有跟上潮流。Httpwatch固然老牌,但是貌似在64位系统下不兼容。这里我用的是Wireshark,一款相当nice的抓包工具,当然如果你是Firefox浏览器的话,可以直接用自带的debug。

名称:  图片2.png
查看次数: 1
文件大小:  57.8 KB



具体操作可以百度Wireshark的user manual,我这里不多加阐述。



根据Wireshark抓包,可以知道抓到的包是POST 类型的,当然在网页的源码里也能找到:

名称:  图片3.png
查看次数: 1
文件大小:  17.1 KB



当然,后面的便是date.resultCode为0时,就登录成功,如果你能成功控制服务器,把resultCode设置成0,则会永远登录成功,显然这是不明智的。



回归正题,我们需要发送的post数据包为:

网址:http://61.137.86.87:8080/portalNat444/AccessServices/login

方式:POST

数据内容:

accountID=010103100527%40zndx.inter   //这里的%40 代表的是@

&password=56aad664fa33bffb42b2c0be23ebc5efce17d7f82c0d75ade387941c690063382fef34369b1d7c929945fdbd4ba28bc77db7b028d022464646165acedf2b5deb2ce1fb3d4dc074c55888e299d384af306572a368f468d88fdafdaefebfa39bf84fad0530775d37f35dc79594ba62be4fc5189544397ed97054f4fc375903b6

&brasAddress=59df7586

&userIntranetAddress=10.96.85.80

我们可以看到,一共发送给了服务器4个参数:

第一个参数accountID:(学号加上@zndx.inter)

第二个参数password:顾名思义,这是密码。不过并不是我们所期待的6位数字,这是因为他经过了处理,加密了,加密算法为RSA1024bit,这个算法后面会讲到。

第三个参数brasAddress:我这里是59df7586,应该是本机的物理特征,多抓取了几个封包,发现这个不变,就不必管它了,不影响我们工作。

第四个参数userIntranetAddress:这是本机内网IP,我们可以在cmd中输入ipconfig/all或者ipconfig进行查看:

名称:  图片4.png
查看次数: 2
文件大小:  1.1 KB



也可以写一个小程序遍历本机的ip地址。



这是我写的一个小程序:

名称:  图片5.png
查看次数: 2
文件大小:  10.7 KB



也可以用C++:

名称:  图片6.png
查看次数: 1
文件大小:  4.3 KB



程序C++源码如下:

*****************************************************************************

#include <stdio.h> 

#include <winsock2.h> 

#pragma comment(lib,"ws2_32.lib") 



int doit(int, char **) 



  char host_name[255]; 

  //获取本地主机名称 

  if (gethostname(host_name, sizeof(host_name)) == SOCKET_ERROR) { 

    printf("Error %d when getting local host name.\n", WSAGetLastError()); 

    return 1; 

  } 

  printf("Host name is: %s\n", host_name); 



  //从主机名数据库中得到对应的“主机” 

  struct hostent *phe = gethostbyname(host_name); 

  if (phe == 0) { 

    printf("Yow! Bad host lookup."); 

    return 1; 

  } 



  //循环得出本地机器所有IP地址 

  for (int i = 0; phe->h_addr_list[i] != 0; ++i) { 

    struct in_addr addr; 

    memcpy(&addr, phe->h_addr_list[i], sizeof(struct in_addr)); 

    printf("IPAddress %d : %s\n" , i, inet_ntoa(addr)); 

  } 

    printf("如果有10.96的IP address,则说明此Ip为本机Ipv4地址******************  \n" );

    printf("如果无10.96的IP address,则说明计算机未连通校园网******************  \n" );

  return 0; 





int main(int argc, char *argv[]) 



  WSAData wsaData; 

  if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) { 

    return 255; 

  } 



  int retval = doit(argc, argv); 



  WSACleanup(); 



  return retval; 

}

****************************************************************************

  好了,一共4个参数,我们解决了3个,头痛的是第二个被加密的密码是如何由6位数字转换成256位的加密后的字符串的。

  

  256位的加密字符串很容易让人联想到RSA1024加密,这是一种单向加密,多用于商业用途,强度取决于对大数的因式分解。具体可以到维基百科看。

  这种过高的加密强度使得我望而却步。

  正要放弃,却发现了一个致命的弱点,有一个security.js的文件又再给人一线希望。将源文件下载到本地,分析后就知道了由6位数字如何魔术般成为了256位字符。

一共有这么几个文件:

点击图片以查看大图

图片名称:	图片7.png
查看次数:	6
文件大小:	9.2 KB
文件 ID :	87995









我们打开security.js,可以发现,我们的猜测并没有错:

点击图片以查看大图

图片名称:	图片8.png
查看次数:	8
文件大小:	36.2 KB
文件 ID :	87996



一共700行代码,不一一贴出

***************************************************************************

无论是注解还是函数名称,都证明了是RSA1024无疑。可笑的是,这个代码是05年写的,10年经过修改。并且在调试过程中,我发现了供应商是华为,无疑。

点击图片以查看大图

图片名称:	图片9.png
查看次数:	10
文件大小:	19.0 KB
文件 ID :	87997

既然有了源码,我们也能发现这和我们抓包所得到的数据一致,只是密码用了一个函数encodeURIComponent()函数进行编码后再用security.js里写好的RSA加密算法进行加密。



搞定了POST的四个参数,用一个循环和100万个密码进行暴力破解,也就能实现用别人的一个已知的学号(默认密码)进行登录。



二、暴力破解的效率

  百度网盘曾经有段时间是4位数字密码,即1万个数字,即使算最后一次才尝试成功,也在10分钟以内。我们就按这个概率算,当然,你可以计算时间的期望值如果你的概率论学得不错。就算10分钟,1000分钟也能尝试出一个密码,约16个小时。是不是很nice,按期望的话,平均9小时就差不多能得到一个帐号的密码。

  当然官方不是吃素的,他当然会考虑到这个可能性。

  

三、官方限制

  可能考虑到有人会尝试穷举所有密码,或是因为代码的严谨性,名称:  图片10.png
查看次数: 1
文件大小:  3.2 KB这个文件里的内容就是来限制大家的次数,我大概尝试了下,1个帐号连续输错10次密码后会提示错误信息“无法获取”,大约停止3分钟。如果按照这个官方设计好的方式来算,10次密码耗时3分钟,100万次耗时30万分钟,约208天的时间,当然,就不存在穷举来窃取他人帐号,因为没有人愿意发大半年时间就破解一个密码,可能还不够交电费。那我们就放弃吗?

  Of course not!尽管它是限制了次数,我们可以用一种巧妙的方法躲过,方法很简单:我们可以尝试010103100101的密码10次,一直到无法获取,开始尝试2号学号的10次,这样我们电脑的效率能实现最大化,概率当然不变,还是9小时左右能拿到一个号。

  我还发现,代码里存在一个登录标志,这使得多线程无法得以实现。不过不怕,每个寝室不是你一个人在战斗,跟他们说清情况,结果可想而知,你懂的。

  

四、优化

  100万次的次数太多,为了使得尝试次数减少,我向同学要了大概10个左右的密码,基本可以剔除6位数字里全相同的,5个数字相同的以及4个数字相同的密码。

  这样的密码可以不用尝试:

  11111;22222;11115;344445;863888;

  用排列组合,我们可以算出,剔除了以上几种可能后,密码的尝试次数将减少到746640次,这样的话,时间又能缩短了。当然,你还可以去除一些123456;765432;这样的密码,具体可以参考双色球的一些软件的算法。这里不做赘述。

  

五、其他

  除了温柔的暴力拆解密码以外,当然可以采取直接的入侵手段,那样便会方便很多,当然完成后记得删除telnet 和http等日志。

  

  总的来说,数字XX高校还是设计得不够完善。

  提出几点建议如下:

  大家不要嫌麻烦,建议改下密码,6位数字并不安全。

  数字XX高校应把源码藏好,不能让外面轻易得到,这点是很值得改善的。

  源代码里的验证码都被注释了起来:

名称:  图片11.png
查看次数: 2
文件大小:  13.1 KB



图一:jsp中的

Js中的validateCode 也全部不再使用,尽管提高了学生上网的方便,同时也使得帐号的安全性下降了。

其他的就是网络攻防了,这就看管理员的水平了。

--------------------------------------------------------------------------------

声明:本人水平有限,若有不正确之处,还望各位大侠指正。

-----------------------------------------------------------------------------------

                                                                  Xiaoyu

                                                             2014年03月22日

  

  

附录一:公钥定义处

点击图片以查看大图

图片名称:	图片12.png
查看次数:	187
文件大小:	32.3 KB
文件 ID :	88000

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: