17reverse analysis of track interface

There is no complete code after the modification. It is pure learning. This website is good. It is free to query. It also supports 40 order numbers to check together. Who has a better way to find_ The memory in 0x4f3f is broken. Welcome to teach me!


The Express query interface of 17track can see the request through the debugging tool, but there is no result directly through the POST tool. The last event ID cookie needs to be added to the final test

After reading the JS file loaded by the web page, there is only an encrypted track Min.js, and found a very suspicious setCookie, as well as the last event ID character. The first line is an array, followed by two self executing anonymous functions.

(function(_0x2297ee, _0x5f41f3) {
}(_0x50c7, 0x9f));
(function() {
    var _0x10f375

Set breakpoints for the two functions, refresh the clear storage, and then debug step by step. Here, as long as we call the function, we will break the function. When you follow_ 0x4f3f this function is called in many places. It is found that the returned string is the lower breakpoint. Just cancel the breakpoint and continue to follow, otherwise the hand should be soft. Last called by the second self executing function_ 0x4cec2b_ 0x4cec2b last called_ 0x3966d3, when it is cut to_ The request information can be seen by 0x3966d3_ 0x164a16 is the JSON of post_ 0x152eb7 is an ajax request

Follow_ 0x3966d3, you can see that the first two parameters are functions and the last one is a number. Keep going step by step, pay attention_ 0x126b58 this value is changing.

Finally, I found the last event ID here. I took it to post and tried it. It was successful.

Analysis code

We restore the code that sets the last event ID.

document[_0x4f3f('0x67', 'x3Lg')] = _0x2ec18e[_0x4f3f('0x68', '^p2Z')](_0x316f08, '=') + _0x472ff2[_0x4f3f('0x4d', 'uFIh')]('') + _0x2ec18e[_0x4f3f('0x69', 'aeh^')] + _0x1720d7[_0x4f3f('0x6a', 'LaH7')](); 

Call directly on the console_ 0x4f3f function gets

document["cookie"] = _0x2ec18e["GAOJi"]('Last-Event-ID', '=') + _0x472ff2["join"]('') + _0x2ec18e["FPaVy"] + _0x1720d7["toGMTString"](); 

_0x472ff2["join"]('')//That's the last event ID we need

_The 0x472ff2 is an important variable. Copy all encryption codes, format them, and put them into a new web page for execution. Hahaha, collapsed.

It seems that there is a detection code. I don't know how to set the breakpoint here. I only write the wrong code step by step to see whether it crashes first or reports an error first to determine the location of the detection code. Is there a big guy with a good way?

_0x3184d0['prototype']['yzecjS'] = function() {
                var _0x5e1a47 = new RegExp(this['IbesCh'] + this['kRbSMK']);
                var _0x44235e = _0x5e1a47['test'](this['ZDEFCw']['toString']()) ? --this['LoqXko'][0x1] : --this['LoqXko'][0x0];//Here is a regular match_ 0x44235e set to -1 to skip
                return this['NUSOYG'](_0x44235e);

Refresh and execute, and report a new error. This error directly displays the location. The next breakpoint is compared with the original web page

var _0xd2c455 = function(_0x570d92) {
                var _0x6d545d = ~-0x4 >> 0x1 + 0xff % 0x0;
                if (_0x570d92['\x69\x6e\x64\x65\x78\x4f\x66']((!![] + '')[0x3]) !== _0x6d545d) { //If this judgment is changed to false, you can skip it

Here, go on, or report an error. The error is simple and clear. jquery is missing. Add it to the web page. Search_ 0x3966d3 find the place to call it.

        _0x2ec18e[_0x4f3f('0x86', 'oD72')]($, document)[_0x4f3f('0x87', 'tG@(')](function(_0x2c3354, _0x28d1d7, _0x152eb7) {
            if (_0x152eb7[_0x4f3f('0x88', 'Ho1%')][_0x4f3f('0x89', 'klod')](_0x4f3f('0x8a', 'L*ZS')) && _0x152eb7['data']) {
                _0x567d6b = _0x152eb7[_0x4f3f('0x8b', 'oD72')];
                var _0x164a16;
                try {
                    _0x164a16 = JSON['parse'](_0x567d6b);
                } catch (_0x198faf) {
                    if (_0x2ec18e[_0x4f3f('0x8c', 'bv*^')](_0x2ec18e[_0x4f3f('0x8d', '!nz(')], _0x4f3f('0x8e', 'PGF('))) {
                        var _0x574153 = _0x56b4ca[_0x4f3f('0x8f', 'qd7c')](_0x3df0c1, str, seed);
                        if (tag) {
                            _0x472ff2[0x5] = _0x56b4ca[_0x4f3f('0x90', 'm^Gz')](_0x2c724a, _0x574153[_0x4f3f('0x91', 'x3Lg')](0x10));
                        _0x472ff2[0x4] = _0x2c724a(_0x574153['toString'](0x10));
                    } else {
                        _0x164a16 = null;
                if (_0x164a16 && _0x2ec18e[_0x4f3f('0x92', 'x3Lg')](_0x164a16[_0x4f3f('0x93', 'H0Sy')], '')) {
                    try {
                        _0x2ec18e[_0x4f3f('0x94', '!nz(')](_0x9ff66b, _0x567d6b, _0x567d6b[_0x4f3f('0x95', 'l3oQ')], !![]);
                        var _0x3fd2d0 = _0x4f3f('0x96', '7la!') + _0x4f3f('0x97', 'ttkq') + ']';
                        var _0x3a6885 = _0x2ec18e[_0x4f3f('0xe', '#C9L')]($, _0x3fd2d0);
                        _0x3966d3(_0x28d1d7, _0x3a6885, _0x1a395d(_0x3a6885[_0x4f3f('0x98', 'QKX0')]));
                    } catch (_0x1739bd) {}

After restore

        $(document).ajaxSend(function (_0x2c3354, _0x28d1d7, _0x152eb7) {
            if (_0x152eb7['url']['match']('(//[a-z]+.17track.net/restapi/track)') && _0x152eb7['data']) {
                _0x567d6b = _0x152eb7['data']; //post data {"data":[{"num":"***","fc":0,"sc":0}],"guid":"","timeZoneOffset":-480}
                var _0x164a16; 
                try {
                    _0x164a16 = JSON['parse'](_0x567d6b);//Execute json Parse get object
                } catch (_0x198faf) {
                    //Omit here
                if (_0x164a16 && _0x2ec18e['ZIKlo'](_0x164a16['guid'], '')) { //guid parameter is null
                    try {
                        //_0x2ec18e['WaYmY'](_0x9ff66b, _0x567d6b, _0x567d6b.length, true);
                        _0x9ff66b(_0x567d6b, _0x567d6b.length, true);//This sentence is the same as the above sentence, calling_ 0x9ff66b data and length are transmitted. Go to see_ 0x9ff66b function actual pair_ 0x472ff2 key variables are set
                        var _0x3fd2d0 = _0x4f3f('0x96', '7la!') + _0x4f3f('0x97', 'ttkq') + ']';//_0x3fd2d0 = "[class*='yq-']";
                        var _0x3a6885 = _0x2ec18e[_0x4f3f('0xe', '#C9L')]($, _0x3fd2d0);//_0x3a6885 = $("[class*='yq-']");
                        _0x3966d3(_0x28d1d7, _0x3a6885, _0x1a395d(_0x3a6885[_0x4f3f('0x98', 'QKX0')]));//Call_ 0x3966d3 parameters passed in_ 0x28d1d7 is XMLHttpRequest_ 0x3a6885 = $("[class*='yq-']")_ 0x3a6885[\u 0x4f3f ('0x98','qkx0')] =_ 0x3a6885['length'] = $("[class*='yq-']) Length, which is actually equal to 21, then_ 0x1a395d function passed in $("[class*='yq-']) Length,
                    } catch (_0x1739bd) { }

_The 0x1a395d function

    function _0x1a395d(_0x3e48ff) { //Coming 21
        var _0x402f82 = _0x3e48ff;
        if (window && document && window['innerHeight'] && window[_0x4f3f('0x19', 'VMDb')] > 0x0) {//innerHeight is judged here, and we need to remove this judgment
            var _0x5027d7 = window[_0x4f3f('0x1a', 'klod')]['random']();//_0x5027d7 = Math.random();
            _0x402f82 = window[_0x4f3f('0x1b', 'DYwS')]['round'](_0x2ec18e[_0x4f3f('0x1c', '0BWm')](_0x5027d7, _0x3e48ff));//Math Round (\u 0x5027d7 * \u 0x3e48ff)// Generated a random number_ 0x402f82 
        //Set key variables_ 0x472ff2
        _0x472ff2[0x1] = _0x402f82[_0x4f3f('0x1d', 'sge9')](0x10);//_0x402f82.toString(16);
        _0x472ff2[0x2] = _0x402f82[_0x4f3f('0x1e', 'PGF(')](0x10)['length'];//_0x402f82.toString(16).length;
        return _0x402f82;//Returned this number

_The 0x3966d3 function

    function _0x3966d3(_0x8517d0, _0xae9512, _0x1e1c09) { //_The 0x1e1c09 =_ 0x1a395d generated number,
        var _0x126b58 = _0x4f3f('0x56', '#C9L');//_0x126b58  = "yq-";
        var _0x316f08 = _0x4f3f('0x57', 'tG@(');//_0x316f08 = 'Last-Event-ID';
        if (_0xae9512[_0x4f3f('0x58', 'V91Y')] > _0x1e1c09 && document && document[_0x4f3f('0x59', 'Tbb9')]) {//$("[class*='yq-']").length > _0x1e1c09 && document && document['removeEventListener'],_0xae9512['length'] = $("[class*='yq-']").length;
            _0x126b58 = _0xae9512[_0x1e1c09]['className'];//Modified here_ 0x126b58 value, finally I put_ 0x1a395d the generated number is set to a fixed value_ 0x126b58 is also set to the corresponding className. This judgment can be removed.
        _0x126b58 = _0x126b58 + '/' + window[_0x4f3f('0x5a', 'fxzh')]['now']()[_0x4f3f('0x5b', 'VMDb')](0x10) + '/' + window[_0x4f3f('0x5c', 'MtlY')][_0x4f3f('0x5b', 'VMDb')](0x10) + '/' + _0x4ba351(); //_The 0x126b58 +'/'+ date Now() ToString (16) + '/' + window Innerheight ToString (16) + '/' +_ 0x4ba351(); Finally, I want to run without the browser, window Innerheight ToString (16) can be set to a fixed value, and finally_ 0x4ba351 this function
        _0x9ff66b(_0x126b58, _0x1e1c09);//_The 0x9ff66 called_ 0x3df0c1_ 0x3df0c1 called_ 0x5e7be4_ 0x5e7be4 detection function
        _0x126b58 = _0x2ec18e[_0x4f3f('0x5d', 'H0Sy')](_0x3c4889, _0xd74c71(_0x126b58));
        _0x472ff2[0x0] = _0x126b58;
        //The following code is useless. The purpose is to get the last event ID
        var eid = _0x472ff2.join("");
        return eid;


    function _0x4ba351() {  //This is a large area. The main purpose is to generate XMLHttpRequest and return a true. We don't need XMLHttpRequest. Just return true directly
        if (_0x2ec18e[_0x4f3f('0x39', '4PG(')] === _0x4f3f('0x3a', 'VuqV')) {
            var _0x2371bc = _0x4f3f('0x3b', 'f*#]');
            var _0x135745 = _0x2ec18e[_0x4f3f('0x3c', '1gMZ')];
            if (objs[_0x4f3f('0x3d', 'DYwS')] > rndNo && document && document[_0x4f3f('0x3e', 'V91Y')]) {
                _0x2371bc = objs[rndNo][_0x4f3f('0x3f', 'tG@(')];
            _0x2371bc = _0x2ec18e[_0x4f3f('0x40', 'Ho1%')](_0x2ec18e[_0x4f3f('0x41', 'VuqV')](_0x2371bc + '/' + window[_0x4f3f('0x42', 'sge9')]['now']()['toString'](0x10) + '/', window[_0x4f3f('0x43', 'm^Gz')][_0x4f3f('0x44', 'kG!t')](0x10)), '/') + _0x2ec18e[_0x4f3f('0x45', 'f*#]')](_0x4ba351);
            _0x2ec18e[_0x4f3f('0x46', '4PG(')](_0x9ff66b, _0x2371bc, rndNo);
            _0x2371bc = _0x2ec18e[_0x4f3f('0x47', 'x3Lg')](_0x3c4889, _0xd74c71(_0x2371bc));
            _0x472ff2[0x0] = _0x2371bc;
            if (navigator[_0x4f3f('0x48', 'm48V')]) {
                var _0x55d807 = new Date();
                _0x55d807[_0x4f3f('0x49', 'Tbb9')](_0x2ec18e[_0x4f3f('0x4a', 'H0Sy')](_0x55d807[_0x4f3f('0x4b', 'KKV$')](), 0x12c * 0x3e8));
                document[_0x4f3f('0x4c', 'NJ5J')] = _0x135745 + '=' + _0x472ff2[_0x4f3f('0x4d', 'uFIh')]('') + ';path=/;domain=17track.net;expires=' + _0x55d807[_0x4f3f('0x4e', 'KKV$')]();
                _0x55d807 = new Date();
                _0x55d807[_0x4f3f('0x4f', 'kG!t')](_0x55d807['getTime']() + 0x12c * 0x3e8);
                document['cookie'] = _0x135745 + '=' + _0x472ff2[_0x4f3f('0x50', 'sge9')]('') + ';path=/;domain=17track.net;expires=' + _0x55d807[_0x4f3f('0x51', 'DYwS')]();
            if (!_0x411c47(_0x135745)) {
                xhr[_0x4f3f('0x52', 'x3Lg')](_0x135745, _0x472ff2[_0x4f3f('0x53', 'tG@(')](''));
        } else {
            var _0x47b984;
            try {
                _0x47b984 = new XMLHttpRequest();
            } catch (_0x3ef69c) {
                try {
                    _0x47b984 = new ActiveXObject(_0x4f3f('0x54', 'VMDb'));
                } catch (_0x494a23) {
                    try {
                        _0x47b984 = new ActiveXObject(_0x4f3f('0x55', 'jc9G'));
                    } catch (_0x1f73b5) {
                        return ![];
            _0x47b984 = null;
            return !![];


    function _0x5e7be4(_0x14393c) {
        if (_0x2ec18e[_0x4f3f('0x27', '#C9L')](_0x4f3f('0x28', '7la!'), _0x4f3f('0x29', 'y*Cp'))) {
            if (window && window[_0x4f3f('0x2a', 'ttkq')] && window[_0x4f3f('0x2b', '#C9l')] > 0x0 & & document & & document[\u 0x4f3f ('0x2c','kg! T')]['hostname'][\u 0x4f3f ('0x2d','^p2z')] (\u 0x4f3f ('0x2e','dyws') {/ / if (window & & window['innerwidth'] & & window['innerwidth'] > 0 & & document & & document ['location']['hostname']['match'] ('.17track.net') {let this judgment always be true
                if (!_0x14393c) {  
                    _0x472ff2[0x3] = 0x1;
                } else { //As you can see below, yes_ 0x472ff2 is set
                    if (_0x4f3f('0x2f', '!nz(') !== _0x4f3f('0x30', 'klod')) {
                        _0x472ff2[0x3] = 0x1;
                    } else {
                        _0x472ff2[0x3] = _0x14393c;
            } else {
                if (_0x4f3f('0x31', 'm^Gz') !== _0x2ec18e[_0x4f3f('0x32', 'm48V')]) {
                    that['console'] = function(_0x114f36) {
                        var _0x49a662 = {};
                        _0x49a662[_0x4f3f('0x33', 'f*#]')] = _0x114f36;
                        _0x49a662[_0x4f3f('0x34', 'l3oQ')] = _0x114f36;
                        _0x49a662[_0x4f3f('0x35', 'f*#]')] = _0x114f36;
                        _0x49a662['info'] = _0x114f36;
                        _0x49a662[_0x4f3f('0x36', 'V91Y')] = _0x114f36;
                        _0x49a662[_0x4f3f('0x37', 'l3oQ')] = _0x114f36;
                        _0x49a662[_0x4f3f('0x38', 'klod')] = _0x114f36;
                        return _0x49a662;
                } else {
                    _0x472ff2[0x3] = 0x0;
        } else {
            _0x472ff2[0x3] = _0x14393c;

Finally, we delete the call_ The code of 0x3966d3 is removed. All the places where $is used have been set to a fixed value. The second self executing function is removed, and then_ 0x4cec2b add a parameter

function _0x4cec2b(_0x567d6b) {
    var _0x164a16 = JSON['parse'](_0x567d6b);
    _0x9ff66b(_0x567d6b, _0x567d6b.length, true);
    var eid = _0x3966d3(0, 0, _0x1a395d(21));
    return eid;

Finally, you can directly call to get the last event ID pull. Take python or nodejs to the wave!

var eid  = _0x4cec2b('{"data":[{"num":"***","fc":0,"sc":0}],"guid":"","timeZoneOffset":-480}'));

Another way

Take out the universal python and use selenium, which is resource consuming and slow. If you need any last event ID, you can directly analyze the results.

from selenium import webdriver
import json
import requests

options.add_experimental_option('excludeSwitches', ['enable-automation'])

driver = webdriver.Chrome(executable_path="chromedriver.exe",chrome_options=options)

cookie = driver.get_cookie('Last-Event-ID')
eid = cookie['value']

Tags: Javascript

Posted by BK87 on Wed, 01 Jun 2022 03:45:05 +0530