Article / 文章中心

文章分类

安全测试:你的短信接口有没有这些问题,稍不留神可能损失过万?

发布时间:2021-03-08 点击数:384

– “隐患险于明火,防范胜于救灾,责任重于泰山”

 

安全问题不容忽视,不要亡羊补牢!

 

前言

本文详细介绍了针对发送短信验证码接口的安全性测试过程,包含思路、部分测试代码已经测试结果。
本次测试网站 —听云(tingyun.com)
听云是一家提供数字化运维服务的网站,给运维人元提供数字化运维后台,能为运维工作提供便利。

一丶找到对外短信接口

从该网站注册入口可以发现,有发送短信验证码的地方。
在这里插入图片描述

二丶分析外部防御措施

  1. 输入手机号
    在这里插入图片描述

  2. 点击发送验证码

发现并没有图片验证码等人机校验

外部防御措施:无

三丶查看请求报文

1. 找到发送短信的请求

按下F12打开浏览器控制台,再次点击发送验证码按钮通过控制台找出发送短信的那个请求。
在这里插入图片描述
2. 查看请求方式
在这里插入图片描述
3. 查看请求报文头
在这里插入图片描述
4. 查看请求参数
在这里插入图片描述
5. 查看返回值
在这里插入图片描述

四丶分析测试

1. 直接在浏览器测试

该请求为get请求,又无可疑参数,可直接复制到地址栏里进行访问,试一下。

在这里插入图片描述
果然可以,那么再试试直接换个手机号。
在这里插入图片描述
多刷新几次页面。

在这里插入图片描述
这时候返回了别的参数,再次更改手机号。
在这里插入图片描述

发现又返回了success,可以判断出,他们做了单手机号频率限制。

2. 用代码进行测试

利用Java模拟报文请求 ,进行测试。部分代码如下:

//配置请求头
public Object setHeads(CloseableHttpClient httpclient, CookieStore cookieStore, Hashtable<String, String> inheads, LinkedHashMap<String, String> outheads, Hashtable<String, String> input) {
		inheads.put("Accept", "application/json, text/plain, */*");
		inheads.put("Cache-Control", "no-cache");
		inheads.put("Connection", "keep-alive");
		inheads.put("Host", "account.tingyun.com");
		inheads.put("Pragma", "no-cache");
		inheads.put("Referer", "https://account.tingyun.com/reg/register?userFrom=tingyun");
		inheads.put("Sec-Fetch-Mode", "cors");
		inheads.put("Sec-Fetch-Site", "same-origin");
		inheads.put("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36");
		inheads.put("X-Tingyun-Id", "V1uX-VqWBw4;r=624124609");
		getCookie(cookieStore, httpclient, "https://account.tingyun.com/reg/register?userFrom=tingyun", inheads, outheads);
		String cookieStr = GetCookieHead.CookieHashToString(outheads);
		if (cookieStr != null) {
			inheads.put("Cookie", cookieStr);
		}
		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<>();
		paramList.add(new BasicNameValuePair("ctime", new SimpleDateFormat("'\"'yyyy-MM-dd'T'HH:mm:ss.SSS'Z\"'").format(System.currentTimeMillis())));
		paramList.add(new BasicNameValuePair("mobile", phone));
		paramList.add(new BasicNameValuePair("type", "registerNew"));
		paramList.add(new BasicNameValuePair("webc", "regweb"));
		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<>();
		httpclient = createSSLClientDefault();
		RetEntity retEntity = this.userClick(httpclient, cookieStore, "get", "https://account.tingyun.com/reg/ldaf_send_mobile_new283455", inheads, outheads, input, phone);
		closeHttpClient(httpclient);
		return retEntity;
	}

启动测试:

1-40次:{"status":"Sucess"}

>40次:{"status":"randomCountError"}
在这里插入图片描述
猜测可能是Ip限制,更换ip后再次测试。

结果为:{"status":"Sucess"}

五丶结果分析

测试目标:

针对发送短信验证码接口进行安全性测试。

测试思路:

1.找到请求接口
2.分析请求报文
3.模拟请求测试

测试结果:

1.单手机号频率限制(3次/分钟)
2.单IP次数限制(50次/天)

测试结论:

单做了手机号频率以及IP次数限制,当遇到大量更换手机号以及IP的攻击时,该网站的所有防御措施均无效。

风险等级: 

六丶结语

很多人在短信服务刚开始建设的阶段,可能不会在安全方面考虑太多,理由有很多。
比如:“ 需求这么赶,当然是先实现功能啊 ”,“ 业务量很小啦,系统就这么点人用,不怕的 ” , “ 我们怎么会被盯上呢,不可能的 ”等等。

有一些理由虽然有道理,但是该来的总是会来的。前期欠下来的债,总是要还的。越早还,问题就越小,损失就越低。

所以大家在安全方面还是要重视。(血淋淋的栗子!)#安全短信#