js逆向(三)

65 阅读11分钟

案例1

艺恩实战:www.endata.com.cn/BoxOffice/B…

const _grsa_JS = require("crypto-js")


var webDES = function() {
    var _0x4da59e = {
        'bUIIa': function _0x2a2af9(_0x779387, _0x4a4fec) {
            return _0x779387 + _0x4a4fec;
        }
    };
    var _0x9843d3 = function(_0x29d556, _0xcc6df, _0x3d7020) {
        if (0x0 == _0xcc6df)
            return _0x29d556['substr'](_0x3d7020);
        var _0x48914b;
        _0x48914b = '' + _0x29d556['substr'](0x0, _0xcc6df);
        return _0x48914b += _0x29d556['substr'](_0x4da59e['bUIIa'](_0xcc6df, _0x3d7020));
    };
    this['shell'] = function(_0xa0c834) {
        var _0x51eedc = {
            'pKENi': function _0x2f627(_0x5b6f5a, _0x440924) {
                return _0x5b6f5a === _0x440924;
            },
            'wnfPa': 'ZGz',
            'VMmle': '7|1|8|9|5|2|3|6|0|4',
            'GKWFf': function _0x1a4e13(_0x40cfde, _0x16f3c2) {
                return _0x40cfde == _0x16f3c2;
            },
            'MUPgQ': function _0x342f0d(_0x19038b, _0x4004d6) {
                return _0x19038b >= _0x4004d6;
            },
            'hLXma': function _0x55adaf(_0x45a871, _0x161bdf) {
                return _0x45a871 + _0x161bdf;
            },
            'JdOlO': function _0x13e00a(_0x5899a9, _0x4bb34d) {
                return _0x5899a9 + _0x4bb34d;
            },
            'qrTpg': function _0x1198fb(_0x55b317, _0x22e1db, _0x1b091a) {
                return _0x55b317(_0x22e1db, _0x1b091a);
            },
            'pdmMk': function _0xe2b022(_0x4af286, _0x4c2fd4) {
                return _0x4af286 - _0x4c2fd4;
            },
            'xVKWW': function _0x1094a3(_0x5f3627, _0x2a0ac5, _0x3ad2e5) {
                return _0x5f3627(_0x2a0ac5, _0x3ad2e5);
            }
        };
        if (_0x51eedc['pKENi']('tgg', _0x51eedc['wnfPa'])) {
            this['_append'](a);
            return this['_process']();
        } else {
            var _0x492a62 = _0x51eedc['VMmle']['split']('|')
                , _0x356b01 = 0x0;
            while (!![]) {
                switch (_0x492a62[_0x356b01++]) {
                    case '0':
                        _0x554c90 = _grsa_JS['DES']['decrypt']({
                            'ciphertext': _grsa_JS['enc']['Hex']['parse']
                            (_0xa0c834)
                        }, _0x2cf8ae, {
                            'iv': _0x554c90,
                            'mode': _grsa_JS['mode']['ECB'],
                            'padding': _grsa_JS['pad']['Pkcs7']
                        })['toString'](_grsa_JS['enc']['Utf8']);
                        console.log(_0x554c90)
                        continue;
                    case '1':
                        if (_0x51eedc['GKWFf'](null, _0xa0c834) ||
                            _0x51eedc['MUPgQ'](0x10, _0xa0c834['length']))
                            return _0xa0c834;
                        continue;
                    case '2':
                        _0xa0c834 = _0x9843d3(_0xa0c834, _0x2cf8ae, 0x8);
                        continue;
                    case '3':
                        _0x2cf8ae = _grsa_JS['enc']['Utf8']['parse'](_0x554c90);
                        continue;
                    case '4':
                        return _0x554c90['substring'](0x0, _0x51eedc['hLXma']
                        (_0x554c90['lastIndexOf']('}'), 0x1));
                    case '5':
                        _0x554c90 = _0xa0c834['substr'](_0x2cf8ae, 0x8);
                        continue;
                    case '6':
                        _0x554c90 = _grsa_JS['enc']['Utf8']['parse'](_0x554c90);
                        continue;
                    case '7':
                        navigator={'userAgent':'abc'}
                        if (!navigator || !navigator['userAgent'])
                            return '';
                        continue;
                    case '8':
                        var _0x554c90 = _0x51eedc['JdOlO'](_0x51eedc['qrTpg']
                        (parseInt, _0xa0c834[_0x51eedc['pdmMk'](_0xa0c834['length'], 0x1)], 0x10), 0x9)
                            , _0x2cf8ae = _0x51eedc['xVKWW'](parseInt,
                            _0xa0c834[_0x554c90], 0x10);
                        continue;
                    case '9':
                        _0xa0c834 = _0x9843d3(_0xa0c834, _0x554c90, 0x1);
                        continue;
                }
                break;

            }
        }
    }
    ;
}
webInstace = new webDES();

案例二

雪球网:xueqiu.com/today

import requests


headers = {
    "Accept": "*/*",
    "Accept-Language": "zh-CN,zh;q=0.9",
    "Connection": "keep-alive",
    "Referer": "https://xueqiu.com/today",
    "Sec-Fetch-Dest": "empty",
    "Sec-Fetch-Mode": "cors",
    "Sec-Fetch-Site": "same-origin",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
    "X-Requested-With": "XMLHttpRequest",
    "elastic-apm-traceparent": "00-37c7148d122adc3e47050471b9580217-ef0cd8289768fb99-00",
    "sec-ch-ua": ""Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"",
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": ""Windows""
}
cookies = {
    # "b-user-id": "068c43cc-b876-c956-af3b-b47e27a376ac",
    "xq_a_token": "76d4e5ee97f60e0be2c9b6c094156d577fba5c5b",
    # "xqat": "76d4e5ee97f60e0be2c9b6c094156d577fba5c5b",
    # "xq_r_token": "2537d01490f74c00d7d4a37578ac84f1b7481ca1",
    # "xq_id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1aWQiOi0xLCJpc3MiOiJ1YyIsImV4cCI6MTcxMTA2ODM4MiwiY3RtIjoxNzA5NDYzMTY0ODczLCJjaWQiOiJkOWQwbjRBWnVwIn0.i6wDeYMy_rJknb_Lm5MC3QRpM9oRoghVbd1ZALIfPScEGivxvHaYQ2YR4k-dNBo7qB1zb8tjf1isNDbyGtlQ26fIohz9Y38YyGF8jRrAvQnGXNNA_k8jC0faFMxrwyAbwCZvj2zjZGgeS809G4z9XWobGR0Ie_gCg4wthGvQ5KF964OfctpuPT2pef7q3CKcb8jDnvp1EIUZZLUG5TmZsKNEVyBhGOCVVBbEoI08-XkMa6Lp60GVcHFOjNTyta1ipfjdNQ-KRwtu1qlsErDb8j2VP8OeWDqSDnVFcdUjTq8qp_iGGqYEz2tnPsB35oq7KHFpdJrD4-csjqJjsC-ntA",
    # "cookiesu": "971709463194191",
    # "u": "971709463194191",
    # "Hm_lvt_1db88642e346389874251b5a1eded6e3": "1709463211",
    # "device_id": "915f18abfd3cae65850c472546e602c4",
    # "acw_tc": "2760779917094650257157195e0a2f6acbfd931d56186b2e78097f11188abd",
    # "acw_sc__v2": "65e45ed8ea3f756dc0dd285986cf95212ea3f493",
    # "Hm_lpvt_1db88642e346389874251b5a1eded6e3": "1709465320"
}
url = "https://xueqiu.com/statuses/hot/listV2.json"
params = {
    "since_id": "-1",
    "max_id": "601163",
    "size": "15"
}
response = requests.get(url, headers=headers, cookies=cookies, params=params)

print(response.text)
print(response)

通过重放请求,查看是哪个cookie决定了⽂件的请求

重放请求

  • 可以通过代码调试,也可以在浏览器中删除cookie进⾏测试
  • 在浏览器的应⽤程序-》cookie管理中删除⼀些cookie
  • 然后通过右键复制fetch在浏览器⾥⾯运⾏,进⾏重放请求

建议使⽤代码进⾏重放请求,速度快点。 对cookie的数据进⾏⼀条条注释,运⾏看是否可以获取数据。

最后得出影响获取的值

"xq_a_token": "76d4e5ee97f60e0be2c9b6c094156d577fba5c5b",

确认cookie来源

需要确认是服务器请求还是客⼾端js⽣成

  • 如果是服务端返回,需要找到返回的连接,看是通过哪个请求set的cookie
  • 如果是客户端,需要hook cookie,进⾏js逆向

image.png 带上勾选的是服务器返回的。可以看到该请求是服务器返回的,我们需要去找到该参数返回的⽹站

可以通过复制cookie的值,进⾏搜索,但是⼀般情况是搜索不到的。

因为cookie有⼀定的期限,我们需要在应⽤程序中清除所有的cookie,重新再获取,才能搜索到。

⽆限debug解决方案

在这个时候我们会遇上⽆限debug

image.png

解决可以: 1. 通过修改条件的表达式为false进行跳过

image.png

在添加条件断点处,添加一个false即可

2. 也可以通过运⾏hook脚本进⾏,跳过

hook脚本的使⽤

先进⼊到源代码,勾选上脚本→第⼀个js代码

image.png

然后重新进⾏刷新,当代码断住后开始注⼊代码

在源代码中添加⼀个代码⽂件,并且添加上debug的hook代码,这个代码的作⽤是修改debug的

image.png

代码重写了 Function.prototype.constructor ,在传⼊的参数中检查是否包 含’debugger’,如果包含则直接返回不执⾏任何操作,否则继续调⽤保存的原始 Function.prototype.constructor 进⾏处理参数

// 1. 备份之前的Function.prototype.constructor
Function.prototype.constructor_ = Function.prototype.constructor
// 2. 重写Function.prototype.constructor
Function.prototype.constructor = function() {
    if (arguments[0] === 'debugger') {
        return
    } else {
        return Function.prototype.constructor_.apply(this, arguments)
    }
}

这样如果是debug过来就直接返回,不会再对代码进⾏调试。

写好后右键⽂件运⾏。然后再继续运⾏获取cookie。这个时候再搜索就可以找到cookie服务器的返回请求了。

image.png

注意:session请求是利用上一个请求之后,下一次请求就自带上次请求的cookie等信息。

import requests

session=requests.session()

headers = {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
    "Accept-Language": "zh-CN,zh;q=0.9",
    "Cache-Control": "max-age=0",
    "Connection": "keep-alive",
    "Referer": "https://xueqiu.com/today",
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Site": "same-origin",
    "Upgrade-Insecure-Requests": "1",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
    "sec-ch-ua": ""Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"",
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": ""Windows""
}
cookies = {
    "acw_tc": "276077a317094671377365936e65af22695bde71a5987bd2ad284a6b71ad5f",
    "b-user-id": "a379997a-19ef-3e51-7375-a2ea83cf78c8",
    "acw_sc__v2": "65e4660171402759cb489aa41a71d96ce06051b6"
}
url = "https://xueqiu.com/today"
response = requests.get(url, headers=headers, cookies=cookies)

print(response.text)
print(response.cookies)

通过重放请求可以知道是acw_sc__v2,另外⼀个不影响。

image.png 这个参数是客⼾端js代码⽣成的,需要进⾏cookie hook。

Hook cookie

(function() {
    'use strict';
    var _cookie = "";
    // hook cookie
    Object.defineProperty(document, 'cookie', {
        set: function(val) {
            console.log('cookie set->', new Date().getTime(), val);
            debugger ;_cookie = val;
            return val;
        },
        get: function() {
            return _cookie;
        }
    });
}
)()

将代码断住后,注⼊hook代码,然后进⾏调试。

调试需要注意,先前的cookie已经存在,需要清空

通过运⾏hook脚本抓取到acw_sc__v2 ⽣成

image.png 当值确认后,我们通过堆栈进⾏查找。获取到值后进⾏cookie的js逆向

xq.js

String['prototype']['unsbox'] = function() {
    var _0x4b082b = [0xf, 0x23, 0x1d, 0x18, 0x21, 0x10, 0x1, 0x26, 0xa, 0x9, 0x13, 0x1f, 0x28, 0x1b, 0x16, 0x17, 0x19, 0xd, 0x6, 0xb, 0x27, 0x12, 0x14, 0x8, 0xe, 0x15, 0x20, 0x1a, 0x2, 0x1e, 0x7, 0x4, 0x11, 0x5, 0x3, 0x1c, 0x22, 0x25, 0xc, 0x24];
    var _0x4da0dc = [];
    var _0x12605e = '';
    for (var _0x20a7bf = 0x0; _0x20a7bf < this['length']; _0x20a7bf++) {
        var _0x385ee3 = this[_0x20a7bf];
        for (var _0x217721 = 0x0; _0x217721 < _0x4b082b['length']; _0x217721++) {
            if (_0x4b082b[_0x217721] == _0x20a7bf + 0x1) {
                _0x4da0dc[_0x217721] = _0x385ee3;
            }
        }
    }
    _0x12605e = _0x4da0dc['join']('');
    return _0x12605e;
}

String['prototype']['hexXor'] = function(_0x4e08d8) {
    var _0x5a5d3b = '';
    for (var _0xe89588 = 0x0; _0xe89588 < this['length'] && _0xe89588 < _0x4e08d8['length']; _0xe89588 += 0x2) {
        var _0x401af1 = parseInt(this['slice'](_0xe89588, _0xe89588 + 0x2), 0x10);
        var _0x105f59 = parseInt(_0x4e08d8['slice'](_0xe89588, _0xe89588 + 0x2), 0x10);
        var _0x189e2c = (_0x401af1 ^ _0x105f59)['toString'](0x10);
        if (_0x189e2c['length'] == 0x1) {
            _0x189e2c = '\x30' + _0x189e2c;
        }
        _0x5a5d3b += _0x189e2c;
    }
    return _0x5a5d3b;
}

_0x5e8b26="3000176000856006061501533003690027800375"
arg1='75473B936EAF2358783179F46B18E0FA7555326F'
var _0x23a392 = arg1["unsbox"]();
arg2 = _0x23a392["hexXor"](_0x5e8b26);
console.log(arg2);