Javascript函数审计分析进阶版案例-二次函数绕过使用功能/间接跳过函数校检
Javascript函数审计分析进阶版案例-二次函数绕过使用功能/间接跳过函数校检
漏洞成因:
由于前端BindUpdateUserClickEvent()函数代码段存在问题,导致二次函数绕过,
默认的AntiForgery也许是隐患
我们在分析JS函数的时候,需要注重全文通读,因为你只要通读了他的整个过程,代码事件
你才知道如何去利用薄弱环节,漏洞点,完成漏洞复现
案例1:间接跳过函数强校检
打开源代码进行分析
首先分析了一下函数
我们简单分析了一下
var regex = new RegExp('(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[^a-zA-Z0-9]).{8,30}');
可以看到,这里取了一个正则
if (regex.test(Pwd) != true) { // alert("你设置密码太简单,至少要包括大小写字母、数字、特殊字符,需要重新设置密码!"); var temp = data.substring(3); //alert(temp); $("#ID").val(temp);
这里有有一个输入的判断
我们先来梳理一下登陆流程
首先是SmsSubmitLogin登陆函数,接着判断密码的复杂度
如果密码简单,则触发到BindGroupSelectButtonClickEvent
函数
强制修改密码,才能够登陆
然后这里有一个函数
BindUpdateUserClickEvent()
这个函数,相当于第二层验证,他这里,
/首先判断前台的验证是否通过 var valid = $('#UpdateUserInfo').form('validate'); if (valid == false) { return false;
有一个前台的验证,验证通过的UpdateUserInfo才能生效跳到下一步
也就是说不能通过前台的验证,则不能通过这一步
而/UName1,Pwd1,PwdOK1,Phone1,Mail1
则是构造的所需参数
//设置CSRF的AntiForgery的验证 if (postData != null) { postData.__RequestVerificationToken = $("input[name='__RequestVerificationToken']").val(); } else { postData = new Object; postData.__RequestVerificationToken = $("input[name='__RequestVerificationToken']").val(); }
这里有CSRF的AntiForgery验证
最后通过异步修改用户的密码
我们来到这里,前后对比一下
这里不就是前台取验证的吗
那么我们继续看
第一个函数是
BindGroupSelectButtonClickEvent
点击后,则触发修改密码
那么这个函数在
BindGroupSelectButtonClickEvent
在这里意义是什么呢
很明显了,他调用了
前面是调用这个函数
后面这个是具体调用的功能验证
可以看到这里 window.location.href = "/Home/Index";
他调到home/index,就是验证通过的意思了
那么在这里,
else { alert(data); window.location.href = "/Login/Index/"; }
否则跳转到首页
我们先来尝试一遍
触发了登陆函数
随便提交错误数据
验证码没对,重新填入
这里提示用户密码错误,点击,就不能继续了
没通过验证
那么我们先来尝试一下修改密码的函数,我们是否能通过函数直接绕过他
按照思路,应该是直接选调这个函数
把void 改成修改的函数
注意,这是登陆的函数
那么修改的函数,点击确定后
关键他这个函数调用,执行一次,这时候需要截取数据包,因为他是强验证,所以他会跳转到首页
这时候我们发点击确定的时候,自动跳出来一个窗口,证明函数调用成功,现ID是没有给值的,因为这里没有取到
//var val = sessionStorage.getItem("UserInfo");
所以ID是空
我们就简单填入
50asddzssda*)&
密码:50asddzssda*)&
50asddzssda*)18
这里我们说了
不能直接调用BindUpdateUserClickEvent()
函数
因为有前台验证
那我们来尝试
调用修改函数之后,再调用BindUpdateUserClickEvent()
函数,来试试
我们可以发现这里,我们需要再次把BindUpdateUserClickEvent()
写入
点击确定就会flase
flase是调到哪里呢?
那么没过前台验证嘛,所以直接flase
流程我们清楚了,那么我们回到前台验证代码段
注意这里
这是前台的验证阶段
那么这个函数我们能否调用呢
BindGroupSelectButtonClickEvent()
那么这个函数,可以理解成什么呢
他间接了逃过了这个函数BindUpdateUserClickEvent()的校检
我们来试试,通过修改函数,换成
BindUpdateUserClickEvent()
看是否能逃到这一步
我们首先还是触发修改函数
接着把密码填入
这里需要注意,修改成 BindGroupSelectButtonClickEvent()函数,
而不是
BindUpdateUserClickEvent()
我们这样做的目的,就是要看一看,是否真的能够通过BindGroupSelectButtonClickEvent()函数
间接逃过BindUpdateUserClickEvent()
的强校检
如果能逃过,那么就会直接带入到
当我们点了两次,第一次,触发错误的登陆函数信息,也就是这里
接着触发了BindGroupSelectButtonClickEvent()函数,点击确定
之后发现是过了
到了
这里
那证明我们利用函数逃过了BindUpdateUserClickEvent()
函数强校检
==================================================
案例2:二次函数绕过使用功能
我们来看看其他的函数
注意这里,有一个函数
ShowSmsPhoneDialog()
这里提示输入手机号码
还有一个函数ShowSmsVerifyDialog()
这里提示手机号码输入判断
我们先看看能不能直接调用ShowSmsVerifyDialog()
函数
可以调用
那么我们就把用户名写成手机号码,1358888888
我们注意
默认是用户密码错误
我们现在做的就是函数调用他的原始功能
怎么调呢
首先
我们把用户名换成手机号了
换成13188888888
默认是用户密码错误
我们现在做的就是函数调用他的原始功能
怎么调呢
首先
我们把用户名换成手机号了
换成13188888888
我们发现直接调是有误区的,为啥呢,直接调的话,手机号码参数就不对啊
怎么输入都是手机号码错误,弹回flase
虽然调了函数,但是用户名参数始终还是uname
没有变成Phone_NO嘛,所以他才会报错
也就证明不能直接调用,因为我们不可能让uname变成Phone_NO
那么我们先看看流程
我们发现其实ShowSmsVerifyDialog()函数和ShowSmsPhoneDialog()
是有依赖的,什么依赖呢,它们两个函数代表了一个流程
怎么走
比如说ShowSmsPhoneDialog()
可以理解成输入用户的手机号码:1388888888
接着,触发到ShowSmsVerifyDialog(),进行发送验证码
是这么一个流程
那么我们既然知道了流程,就先调用ShowSmsPhoneDialog()
当我们点击确定的时候,发现直接把ShowSmsPhoneDialog()
函数的功能成功调取出来了,接着我们看看验证码这里,我们发现是void
这里是走不了下一步的,所以,我们得二次再去填入一个ShowSmsPhoneDialog()
让他走下去
这里我们试试
修改函数
我们这样做的目的就是让ShowSmsVerifyDialog()函数生效
重放一下
再重放一次
我们到这里可以发现&Phone_NO起作用了
成功带入了Phone_NO参数,也就是说流程是触发到ShowSmsVerifyDialog()函数
我们注意这里
__RequestVerificationToken=ywC7UQ3uABD6IG0NJBlu66AHA0xmoOEqIZPDzOcCQjE2hG1YzJOi3IV6bFPhweS3bxmGAAF7oxoGpVsiSc_K2_9tiuPzeyFSiGnaH3p5fxs1
这里是一个验证token
我们把它去掉后看看效果
变成302状态了
原因是啥呢
这是一个重定向,代表对象被移动
所以还是需要__RequestVerificationToken
我们加入它
点击执行
我们发现功能就可以使用了
正确判断了
二次函数利用成功
<< 上一篇
下一篇 >>