– “隐患险于明火,防范胜于救灾,责任重于泰山”
前言
本文详细介绍了针对发送短信验证码接口的安全性测试过程,包含思路、部分测试代码已经测试结果。
本次测试网站 —孔夫子旧书网(kongfz.com)
孔夫子旧书网是国内领先的古旧书交易平台,汇集全国各地13000家网上书店,50000家书摊,展示多达9000万种书籍;
一丶找到对外短信接口
从该网站注册入口可以发现,有提供发送短信验证码的服务。
二丶分析外部防御措施
-
输入手机号
-
点击发送验证码
发现需要先输入图片验证码,输入后才可点击发送
外部防御措施:图片验证码
三丶查看请求报文
1. 找到发送短信的请求
按下F12
打开浏览器控制台,再次点击发送验证码
按钮通过控制台找出发送短信的请求。
2. 查看请求方式
3. 查看请求报文头
4. 查看请求参数
captchaCode
为图片验证码的值
5. 查看返回值
四丶分析测试
1. 分析测试要点
- 请求须携带图形验证码参数
- 请求为post请求无法在地址栏直接访问测试
2. 编写代码模拟请求进行测试
该网站的图形验证码为普通的数字加字母或者简单计算题的验证码:
解决方案:通过机器学习,图像处理等方法创建识别库。
大致思路:
- 处理图片,将图片通过降噪,二值化等方式处理
- 将字符分割,学习训练
- 最终识别出图片中的各个字符
这里不做赘诉,感兴趣可以看下相关验证码识别的文章:
《使用深度学习来破解 captcha 验证码》
《验证码终结者-基于CNN+BLSTM+CTC的训练部署套件》
接着利用Java模拟报文请求 ,进行测试。部分代码如下:
//配置请求头
public Object setHeads(CloseableHttpClient httpclient, CookieStore cookieStore, Hashtable<String, String> inheads,
LinkedHashMap<String, String> outheads, Hashtable<String, String> input) {
getCookie(cookieStore, httpclient, "https://login.kongfz.com/register/index.html", inheads, outheads);
String cookieStr = GetCookieHead.CookieHashToString(outheads);
if (cookieStr != null) {
inheads.put("Cookie", cookieStr);
}
inheads.put("Host", "login.kongfz.com");
inheads.put("Accept", "application/json, text/javascript, */*; q=0.01");
inheads.put("Origin", "https://login.kongfz.com");
inheads.put("X-Requested-With", "XMLHttpRequest");
inheads.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
inheads.put("Referer", "https://login.kongfz.com/Pc/Login/iframe");
return inheads;
}
//配置请求参数
public Object setParams(CloseableHttpClient httpclient, CookieStore cookieStore, Hashtable<String, String> inheads, LinkedHashMap<String, String> outheads, Hashtable<String, String> input, String phone) {
List<BasicNameValuePair> paramList = new ArrayList<>();
paramsList.add(new BasicNameValuePair("mobile", phone));
paramsList.add(new BasicNameValuePair("captchaCode", input.get("imgCode")));
paramsList.add(new BasicNameValuePair("bizType", "2"));
return paramList;
}
//配置请求
public RetEntity reg(CloseableHttpClient httpclient, CookieStore cookieStore, Hashtable<String, String> input, String phone) {
Hashtable<String, String> inheads = new Hashtable<>();
LinkedHashMap<String, String> outheads = new LinkedHashMap<>();
String imgCode = this.getImgeCode(phone, httpclient, cookieStore, "get", imgUrl, inheads, outheads, input,
imgOutMap);
input.put("imgCode", imgCode != null ? imgCode : "");
retEntity = this.userClick(httpclient, cookieStore, "post", smsUrl, inheads, outheads, input, phone);
return retEntity;
}
启动测试:
1次:
手机号码唯一,IP唯一:
10次 --间隔时间1秒:
10次 --间隔时间60秒:
手机号码不唯一,IP唯一:
10次 --间隔时间1秒:
10次 – 间隔时间10秒:
10次 – 间隔时间20秒:
五丶结果分析
测试目标:
针对发送短信验证码接口进行安全性测试。
测试思路:
1.找到请求接口
2.分析请求报文
3.模拟请求测试
测试结果:
1.单手机号频率限制(1次/分钟)兼次数限制
2.单IP频率限制(3次/分钟)
测试结论:
前台通过图形验证码进行限制,后台手机号和Ip均有频率限制或次数限制,当遇到大量更换手机号以及IP的攻击时,该网站的所有防御措施均无效。
风险等级: 高
六丶结语
很多人在短信服务刚开始建设的阶段,可能不会在安全方面考虑太多,理由有很多。
比如:“ 需求这么赶,当然是先实现功能啊 ”,“ 业务量很小啦,系统就这么点人用,不怕的 ” , “ 我们怎么会被盯上呢,不可能的 ”等等。有一些理由虽然有道理,但是该来的总是会来的。前期欠下来的债,总是要还的。越早还,问题就越小,损失就越低。
所以大家在安全方面还是要重视。(血淋淋的栗子!)#安全短信#
谷歌图形验证码在AI 面前已经形同虚设,所以谷歌宣布退出验证码服务, 那么当所有的图形验证码都被破解时,大家又该如何做好防御呢?
>>相关阅读
《腾讯防水墙滑动拼图验证码》
《百度旋转图片验证码》
《网易易盾滑动拼图验证码》
《顶象区域面积点选验证码》
《顶象滑动拼图验证码》
《极验滑动拼图验证码》
《使用深度学习来破解 captcha 验证码》
《验证码终结者-基于CNN+BLSTM+CTC的训练部署套件》
转载:https://blog.csdn.net/weixin_44549063/article/details/114926351