[武汉大学教务系统入侵&窃取数据全过程记录]
[PHP验证码识别(OCR)技术科普贴]
[论教务系统修改默认密码的重要性]
[论教务系统修改默认密码的重要性]
[这么作死真的不会死吗?]
2014.8.15
玩着我自己写的微信订阅号("月翼科技"),突然想到传说中的(因为我只听说过,没用过额)神器"武大助手"貌似可以查成绩,百度了下,它是抓取的教务系统里面的数据,可是教务系统不是有验证码的吗,即使有了账号密码,过不了验证码还是没办法抓取数据的啊。那么,它是怎么解决这个问题的呢?
看了下教务系统的登录页面,额,每次刷新验证码服务器重新分配Session,客户端这边只存了一个SessionID的Cookies(如上图)。
也就是说,浏览这个页面的时候,客户端除了验证码这张图,根本没有获得任何关于验证码的内容的信息。
这是目前我知道的最标准最科学的做法了,貌似无懈可击啊。
难道是因为验证码太简单,武大助手他萌可以用第三方的类库破解掉?
果断百度,结果发现有可以识别数字的类库Valite,但是对验证码本身要求很高(清晰并且黑白分明),有可以识别字母和数字的第三方类库Tesseract,貌似还开源……但是下载下来发现,安装之后还需要复杂的教学过程……
总之,搜索PHP+验证码识别,基本找不到好的教程或者源码什么的,简直无奈。
妈蛋,作为一名ITer,太依赖第三方类库果断不是好习惯,没有类库就自己写!
参照那个识别数字验证码的思路,首先……
把图片每一个像素分开成一个矩阵(或者叫,2维数组?)。
分析每一个点的RGB值,观察验证码的放大图,很明显,字的部分,R(Red红色)的值比较高。
于是把字的那部分像素点给予不同的值以示区分。
最后的效果类似下图:
好吧,现在程序是能"分析"这张图了,但是程序要怎么"理解"它呢?
按照百度到的姿势,我们需要对这张"图"进行一些处理,首先,把能排除掉的没用的"噪点"去掉:
Then:
于是现在,这张"图"看起来就好辨认多了。
当然不是每次的图都这么清晰的,比如有这样的:
于是,我想到,可以把除去"噪点"的过程再来一遍,这样:
接下来,"除去"点的过程完成,开始"补充"一些点,让字母看起来更"连贯"一些:
验证码里面有4个字母,很明显我需要把它萌分开,于是竖着切几刀:
额,不过有时候会切错位置,额,比如这样:
经过一番努力(死了N个脑细胞),总算不会切错了,然后横着再切:
2014.8.16
到这里的时候,我突然识别验证码貌似也没辣么难嘛。
如上图,其实相同的字母切出来之后,它的长度和宽度,以及里面的黑白位置基本是一样的。
于是,果断把字母的长宽和排列位置存下来(如上图,N个txt文件)。
如上图,根据长度和宽度,基本就可以确定可能是哪几个字母了。
但是当我收集了越来越多的字母长宽的时候,情况变成了这样:
当然,运气好的时候,可以是下面这样的:
不过光靠运气的话,识别成功率也太低了,果然还是要比对字母的矩阵(二维数组)的相似度来判断。
(在这里写了N层的循环,发现智商完全不够用了。)
随着存字母形状的txt文件越来越多,果断还是模糊匹配用到的更多:
接着,不断进行识别测试,终于让我发现了一个丧心病狂的例子(3个字母粘连在了一起):
2014.8.15
玩着我自己写的微信订阅号("月翼科技"),突然想到传说中的(因为我只听说过,没用过额)神器"武大助手"貌似可以查成绩,百度了下,它是抓取的教务系统里面的数据,可是教务系统不是有验证码的吗,即使有了账号密码,过不了验证码还是没办法抓取数据的啊。那么,它是怎么解决这个问题的呢?
看了下教务系统的登录页面,额,每次刷新验证码服务器重新分配Session,客户端这边只存了一个SessionID的Cookies(如上图)。
也就是说,浏览这个页面的时候,客户端除了验证码这张图,根本没有获得任何关于验证码的内容的信息。
这是目前我知道的最标准最科学的做法了,貌似无懈可击啊。
难道是因为验证码太简单,武大助手他萌可以用第三方的类库破解掉?
果断百度,结果发现有可以识别数字的类库Valite,但是对验证码本身要求很高(清晰并且黑白分明),有可以识别字母和数字的第三方类库Tesseract,貌似还开源……但是下载下来发现,安装之后还需要复杂的教学过程……
总之,搜索PHP+验证码识别,基本找不到好的教程或者源码什么的,简直无奈。
妈蛋,作为一名ITer,太依赖第三方类库果断不是好习惯,没有类库就自己写!
参照那个识别数字验证码的思路,首先……
把图片每一个像素分开成一个矩阵(或者叫,2维数组?)。
分析每一个点的RGB值,观察验证码的放大图,很明显,字的部分,R(Red红色)的值比较高。
于是把字的那部分像素点给予不同的值以示区分。
最后的效果类似下图:
好吧,现在程序是能"分析"这张图了,但是程序要怎么"理解"它呢?
按照百度到的姿势,我们需要对这张"图"进行一些处理,首先,把能排除掉的没用的"噪点"去掉:
Then:
于是现在,这张"图"看起来就好辨认多了。
当然不是每次的图都这么清晰的,比如有这样的:
于是,我想到,可以把除去"噪点"的过程再来一遍,这样:
接下来,"除去"点的过程完成,开始"补充"一些点,让字母看起来更"连贯"一些:
验证码里面有4个字母,很明显我需要把它萌分开,于是竖着切几刀:
额,不过有时候会切错位置,额,比如这样:
经过一番努力(死了N个脑细胞),总算不会切错了,然后横着再切:
2014.8.16
到这里的时候,我突然识别验证码貌似也没辣么难嘛。
如上图,其实相同的字母切出来之后,它的长度和宽度,以及里面的黑白位置基本是一样的。
于是,果断把字母的长宽和排列位置存下来(如上图,N个txt文件)。
如上图,根据长度和宽度,基本就可以确定可能是哪几个字母了。
但是当我收集了越来越多的字母长宽的时候,情况变成了这样:
当然,运气好的时候,可以是下面这样的:
不过光靠运气的话,识别成功率也太低了,果然还是要比对字母的矩阵(二维数组)的相似度来判断。
(在这里写了N层的循环,发现智商完全不够用了。)
随着存字母形状的txt文件越来越多,果断还是模糊匹配用到的更多:
接着,不断进行识别测试,终于让我发现了一个丧心病狂的例子(3个字母粘连在了一起):
(卧槽,不带这样的!)
(于是重新回去改切字母的代码,妈蛋,终于,就算4个字母都连在了一起都能给准确的切开了。)
突发奇想,其实在最开始的时候可以给验证码加一个"黑色"的边框,这样边缘位置的"白色"点也可以在"降噪"过程中被当做"噪点"去掉了。
虽然各种奇葩的验证码都有,不过也有下面这样的,就靠这种完全规范的验证码给我信心了:
随着收集的字母"样式"的txt文件越来越多,发现了最好识别的两个字母:O和C,简直完全对称,而且试验了很多次,O和C就米有别的样子的,只有这样的:
一共测试了200+的验证码,不断测试,找出错误,保存TXT,修正代码……
代码Part1(根据REB颜色分析图片):
代码Part2(根据TXT文件保存的字母信息进行模糊匹配):
之前都是把验证码图片下载到本地然后识别的,现在果断改成即时获取,即时识别。
识别成功截图:
识别失败截图:
统计时间(识别的速度还是挺好的,相对于获取一张验证码的时间,识别的时间简直可以忽略不计):
开始在教务系统上验证效果(很明显问题不大):
2014.8.17
接下来,开始做和"武大助手"类似的事情,抓取我自己的账号的数据:
表示做这个系统的人的代码命名习惯非常好(最喜欢这种人了),很明显方便了他萌开发的过程(当然也方便了我啊)。
成绩和课表的位置很容易就找到了。
=。=
于是,愉快地开始试验抓取数据了:
And:
And:
表示抓取数据的时间貌似就略长一些了:
Now,写一个猜密码的php,配合我之前的用.NET写的一个攻击老师作业网站的程序,开始暴力猜密码,Yeah。
(话说PHP实际是单线程的,这是它相对ASP.NET和JSP的一个缺陷吧,而且PHP理论上说,最好是限制执行时间的,so,不适合直接写DDOS攻击程序。)
(果断多会几门语言,玩技术会更Happy=。=)
猜密码,Yeah。(好喜欢~(≧▽≦)/~)
表示其实教务系统的密码没有很难猜的,我是从19930101一直猜到19971231的,最多也就试366*5=1830而已。
对于机器来说,循环尝试1830次……so easy嘛。
自己写的可以用命令行的攻击程序:
(参数意思是从2013302580001一直试到2013302580315,开5个线程试。)
Like this:
后来发现太慢了,额,于是:
因为验证码其实不是很大(1-2KB的样纸),所以,貌似不是很占网速:
于是,额,下图是个程序bug,额,已经猜出来密码的账号,程序还在不停试密码,额,果断修正代码。
实验结果:30个线程,1小时,猜出了大约30个账号的密码。
2014.8.18
昨晚用了大约6-7个小时的时间,额,猜出了一堆密码,下图:
(Fail的代表试了1830个密码还试不粗来的,额,有可能是验证码识别错了,不过更大的可能是:这些孩纸早就机智地改了密码了!!!23333)
把txt整合到php文件里面去,方便上传到我的SAE服务器(貌似也能提高一些效率吧)。
改一下代码,果断还是下面这样的更有效率:
把php文件压缩一下,果断上传到我的SAE的服务器,嗯。
And:
用SAE去教务系统抓验证码会不会快一点?我也不造。
不过酱紫,至少符合所谓"负载均衡"吧(还可以叫小伙们萌协助我)……
(我的新浪的豆豆还没花超过50个呢,看看酱紫能烧掉多点豆=。=)
开始布置数据库,准备抓取大量的数据了:
晚上7点,额,关掉猜密码程序,数了下,一共Get了全院119个学号的密码,果断开始存数据……
最终一共获得分数记录项2655条,下学期的选课记录项1452条。
话说这次是时间不多,要不然可以扫完全院的数据的,有空也可以扫一下全校的。~(≧▽≦)/~
用已有的数据算了下平均分,额,发现最高的课程是军事理论(92.8),最低的大约是数字逻辑(60.1),额,还好我当初嫌它太偏硬件,没选,我还是挺机智的。
话说比较奇怪的是,C++程序设计(实验)平均分是78.6,但是C++程序设计的平均分居然只有60.1(比数字逻辑高0.06,额)。
万恶的大学物理B(上),平均分是66.9,额。
大学英语2的平均分只有75.2,意思是有一大半的人下学期都不能考4级咩?
好了,下面切回正题,武大助手(后来想到还有课程格子)是怎么导入教务系统的信息的呢?
其实,他们是这么做的:
卧槽啊!我早该想到的!验证码当然是发给用户自己去识别啊!!!
好吧,这已经不重要了。
=。=
[PS:这篇文章有木有点冷笑话的感觉?]