前些日子遇到这种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
总结一下:
对于这种存在可读性可能的混淆,一步一步来就行了,没有技术含量。总结几点方法:
- 把被提取出来的东西放回去
var _$_ab37 = ["\x6C\x65\x6E\x67\x74\x68"...]
- 根据函数名给变量命名(函数名没被替换的情况)
- 根据逻辑习惯给变量命名,如:for循环内的变量、临时变量等
有兴趣的可以加QQ群(857149419)交流,新群,欢迎大家一起学习和交流。