JS反混淆 - 一个爬虫搬砖工的必备修养

前些日子遇到这种JS代码,根据以往CTF比赛的经验,猜测大概是个DES的重写。

源代码:

var _$_ab37 = ["\x6C\x65\x6E\x67\x74\x68", "", "\x76\x65\x72\x74", "\x73\x75\x62\x73\x74\x72\x69\x6E\x67", "\x63\x68\x61\x72\x43\x6F\x64\x65\x41\x74", "\x30", "\x30\x30\x30\x30", "\x31", "\x30\x30\x30\x31", "\x32", "\x30\x30\x31\x30", "\x33", "\x30\x30\x31\x31", "\x34", "\x30\x31\x30\x30", "\x35", "\x30\x31\x30\x31", "\x36", "\x30\x31\x31\x30", "\x37", "\x30\x31\x31\x31", "\x38", "\x31\x30\x30\x30", "\x39", "\x31\x30\x30\x31", "\x41", "\x31\x30\x31\x30", "\x42", "\x31\x30\x31\x31", "\x43", "\x31\x31\x30\x30", "\x44", "\x31\x31\x30\x31", "\x45", "\x31\x31\x31\x30", "\x46", "\x31\x31\x31\x31", "\x66\x72\x6F\x6D\x43\x68\x61\x72\x43\x6F\x64\x65"];

function strEnc(_0xD8A4, _0xD93A, _0xD96C, _0xDA34, _0xDB60) {
    var _0xD5E8 = _0xD8A4[_$_ab37[0]];
    var _0xD908 = _$_ab37[1];
    var _0xD99E, _0xDA66, _0xDB92, _0xD9D0, _0xDA98, _0xDBC4;
    if (_0xD96C != null && _0xD96C != _$_ab37[1]) {
        _0xD96C = _$_ab37[2];
        _0xD99E = getKeyBytes(_0xD96C);
        _0xD9D0 = _0xD99E[_$_ab37[0]]
    }
    ;
    if (_0xDA34 != null && _0xDA34 != _$_ab37[1]) {
        _0xDA66 = getKeyBytes(_0xDA34);
        _0xDA98 = _0xDA66[_$_ab37[0]]
    }
    ;
    if (_0xDB60 != null && _0xDB60 != _$_ab37[1]) {
        _0xDB92 = getKeyBytes(_0xDB60);
        _0xDBC4 = _0xDB92[_$_ab37[0]]
    }
    ;
    if (_0xD93A != null && _0xD93A != _$_ab37[1]) {
        fineKeyBt = getKeyBytes(_0xD93A);
        fineLength = fineKeyBt[_$_ab37[0]]
    }
    ;
    if (_0xD5E8 > 0) {
        if (_0xD5E8 < 4) {
            var _0xD070 = strToBt(_0xD8A4);
            var _0xD8D6;
            if (_0xD96C != null && _0xD96C != _$_ab37[1] && _0xDA34 != null && _0xDA34 != _$_ab37[1] && _0xDB60 != null && _0xDB60 != _$_ab37[1]) {
                var _0xDACA;
                var _0xDBF6, _0xDC28, _0xDC5A;
                _0xDACA = _0xD070;
                for (_0xDBF6 = 0; _0xDBF6 < _0xD9D0; _0xDBF6++) {
                    _0xDACA = enc(_0xDACA, _0xD99E[_0xDBF6])
                }
                ;
                for (_0xDC28 = 0; _0xDC28 < _0xDA98; _0xDC28++) {
                    _0xDACA = enc(_0xDACA, _0xDA66[_0xDC28])
                }
                ;
                for (_0xDC5A = 0; _0xDC5A < _0xDBC4; _0xDC5A++) {
                    _0xDACA = enc(_0xDACA, _0xDB92[_0xDC5A])
                }
                ;_0xD8D6 = _0xDACA
            } else {
                if (_0xD96C != null && _0xD96C != _$_ab37[1] && _0xDA34 != null && _0xDA34 != _$_ab37[1]) {
                    var _0xDACA;
                    var _0xDBF6, _0xDC28;
                    _0xDACA = _0xD070;
                    for (_0xDBF6 = 0; _0xDBF6 < _0xD9D0; _0xDBF6++) {
                        _0xDACA = enc(_0xDACA, _0xD99E[_0xDBF6])
                    }
                    ;
                    for (_0xDC28 = 0; _0xDC28 < _0xDA98; _0xDC28++) {
                        _0xDACA = enc(_0xDACA, _0xDA66[_0xDC28])
                    }
                    ;_0xD8D6 = _0xDACA
                } else {
                    if (_0xD96C != null && _0xD96C != _$_ab37[1]) {
                        var _0xDACA;
                        var _0xDBF6 = 0;
                        _0xDACA = _0xD070;
                        for (_0xDBF6 = 0; _0xDBF6 < _0xD9D0; _0xDBF6++) {
                            _0xDACA = enc(_0xDACA, _0xD99E[_0xDBF6])
                        }
                        ;_0xD8D6 = _0xDACA
                    }
                }
            }
            ;_0xD908 = bt64ToHex(_0xD8D6)
        } else {
            var _0xD584 = parseInt(_0xD5E8 / 4);
            var _0xD61A = _0xD5E8 % 4;
            var _0xD1CE = 0;
            for (_0xD1CE = 0; _0xD1CE < _0xD584; _0xD1CE++) {
                var _0xDB2E = _0xD8A4[_$_ab37[3]](_0xD1CE * 4 + 0, _0xD1CE * 4 + 4);
                var _0xDAFC = strToBt(_0xDB2E);
                var _0xD8D6;
                if (_0xD96C != null && _0xD96C != _$_ab37[1] && _0xDA34 != null && _0xDA34 != _$_ab37[1] && _0xDB60 != null && _0xDB60 != _$_ab37[1]) {
                    var _0xDACA;
                    var _0xDBF6, _0xDC28, _0xDC5A;
                    _0xDACA = _0xDAFC;
                    for (_0xDBF6 = 0; _0xDBF6 < _0xD9D0; _0xDBF6++) {
                        _0xDACA = enc(_0xDACA, _0xD99E[_0xDBF6])
                    }
                    ;
                    for (_0xDC28 = 0; _0xDC28 < _0xDA98; _0xDC28++) {
                        _0xDACA = enc(_0xDACA, _0xDA66[_0xDC28])
                    }
                    ;
                    for (_0xDC5A = 0; _0xDC5A < _0xDBC4; _0xDC5A++) {
                        _0xDACA = enc(_0xDACA, _0xDB92[_0xDC5A])
                    }
                    ;_0xD8D6 = _0xDACA
                } else {
                    if (_0xD96C != null && _0xD96C != _$_ab37[1] && _0xDA34 != null && _0xDA34 != _$_ab37[1]) {
                        var _0xDACA;
                        var _0xDBF6, _0xDC28;
                        _0xDACA = _0xDAFC;
                        for (_0xDBF6 = 0; _0xDBF6 < _0xD9D0; _0xDBF6++) {
                            _0xDACA = enc(_0xDACA, _0xD99E[_0xDBF6])
                        }
                        ;
                        for (_0xDC28 = 0; _0xDC28 < _0xDA98; _0xDC28++) {
                            _0xDACA = enc(_0xDACA, _0xDA66[_0xDC28])
                        }
                        ;_0xD8D6 = _0xDACA
                    } else {
                        if (_0xD96C != null && _0xD96C != _$_ab37[1]) {
                            var _0xDACA;
                            var _0xDBF6;
                            _0xDACA = _0xDAFC;
                            for (_0xDBF6 = 0; _0xDBF6 < _0xD9D0; _0xDBF6++) {
                                _0xDACA = enc(_0xDACA, _0xD99E[_0xDBF6])
                            }
                            ;_0xD8D6 = _0xDACA
                        }
                    }
                }
                ;_0xD908 += bt64ToHex(_0xD8D6)
            }
            ;
            if (_0xD61A > 0) {
                var _0xDA02 = _0xD8A4[_$_ab37[3]](_0xD584 * 4 + 0, _0xD5E8);
                var _0xDAFC = strToBt(_0xDA02);
                var _0xD8D6;
                if (_0xD96C != null && _0xD96C != _$_ab37[1] && _0xDA34 != null && _0xDA34 != _$_ab37[1] && _0xDB60 != null && _0xDB60 != _$_ab37[1]) {
                    var _0xDACA;
                    var _0xDBF6, _0xDC28, _0xDC5A;
                    _0xDACA = _0xDAFC;
                    for (_0xDBF6 = 0; _0xDBF6 < _0xD9D0; _0xDBF6++) {
                        _0xDACA = enc(_0xDACA, _0xD99E[_0xDBF6])
                    }
                    ;
                    for (_0xDC28 = 0; _0xDC28 < _0xDA98; _0xDC28++) {
                        _0xDACA = enc(_0xDACA, _0xDA66[_0xDC28])
                    }
                    ;
                    for (_0xDC5A = 0; _0xDC5A < _0xDBC4; _0xDC5A++) {
                        _0xDACA = enc(_0xDACA, _0xDB92[_0xDC5A])
                    }
                    ;_0xD8D6 = _0xDACA
                } else {
                    if (_0xD96C != null && _0xD96C != _$_ab37[1] && _0xDA34 != null && _0xDA34 != _$_ab37[1]) {
                        var _0xDACA;
                        var _0xDBF6, _0xDC28;
                        _0xDACA = _0xDAFC;
                        for (_0xDBF6 = 0; _0xDBF6 < _0xD9D0; _0xDBF6++) {
                            _0xDACA = enc(_0xDACA, _0xD99E[_0xDBF6])
                        }
                        ;
                        for (_0xDC28 = 0; _0xDC28 < _0xDA98; _0xDC28++) {
                            _0xDACA = enc(_0xDACA, _0xDA66[_0xDC28])
                        }
                        ;_0xD8D6 = _0xDACA
                    } else {
                        if (_0xD96C != null && _0xD96C != _$_ab37[1]) {
                            var _0xDACA;
                            var _0xDBF6;
                            _0xDACA = _0xDAFC;
                            for (_0xDBF6 = 0; _0xDBF6 < _0xD9D0; _0xDBF6++) {
                                _0xDACA = enc(_0xDACA, _0xD99E[_0xDBF6])
                            }
                            ;_0xD8D6 = _0xDACA
                        }
                    }
                }
                ;_0xD908 += bt64ToHex(_0xD8D6)
            }
        }
    }
    ;
    return _0xD908
}

function getKeyBytes(_0xD2FA) {
    var _0xD5B6 = new Array();
    var _0xD5E8 = _0xD2FA[_$_ab37[0]];
    var _0xD584 = parseInt(_0xD5E8 / 4);
    var _0xD61A = _0xD5E8 % 4;
    var _0xD1CE = 0;
    for (_0xD1CE = 0; _0xD1CE < _0xD584; _0xD1CE++) {
        _0xD5B6[_0xD1CE] = strToBt(_0xD2FA[_$_ab37[3]](_0xD1CE * 4 + 0, _0xD1CE * 4 + 4))
    }
    ;
    if (_0xD61A > 0) {
        _0xD5B6[_0xD1CE] = strToBt(_0xD2FA[_$_ab37[3]](_0xD1CE * 4 + 0, _0xD5E8))
    }
    ;
    return _0xD5B6
}

function strToBt(_0xD138) {
    var _0xD5E8 = _0xD138[_$_ab37[0]];
    var _0xD070 = new Array(64);
    if (_0xD5E8 < 4) {
        var _0xD1CE = 0, _0xD296 = 0, _0xDC8C = 0, _0xDCBE = 0;
        for (_0xD1CE = 0; _0xD1CE < _0xD5E8; _0xD1CE++) {
            var _0xD2C8 = _0xD138[_$_ab37[4]](_0xD1CE);
            for (_0xD296 = 0; _0xD296 < 16; _0xD296++) {
                var _0xD106 = 1, _0xD390 = 0;
                for (_0xD390 = 15; _0xD390 > _0xD296; _0xD390--) {
                    _0xD106 *= 2
                }
                ;_0xD070[16 * _0xD1CE + _0xD296] = parseInt(_0xD2C8 / _0xD106) % 2
            }
        }
        ;
        for (_0xDC8C = _0xD5E8; _0xDC8C < 4; _0xDC8C++) {
            var _0xD2C8 = 0;
            for (_0xDCBE = 0; _0xDCBE < 16; _0xDCBE++) {
                var _0xD106 = 1, _0xD390 = 0;
                for (_0xD390 = 15; _0xD390 > _0xDCBE; _0xD390--) {
                    _0xD106 *= 2
                }
                ;_0xD070[16 * _0xDC8C + _0xDCBE] = parseInt(_0xD2C8 / _0xD106) % 2
            }
        }
    } else {
        for (_0xD1CE = 0; _0xD1CE < 4; _0xD1CE++) {
            var _0xD2C8 = _0xD138[_$_ab37[4]](_0xD1CE);
            for (_0xD296 = 0; _0xD296 < 16; _0xD296++) {
                var _0xD106 = 1;
                for (_0xD390 = 15; _0xD390 > _0xD296; _0xD390--) {
                    _0xD106 *= 2
                }
                ;_0xD070[16 * _0xD1CE + _0xD296] = parseInt(_0xD2C8 / _0xD106) % 2
            }
        }
    }
    ;
    return _0xD070
}

function bt4ToHex(_0xD00C) {
    var _0xD03E;
    switch (_0xD00C) {
        case _$_ab37[6]:
            _0xD03E = _$_ab37[5];
            break;
        case _$_ab37[8]:
            _0xD03E = _$_ab37[7];
            break;
        case _$_ab37[10]:
            _0xD03E = _$_ab37[9];
            break;
        case _$_ab37[12]:
            _0xD03E = _$_ab37[11];
            break;
        case _$_ab37[14]:
            _0xD03E = _$_ab37[13];
            break;
        case _$_ab37[16]:
            _0xD03E = _$_ab37[15];
            break;
        case _$_ab37[18]:
            _0xD03E = _$_ab37[17];
            break;
        case _$_ab37[20]:
            _0xD03E = _$_ab37[19];
            break;
        case _$_ab37[22]:
            _0xD03E = _$_ab37[21];
            break;
        case _$_ab37[24]:
            _0xD03E = _$_ab37[23];
            break;
        case _$_ab37[26]:
            _0xD03E = _$_ab37[25];
            break;
        case _$_ab37[28]:
            _0xD03E = _$_ab37[27];
            break;
        case _$_ab37[30]:
            _0xD03E = _$_ab37[29];
            break;
        case _$_ab37[32]:
            _0xD03E = _$_ab37[31];
            break;
        case _$_ab37[34]:
            _0xD03E = _$_ab37[33];
            break;
        case _$_ab37[36]:
            _0xD03E = _$_ab37[35];
            break
    }
    ;
    return _0xD03E
}

function hexToBt4(_0xD03E) {
    var _0xD00C;
    switch (_0xD03E) {
        case _$_ab37[5]:
            _0xD00C = _$_ab37[6];
            break;
        case _$_ab37[7]:
            _0xD00C = _$_ab37[8];
            break;
        case _$_ab37[9]:
            _0xD00C = _$_ab37[10];
            break;
        case _$_ab37[11]:
            _0xD00C = _$_ab37[12];
            break;
        case _$_ab37[13]:
            _0xD00C = _$_ab37[14];
            break;
        case _$_ab37[15]:
            _0xD00C = _$_ab37[16];
            break;
        case _$_ab37[17]:
            _0xD00C = _$_ab37[18];
            break;
        case _$_ab37[19]:
            _0xD00C = _$_ab37[20];
            break;
        case _$_ab37[21]:
            _0xD00C = _$_ab37[22];
            break;
        case _$_ab37[23]:
            _0xD00C = _$_ab37[24];
            break;
        case _$_ab37[25]:
            _0xD00C = _$_ab37[26];
            break;
        case _$_ab37[27]:
            _0xD00C = _$_ab37[28];
            break;
        case _$_ab37[29]:
            _0xD00C = _$_ab37[30];
            break;
        case _$_ab37[31]:
            _0xD00C = _$_ab37[32];
            break;
        case _$_ab37[33]:
            _0xD00C = _$_ab37[34];
            break;
        case _$_ab37[35]:
            _0xD00C = _$_ab37[36];
            break
    }
    ;
    return _0xD00C
}

function byteToString(_0xD0A2) {
    var _0xD138 = _$_ab37[1];
    for (i = 0; i < 4; i++) {
        var _0xD0D4 = 0;
        for (j = 0; j < 16; j++) {
            var _0xD106 = 1;
            for (m = 15; m > j; m--) {
                _0xD106 *= 2
            }
            ;_0xD0D4 += _0xD0A2[16 * i + j] * _0xD106
        }
        ;
        if (_0xD0D4 != 0) {
            _0xD138 += String[_$_ab37[37]](_0xD0D4)
        }
    }
    ;
    return _0xD138
}

function bt64ToHex(_0xD0A2) {
    var _0xD03E = _$_ab37[1];
    for (i = 0; i < 16; i++) {
        var _0xD070 = _$_ab37[1];
        for (j = 0; j < 4; j++) {
            _0xD070 += _0xD0A2[i * 4 + j]
        }
        ;_0xD03E += bt4ToHex(_0xD070)
    }
    ;
    return _0xD03E
}

function hexToBt64(_0xD03E) {
    var _0xD00C = _$_ab37[1];
    for (i = 0; i < 16; i++) {
        _0xD00C += hexToBt4(_0xD03E[_$_ab37[3]](i, i + 1))
    }
    ;
    return _0xD00C
}

function enc(_0xD16A, _0xD32C) {
    var _0xD35E = generateKeys(_0xD32C);
    var _0xD200 = initPermute(_0xD16A);
    var _0xD232 = new Array(32);
    var _0xD264 = new Array(32);
    var _0xD3F4 = new Array(32);
    var _0xD1CE = 0, _0xD296 = 0, _0xD2C8 = 0, _0xD390 = 0, _0xD3C2 = 0;
    for (_0xD2C8 = 0; _0xD2C8 < 32; _0xD2C8++) {
        _0xD232[_0xD2C8] = _0xD200[_0xD2C8];
        _0xD264[_0xD2C8] = _0xD200[32 + _0xD2C8]
    }
    ;
    for (_0xD1CE = 0; _0xD1CE < 16; _0xD1CE++) {
        for (_0xD296 = 0; _0xD296 < 32; _0xD296++) {
            _0xD3F4[_0xD296] = _0xD232[_0xD296];
            _0xD232[_0xD296] = _0xD264[_0xD296]
        }
        ;var _0xD2FA = new Array(48);
        for (_0xD390 = 0; _0xD390 < 48; _0xD390++) {
            _0xD2FA[_0xD390] = _0xD35E[_0xD1CE][_0xD390]
        }
        ;var _0xD426 = xor(pPermute(sBoxPermute(xor(expandPermute(_0xD264), _0xD2FA))), _0xD3F4);
        for (_0xD3C2 = 0; _0xD3C2 < 32; _0xD3C2++) {
            _0xD264[_0xD3C2] = _0xD426[_0xD3C2]
        }
    }
    ;var _0xD19C = new Array(64);
    for (_0xD1CE = 0; _0xD1CE < 32; _0xD1CE++) {
        _0xD19C[_0xD1CE] = _0xD264[_0xD1CE];
        _0xD19C[32 + _0xD1CE] = _0xD232[_0xD1CE]
    }
    ;
    return finallyPermute(_0xD19C)
}

function initPermute(_0xD64C) {
    var _0xD200 = new Array(64);
    for (i = 0, m = 1, n = 0; i < 4; i++, m += 2, n += 2) {
        for (j = 7, k = 0; j >= 0; j--, k++) {
            _0xD200[i * 8 + k] = _0xD64C[j * 8 + m];
            _0xD200[i * 8 + k + 32] = _0xD64C[j * 8 + n]
        }
    }
    ;
    return _0xD200
}

function expandPermute(_0xD48A) {
    var _0xD458 = new Array(48);
    for (i = 0; i < 8; i++) {
        if (i == 0) {
            _0xD458[i * 6 + 0] = _0xD48A[31]
        } else {
            _0xD458[i * 6 + 0] = _0xD48A[i * 4 - 1]
        }
        ;_0xD458[i * 6 + 1] = _0xD48A[i * 4 + 0];
        _0xD458[i * 6 + 2] = _0xD48A[i * 4 + 1];
        _0xD458[i * 6 + 3] = _0xD48A[i * 4 + 2];
        _0xD458[i * 6 + 4] = _0xD48A[i * 4 + 3];
        if (i == 7) {
            _0xD458[i * 6 + 5] = _0xD48A[0]
        } else {
            _0xD458[i * 6 + 5] = _0xD48A[i * 4 + 4]
        }
    }
    ;
    return _0xD458
}

function xor(_0xDCF0, _0xDD22) {
    var _0xDD54 = new Array(_0xDCF0[_$_ab37[0]]);
    for (i = 0; i < _0xDCF0[_$_ab37[0]]; i++) {
        _0xDD54[i] = _0xDCF0[i] ^ _0xDD22[i]
    }
    ;
    return _0xDD54
}

function sBoxPermute(_0xD6E2) {
    var _0xD6B0 = new Array(32);
    var _0xD00C = _$_ab37[1];
    var _0xD714 = [[14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7], [0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8], [4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0], [15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13]];
    var _0xD746 = [[15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10], [3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5], [0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15], [13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9]];
    var _0xD778 = [[10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8], [13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1], [13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7], [1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12]];
    var _0xD7AA = [[7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15], [13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9], [10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4], [3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14]];
    var _0xD7DC = [[2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9], [14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6], [4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14], [11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3]];
    var _0xD80E = [[12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11], [10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8], [9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6], [4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13]];
    var _0xD840 = [[4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1], [13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6], [1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2], [6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12]];
    var _0xD872 = [[13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7], [1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2], [7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8], [2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]];
    for (m = 0; m < 8; m++) {
        var _0xD1CE = 0, _0xD296 = 0;
        _0xD1CE = _0xD6E2[m * 6 + 0] * 2 + _0xD6E2[m * 6 + 5];
        _0xD296 = _0xD6E2[m * 6 + 1] * 2 * 2 * 2 + _0xD6E2[m * 6 + 2] * 2 * 2 + _0xD6E2[m * 6 + 3] * 2 + _0xD6E2[m * 6 + 4];
        switch (m) {
            case 0:
                _0xD00C = getBoxBinary(_0xD714[_0xD1CE][_0xD296]);
                break;
            case 1:
                _0xD00C = getBoxBinary(_0xD746[_0xD1CE][_0xD296]);
                break;
            case 2:
                _0xD00C = getBoxBinary(_0xD778[_0xD1CE][_0xD296]);
                break;
            case 3:
                _0xD00C = getBoxBinary(_0xD7AA[_0xD1CE][_0xD296]);
                break;
            case 4:
                _0xD00C = getBoxBinary(_0xD7DC[_0xD1CE][_0xD296]);
                break;
            case 5:
                _0xD00C = getBoxBinary(_0xD80E[_0xD1CE][_0xD296]);
                break;
            case 6:
                _0xD00C = getBoxBinary(_0xD840[_0xD1CE][_0xD296]);
                break;
            case 7:
                _0xD00C = getBoxBinary(_0xD872[_0xD1CE][_0xD296]);
                break
        }
        ;_0xD6B0[m * 4 + 0] = parseInt(_0xD00C[_$_ab37[3]](0, 1));
        _0xD6B0[m * 4 + 1] = parseInt(_0xD00C[_$_ab37[3]](1, 2));
        _0xD6B0[m * 4 + 2] = parseInt(_0xD00C[_$_ab37[3]](2, 3));
        _0xD6B0[m * 4 + 3] = parseInt(_0xD00C[_$_ab37[3]](3, 4))
    }
    ;
    return _0xD6B0
}

function pPermute(_0xD6B0) {
    var _0xD67E = new Array(32);
    _0xD67E[0] = _0xD6B0[15];
    _0xD67E[1] = _0xD6B0[6];
    _0xD67E[2] = _0xD6B0[19];
    _0xD67E[3] = _0xD6B0[20];
    _0xD67E[4] = _0xD6B0[28];
    _0xD67E[5] = _0xD6B0[11];
    _0xD67E[6] = _0xD6B0[27];
    _0xD67E[7] = _0xD6B0[16];
    _0xD67E[8] = _0xD6B0[0];
    _0xD67E[9] = _0xD6B0[14];
    _0xD67E[10] = _0xD6B0[22];
    _0xD67E[11] = _0xD6B0[25];
    _0xD67E[12] = _0xD6B0[4];
    _0xD67E[13] = _0xD6B0[17];
    _0xD67E[14] = _0xD6B0[30];
    _0xD67E[15] = _0xD6B0[9];
    _0xD67E[16] = _0xD6B0[1];
    _0xD67E[17] = _0xD6B0[7];
    _0xD67E[18] = _0xD6B0[23];
    _0xD67E[19] = _0xD6B0[13];
    _0xD67E[20] = _0xD6B0[31];
    _0xD67E[21] = _0xD6B0[26];
    _0xD67E[22] = _0xD6B0[2];
    _0xD67E[23] = _0xD6B0[8];
    _0xD67E[24] = _0xD6B0[18];
    _0xD67E[25] = _0xD6B0[12];
    _0xD67E[26] = _0xD6B0[29];
    _0xD67E[27] = _0xD6B0[5];
    _0xD67E[28] = _0xD6B0[21];
    _0xD67E[29] = _0xD6B0[10];
    _0xD67E[30] = _0xD6B0[3];
    _0xD67E[31] = _0xD6B0[24];
    return _0xD67E
}

function finallyPermute(_0xD4BC) {
    var _0xD4EE = new Array(64);
    _0xD4EE[0] = _0xD4BC[39];
    _0xD4EE[1] = _0xD4BC[7];
    _0xD4EE[2] = _0xD4BC[47];
    _0xD4EE[3] = _0xD4BC[15];
    _0xD4EE[4] = _0xD4BC[55];
    _0xD4EE[5] = _0xD4BC[23];
    _0xD4EE[6] = _0xD4BC[63];
    _0xD4EE[7] = _0xD4BC[31];
    _0xD4EE[8] = _0xD4BC[38];
    _0xD4EE[9] = _0xD4BC[6];
    _0xD4EE[10] = _0xD4BC[46];
    _0xD4EE[11] = _0xD4BC[14];
    _0xD4EE[12] = _0xD4BC[54];
    _0xD4EE[13] = _0xD4BC[22];
    _0xD4EE[14] = _0xD4BC[62];
    _0xD4EE[15] = _0xD4BC[30];
    _0xD4EE[16] = _0xD4BC[37];
    _0xD4EE[17] = _0xD4BC[5];
    _0xD4EE[18] = _0xD4BC[45];
    _0xD4EE[19] = _0xD4BC[13];
    _0xD4EE[20] = _0xD4BC[53];
    _0xD4EE[21] = _0xD4BC[21];
    _0xD4EE[22] = _0xD4BC[61];
    _0xD4EE[23] = _0xD4BC[29];
    _0xD4EE[24] = _0xD4BC[36];
    _0xD4EE[25] = _0xD4BC[4];
    _0xD4EE[26] = _0xD4BC[44];
    _0xD4EE[27] = _0xD4BC[12];
    _0xD4EE[28] = _0xD4BC[52];
    _0xD4EE[29] = _0xD4BC[20];
    _0xD4EE[30] = _0xD4BC[60];
    _0xD4EE[31] = _0xD4BC[28];
    _0xD4EE[32] = _0xD4BC[35];
    _0xD4EE[33] = _0xD4BC[3];
    _0xD4EE[34] = _0xD4BC[43];
    _0xD4EE[35] = _0xD4BC[11];
    _0xD4EE[36] = _0xD4BC[51];
    _0xD4EE[37] = _0xD4BC[19];
    _0xD4EE[38] = _0xD4BC[59];
    _0xD4EE[39] = _0xD4BC[27];
    _0xD4EE[40] = _0xD4BC[34];
    _0xD4EE[41] = _0xD4BC[2];
    _0xD4EE[42] = _0xD4BC[42];
    _0xD4EE[43] = _0xD4BC[10];
    _0xD4EE[44] = _0xD4BC[50];
    _0xD4EE[45] = _0xD4BC[18];
    _0xD4EE[46] = _0xD4BC[58];
    _0xD4EE[47] = _0xD4BC[26];
    _0xD4EE[48] = _0xD4BC[33];
    _0xD4EE[49] = _0xD4BC[1];
    _0xD4EE[50] = _0xD4BC[41];
    _0xD4EE[51] = _0xD4BC[9];
    _0xD4EE[52] = _0xD4BC[49];
    _0xD4EE[53] = _0xD4BC[17];
    _0xD4EE[54] = _0xD4BC[57];
    _0xD4EE[55] = _0xD4BC[25];
    _0xD4EE[56] = _0xD4BC[32];
    _0xD4EE[57] = _0xD4BC[0];
    _0xD4EE[58] = _0xD4BC[40];
    _0xD4EE[59] = _0xD4BC[8];
    _0xD4EE[60] = _0xD4BC[48];
    _0xD4EE[61] = _0xD4BC[16];
    _0xD4EE[62] = _0xD4BC[56];
    _0xD4EE[63] = _0xD4BC[24];
    return _0xD4EE
}

function getBoxBinary(_0xD1CE) {
    var _0xD00C = _$_ab37[1];
    switch (_0xD1CE) {
        case 0:
            _0xD00C = _$_ab37[6];
            break;
        case 1:
            _0xD00C = _$_ab37[8];
            break;
        case 2:
            _0xD00C = _$_ab37[10];
            break;
        case 3:
            _0xD00C = _$_ab37[12];
            break;
        case 4:
            _0xD00C = _$_ab37[14];
            break;
        case 5:
            _0xD00C = _$_ab37[16];
            break;
        case 6:
            _0xD00C = _$_ab37[18];
            break;
        case 7:
            _0xD00C = _$_ab37[20];
            break;
        case 8:
            _0xD00C = _$_ab37[22];
            break;
        case 9:
            _0xD00C = _$_ab37[24];
            break;
        case 10:
            _0xD00C = _$_ab37[26];
            break;
        case 11:
            _0xD00C = _$_ab37[28];
            break;
        case 12:
            _0xD00C = _$_ab37[30];
            break;
        case 13:
            _0xD00C = _$_ab37[32];
            break;
        case 14:
            _0xD00C = _$_ab37[34];
            break;
        case 15:
            _0xD00C = _$_ab37[36];
            break
    }
    ;
    return _0xD00C
}

function generateKeys(_0xD32C) {
    var _0xD2FA = new Array(56);
    var _0xD35E = new Array();
    _0xD35E[0] = new Array();
    _0xD35E[1] = new Array();
    _0xD35E[2] = new Array();
    _0xD35E[3] = new Array();
    _0xD35E[4] = new Array();
    _0xD35E[5] = new Array();
    _0xD35E[6] = new Array();
    _0xD35E[7] = new Array();
    _0xD35E[8] = new Array();
    _0xD35E[9] = new Array();
    _0xD35E[10] = new Array();
    _0xD35E[11] = new Array();
    _0xD35E[12] = new Array();
    _0xD35E[13] = new Array();
    _0xD35E[14] = new Array();
    _0xD35E[15] = new Array();
    var _0xD520 = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1];
    for (_0xD1CE = 0; _0xD1CE < 7; _0xD1CE++) {
        for (j = 0, k = 7; j < 8; j++, k--) {
            _0xD2FA[_0xD1CE * 8 + j] = _0xD32C[8 * k + _0xD1CE]
        }
    }
    ;var _0xD1CE = 0;
    for (_0xD1CE = 0; _0xD1CE < 16; _0xD1CE++) {
        var _0xD3F4 = 0;
        var _0xD426 = 0;
        for (j = 0; j < _0xD520[_0xD1CE]; j++) {
            _0xD3F4 = _0xD2FA[0];
            _0xD426 = _0xD2FA[28];
            for (k = 0; k < 27; k++) {
                _0xD2FA[k] = _0xD2FA[k + 1];
                _0xD2FA[28 + k] = _0xD2FA[29 + k]
            }
            ;_0xD2FA[27] = _0xD3F4;
            _0xD2FA[55] = _0xD426
        }
        ;var _0xD552 = new Array(48);
        _0xD552[0] = _0xD2FA[13];
        _0xD552[1] = _0xD2FA[16];
        _0xD552[2] = _0xD2FA[10];
        _0xD552[3] = _0xD2FA[23];
        _0xD552[4] = _0xD2FA[0];
        _0xD552[5] = _0xD2FA[4];
        _0xD552[6] = _0xD2FA[2];
        _0xD552[7] = _0xD2FA[27];
        _0xD552[8] = _0xD2FA[14];
        _0xD552[9] = _0xD2FA[5];
        _0xD552[10] = _0xD2FA[20];
        _0xD552[11] = _0xD2FA[9];
        _0xD552[12] = _0xD2FA[22];
        _0xD552[13] = _0xD2FA[18];
        _0xD552[14] = _0xD2FA[11];
        _0xD552[15] = _0xD2FA[3];
        _0xD552[16] = _0xD2FA[25];
        _0xD552[17] = _0xD2FA[7];
        _0xD552[18] = _0xD2FA[15];
        _0xD552[19] = _0xD2FA[6];
        _0xD552[20] = _0xD2FA[26];
        _0xD552[21] = _0xD2FA[19];
        _0xD552[22] = _0xD2FA[12];
        _0xD552[23] = _0xD2FA[1];
        _0xD552[24] = _0xD2FA[40];
        _0xD552[25] = _0xD2FA[51];
        _0xD552[26] = _0xD2FA[30];
        _0xD552[27] = _0xD2FA[36];
        _0xD552[28] = _0xD2FA[46];
        _0xD552[29] = _0xD2FA[54];
        _0xD552[30] = _0xD2FA[29];
        _0xD552[31] = _0xD2FA[39];
        _0xD552[32] = _0xD2FA[50];
        _0xD552[33] = _0xD2FA[44];
        _0xD552[34] = _0xD2FA[32];
        _0xD552[35] = _0xD2FA[47];
        _0xD552[36] = _0xD2FA[43];
        _0xD552[37] = _0xD2FA[48];
        _0xD552[38] = _0xD2FA[38];
        _0xD552[39] = _0xD2FA[55];
        _0xD552[40] = _0xD2FA[33];
        _0xD552[41] = _0xD2FA[52];
        _0xD552[42] = _0xD2FA[45];
        _0xD552[43] = _0xD2FA[41];
        _0xD552[44] = _0xD2FA[49];
        _0xD552[45] = _0xD2FA[35];
        _0xD552[46] = _0xD2FA[28];
        _0xD552[47] = _0xD2FA[31];
        switch (_0xD1CE) {
            case 0:
                for (m = 0; m < 48; m++) {
                    _0xD35E[0][m] = _0xD552[m]
                }
                ;
                break;
            case 1:
                for (m = 0; m < 48; m++) {
                    _0xD35E[1][m] = _0xD552[m]
                }
                ;
                break;
            case 2:
                for (m = 0; m < 48; m++) {
                    _0xD35E[2][m] = _0xD552[m]
                }
                ;
                break;
            case 3:
                for (m = 0; m < 48; m++) {
                    _0xD35E[3][m] = _0xD552[m]
                }
                ;
                break;
            case 4:
                for (m = 0; m < 48; m++) {
                    _0xD35E[4][m] = _0xD552[m]
                }
                ;
                break;
            case 5:
                for (m = 0; m < 48; m++) {
                    _0xD35E[5][m] = _0xD552[m]
                }
                ;
                break;
            case 6:
                for (m = 0; m < 48; m++) {
                    _0xD35E[6][m] = _0xD552[m]
                }
                ;
                break;
            case 7:
                for (m = 0; m < 48; m++) {
                    _0xD35E[7][m] = _0xD552[m]
                }
                ;
                break;
            case 8:
                for (m = 0; m < 48; m++) {
                    _0xD35E[8][m] = _0xD552[m]
                }
                ;
                break;
            case 9:
                for (m = 0; m < 48; m++) {
                    _0xD35E[9][m] = _0xD552[m]
                }
                ;
                break;
            case 10:
                for (m = 0; m < 48; m++) {
                    _0xD35E[10][m] = _0xD552[m]
                }
                ;
                break;
            case 11:
                for (m = 0; m < 48; m++) {
                    _0xD35E[11][m] = _0xD552[m]
                }
                ;
                break;
            case 12:
                for (m = 0; m < 48; m++) {
                    _0xD35E[12][m] = _0xD552[m]
                }
                ;
                break;
            case 13:
                for (m = 0; m < 48; m++) {
                    _0xD35E[13][m] = _0xD552[m]
                }
                ;
                break;
            case 14:
                for (m = 0; m < 48; m++) {
                    _0xD35E[14][m] = _0xD552[m]
                }
                ;
                break;
            case 15:
                for (m = 0; m < 48; m++) {
                    _0xD35E[15][m] = _0xD552[m]
                }
                ;
                break
        }
    }
    ;
    return _0xD35E
}

准备工作:

那么怎么解呢,首先把十六进制的["\x6C\x65\x6E\x67\x74\x68", "", "\x76\x65\x72\x74", "\x73\x75\x62\x73\x74\x72\x69\x6E\x67", "\x63\x68\x61\x72\x43\x6F\x64\x65\x41\x74", "\x30", "\x30\x30\x30\x30", "\x31", "\x30\x30\x30\x31", "\x32", "\x30\x30\x31\x30", "\x33", "\x30\x30\x31\x31", "\x34", "\x30\x31\x30\x30", "\x35", "\x30\x31\x30\x31", "\x36", "\x30\x31\x31\x30", "\x37", "\x30\x31\x31\x31", "\x38", "\x31\x30\x30\x30", "\x39", "\x31\x30\x30\x31", "\x41", "\x31\x30\x31\x30", "\x42", "\x31\x30\x31\x31", "\x43", "\x31\x31\x30\x30", "\x44", "\x31\x31\x30\x31", "\x45", "\x31\x31\x31\x30", "\x46", "\x31\x31\x31\x31", "\x66\x72\x6F\x6D\x43\x68\x61\x72\x43\x6F\x64\x65"]
翻译成["length", "", "vert", "substring", "charCodeAt", "0", "0000", "1", "0001", "2", "0010", "3", "0011", "4", "0100", "5", "0101", "6", "0110", "7", "0111", "8", "1000", "9", "1001", "A", "1010", "B", "1011", "C", "1100", "D", "1101", "E", "1110", "F", "1111", "fromCharCode"]

变量 _$_ab37 中的 length、substring、charCodeAt是不是很熟悉,我们来个一次性替换吧

var _0xD5E8 = _0xD8A4["length"];

我们用python替换一下

v = ["length", "", "vert", "substring", "charCodeAt", "0", "0000", "1", "0001", "2", "0010", "3", "0011", "4", "0100", "5", "0101", "6", "0110", "7", "0111", "8", "1000", "9", "1001", "A", "1010", "B", "1011", "C", "1100", "D", "1101", "E", "1110", "F", "1111", "fromCharCode"];

with open("1.js", encoding="utf-8") as f:
    d = "".join(f.readlines())

for i in range(len(v)):
    d = d.replace('_$_ab37[{}]'.format(i), '"{}"'.format(v[i]))

print(v)

开工:

多数的加密都是操作字节码,根据下面的函数名,我们能知道,_0xD99E、_0xDA66、_0xDB92、fineKeyBt 分别为_0xD96C、_0xDA34、_0xDB60、_0xD93A 的key的字节码(bytes形式)

_0xD99E = getKeyBytes(_0xD96C);
...
_0xDA66 = getKeyBytes(_0xDA34);
...
_0xDB92 = getKeyBytes(_0xDB60);
...
fineKeyBt = getKeyBytes(_0xD93A);

我们为其正名:

function strEnc(data, key1, key2, key3, key4) {
    var data_length = data["length"];
    var _0xD908 = "";
    var key2byte, key3byte, key4byte, key2byteLength, key3byteLength, key4byteLength;
    if (key2 != null && key2 != "") {
        key2 = "vert";
        key2byte = getKeyBytes(key2);
        key2byteLength = key2byte["length"]
    };
    if (key3 != null && key3 != "") {
        key3byte = getKeyBytes(key3);
        key3byteLength = key3byte["length"]
    };
    if (key4 != null && key4 != "") {
        key4byte = getKeyBytes(key4);
        key4byteLength = key4byte["length"]
    };
    if (key1 != null && key1 != "") {
        fineKeyBt = getKeyBytes(key1);
        fineLength = fineKeyBt["length"]
    };

是不是清爽多了,再往下看,strToBt()这个函数顾名思义把字符串转成Bytes,保险起见可以跳转进函数内部瞧一瞧,我确认过了这里就不再赘述了,接下来看

if (key2 != null && key2 != "" && key3 != null && key3 != "" && key4 != null && key4 != "") {
    var _0xDACA;
    var _0xDBF6, _0xDC28, _0xDC5A;
    _0xDACA = _0xD070;
    for (_0xDBF6 = 0; _0xDBF6 < key2byteLength; _0xDBF6++) {
        _0xDACA = enc(_0xDACA, key2byte[_0xDBF6])
    };
    for (_0xDC28 = 0; _0xDC28 < key3byteLength; _0xDC28++) {
        _0xDACA = enc(_0xDACA, key3byte[_0xDC28])
    };
    for (_0xDC5A = 0; _0xDC5A < key4byteLength; _0xDC5A++) {
        _0xDACA = enc(_0xDACA, key4byte[_0xDC5A])
    };
    _0xD8D6 = _0xDACA
}

for(? = 0; ? < ?; ?++) 这种形式是不是特别熟悉
变量 _0xDBF6、_0xDC28、_0xDC5A 分别是上面循环的索引,虽然本质是一样的东西,我们却不擅长看这种变量,那就写成熟悉的模样

for (var i = 0; i < key2byteLength; i++) {
    _0xDACA = enc(_0xDACA, key2byte[i])
};
for (var j = 0; j < key3byteLength; j++) {
    _0xDACA = enc(_0xDACA, key3byte[j])
};
for (var k = 0; k < key4byteLength; k++) {
    _0xDACA = enc(_0xDACA, key4byte[k])
};

_0xDACA 可以追溯到这里:

var _0xD070 = strToBt(data);
...
var _0xDACA;
 _0xDACA = _0xD070;
...
_0xDACA = enc(_0xDACA, key2byte[i])

本质就是被转换成Bytes类型的待加密内容(data)
我们再美化一下:

var dataBytes = strToBt(data);
var encryptedData;
if (key2 != null && key2 != "" && key3 != null && key3 != "" && key4 != null && key4 != "") {
    var encryptTemp;
    encryptTemp = dataBytes;
    for (var i = 0; i < key2byteLength; i++) {
        encryptTemp = enc(encryptTemp, key2byte[i])
    };
    for (var j = 0; j < key3byteLength; j++) {
        encryptTemp = enc(encryptTemp, key3byte[j])
    };
    for (var k = 0; k < key4byteLength; k++) {
        encryptTemp = enc(encryptTemp, key4byte[k])
    };
    encryptedData = encryptTemp
}

到这里小编已经编不下去了,反混淆是个苦力活,小编已经将毕生的连蒙带猜的功法传授给大家了。这次是运气好遇到只是替换了变量名的混淆js。
这个JS加密最大的秘密大概就是下面这句狸猫换太子了。

if (key2 != null && key2 != "") {
    key2 = "vert";
    key2byte = getKeyBytes(key2);
    key2byteLength = key2byte["length"]
};

最后一步了:

对方网站调用语句

strEnc($("#lgyz").val(),"lgyz",Math.random())

看似传入很多,其实都是虚晃一枪的障眼法。
手撸了Java加密代码,篇幅原因只放了其中一部分:

public String strEnc(String data, String firstKey) {

    int length = data.length();
    StringBuilder encData = new StringBuilder();
    List firstKeyBt = null;
    int firstLength = 0;
    if (firstKey != null && !firstKey.equals("")) {
        firstKeyBt = getKeyBytes(firstKey);
        firstLength = firstKeyBt.size();
    }

    int iterator = (length / 4);
    int remainder = length % 4;
    for (int i = 0; i < iterator; i++) {
        String tempData = data.substring(i * 4, i * 4 + 4);
        int[] tempByte = strToBt(tempData);
        int[] encByte = getInts(firstKey, firstKeyBt, firstLength, tempByte);
        encData.append(bt64ToHex(encByte));
    }
    if (remainder > 0) {
        String remainderData = data.substring(iterator * 4,
            length);
        int[] tempByte = strToBt(remainderData);
        int[] encByte = getInts(firstKey, firstKeyBt, firstLength, tempByte);
        encData.append(bt64ToHex(encByte));
    }
    return encData.toString();
}

验证:

# 加密前:E65788941F5B4B08B0A996A93B4FCCAA
# 加密后:CF7DB719F88AB5071520F74332841F62DF73F4DD82B65235DA54B00C5AE136522B3FE4DAAC23CE7FAAEA019694D33A867F4D258BD16C2E0B2A7C9ABC5C777231

总结一下:

对于这种存在可读性可能的混淆,一步一步来就行了,没有技术含量。总结几点方法:

  1. 把被提取出来的东西放回去
var _$_ab37 = ["\x6C\x65\x6E\x67\x74\x68"...]
  1. 根据函数名给变量命名(函数名没被替换的情况)
  2. 根据逻辑习惯给变量命名,如:for循环内的变量、临时变量等

有兴趣的可以加QQ群(857149419)交流,新群,欢迎大家一起学习和交流。

你可能感兴趣的:(JS反混淆 - 一个爬虫搬砖工的必备修养)