大数跨境

【技术专栏】javascript审计分析案例

【技术专栏】javascript审计分析案例 君立华域
2022-05-19
1
导读:01前言平常我们做渗透测试项目过程中,经常会遇到客户提供的一些网络资产,如网站这类的,我们需要对这些资产做一


01

前言


平常我们做渗透测试项目过程中,经常会遇到客户提供的一些网络资产,如网站这类的,我们需要对这些资产做一系列的渗透测试,而这类资产通常可能就是一个网站地址,一个IP地址,APP下载,那么在网站前端,很多都是一些后台页面,或者空白页面,这时候就需要我们去通过一些现成的扫描工具,使用漏洞挖掘的方法去突破,找到网站的薄弱环节,完成工作任务,那么常见的漏洞挖掘失败之后,我们还可以使用哪些思路呢,今天我们就带来一篇关于前端函数javascript的审计分析案例。


02

技巧


1.审计前端javascript的一些技巧


这里如何去注意技巧,首先是查看源代码,看到很多函数,先理解一下整个函数过程,然后再去对函数之间的关系进行梳理。


2.审计哪些函数可以被调用,哪些不能被调用


可以调用的函数是指当前前端在用户功能上相对应的函数,这里需要注意是功能函数的实现方法,不能被调用的是指函数之间的参数引用多处,有的函数在APP端,那么在网站端接口,如果进行调用,那么意义不大,就像做白盒代码审计,去回溯静态跟踪,你可能也会忽略掉对APP端的代码审计,也不去考虑后台的函数漏洞,只会考虑前端的白盒代码审计。


这里就好比是3扇门,第一扇门是登陆的函数,而有时候我们需要去利用的第二扇门的钥匙,在第一扇门触发,最终才能打开第三扇门,而第一扇门是有验证的,那么不确保第二扇门一定有验证,所以这就造成了漏洞。


3.函数与参数之间的逻辑关系


这里就是两者之间的引用关系,函数对应的参数指向了多处,那么在很多函数会有一系列的逻辑判断,判断用户是否正常去触发这些功能函数,就好比一个用户按照正常逻辑,输入用户和密码,还有验证码,然后点击登陆,就进入后台,就是这样一个方法,我们可以把用户这一系列的操作方法理解为一个动作,如果用户是明文,那么长时间的网页交互,可能会造成什么漏洞呢,那么很明显,可能就会造成COOKIE记忆漏洞(案例4)


4.全文通读代码和单函数通读代码的区别


全文通读是指理解整个前端的函数代码,然后进行分析这是耗时比较长的,但是能够把整个前端可能出现的问题进行分析并利用,单函数,就是只是对某个前端的函数进行分析那么效果就是也可以利用,但是你没有理解函数对应的参数与其他的关系,那么这样做效果是不好的。


03

案例演示


案例1:


某网站系统函数可被随意调用,由于前端代码没正确判断用户密码是否正确,导致函数可被随意绕过,函数被随意调用,可能导致系统某些功能被绕过


首先是登陆函数



在这里可以看到,登陆的函数是onLoginComplete,点击登录按钮完成事件,这里是有个判断,我们不能使用默认错误,来调用函数,这里会涉及校检密码


document.getElementById("loginForm:loginName").focus();    document.getElementById("loginForm:password").value = "";    if(dealFlag=="1"){        var framePage=document.getElementById("loginForm:framePage").value;        if("Y"==framePage){            document.location.href = "/index.do";        }else//即便这里是正确的if(dealFlag=="1"){    var framePage=document.getElementById("loginForm:framePage").value;    if("Y"==framePage){        document.location.href = "/index.do";    }else    //但是我们因为密码没过a4j的校检,所以会失败


分析了他的判断逻辑我们发现只有4和10#是可以直接调用二次处理的,我们就可以使用4来试试


if(dealFlag.indexOf("10#") != -1){


//新用户第一次登录,强制进入修改密码页面

              

if(dealFlag=="4"){ //alert("您是新用户,第一次登录需要修改密码!");$.messager.alert("登录提示","您是新用户,第一次登录需要修改密码!","info",function(){


注意4,我们看看是否有其他扩展


function smsValCode(val) {function completeSMS(data){if(data=="0"){


这里也不能直接调用,因为我们的用户名和密码都是错误的,所以只能到验证的地方

 //短信登录验证function smsLoginValidate(){


这里好像可以调用

那么就是CTRL+SHIFT+C,打开代码检测器,注意这里



换成4后点击提交



function smsLoginComplete(dealFlag){//短信登录验证function smsLoginValidate()


这里不能直接调用,因为未校检,只有找到一个可以利用的二次参数框架调用


function singleLogincomplete(){


我们发现 singleLogincomplete(){

函数可以调用

那么注意这里,有一个按钮

我们调试的时候就发现debug了



那么直接就是javascript:singleLogincomplete()

点击提交



点击存储->然后burp开代理

我们目的就是让他跳到singleLogincomplete函数的代码段,而不是直接跳到主页

点击确定singleLogincomplete函数的参数就会带进去


AJAXREQUEST=_viewRoot&j_id22=j_id22&javax.faces.ViewState=j_id8&j_id22%3Aj_id23=j_id22%3Aj_id23&


然后接受response!

自动会跳到


/baf/jsp/uiframe/modifyPassword.xhtml?userId=&loginName=wangwei


证明函数是利用成功的


c1K5tW0w6_=rVbj6Fv.BXyGLDEvsa_eEEJJApKx3uKR0iZczaKlFhQ5_9gA78nj9bASRAKKn0MV


id="org.ajax4jsf.oncomplete">alert('您的密码为弱密码,请修改后再登录!'); document.location.href = '/baf/jsp/uiframe/modifyPassword.xhtml?userId='+document.getElementById('loginForm:userId').value;


点击form就会弹出


您的密码为弱密码,请修改后再登录!


证明已经成功绕过了他的功能,前端并没有正确校检用户和密码,我们发现还有一个send()函数是取用户验证的。那么loginname参数可能会带入到用户库进行查询

那么还可以直接引用send()函数,思路是弹出错误信息,直接调用,点击确定将会调用send()函数的代码。


AJAXREQUEST=_viewRoot&j_id24=j_id24&autoScroll=&javax.faces.ViewState=j_id14&lname=wangwei&j_id24%3Aj_id25=j_id24%3Aj_id25&


然后接收response

我们注意观察send()函数的代码









我们注意观察send()函数的代码

看到completeSend就知道了,证明这一步功能被成功绕过,而默认是onLoginComplete函数


案例2


超级管理员密码信息泄露漏洞(通用型漏洞)


漏洞成因:因为前端 javascript函数可被调用,通过函数调用能够一键读取超级管理员的密码,以及查询到用户,导致信息泄漏漏洞。



看到这里,看到两个函数


getLoginSecret()


另外一个


queryCompanyList()


event就是用户输入的事件,这里感觉无法调用changeQrCode()  扫码的函数, APP端uuidFun1()checkUser() 取用户的,这个跟queryCompanyList()函数应该差不多forwardUpdatePassword()这个函数已经直接调用了,我们不用管那么多我们回到getLoginSecret()函数注意这里:


查询用户的密码加密key->这里管理员声明是查询用户的密码加密key ->那么看他的提交方式默认变量loginSecret为空url : "


/user/goLoginSecretcontentType : application / json ",         type : "post ",         async : false,         data : JSON.stringify({            otherAccount: $("# account ").val(),            account: $("# accountOnly ").val()         }),         success : function(data) {            console.log(data)            loginSecret = data.data;         }       });      return loginSecret;JSON去传了otherAccount参数contentType : "application / json ",         type : "post ",         async : false,         data : JSON.stringify({            otherAccount:$("# account ").val()         }),


那么如果这里可以被利用的话,这是查询用户的我在想是管理员故意留的后门,还是没注意,以为这种方式很安全,这么想恰恰错了我们注意是queryCompanyList()函数触发的我们为了验证这个函数的有效性,就需要找一个可以调用的函数,来触发


这里需要注意;onclick是触发事件,那么除了onclick我们还可以怎么用呢,那就是观察href:引用javascript:void();,分析他包含的 href指向哪里,或者input id=:

先看看登陆这里,没什么利用点这里有一个忘记密码




注意onclick这里默认是调用的forwardUpdatePassword()函数我们可以修改一下,让他触发到queryCompanyList()函数,然后截取数据包如果成功利用,queryCompanyList()函数的参数将会被带入,果然参数被触发了触发到了otherAccount参数这时候,我们来查询一下用户,输入admin




证明存在这个用户


那么我们再看另外一个函数getLoginSecret()这是查询base64密码的如果被成功调用,那么就可以查询到用户密码了接着把函数改成getLoginSecret(),果然被带入了两个json参数{"otherAccount":"","account":""}我们在这里输入admin



{"data":"2Zsh8NMP9wwmgOpXs8vkWg==","code":0}


返回结果得出结论用户:admin

Base64密码:2Zsh8NMP9wwmgOpXs8vkWg==

然后我们知道了这个漏洞,那么就编写一个EXP来实现这个过程



我们还通过base64 解密

放入密文

然后直接输入命令

base64 --decode base64.b64 base64.tmp

然后使用二进制打开密文



二进制结果为:D99B21F0D30FF70C2680EA57B3CBE45A


案例3


如何在巧妙运用在超链接#兼容性模式,调出函数完成漏洞利用编写EXP(某网站系统)



这里相当于通过实例object对象,调用data并获取了当前用户的email邮箱,其中判断变量的rmail当前是否是email,如果是,则发送该邮件,但是我们没有发现对rmail进行具体用户的实例判断,这样一来,我们可以看到是json格式的,取用户的json对象,那么我们可以这样认为,那么如果是其他邮件,但是只要用户的参数是对的,他是否能绕过呢,为了判断这个可能性,我们来尝试绕过,但是如何绕过

我们仔细观察了一下代码

我们注意这里:


/forgotpassword


这里好像是重置密码的点

我们在源代码分析中,发现一个问题


 type: "post",                 url: '/forgotpassword', function showlayer() { function showlayer() {     //必须输入字符,切正确后,才能弹出该框


也就是输入正确,才能弹出

但是默认这里没有弹出的窗口,那我们不知道密码的情况下,如何弹出调用窗口,我们先试试,输入错误的密码,进行截包


我们想办法调用出这个窗口,或许就能发现问题

证明,弹窗失败

那么我们如何,能让弹窗实现呢

我们看了看界面,发现除了一个登陆,先检查一下元素



验证码这里


为了提高系统的使用性能,请尽量使用谷歌浏览器。若使用IE浏览器,请设置成兼容模式


注意这个兼容模式

我们注意这里onclick=show,貌似可以利用的感觉


我们这里需要用到一个技巧,但是技巧的前提是,如果他当前系统验证了用户的密码,那么可能会失败,没有没有检查用户密码,可能就会成功。


我们再看看漏洞的代码是什么


function showlayer() {     //必须输入字符,切正确后,才能弹出该框


注意这里,我们如果不把他弹出来,就不能进行后续的代码


我们利用的点就在这里,我们可以使用onclick事件来试试


测试方法:先从XSS开始


onclick="showWin();"


把他修改成:onclick=javascript:alert(“1”);

点击存储,看是否能否执行1

那我们是否能调用function 声明的showlayer函数

只有成功调用他,才能够让代码继续走下去

我们试试,把onclick=javascript:alert(“1”); ,弹出了111,那么证明可以调用

那么我们需要把代码改成

onclick=javascript:showlayer();

触发



我们先进行用户,密码输入,然后点击兼容模式

到这里,我们发现我们成功showlayer函数调用出来了



然后通过该漏洞,成功编写一个EXP,实现过程



拿到了加密的KEY


KEY=connect=NzcwYzlmY2VmYjliNmI0YWZhN2FiOTM2YjA3NDgxNGVfMTY0MzQ2MjkyMDEwOQ==


最后成功利用该漏洞进入管理系统


04

总结



常见的漏洞挖完了,没发现问题,不妨分析一下函数,或许能够事半功倍前端函数分析是一个周期的过程,不是理解单函数就可以突破的,网页如果存在过多函数就需要一一分析,最终目的是突破网站薄弱环节...





END





注:本文作者为君立华域渗透测试专家组负责人喻青


【声明】内容源于网络
0
0
君立华域
【无安全,不低空】低空&信息安全产品、服务提供商。7*24h hotline:400-860-5109
内容 136
粉丝 0
君立华域 【无安全,不低空】低空&信息安全产品、服务提供商。7*24h hotline:400-860-5109
总阅读83
粉丝0
内容136