如何“爆破检测”加密密码字段和存在验证码的Web系统

*本文原创作者:shystartree,本文属FreeBuf原创奖励计划,未经许可禁止转载

一、背景

一直想对本人公司所在的某管理平台(下文简称为A平台)进行一下弱口令检测,但是该平台做了设置验证码(做了一定的干扰效果)和密码加密等防御措施而无法使用一些常规的爆破工具进行攻击。本文将结合在检测过程中遇到的问题一步步地讲解如何突破障碍达到检测的目的,各位读者可以举一反三进行其他系统的爆破测试。

二、寻找一个简单的爆破点

A平台算是公司内部的一个通用平台,所以其的账号密码也能在其他系统上登录,但是这些系统多多少少都做了一定的防御,基本都具有密码次数过多封ip、验证码、密码字段加密、请求间隔时间检测等的爆破防御,故本文选择了一个仅仅拥有密码字段加密和设置验证码(验证码干扰量最少)的A平台,如果读者非不得已要突破密码次数过多封ip的防御,可以在本文的基础上加入代理池,如何筛选出有效的代理池还请自行研究。

下面是A平台的post数据:

可以见到A平台的密码字段Password是经过前端加密了,可想而知要爆破这个系统,验证码识别和如何生成这个密文是重点突破点。

三、对验证码的机器识别

一开始,本文使用python的pytesseract进行了对A平台的验证码进行测试,删除了干扰线和灰化后,依然无法对该验证码图片正确识别,其原因是验证码的字体稍微做了变形。

图为处理完的验证码:

其实经过处理后这个验证码看起来已经是很好识别了,不料pytesseract还是无法全部识别成功,如读者还有其他方法能把该图片处理到让pytesseract识别的程度欢迎留言交流。

很早就听过tensorflow这个框架,这个框架是目前最流行的深度学习框架,我们可以用它来搭建自己的卷积神经网络并训练自己的分类器,接下来,本文将简要地描述下训练分类器和使用生成好的模型进行识别验证码:

3.1 收集图片并设置标签

为了训练分类器模型,需要从服务器取得一定量的训练图片,本文写了一个脚本从服务器取了200张图片,并花了一个多小时对这些图片进行了码标签(重命名图片文件)。

最终码完标签的结果大概是这样:

3.2 训练分类模型

本文主要搬运tensorflow_cnn这里的代码,由于该代码中所使用图片大小为60160,而原始下载保存好的图片大小为2788,构建CNN的参数无法适用,为了省心省力,故在生成图片的时候直接把图片调整为60*160。

训练模型:

运行该脚本,当训练的准确率大于99%的时候就会在运行的目录下就会保存crack_capcha.model-1300.data-00000-of-00001、crack_capcha.model-1300.index、crack_capcha.model-1300.meta这三个文件,本文的机器大概运行了一个半小时。

3.3 使用模型

经过测试,该模型对于A平台的验证码识别效率还算不错,平均10次只有1、2次识别错误。

好了,现在第一个难点验证码识别已经解决了,接下来将讲解如何生成密码密文实现自动化爆破。

四、生成靠谱的弱口令字典

这步应该是这次爆破的关键,能否最终爆破出正确的密码也是看字典的质量。除了检测一些常见的弱口令(top100)外,还应该根据姓名、出生年月、手机号生成一系列的社工字典。 于是,本文首先整理一份包含所有员工的姓名、身份证号、手机号、邮箱的excel文档。 首先处理每个员工的信息,关于如何处理信息,本文的做法是:

若姓名为凌星星的人,将返回lxx、Lxx、Lin、LIN、linxinxin;

若公司为freebuf,将返回freebuf、fb

然后根据处理后的信息生成对应的弱口令,本文生成的社工弱口令字典主要包含三种:字母(姓名、公司名等)+ 特殊字符(@、#、、-等)+ 数字(手机号、出生日期、常见的连续数字、年份等)、 字母(姓名、公司名等)+ 数字(手机号、出生日期、常见的连续数字、年份等) + 特殊字符(@、#、等)、字母(姓名、公司名等)+ 数字(手机号、出生日期、常见的连续数字、年份等)。考虑到正常人的习惯,一般人很少把数字和特殊字符作为开头,故去掉数字和特殊字符开头的。

最后加上top100的弱口令,每个员工生成对应的弱口令达3000个。

图为生成字典的结果:

五、对加密字段的探索

分析前端的登录界面,最终找到该密码字段的加密方式,可以见到该字段是经过js rsa加密的。

怎么找到该公钥的呢,很简单,打开chrome的控制台,直接输入login.pubkey即可。

其实,要破解这种加密方式,无非是就是三种方法:

理清js中的加密过程,使用编程语言进行复现

使用selenium webdriver,本地驱动一个浏览器,完全模拟浏览器的操作(Node.js,按键精灵,QTP 工具等也可以)

建一个小型的web服务器,利用浏览器页面将js运行起来,把加密后的密文发给本地服务器

本文先尝试寻找一种后台加密的算法:

1、尝试复现该js rsa加密算法:

但是通过该加密后的密文在A平台无法通过验证,服务器返回的是System.Security.Cryptography.CryptographicException的不正确数据异常。

2、使用pyv8执行js得到密文

使用selenium的话,本文觉得比较笨重,故没考虑此法。 于是本文使用Django搭建一个小型服务器来生成密文字典:

view.py:

layout.html:

由于弱口令有60多万行,而浏览器执行的时间也不能持久,总是在执行一半的时候浏览器就显示崩溃,不知读者有什么办法让浏览器能够持久等待操作量较大的js执行完成,欢迎留言交流。

本文对这60多万行的文件分割成5份,依次执行这段js,得到一个120MB大小的密文字典。 图为生成密文后的结果:

六、愉快地进行爆破

A平台的两大难点都被解决,接下来,就可以编写代码进行自动化爆破了。

1 分析登录过程

A平台的登录过程很简单,通过burpsuite的抓包,每次登录大概就是两个数据包,第一个数据包先生成验证码,第二个数据包是提交登录的post数据,所以就模拟这两步操作就行了。

而这两个数据包中的验证码是根据cookie来关联的,cookie大概长这样

Cookie: UM_distinctid=1621eb9934f296-0f74fe8371ca48-32657b04-13c680-1621eb993521bb; ASP.NET_SessionId=ctmbshfmeefqceu0xzlyl00p; __RequestVerificationToken=iro_srRkgpI8lmqajlJCLCDRKY1_0KkPPmYggezXXCoiXAWPl-4vZiA3jIlpY9Ib6M2xI56r_MPEGt1ZILQdaqNiwHwW-NTW-nGUALwV_BQ1

也就是说,在新建一个会话请求生成验证码的时候,服务器会生成一个这样的cookie,而然后登录请求的post也会根据这个cookie来判断验证码是否生成过。

经过测试,在正确的登录顺序下,发现服务器在登录post请求返回只会返回三种:{“error”:”验证码错误”}、{“success”:”/Default.aspx”}、{“error”:”用户名或密码错误”}

如果在请求登录的时候,关联cookie的数据包没先执行第一步,即生成验证码,会返回{“error”:”验证码失效”}

2 模拟登录过程

由于cookie是验证码的关联因素,为了提高爆破效率实现多进程爆破(tensorflow使用多线程执行效率好低,具体原因不清楚,有经验的读者求分享解决方法),本文使用selenium的get_cookies()获取了10个不同会话生成的cookie,

第一步,请求生成验证码,同时返回tensorflow识别的结果:

第二步,模拟登录的post请求,获取返回的结果,而后在另外一个文件中开启10个进程执行(把密文字典分割成10份)。

至此,自动化爆破A平台的目的达到了,但是在执行过程中,可能是因为使用了tensorflow的原因,在刚开始的时候还能顺利地进行爆破,大概一两个小时后,爆破效率急剧下降,甚至停住。于是本文把执行过程中密码错误的记录写入文件,然后写了一个sh脚本(先清除执行过的记录,重新运行爆破的python脚本),命名为run.sh:

设置系统的crontab定时任务,每隔50分钟执行一次这个脚本。

七、总结

在本文所涉及到的200名员工中,60多万条记录中最终爆破出30多名员工存在弱口令问题,历时5天。可想在企业中普遍存在弱口令问题,而且A平台是对外开放的,影响极为严重。

关于这次的爆破过程,还有好多待改进的地方。tensorflow虽然识别效率高,但是随着时间的推移执行效率急剧下降,本文最终使用了一种治标不治本的方法顺利完成爆破。如果有经验的读者对tensorflow的稳定执行有所探索,还望留言交流。

参考链接:

对登录中账号密码进行加密之后再传输的爆破的思路和方式

基于TensorFlow识别Captcha库验证码图文教程

*本文原创作者:shystartree,本文属FreeBuf原创奖励计划,未经许可禁止转载

  • 发表于:
  • 原文链接:https://kuaibao.qq.com/s/20180731B1LWVK00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券