大数据安全入门js部分习题试炼

学习目标

今天给大家带来2道我们内部靶场的题目,题目难度适中,主题是js代码在浏览器中能够运行,而到了nodejs中会面临各种各样的环境监测,我们如何能通过补环境的方式来绕过这些检测,让抄来的js代码跑起来,本体通过学员的角度进行讲解,顺便把坑也踩了一遍(蓝师傅yyds)

题目 内部靶场第二题

1 特征观察

先进入题目发现,只有一个按钮和设备指纹检测的提示字段如下图

点击一下查看有什么反应如下图

发现弹框了,并提示环境检测通过,那么这道题蓝师傅想考察的就是如何在nodejs中模拟浏览器环境。之后打开开发者模式查看一下网络请求如下图

发现浏览器发送了一条参数为data和sign的post请求,data和sign都为加密状态无法识别是什么,其中data一四base64,解密一下data如下图,发现base64解密为乱码,所以不是常规base64.

观察sign长度如下图为32,那么猜测sign是否为md5(先保留疑问,不做验证)

观察调用栈如下图,发现除了vue框架代码还有一个fingerprintob.js,就是发包代码

2 js分析

跟进去看一下如下图,简直一坨没法正常观察

打个断点,看一下js代码的解密状态,发现是XMLHttpRequest对象的实例调用的send方法

查看一下send函数的参数是什么,直接在控制台中打印

('data=' + encodeURIComponent(_0x392f2d) + _0x369354(0xbe) + _0xd9e63f)

结果如下图,发现就是post请求的参数data和sign

浏览器中没法回溯参数,所以蓝师傅教我们将代码复制到ptcharm中进行参数回溯,按ctrl+鼠标左键,找到了这里,再生成断点

在控制台中打印这两个函数,发现就是我们要找的答案

这时候就可以跟进去这个函数看一下它的具体逻辑(是不是很简单,so easy),在控制台中输入函数名称双击进去,可以看见这个函数在套娃恶心人,5555哭了

3 模拟执行

这里蓝师傅领我们回顾了一下之前第一节课的内容,代码太恶心,就可以放到pycharm里面模拟跑一下,发现直接可以跑起来 开心的一笔

后来发现自己sb了,没调用request函数…,果然报错了

开始补环境,第一步生成window,然后把上节课的代理器导v入如下图


运行,继续报错

然后就是漫长的补环境阶段
先补XMLHttpRequest,然后运行,发现报错navigator未定义,继续补navigator,并且导入拦截器
1.js

let mywindow={
    
    
XMLHttpRequest:function (){
    
    }
}

let mynavigator={
    
    

}
const navigator=new Proxy(Object.create(mynavigato),getObjhandle("navigator"))
module.exports = {
    
    
    window,navigator

}

work.js

let {
    
     window,navigator} = require('./1.js');

然后运行,发现报错screen未定义,继续补screen,并且导入拦截器

let myscreen={
    
    

}
const screen=new Proxy(Object.create(myscreen),getObjhandle("screen"))
module.exports = {
    
    
    window,screen,navigator

}

work.js

let {
    
     window,screen,navigator} = require('./1.js');

接着报错未找到方法如下图,这时候我就困惑了,这个怎么会找不到方法,接着根据,报错回溯,发现是request的最下面的的三个函数报错,找到浏览器中查看一下,发现是三个发包函数,蓝师傅说发包函数对我们做分析的来说没啥用,可以删掉,我们只需要打印参数即可。


删掉

    _0xd532a8[_0x369354('0xbb')](_0x369354(0x9d), '/checkfing' + _0x369354(0xb9), !![]),
    _0xd532a8[_0x369354(0x97) + _0x369354(0x93)](_0x369354('0xb4') + 'pe', _0x369354('0xb5') + _0x369354(0xad) + _0x369354(0xa0) + _0x369354('0xbc')),
    _0xd532a8[_0x369354(0xc5)]('data=' + encodeURIComponent(_0x392f2d) + _0x369354(0xbe) + _0xd9e63f);

增加

   console.log(encodeURIComponent(_0x392f2d)),
    console.log(_0xd9e63f);

继续运行发现结果出来了,兴高采烈的去试一下,看看能不能过检测

右击请求包,右键copy->copy as curl(bash),就会复制到下面这一段

curl 'Method Not Allowed' \
  -H 'Connection: keep-alive' \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36' \
  -H 'Content-type: application/x-www-form-urlencoded' \
  -H 'Accept: */*' \
  -H 'Origin: 404 Not Found' \
  -H 'Referer: FingerprintJS' \
  -H 'Accept-Language: en-US,en;q=0.9' \
  -H 'Cookie: access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MjkyNTE5MDMsIm5iZiI6MTYyOTI1MTkwMywianRpIjoiYjJiNTdjZjQtNmM0Ni00NTNkLThkM2EtZDNjY2IwN2U5NmQxIiwiZXhwIjoxNjI5MjU1NTAzLCJpZGVudGl0eSI6eyJ1aWQiOjQ1LCJzY29wZSI6ImxpbiJ9LCJmcmVzaCI6ZmFsc2UsInR5cGUiOiJhY2Nlc3MiLCJ1c2VyX2NsYWltcyI6eyJ1aWQiOjQ1LCJzY29wZSI6ImxpbiIsInJlbW90ZV9hZGRyIjpudWxsfX0.CAnZ_Wu8VdX0rO7oiQ2kV-ypPc4BIeQHeg_43AgFKcU; refresh_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MjkyNTE5MDMsIm5iZiI6MTYyOTI1MTkwMywianRpIjoiNzlkYWI0MDQtODkzZS00MWEwLWE4YzktZjMzZjg4OWQ2YjM5IiwiZXhwIjoxNjMxODQzOTAzLCJpZGVudGl0eSI6eyJ1aWQiOjQ1LCJzY29wZSI6ImxpbiJ9LCJ0eXBlIjoicmVmcmVzaCJ9.-o5jGkDi0fdpIm0vVXs4korUv5a32LtDL37ASPkEqVM' \
  --data-raw 'data=R6bq%2B6Mofhg9sLXriu4xkAT04dIrRc8rIRXpIjoraVbDZL8xn3u2W1McaNaEhNcVsw%2FwZt5wZEXShVC%2FR%2F2on1Mx%2BN%2FrTNaL%2BNgxn3ZSWAbQOhg7IE52sL89IR%2FpIRIMnuZCOAut%2Bhg9IwWpIwfLntIdILm5IRn5IPrtZYILntVVUjXLntZVWzacntIL4Pv9OhILnNOCkPZcntILOAuoWN%2FLntZAf6MwOhILnNOCkPZcntILOAuoWN%2FLntZAf6MwOhILnNOCkPZcntIL4Pv9OhILnVZSWAbQOhm8T3fr%2F1M9ONcpULx8kdvVf6voOhm3kNZ9k6ap4Ym1kdvQfD8qUAu2W1MxfNuV%2B6bpsdrQONb0ONMcs6ZSWAbQOh92O1OKW1TAUVZSWAbQOhm8T3fraAcc4NatULSqUAu2W1MxfNuV%2B6bpsdmyOz72O1fGRAuV%2BDOcn3Zo%2B6ap4jSqULxCWPmo%2B6ZC41c0kEb5s67CfNMKs1u2W1MxfNuV%2B6bpsdrQW17CfNMK&sign=0e7586abb2c960c1a32463d5de54bb42' \
  --compressed \
  --insecure

然后进入网站 Convert curl command syntax to Python requests, Ansible URI, browser fetch, MATLAB, Node.js, R, PHP, Strest, Go, Dart, Java, JSON, Elixir, and Rust code 直接把复制的内容粘贴到左面,复制右面的内容到pycharm的新建项目中

运行如下图

说明我们走对了路,接下来就是过检测
首先是谷歌浏览器,看一下之前的代理器拦截到了什么

UA那我们就补一个UA

let mynavigator={
    
    
    userAgent:"\"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36\""
}

运行一下 看一下

可见没有过,而且这会连个提示都没有气死,只能慢慢看自己hook的内容了

可以看到screen和window有很多次调用,先补一下screen,直接把浏览器中screen打印出来如下面

availHeight: 690
availLeft: 0
availTop: 0
availWidth: 1280
colorDepth: 24
height: 720
orientation: ScreenOrientation {
    
    angle: 0, type: "landscape-primary", onchange: null}
pixelDepth: 24
width: 1280
[[Prototype]]: Screen

然后复制进1.js里面

let myscreen={
    
    
    availHeight: 690
,availLeft: 0
,availTop: 0
,availWidth: 1280
,colorDepth: 24
,height: 720
,pixelDepth: 24
,width: 1280
}

再次运行,还是过不了,考虑补一下window,看一看都用到了哪些,发现有很多监控原型链,就在代理器下面使用

把window这些都补一下,可以看到通过了getOwnPropertyDescriptor查看属性是原型链上的方法还是自身的方法,所以new代理器的时候使用Object.create(mynavigator)来进行一层继承,躲过检测

let mywindow={
    
    
XMLHttpRequest:function (){
    
    },
    sessionStorage:{
    
    length: 0},
    localStorage:{
    
    length: 0}

}
let mynavigator={
    
    
    userAgent:"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36"
,appCodeName:"Mozilla"
    ,language:"en-US"
    ,platform:"Win32"
}
const navigator=new Proxy(Object.create(mynavigator),getObjhandle("navigator"))

进阶习题

题目 运行课件中给出的一段js代码,输出正确的结果

先用第一题中给出的1.js补的环境跑一下试一下,写在脚本的开头

let {
    
     window,screen,navigator } = require('./1.js');


依旧报错补一下,window.navigator

let mywindow={
    
    
XMLHttpRequest:function (){
    
    },
    sessionStorage:{
    
    length: 0},
    localStorage:{
    
    length: 0},
    navigator:mynavigator


}

然后运行一下发现卡住了如下图

蓝师傅说eval很难调试所以把代码格式化一下,把eval去掉,直接将t1000换成debug中调试出来的t1000Source函数,然后格式化,最后补一下环境,将webdriver和scrollTo补成和浏览器一模一样的

let mywindow={
    
    
XMLHttpRequest:function (){
    
    },
    sessionStorage:{
    
    length: 0},
    localStorage:{
    
    length: 0},
    navigator:mynavigator,
    scrollTo:function(){
    
    }

}
let mynavigator={
    
    
    userAgent:"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36"
,appCodeName:"Mozilla"
    ,language:"en-US"
    ,platform:"Win32"
    ,webdriver:false
}

可以看到过了反调试检测,不会再卡住了,但是报错,然后最后报了一个错缺少location

先把他们都补上,但是有些我找不到他们的网站没法补,就先把location补上,最后报错出现了indexOf函数,那就是说明这段代码用了大量大indexOf来匹配字符串,所以我们可以重写indexOf来监控他匹配了那些字符串

let st=String.prototype.indexOf;
String.prototype.indexOf=function (cc){
    
    
    console.log(cc)
    return st(cc)
}
let mylocation={
    
    
    cestorOrigins: {
    
    length: 0}
,hash: ""
,host: "new-tab-page"
,hostname: "new-tab-page"
,href: "chrome://new-tab-page/"
,origin: "chrome://new-tab-page"
,pathname: "/"
,port: ""
,protocol: "chrome:"
,reload: function (){
    
    }
,replace:function(){
    
    }
,search: ""

}


补完之后发现又卡住了,真…,这会只能用蓝师傅的debug然后在暂停的方式,来看看到底是哪里的问题。

暂停之后看一下调用栈发现一处判断将其直接改成false(!_0x2f5962的反义)
然后直接运行发现报错,气死我了提示方法未定义,试了好久都没有进展,最后将格式化之前的代码直接使用,然后再补一下document发现终于出来数据了,最后补的环境如下,虽然报错但是已经有数据了

var st=String.prototype.indexOf;
String.prototype.indexOf=function (cc){
    
    
    console.log(cc)
    return st.call(this,cc)
}
let mylocation={
    
    
    cestorOrigins: {
    
    length: 0}
,hash: ""
,host: "***.com"
,hostname: "new-tab-page"
,href: "chrome://new-tab-page/"
,origin: "chrome://new-tab-page"
,pathname: "/interdetailflightdetailinterlistflight_touch_react"
,port: ""
,protocol: "chrome:"
,reload: function (){
    
    }
,replace:function(){
    
    }
,search: ""


}
let mynavigator={
    
    
    userAgent:"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36"
,appCodeName:"Mozilla"
    ,language:"en-US"
    ,platform:"Win32"
    ,webdriver:false
}
let mywindow={
    
    
XMLHttpRequest:function (){
    
    },
    sessionStorage:{
    
    length: 0},
    localStorage:{
    
    length: 0},
    navigator:mynavigator
    ,scrollTo:function (){
    
    }
    ,location:mylocation
}
let myscreen={
    
    
    availHeight: 690
,availLeft: 0
,availTop: 0
,availWidth: 1280
,colorDepth: 24
,height: 720
,pixelDepth: 24
,width: 1280
}

var Image=function (){
    
    }
let mydocument={
    
    createElement:function (img){
    
    return img},
getElementsByTagName:function (a){
    
    return {
    
    }}}

function getObjhandle(Watchname){
    
    
  let handle={
    
    
  get(target, p, receiver) {
    
    
    let res=Reflect.get(target, p, receiver);
        if (res instanceof Object) {
    
    
                if (typeof res === "function") {
    
    
                    console.log(`get [${
      
      Watchname}] [${
      
      p}] `)
                } else {
    
    
                    console.log(`get [${
      
      Watchname}] [${
      
      p}]  [${
      
      JSON.stringify(res)}]`);
                }
                return new Proxy(res, getObjhandle(`${
      
      Watchname}.${
      
      p}`))
            }
    console.log(`get ${
      
      Watchname} ${
      
      p} ${
      
      res}`)
    return res
  }
  ,set(target, p, value, receiver) {
    
    
    let res=Reflect.set(target, p, value, receiver);
    console.log(` set ${
      
      Watchname} ${
      
      p} ${
      
      value}`)
    return res;
  },
     has(target, p) {
    
    
    let res=Reflect.has(target,p)
    console.log(`has ${
      
      Watchname}  ${
      
      p}`)
    return res
  },deleteProperty(target, p) {
    
    
     let res=Reflect.deleteProperty(target,p)
    console.log(`delete ${
      
      Watchname} ${
      
      p}`)
    return res
  }, getOwnPropertyDescriptor(target, p) {
    
    
       let res=Reflect.getOwnPropertyDescriptor(target,p)
    console.log(`getOwnPropertyDescriptor ${
      
      Watchname} ${
      
      p} ${
      
      JSON.stringify(res)}`)
    return res
  }, defineProperty(target, p, attributes) {
    
    
  let res=Reflect.deleteProperty(target, p, attributes)
   console.log(` defineProperty ${
      
      Watchname} ${
      
      p} ${
      
      attributes} ${
      
      res}`)
   return res;
  }, defineProperty(target, p, attributes) {
    
    
  let res=Reflect.deleteProperty(target, p, attributes)
   console.log(` defineProperty ${
      
      Watchname} ${
      
      p} ${
      
      JSON.stringify(attributes)}`)
   return res;
  },preventExtensions(target) {
    
    
   console.log(`preventExtensions ${
      
      Watchname} `)
   return Reflect.preventExtensions(target)
  },isExtensible(target) {
    
    
   let res=Reflect.isExtensible(target)
  console.log(`isExtensible ${
      
      Watchname} ${
      
      res}`)
    return res;
  },getPrototypeOf(target) {
    
    
      let res=Reflect.getPrototypeOf(target)
  console.log(`getPrototypeOf ${
      
      Watchname} ${
      
      JSON.stringify(res)}`)
    return res;
  },ownKeys(target) {
    
    
            var result = Reflect.ownKeys(target)
            console.log(`ownKeys [${
      
      Watchname}] [${
      
      JSON.stringify(result)}]`)
            return result
        }
      ,setPrototypeOf(target, v) {
    
    
      let res=Reflect.setPrototypeOf(target,v)

  console.log(`setPrototypeOf ${
      
      Watchname} ${
      
      JSON.stringify(v)}`)
    return res;
  },       apply(target, thisArg, argArray) {
    
    
            let result = Reflect.apply(target, thisArg, argArray)
            console.log(`[${
      
      Watchname}] apply function name is [${
      
      target.name -}], argArray is [${
      
      argArray}], result is [${
      
      result}].`)
            return result
        },
        construct(target, argArray, newTarget) {
    
    
            var result = Reflect.construct(target, argArray, newTarget)
            console.log(`[${
      
      Watchname}] construct function name is [${
      
      target.name -}], argArray is [${
      
      argArray}], result is [${
      
      JSON.stringify(result)}].`)
            return result;
        }



}

  return handle;
}

const window=new Proxy(Object.assign(global,mywindow),getObjhandle("window"))
const screen=new Proxy(Object.create(myscreen),getObjhandle("screen"))
const navigator=new Proxy(Object.create(mynavigator),getObjhandle("navigator"))
const location=new Proxy(Object.create(mylocation),getObjhandle("location"))
const document=new Proxy(Object.create(mydocument),getObjhandle("document"))

module.exports = {
    
    
    window,screen,navigator,location,Image,document

}


最后大家欢迎一起学习,可以加微信:r0ysue 共同进步

猜你喜欢

转载自blog.csdn.net/u010559109/article/details/120059922