大数据安全入门试炼2

习题牛刀小试: 找出Flag


可见提示是 hook eval 那我们就试一下,那我们就用油猴脚本hook一下

var _eval=eval;
eval=function (){
    
    
    console.log(arguments)
    return _eval(arguments)
    
}


报了一个错,不能在严格模式下运行这个脚本,那么我们就取消严格模式,并且在一开始就hook他的eval函数


出现了一个假答案,额…(哼恶趣味),输入假答案看看是啥

额过分还有检测,那就上绝招,用代理器hook一下eval函数

eval = new Proxy(eval,{
    
    
 apply(target, thisArg, argArray) {
    
    
  let result = Reflect.apply(target, thisArg, argArray)
  console.log(`function name is ${
      
      target.name}, thisArg is ${
      
      thisArg}, argArray is [${
      
      argArray}], result is ${
      
      result}.`)
  return result
 },
 construct(target, argArray, newTarget) {
    
    
  var result = Reflect.construct(target, argArray, newTarget)
  console.log(`construct function name is ${
      
      target.name}, argArray is [${
      
      argArray}], result is ${
      
      JSON.stringify(result)}.`)
  return result;
  
 }
 , get(target, p, receiver) {
    
    
  let res=Reflect.get(target, p, receiver);
  console.log(`get ${
      
      target.name} ${
      
      res}`)
  return res
 }
 ,set(target, p, value, receiver) {
    
    
  let res=Reflect.set(target, p, value, receiver);
  console.log(` set ${
      
      target.name} ${
      
      value}`)
  return res;
 }
})


让我看到了吧,调用了toString,跟进去看一下,打一个断点,f10开始

混淆了5555,看着好乱,我们就一个个的来看看它做了什么

 eval[_0x5572a4(0x132)]() === _0x5572a4(0x13d) ? window['$eval1'] = !![] : window[_0x5572a4(0x137)] = ![],
    Function[_0x5572a4(0x134)][_0x5572a4(0x132)][_0x5572a4(0x136)](eval) === 'function\x20eval()\x20{\x20[native\x20code]\x20}' ? window[_0x5572a4(0x131)] = !![] : window[_0x5572a4(0x131)] = ![];

_0x5572a4(0x132)="toString"
_0x5572a4(0x13d)="function eval() { [native code] }"
_0x5572a4(0x137)="$eval1"
_0x5572a4(0x134)="prototype"
_0x5572a4(0x132)="toString"
_0x5572a4(0x136)="call"
_0x5572a4(0x131)="$eval2"

翻译一下就是

eval["toString"]=="function eval() { [native code] }"?window['$eval1']=!![]:window['$eval1']=![]
Function['prototype']['toString']['call'](eval)==='function\x20eval()\x20{\x20[native\x20code]\x20}'?window["$eval2"]=!![]:window["$eval2"]=![]

那这样就清晰了,蓝师傅监控了toString方法和原型链上的toString方法
那么我们hook掉这两个方法就好了,最后的代码如下

    var _eval=eval;
eval=function (){
    
    
    console.log(arguments)
    return _eval(arguments)

}


eval.toString=function (){
    
    
    console.log(1111)
    return "function eval() { [native code] }"

}
Function.prototype.toString=function(){
    
    return "function eval() { [native code] }"}

接着刷新一下界面看一下

输入一下啊欢迎来到大数据安全技术学习JS课程,成功了

题目 2021年6月份JS逆向第三题

观察题目只有一个按钮点击后出现浏览器的设备指纹

查看网络请求看他有没有发包

有的那就说明是通过后端校验的,这是我们可以hook AJAX或者通过查看网络请求的调用栈来获得发包的内容,我们采用查看包的调用栈的方式来跟踪,

在app.js中跟进去看一下

this.fingerprint = this.$Encrypt.sign(e),
    p()({
    
    
        method: "post",
        url: "http://www.dtasecurity.cn:35555/subject3202106",
        data: {
    
    
            sign: this.fingerprint,
            fingerprint: window.btoa(e)
        },
        transformRequest: [function (e) {
    
    
            var t = "";
            for (var a in e)
                t += encodeURIComponent(a) + "=" + encodeURIComponent(e[a]) + "&";
            return t = t.substring(0, t.lastIndexOf("&"))
        }
        ],
        headers: {
    
    
            "Content-Type": "application/x-www-form-urlencoded"
        }

发包方式知道了,关键参数就是sign和fingerprint,先看一下sign是如何生成的,追踪进去this.$Encrypt.sign和e,e是明文的很容易就能看懂关键是sign函数我们继续跟踪

发现了md5字样菜猜测是md5算法,尝试一下,发现一模一样那么这里就是md5算法了


接着分析fingerprint也就是e是怎么来的,可以看到下面的这一行代码,那么就分析getfingerprint函数,跟踪进去

 var e = this.getfingerprint();
 getfingerprint: function () {
    
    
    var e = []
        , t = e.push.bind(e);
    return [navigator, location, history].forEach(function (e) {
    
    
        for (var a in _()(window, e),
            e) {
    
    
            var n = e[a];
            n && "string" == typeof n && t(a + ":" + n)
        }
    }),
        e.join("###")
}

getfingerprint函数非常的简单,可以通过nodejs来模拟一下,尝试补出他的环境,如下图开始补环境

let rawindexof = String.prototype.indexOf
String.prototype.indexOf = function (str) {
    
    
    var res = rawindexof.call(this, str)
    console.log(`[String] "${
      
      this}" is indexof "${
      
      str}", res is ${
      
      res}`)
    return res
}
let mydocument = {
    
    
    "head": {
    
    },
    "documentElement": {
    
    
        "getAttribute": function () {
    
    
        }
    },
    "readyState": "complete",
    "addEventListener": function () {
    
    
    },
    "createElement": function () {
    
    
        return {
    
    }
    },
    "getElementsByTagName": function (str) {
    
    
        console.log(str)
        if (str === "meta") {
    
    
            let metaRes = []
            metaRes["meta-pro"] = {
    
    
                "content": {
    
    
                    "length": 6
                }
            }
            return metaRes
        }
    }
}
let mynavigator = Object.create({
    
    
    "vendorSub": "",
    "productSub": "20030107",
    "vendor": "Google Inc.",
    "maxTouchPoints": 0,
    "userActivation": {
    
    },
    "doNotTrack": null,
    "geolocation": {
    
    },
    "connection": {
    
    },
    "plugins": {
    
    
        "0": {
    
    
            "0": {
    
    }
        },
        "1": {
    
    
            "0": {
    
    }
        },
        "2": {
    
    
            "0": {
    
    },
            "1": {
    
    }
        }
    },
    "mimeTypes": {
    
    
        "0": {
    
    },
        "1": {
    
    },
        "2": {
    
    },
        "3": {
    
    }
    },
    "webkitTemporaryStorage": {
    
    },
    "webkitPersistentStorage": {
    
    },
    "hardwareConcurrency": 4,
    "cookieEnabled": true,
    "appCodeName": "Mozilla",
    "appName": "Netscape",
    "appVersion": "5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36",
    "platform": "Linux x86_64",
    "product": "Gecko",
    "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36",
    "language": "zh",
    "languages": [
        "zh",
        "en-US",
        "en"
    ],
    "onLine": true,
    "webdriver": false,
    "scheduling": {
    
    },
    "mediaCapabilities": {
    
    },
    "permissions": {
    
    },
    "mediaSession": {
    
    }
});
let mysrceen = Object.create({
    
    
    height: 852,
    width: 1918,
    colorDepth: 24,
});
let mylocation = {
    
    
    "ancestorOrigins": {
    
    },
    "href": "http://www.dtasecurity.cn:11080/details?url=http%3A%2F%2Fwww.dtasecurity.cn%3A30080%2Fsubject%2F%23%2F202106subject3",
    "origin": "http://www.dtasecurity.cn:11080",
    "protocol": "http:",
    "host": "www.dtasecurity.cn:11080",
    "hostname": "www.dtasecurity.cn",
    "port": "11080",
    "pathname": "/details",
    "search": "?url=http%3A%2F%2Fwww.dtasecurity.cn%3A30080%2Fsubject%2F%23%2F202106subject3",
    "hash": ""
}
let myhistory = {
    
    
    "length": 4,
    "scrollRestoration": "manual",
    "state": {
    
    
        "key": "680.400"
    }
}

let mywindow = {
    
    
    XMLHttpRequest: function () {
    
    
    },
    sessionStorage: {
    
    },
    localStorage: {
    
    },
    navigator: mynavigator,
    scrollTo: function () {
    
    
    },
    addEventListener: function () {
    
    
    },
    attachEvent: function () {
    
    
    },
    screen: mysrceen,
    location: mylocation,
    chrome: {
    
    },
    document: mydocument,
};
let Image = function () {
    
    
};
let rawstringify = JSON.stringify;
JSON.stringify = function (Object) {
    
    
    if ((Object?.value ?? Object) === global) {
    
    
        return "global"
    } else {
    
    
        return rawstringify(Object)
    }
}

function checkproxy() {
    
    
    //Object.keys(window)
    window.a = {
    
    
        "b": {
    
    
            "c": {
    
    
                "d": 123
            }
        }
    }
    window.a.b.c.d = 456
    window.a.b
    window.btoa("123")
    window.atob.name
    "c" in window.a
    delete window.a.b
    Object.defineProperty(window, "b", {
    
    
        value: "bbb"
    })
    Object.getOwnPropertyDescriptor(window, "b")
    Object.getPrototypeOf(window)
    Object.setPrototypeOf(window, {
    
    "dta": "dta"})
    // for (let windowKey in window) {
    
    
    //     windowKey
    // }
    Object.preventExtensions(window)
    Object.isExtensible(window)
}

function getMethodHandler(WatchName) {
    
    
    let methodhandler = {
    
    
        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 methodhandler
}

function getObjhandler(WatchName) {
    
    
    let handler = {
    
    
        get(target, propKey, receiver) {
    
    
            let result = Reflect.get(target, propKey, receiver)
            if (result instanceof Object) {
    
    
                if (typeof result === "function") {
    
    
                    //console.log(`[${WatchName}] getting propKey is [${propKey}] , it is function`)
                    //return new Proxy(result,getMethodHandler(WatchName))
                } else {
    
    
                    console.log(`[${
      
      WatchName}] getting propKey is [${
      
      propKey}], result is [${
      
      JSON.stringify(result)}]`);
                }
                return new Proxy(result, getObjhandler(`${
      
      WatchName}.${
      
      propKey}`))
            }
            console.log(`[${
      
      WatchName}] getting propKey is [${
      
      propKey?.description ?? propKey}], result is [${
      
      result}]`);
            return result;
        },
        set(target, propKey, value, receiver) {
    
    
            if (value instanceof Object) {
    
    
                console.log(`[${
      
      WatchName}] setting propKey is [${
      
      propKey}], value is [${
      
      JSON.stringify(value)}]`);
            } else {
    
    
                console.log(`[${
      
      WatchName}] setting propKey is [${
      
      propKey}], value is [${
      
      value}]`);
            }
            return Reflect.set(target, propKey, value, receiver);
        },
        has(target, propKey) {
    
    
            var result = Reflect.has(target, propKey);
            console.log(`[${
      
      WatchName}] has propKey [${
      
      propKey}], result is [${
      
      result}]`)
            return result;
        },
        deleteProperty(target, propKey) {
    
    
            var result = Reflect.deleteProperty(target, propKey);
            console.log(`[${
      
      WatchName}] delete propKey [${
      
      propKey}], result is [${
      
      result}]`)
            return result;
        },
        getOwnPropertyDescriptor(target, propKey) {
    
    
            var result = Reflect.getOwnPropertyDescriptor(target, propKey);
            console.log(`[${
      
      WatchName}] getOwnPropertyDescriptor  propKey [${
      
      propKey}] result is [${
      
      JSON.stringify(result)}]`)
            return result;
        },
        defineProperty(target, propKey, attributes) {
    
    
            var result = Reflect.defineProperty(target, propKey, attributes);
            console.log(`[${
      
      WatchName}] defineProperty propKey [${
      
      propKey}] attributes is [${
      
      JSON.stringify(attributes)}], result is [${
      
      result}]`)
            return result
        },
        getPrototypeOf(target) {
    
    
            var result = Reflect.getPrototypeOf(target)
            console.log(`[${
      
      WatchName}] getPrototypeOf result is [${
      
      JSON.stringify(result)}]`)
            return result;
        },
        setPrototypeOf(target, proto) {
    
    
            console.log(`[${
      
      WatchName}] setPrototypeOf proto is [${
      
      JSON.stringify(proto)}]`)
            return Reflect.setPrototypeOf(target, proto);
        },
        preventExtensions(target) {
    
    
            console.log(`[${
      
      WatchName}] preventExtensions`)
            return Reflect.preventExtensions(target);
        },
        isExtensible(target) {
    
    
            var result = Reflect.isExtensible(target)
            console.log(`[${
      
      WatchName}] isExtensible, result is [${
      
      result}]`)
            return result;
        },
        ownKeys(target) {
    
    
            var result = Reflect.ownKeys(target)
            console.log(`[${
      
      WatchName}] invoke ownkeys, result is [${
      
      JSON.stringify(result)}]`)
            return result
        },
        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 handler;
}

const navigator = new Proxy(mynavigator, getObjhandler("navigator"));
const screen = new Proxy(mysrceen, getObjhandler("screen"));
const location = new Proxy(mylocation, getObjhandler("location"));
const document = new Proxy(mydocument, getObjhandler("document"));
const history = new Proxy(myhistory, getObjhandler("history"));
const window = new Proxy(Object.assign(global, mywindow), getObjhandler("window"));

//checkproxy()
module.exports = {
    
    
    window,
    navigator,
    screen,
    location,
    String,
    Image,
    document,
    history
}

(ps:直接用蓝师傅的环境真香哈),之前讲过就不多说了,接着我们遇到了我们的第一个错误_没定义

回到浏览器中查看一下_是个什么东西,发现到了下面这里,然后继续打断点跟踪

var n = r && r.__esModule ? function() {
    
    
            return r.default
        }

查看一下r.default是什么,是一个属性删除函数,那么这一段的逻辑就是,在浏览器上删除不到这些属性,而在nodejs上能删除这些属性,那么其实_方法是无效的我们根本不需要这个删除方法,就把他删掉就好了

可以正常运行

最后打印一下这个匿名方法

console.log((function () {
    
    
    var e = []
        , t = e.push.bind(e);
    return [navigator, location, history].forEach(function (e) {
    
    
        for (var a in e) {
    
    
            var n = e[a];
            n && "string" == typeof n && t(a + ":" + n)
        }
    }),
        e.join("###")
})());


复制上去访问一下看看能不能过

通过了,可以看到蓝师傅的环境真好用
有兴趣可以一起学习一下呀

猜你喜欢

转载自blog.csdn.net/u010559109/article/details/120159358
今日推荐