python爬虫破解带有CryptoJS的aes加密的反爬机制
发现问题
在一次偶然中,在爬取某个公开网站(非商业型网站)时,老方法,打开调试工具查看请求方式,请求拦截,是否是异步加载,不亦乐乎,当我以为这个网站非常简单的时候,发现二级网页的地址和源码不对应

Ajax异步加载?源码也是这样的

而且这些链接直接访问根本无法访问

用火狐浏览器的event显示:

找到加密方式
源码:

function() {
  var hh = $(this).attr("href");
  if (typeof(hh) == 'undefined' || hh == '#') {
    return
  }
  var aa = hh.split("/");
  var aaa = aa.length;
  var bbb = aa[aaa - 1].split('.');
  var ccc = bbb[0];
  var cccc = bbb[1];
  var r = /^\+?[1-9][0-9]*$/;
  if (r.test(ccc) && cccc.indexOf('jhtml') != -1) {
    var srcs = CryptoJS.enc.Utf8.parse(ccc);
    var k = CryptoJS.enc.Utf8.parse(s);
    var en = CryptoJS.AES.encrypt(srcs, k, {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.Pkcs7
    });
    var ddd = en.toString();
    ddd = ddd.replace(/\//g, "^");
    ddd = ddd.substring(0, ddd.length - 2);
    var bbbb = ddd + '.' + bbb[1];
    aa[aaa - 1] = bbbb;
    var uuu = '';
    for (i = 0; i < aaa; i++) {
      uuu += aa[i] + '/'
    }
    uuu = uuu.substring(0, uuu.length - 1);
    window.open(uuu)
  } else {
    var ee = $(this).attr('target');
    if (ee.typeof('undefined')) {
      window.location = hh
    } else {
      window.open(hh)
    }
  }
  return false
}
根据我的发现,实现的效果就是让源码的链接:
http://xxxx.xxxx.xx:80/jssfdg/3254639.jhtml
变为如下链接:
http://xxxx.xxxx.xx:80/jssfdg/JzRnGhk7J9D1ZNMlh47fMw.jhtml
以上代码缩减了下:
就这几行代码:
var srcs = CryptoJS.enc.Utf8.parse(ccc);
var k = CryptoJS.enc.Utf8.parse(s);
var en = CryptoJS.AES.encrypt(srcs, k, {
         mode: CryptoJS.mode.ECB,
         padding: CryptoJS.pad.Pkcs7
});
var ddd = en.toString();
ddd = ddd.replace(/\//g, "^");
ddd = ddd.substring(0, ddd.length - 2);
return ddd
将以上代码封装为一个函数并在浏览器的控制台测试:
大概的意思就是先将那串数字用utf8加密成数组:

再对密钥操作:

再将上面的两个数组用aes加密

将用aes加密过的en转为字符串:

我渣一看这种字符串像是base64加密
再将带有/符号的转为^,因为在url编码中,/符号有特殊意义

再将数据后面的[==]分割掉

最后的字符串就是需要的数据了
把这段操作封装成一个函数,然后测试:

经过测试,没毛病,返回的这个字符与真实的一致。
卧槽,瞬间激动啦,这还没完,我是直接在当前网页的控制台操作的,换到其他网页的控制台:

需要两个重要的东西:CryptoJS对象 和 s变量
CryptoJS对象都还好,那特么一定是引入的,s变量就难了,从源码找,包含s的太多了,而且还是小写,关键词太多了
而且S变量是已经定义好的,因为我打开控制台直接访问s就能有结果:

所以,那绝对是已定义的,但是我无法确定是写死的还是随机生成的,如果按写死的来,那就难了,所以我必须找到它,它也至关重要,因为就是aes加密需要的密钥,不然无法加密出来希望的格式
我找了一上午,还请教了我的前端大佬同事,也是一时不知道怎么找
最后,我把当天的任务忙完之后,专门腾出两小时时间来再分析,我一个一个js文件慢慢看:
找到key值
结果,他么的,放在jquery源码里面:

而且,还真的是写死的
卧槽!!!!!!!!!!!!!!!!!!!!,太nm骚了,放源码了,按正常人的惯用思维,像什么jquery,vue等的源码,一定是不敢去乱改的,要写js的话,也不敢去乱搞,都是新建一个js文件写入,它这个把密钥写在jquery源码里,简直反其道而行,我不知道说这个网站的前端开发者是高明还是奇葩了
好的,两样东西都齐了,准备用代码实现了,在这之前,先了解下什么是CryptoJS
源码:
!function(t, n) {
    "object" == typeof exports ? module.exports = exports = n() : "function" == typeof define && define.amd ? define([], n) : t.CryptoJS = n()
} (this,
function() {
    var t = t ||
    function(t, n) {
        var i = Object.create ||
        function() {
            function t() {}
            return function(n) {
                var i;
                return t.prototype = n,
                i = new t,
                t.prototype = null,
                i
            }
        } (),
        e = {},
        r = e.lib = {},
        o = r.Base = function() {
            return {
                extend: function(t) {
                    var n = i(this);
                    return t && n.mixIn(t),
                    n.hasOwnProperty("init") && this.init !== n.init || (n.init = function() {
                        n.$super.init.apply(this, arguments)
                    }),
                    n.init.prototype = n,
                    n.$super = this,
                    n
                },
                create: function() {
                    var t = this.extend();
                    return t.init.apply(t, arguments),
                    t
                },
                init: function() {},
                mixIn: function(t) {
                    for (var n in t) t.hasOwnProperty(n) && (this[n] = t[n]);
                    t.hasOwnProperty("toString") && (this.toString = t.toString)
                },
                clone: function() {
                    return this.init.prototype.extend(this)
                }
            }
        } (),
        s = r.WordArray = o.extend({
            init: function(t, i) {
                t = this.words = t || [],
                i != n ? this.sigBytes = i: this.sigBytes = 4 * t.length
            },
            toString: function(t) {
                return (t || c).stringify(this)
            },
            concat: function(t) {
                var n = this.words,
                i = t.words,
                e = this.sigBytes,
                r = t.sigBytes;
                if (this.clamp(), e % 4) for (var o = 0; o < r; o++) {
                    var s = i[o >>> 2] >>> 24 - o % 4 * 8 & 255;
                    n[e + o >>> 2] |= s << 24 - (e + o) % 4 * 8
                } else for (var o = 0; o < r; o += 4) n[e + o >>> 2] = i[o >>> 2];
                return this.sigBytes += r,
                this
            },
            clamp: function() {
                var n = this.words,
                i = this.sigBytes;
                n[i >>> 2] &= 4294967295 << 32 - i % 4 * 8,
                n.length = t.ceil(i / 4)
            },
            clone: function() {
                var t = o.clone.call(this);
                return t.words = this.words.slice(0),
                t
            },
            random: function(n) {
                for (var i, e = [], r = function(n) {
                    var n = n,
                    i = 987654321,
                    e = 4294967295;
                    return function() {
                        i = 36969 * (65535 & i) + (i >> 16) & e,
                        n = 18e3 * (65535 & n) + (n >> 16) & e;
                        var r = (i << 16) + n & e;
                        return r /= 4294967296,
                        r += .5,
                        r * (t.random() > .5 ? 1 : -1)
                    }
                },
                o = 0; o < n; o += 4) {
                    var a = r(4294967296 * (i || t.random()));
                    i = 987654071 * a(),
                    e.push(4294967296 * a() | 0)
                }
                return new s.init(e, n)
            }
        }),
        a = e.enc = {},
        c = a.Hex = {
            stringify: function(t) {
                for (var n = t.words,
                i = t.sigBytes,
                e = [], r = 0; r < i; r++) {
                    var o = n[r >>> 2] >>> 24 - r % 4 * 8 & 255;
                    e.push((o >>> 4).toString(16)),
                    e.push((15 & o).toString(16))
                }
                return e.join("")
            },
            parse: function(t) {
                for (var n = t.length,
                i = [], e = 0; e < n; e += 2) i[e >>> 3] |= parseInt(t.substr(e, 2), 16) << 24 - e % 8 * 4;
                return new s.init(i, n / 2)
            }
        },
        u = a.Latin1 = {
            stringify: function(t) {
                for (var n = t.words,
                i = t.sigBytes,
                e = [], r = 0; r < i; r++) {
                    var o = n[r >>> 2] >>> 24 - r % 4 * 8 & 255;
                    e.push(String.fromCharCode(o))
                }
                return e.join("")
            },
            parse: function(t) {
                for (var n = t.length,
                i = [], e = 0; e < n; e++) i[e >>> 2] |= (255 & t.charCodeAt(e)) << 24 - e % 4 * 8;
                return new s.init(i, n)
            }
        },
        f = a.Utf8 = {
            stringify: function(t) {
                try {
                    return decodeURIComponent(escape(u.stringify(t)))
                } catch(t) {
                    throw new Error("Malformed UTF-8 data")
                }
            },
            parse: function(t) {
                return u.parse(unescape(encodeURIComponent(t)))
            }
        },
        h = r.BufferedBlockAlgorithm = o.extend({
            reset: function() {
                this._data = new s.init,
                this._nDataBytes = 0
            },
            _append: function(t) {
                "string" == typeof t && (t = f.parse(t)),
                this._data.concat(t),
                this._nDataBytes += t.sigBytes
            },
            _process: function(n) {
                var i = this._data,
                e = i.words,
                r = i.sigBytes,
                o = this.blockSize,
                a = 4 * o,
                c = r / a;
                c = n ? t.ceil(c) : t.max((0 | c) - this._minBufferSize, 0);
                var u = c * o,
                f = t.min(4 * u, r);
                if (u) {
                    for (var h = 0; h < u; h += o) this._doProcessBlock(e, h);
                    var p = e.splice(0, u);
                    i.sigBytes -= f
                }
                return new s.init(p, f)
            },
            clone: function() {
                var t = o.clone.call(this);
                return t._data = this._data.clone(),
                t
            },
            _minBufferSize: 0
        }),
        p = (r.Hasher = h.extend({
            cfg: o.extend(),
            init: function(t) {
                this.cfg = this.cfg.extend(t),
                this.reset()
            },
            reset: function() {
                h.reset.call(this),
                this._doReset()
            },
            update: function(t) {
                return this._append(t),
                this._process(),
                this
            },
            finalize: function(t) {
                t && this._append(t);
                var n = this._doFinalize();
                return n
            },
            blockSize: 16,
            _createHelper: function(t) {
                return function(n, i) {
                    return new t.init(i).finalize(n)
                }
            },
            _createHmacHelper: function(t) {
                return function(n, i) {
                    return new p.HMAC.init(t, i).finalize(n)
                }
            }
        }), e.algo = {});
        return e
    } (Math);
    return t
});
//# sourceMappingURL=core.min.js.map
!
function(e, t, i) {
    "object" == typeof exports ? module.exports = exports = t(require("./core.min"), require("./sha1.min"), require("./hmac.min")) : "function" == typeof define && define.amd ? define(["./core.min", "./sha1.min", "./hmac.min"], t) : t(e.CryptoJS)
} (this,
function(e) {
    return function() {
        var t = e,
        i = t.lib,
        r = i.Base,
        n = i.WordArray,
        o = t.algo,
        a = o.MD5,
        c = o.EvpKDF = r.extend({
            cfg: r.extend({
                keySize: 4,
                hasher: a,
                iterations: 1
            }),
            init: function(e) {
                this.cfg = this.cfg.extend(e)
            },
            compute: function(e, t) {
                for (var i = this.cfg,
                r = i.hasher.create(), o = n.create(), a = o.words, c = i.keySize, f = i.iterations; a.length < c;) {
                    s && r.update(s);
                    var s = r.update(e).finalize(t);
                    r.reset();
                    for (var u = 1; u < f; u++) s = r.finalize(s),
                    r.reset();
                    o.concat(s)
                }
                return o.sigBytes = 4 * c,
                o
            }
        });
        t.EvpKDF = function(e, t, i) {
            return c.create(i).compute(e, t)
        }
    } (),
    e.EvpKDF
});
//# sourceMappingURL=evpkdf.min.js.map
!
function(r, e) {
    "object" == typeof exports ? module.exports = exports = e(require("./core.min")) : "function" == typeof define && define.amd ? define(["./core.min"], e) : e(r.CryptoJS)
} (this,
function(r) {
    return function() {
        function e(r, e, t) {
            for (var n = [], i = 0, o = 0; o < e; o++) if (o % 4) {
                var f = t[r.charCodeAt(o - 1)] << o % 4 * 2,
                c = t[r.charCodeAt(o)] >>> 6 - o % 4 * 2;
                n[i >>> 2] |= (f | c) << 24 - i % 4 * 8,
                i++
            }
            return a.create(n, i)
        }
        var t = r,
        n = t.lib,
        a = n.WordArray,
        i = t.enc;
        i.Base64 = {
            stringify: function(r) {
                var e = r.words,
                t = r.sigBytes,
                n = this._map;
                r.clamp();
                for (var a = [], i = 0; i < t; i += 3) for (var o = e[i >>> 2] >>> 24 - i % 4 * 8 & 255, f = e[i + 1 >>> 2] >>> 24 - (i + 1) % 4 * 8 & 255, c = e[i + 2 >>> 2] >>> 24 - (i + 2) % 4 * 8 & 255, s = o << 16 | f << 8 | c, h = 0; h < 4 && i + .75 * h < t; h++) a.push(n.charAt(s >>> 6 * (3 - h) & 63));
                var p = n.charAt(64);
                if (p) for (; a.length % 4;) a.push(p);
                return a.join("")
            },
            parse: function(r) {
                var t = r.length,
                n = this._map,
                a = this._reverseMap;
                if (!a) {
                    a = this._reverseMap = [];
                    for (var i = 0; i < n.length; i++) a[n.charCodeAt(i)] = i
                }
                var o = n.charAt(64);
                if (o) {
                    var f = r.indexOf(o);
                    f !== -1 && (t = f)
                }
                return e(r, t, a)
            },
            _map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
        }
    } (),
    r.enc.Base64
});
//# sourceMappingURL=enc-base64.min.js.map
!
function(e, t, r) {
    "object" == typeof exports ? module.exports = exports = t(require("./core.min"), require("./evpkdf.min")) : "function" == typeof define && define.amd ? define(["./core.min", "./evpkdf.min"], t) : t(e.CryptoJS)
} (this,
function(e) {
    e.lib.Cipher ||
    function(t) {
        var r = e,
        i = r.lib,
        n = i.Base,
        c = i.WordArray,
        o = i.BufferedBlockAlgorithm,
        s = r.enc,
        a = (s.Utf8, s.Base64),
        f = r.algo,
        p = f.EvpKDF,
        d = i.Cipher = o.extend({
            cfg: n.extend(),
            createEncryptor: function(e, t) {
                return this.create(this._ENC_XFORM_MODE, e, t)
            },
            createDecryptor: function(e, t) {
                return this.create(this._DEC_XFORM_MODE, e, t)
            },
            init: function(e, t, r) {
                this.cfg = this.cfg.extend(r),
                this._xformMode = e,
                this._key = t,
                this.reset()
            },
            reset: function() {
                o.reset.call(this),
                this._doReset()
            },
            process: function(e) {
                return this._append(e),
                this._process()
            },
            finalize: function(e) {
                e && this._append(e);
                var t = this._doFinalize();
                return t
            },
            keySize: 4,
            ivSize: 4,
            _ENC_XFORM_MODE: 1,
            _DEC_XFORM_MODE: 2,
            _createHelper: function() {
                function e(e) {
                    return "string" == typeof e ? B: x
                }
                return function(t) {
                    return {
                        encrypt: function(r, i, n) {
                            return e(i).encrypt(t, r, i, n)
                        },
                        decrypt: function(r, i, n) {
                            return e(i).decrypt(t, r, i, n)
                        }
                    }
                }
            } ()
        }),
        h = (i.StreamCipher = d.extend({
            _doFinalize: function() {
                var e = this._process(!0);
                return e
            },
            blockSize: 1
        }), r.mode = {}),
        u = i.BlockCipherMode = n.extend({
            createEncryptor: function(e, t) {
                return this.Encryptor.create(e, t)
            },
            createDecryptor: function(e, t) {
                return this.Decryptor.create(e, t)
            },
            init: function(e, t) {
                this._cipher = e,
                this._iv = t
            }
        }),
        l = h.CBC = function() {
            function e(e, r, i) {
                var n = this._iv;
                if (n) {
                    var c = n;
                    this._iv = t
                } else var c = this._prevBlock;
                for (var o = 0; o < i; o++) e[r + o] ^= c[o]
            }
            var r = u.extend();
            return r.Encryptor = r.extend({
                processBlock: function(t, r) {
                    var i = this._cipher,
                    n = i.blockSize;
                    e.call(this, t, r, n),
                    i.encryptBlock(t, r),
                    this._prevBlock = t.slice(r, r + n)
                }
            }),
            r.Decryptor = r.extend({
                processBlock: function(t, r) {
                    var i = this._cipher,
                    n = i.blockSize,
                    c = t.slice(r, r + n);
                    i.decryptBlock(t, r),
                    e.call(this, t, r, n),
                    this._prevBlock = c
                }
            }),
            r
        } (),
        _ = r.pad = {},
        v = _.Pkcs7 = {
            pad: function(e, t) {
                for (var r = 4 * t,
                i = r - e.sigBytes % r,
                n = i << 24 | i << 16 | i << 8 | i,
                o = [], s = 0; s < i; s += 4) o.push(n);
                var a = c.create(o, i);
                e.concat(a)
            },
            unpad: function(e) {
                var t = 255 & e.words[e.sigBytes - 1 >>> 2];
                e.sigBytes -= t
            }
        },
        y = (i.BlockCipher = d.extend({
            cfg: d.cfg.extend({
                mode: l,
                padding: v
            }),
            reset: function() {
                d.reset.call(this);
                var e = this.cfg,
                t = e.iv,
                r = e.mode;
                if (this._xformMode == this._ENC_XFORM_MODE) var i = r.createEncryptor;
                else {
                    var i = r.createDecryptor;
                    this._minBufferSize = 1
                }
                this._mode && this._mode.__creator == i ? this._mode.init(this, t && t.words) : (this._mode = i.call(r, this, t && t.words), this._mode.__creator = i)
            },
            _doProcessBlock: function(e, t) {
                this._mode.processBlock(e, t)
            },
            _doFinalize: function() {
                var e = this.cfg.padding;
                if (this._xformMode == this._ENC_XFORM_MODE) {
                    e.pad(this._data, this.blockSize);
                    var t = this._process(!0)
                } else {
                    var t = this._process(!0);
                    e.unpad(t)
                }
                return t
            },
            blockSize: 4
        }), i.CipherParams = n.extend({
            init: function(e) {
                this.mixIn(e)
            },
            toString: function(e) {
                return (e || this.formatter).stringify(this)
            }
        })),
        m = r.format = {},
        k = m.OpenSSL = {
            stringify: function(e) {
                var t = e.ciphertext,
                r = e.salt;
                if (r) var i = c.create([1398893684, 1701076831]).concat(r).concat(t);
                else var i = t;
                return i.toString(a)
            },
            parse: function(e) {
                var t = a.parse(e),
                r = t.words;
                if (1398893684 == r[0] && 1701076831 == r[1]) {
                    var i = c.create(r.slice(2, 4));
                    r.splice(0, 4),
                    t.sigBytes -= 16
                }
                return y.create({
                    ciphertext: t,
                    salt: i
                })
            }
        },
        x = i.SerializableCipher = n.extend({
            cfg: n.extend({
                format: k
            }),
            encrypt: function(e, t, r, i) {
                i = this.cfg.extend(i);
                var n = e.createEncryptor(r, i),
                c = n.finalize(t),
                o = n.cfg;
                return y.create({
                    ciphertext: c,
                    key: r,
                    iv: o.iv,
                    algorithm: e,
                    mode: o.mode,
                    padding: o.padding,
                    blockSize: e.blockSize,
                    formatter: i.format
                })
            },
            decrypt: function(e, t, r, i) {
                i = this.cfg.extend(i),
                t = this._parse(t, i.format);
                var n = e.createDecryptor(r, i).finalize(t.ciphertext);
                return n
            },
            _parse: function(e, t) {
                return "string" == typeof e ? t.parse(e, this) : e
            }
        }),
        g = r.kdf = {},
        S = g.OpenSSL = {
            execute: function(e, t, r, i) {
                i || (i = c.random(8));
                var n = p.create({
                    keySize: t + r
                }).compute(e, i),
                o = c.create(n.words.slice(t), 4 * r);
                return n.sigBytes = 4 * t,
                y.create({
                    key: n,
                    iv: o,
                    salt: i
                })
            }
        },
        B = i.PasswordBasedCipher = x.extend({
            cfg: x.cfg.extend({
                kdf: S
            }),
            encrypt: function(e, t, r, i) {
                i = this.cfg.extend(i);
                var n = i.kdf.execute(r, e.keySize, e.ivSize);
                i.iv = n.iv;
                var c = x.encrypt.call(this, e, t, n.key, i);
                return c.mixIn(n),
                c
            },
            decrypt: function(e, t, r, i) {
                i = this.cfg.extend(i),
                t = this._parse(t, i.format);
                var n = i.kdf.execute(r, e.keySize, e.ivSize, t.salt);
                i.iv = n.iv;
                var c = x.decrypt.call(this, e, t, n.key, i);
                return c
            }
        })
    } ()
});
//# sourceMappingURL=cipher-core.min.js.map
!
function(e, i) {
    "object" == typeof exports ? module.exports = exports = i(require("./core.min")) : "function" == typeof define && define.amd ? define(["./core.min"], i) : i(e.CryptoJS)
} (this,
function(e) { !
    function() {
        var i = e,
        t = i.lib,
        n = t.Base,
        s = i.enc,
        r = s.Utf8,
        o = i.algo;
        o.HMAC = n.extend({
            init: function(e, i) {
                e = this._hasher = new e.init,
                "string" == typeof i && (i = r.parse(i));
                var t = e.blockSize,
                n = 4 * t;
                i.sigBytes > n && (i = e.finalize(i)),
                i.clamp();
                for (var s = this._oKey = i.clone(), o = this._iKey = i.clone(), a = s.words, f = o.words, c = 0; c < t; c++) a[c] ^= 1549556828,
                f[c] ^= 909522486;
                s.sigBytes = o.sigBytes = n,
                this.reset()
            },
            reset: function() {
                var e = this._hasher;
                e.reset(),
                e.update(this._iKey)
            },
            update: function(e) {
                return this._hasher.update(e),
                this
            },
            finalize: function(e) {
                var i = this._hasher,
                t = i.finalize(e);
                i.reset();
                var n = i.finalize(this._oKey.clone().concat(t));
                return n
            }
        })
    } ()
});
//# sourceMappingURL=hmac.min.js.map
!
function(e, o, r) {
    "object" == typeof exports ? module.exports = exports = o(require("./core.min"), require("./cipher-core.min")) : "function" == typeof define && define.amd ? define(["./core.min", "./cipher-core.min"], o) : o(e.CryptoJS)
} (this,
function(e) {
    return e.mode.ECB = function() {
        var o = e.lib.BlockCipherMode.extend();
        return o.Encryptor = o.extend({
            processBlock: function(e, o) {
                this._cipher.encryptBlock(e, o)
            }
        }),
        o.Decryptor = o.extend({
            processBlock: function(e, o) {
                this._cipher.decryptBlock(e, o)
            }
        }),
        o
    } (),
    e.mode.ECB
});
//# sourceMappingURL=mode-ecb.min.js.map
!
function(e, r, i) {
    "object" == typeof exports ? module.exports = exports = r(require("./core.min"), require("./cipher-core.min")) : "function" == typeof define && define.amd ? define(["./core.min", "./cipher-core.min"], r) : r(e.CryptoJS)
} (this,
function(e) {
    return e.pad.Pkcs7
});
eval(function(p, a, c, k, e, d) {
    e = function(c) {
        return (c < a ? "": e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36))
    };
    if (!''.replace(/^/, String)) {
        while (c--) d[e(c)] = k[c] || e(c);
        k = [function(e) {
            return d[e]
        }];
        e = function() {
            return '\\w+'
        };
        c = 1;
    };
    while (c--) if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]);
    return p;
} ('$(E(){$("a").Q(E(){3 6=$(A).x("N");f(z(6)==\'y\'||6==\'#\'){q}3 7=6.p("/");3 c=7.e;3 b=7[c-1].p(\'.\');3 d=b[0];3 n=b[1];3 r=/^\\+?[1-9][0-9]*$/;f(r.F(d)&&n.G(\'I\')!=-1){3 u=8.m.l.v(d);3 k=8.m.l.v(s);3 w=8.H.J(u,k,{t:8.t.K,T:8.U.S});3 4=w.V();4=4.R(/\\//g,"^");4=4.D(0,4.e-2);3 o=4+\'.\'+b[1];7[c-1]=o;3 5=\'\';L(i=0;i<c;i++){5+=7[i]+\'/\'}5=5.D(0,5.e-1);h.j(5)}C{3 B=$(A).x(\'P\');f(B.z(\'y\')){h.O=6}C{h.j(6)}}q M})});', 58, 58, '|||var|ddd|uuu|hh|aa|CryptoJS|||bbb|aaa|ccc|length|if||window||open||Utf8|enc|cccc|bbbb|split|return|||mode|srcs|parse|en|attr|undefined|typeof|this|ee|else|substring|function|test|indexOf|AES|jhtml|encrypt|ECB|for|false|href|location|target|click|replace|Pkcs7|padding|pad|toString'.split('|'), 0, {}));
//# sourceMappingURL=pad-pkcs7.min.js.map
!
function(e, r, i) {
    "object" == typeof exports ? module.exports = exports = r(require("./core.min"), require("./enc-base64.min"), require("./md5.min"), require("./evpkdf.min"), require("./cipher-core.min")) : "function" == typeof define && define.amd ? define(["./core.min", "./enc-base64.min", "./md5.min", "./evpkdf.min", "./cipher-core.min"], r) : r(e.CryptoJS)
} (this,
function(e) {
    return function() {
        var r = e,
        i = r.lib,
        n = i.BlockCipher,
        o = r.algo,
        t = [],
        c = [],
        s = [],
        f = [],
        a = [],
        d = [],
        u = [],
        v = [],
        h = [],
        y = []; !
        function() {
            for (var e = [], r = 0; r < 256; r++) r < 128 ? e[r] = r << 1 : e[r] = r << 1 ^ 283;
            for (var i = 0,
            n = 0,
            r = 0; r < 256; r++) {
                var o = n ^ n << 1 ^ n << 2 ^ n << 3 ^ n << 4;
                o = o >>> 8 ^ 255 & o ^ 99,
                t[i] = o,
                c[o] = i;
                var p = e[i],
                l = e[p],
                _ = e[l],
                k = 257 * e[o] ^ 16843008 * o;
                s[i] = k << 24 | k >>> 8,
                f[i] = k << 16 | k >>> 16,
                a[i] = k << 8 | k >>> 24,
                d[i] = k;
                var k = 16843009 * _ ^ 65537 * l ^ 257 * p ^ 16843008 * i;
                u[o] = k << 24 | k >>> 8,
                v[o] = k << 16 | k >>> 16,
                h[o] = k << 8 | k >>> 24,
                y[o] = k,
                i ? (i = p ^ e[e[e[_ ^ p]]], n ^= e[e[n]]) : i = n = 1
            }
        } ();
        var p = [0, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54],
        l = o.AES = n.extend({
            _doReset: function() {
                if (!this._nRounds || this._keyPriorReset !== this._key) {
                    for (var e = this._keyPriorReset = this._key,
                    r = e.words,
                    i = e.sigBytes / 4,
                    n = this._nRounds = i + 6,
                    o = 4 * (n + 1), c = this._keySchedule = [], s = 0; s < o; s++) if (s < i) c[s] = r[s];
                    else {
                        var f = c[s - 1];
                        s % i ? i > 6 && s % i == 4 && (f = t[f >>> 24] << 24 | t[f >>> 16 & 255] << 16 | t[f >>> 8 & 255] << 8 | t[255 & f]) : (f = f << 8 | f >>> 24, f = t[f >>> 24] << 24 | t[f >>> 16 & 255] << 16 | t[f >>> 8 & 255] << 8 | t[255 & f], f ^= p[s / i | 0] << 24),
                        c[s] = c[s - i] ^ f
                    }
                    for (var a = this._invKeySchedule = [], d = 0; d < o; d++) {
                        var s = o - d;
                        if (d % 4) var f = c[s];
                        else var f = c[s - 4];
                        d < 4 || s <= 4 ? a[d] = f: a[d] = u[t[f >>> 24]] ^ v[t[f >>> 16 & 255]] ^ h[t[f >>> 8 & 255]] ^ y[t[255 & f]]
                    }
                }
            },
            encryptBlock: function(e, r) {
                this._doCryptBlock(e, r, this._keySchedule, s, f, a, d, t)
            },
            decryptBlock: function(e, r) {
                var i = e[r + 1];
                e[r + 1] = e[r + 3],
                e[r + 3] = i,
                this._doCryptBlock(e, r, this._invKeySchedule, u, v, h, y, c);
                var i = e[r + 1];
                e[r + 1] = e[r + 3],
                e[r + 3] = i
            },
            _doCryptBlock: function(e, r, i, n, o, t, c, s) {
                for (var f = this._nRounds,
                a = e[r] ^ i[0], d = e[r + 1] ^ i[1], u = e[r + 2] ^ i[2], v = e[r + 3] ^ i[3], h = 4, y = 1; y < f; y++) {
                    var p = n[a >>> 24] ^ o[d >>> 16 & 255] ^ t[u >>> 8 & 255] ^ c[255 & v] ^ i[h++],
                    l = n[d >>> 24] ^ o[u >>> 16 & 255] ^ t[v >>> 8 & 255] ^ c[255 & a] ^ i[h++],
                    _ = n[u >>> 24] ^ o[v >>> 16 & 255] ^ t[a >>> 8 & 255] ^ c[255 & d] ^ i[h++],
                    k = n[v >>> 24] ^ o[a >>> 16 & 255] ^ t[d >>> 8 & 255] ^ c[255 & u] ^ i[h++];
                    a = p,
                    d = l,
                    u = _,
                    v = k
                }
                var p = (s[a >>> 24] << 24 | s[d >>> 16 & 255] << 16 | s[u >>> 8 & 255] << 8 | s[255 & v]) ^ i[h++],
                l = (s[d >>> 24] << 24 | s[u >>> 16 & 255] << 16 | s[v >>> 8 & 255] << 8 | s[255 & a]) ^ i[h++],
                _ = (s[u >>> 24] << 24 | s[v >>> 16 & 255] << 16 | s[a >>> 8 & 255] << 8 | s[255 & d]) ^ i[h++],
                k = (s[v >>> 24] << 24 | s[a >>> 16 & 255] << 16 | s[d >>> 8 & 255] << 8 | s[255 & u]) ^ i[h++];
                e[r] = p,
                e[r + 1] = l,
                e[r + 2] = _,
                e[r + 3] = k
            },
            keySize: 8
        });
        r.AES = n._createHelper(l)
    } (),
    e.AES
});
//# sourceMappingURL=aes.min.js.map
!
function(e, n) {
    "object" == typeof exports ? module.exports = exports = n(require("./core.min")) : "function" == typeof define && define.amd ? define(["./core.min"], n) : n(e.CryptoJS)
} (this,
function(e) {
    return e.enc.Utf8
});
aes加密源码
源码看半天看不懂,我高估了我自己,我搜[ccc]找到了刚才那段加密步骤,找了很多解密方法还没发解密

这里强烈推荐火狐浏览器,就是他妈的牛逼,用火狐可以嗅探到js的事件,而且还显示解密过的js,对的,就是最开始那段代码,具体往上滑,还可以看到源码,以及这段代码在源码文件的哪个位置

那好的,加密过程我们已经知道了
用python实现加密解密
先选用js2py库来跑js代码:

报错,提示没有引入CryptoJS对象
将crypo-js的源码保存到本地js文件里,放在当前目录,
引入crypo-js,还是不行,我傻了,这个需要在当前环境运行的


最后,搞来搞去还是没法,这条路走不通了,最后网上查了下,还是有很多人遇到我这样的问题,并且有的已经解决了的,我开始慢慢找跟我的情况一样的,发现python自己有一个加密库—— Crypto
我研究了半天这个库,pypi文档上看了一遍也没发现个什么东西,跟我用来解密还是有些距离
真的没法了吗?
我想了半天,我觉得我都已经到这一步了,为什么还是不行,一定有我没注意到的情况,最后网上找了很多篇相关的文章,找到如下代码可行,但是到底是哪篇文章我已经不知道了,感谢这位老哥,源地址我真找不到了:
from Crypto.Cipher import AES
import base64 def add_to_16(s):
while len(s) % 16 != 0:
s += (16 - len(s) % 16) * chr(16 - len(s) % 16)
return str.encode(s) # 返回bytes def get_secret_url(text, key='qnbyzzwmdgghmcnm'):
aes = AES.new(str.encode(key), AES.MODE_ECB) # 初始化加密器,本例采用ECB加密模式
encrypted_text = str(base64.encodebytes(aes.encrypt(add_to_16(text))), encoding='utf8').replace('\n', '') # 加密
encrypted_text = encrypted_text.replace('/', "^") # ddd.replace(/\//g, "^")
return encrypted_text[:-2] def get_real_url(first_url, key):
aa = first_url.split('/')
aaa = len(aa)
bbb = aa[aaa - 1].split('.')
ccc = bbb[0]
secret_text = get_secret_url(ccc, key=key)
return first_url.replace(ccc, secret_text) url = 'http://xxx.xxxx.xxx.xxx.cn:80/xxxx/938848.jhtml'
key = 'qnbyzzwmdgghmcnm' # 此处问加密key值
url = get_real_url(url, key=key)
print(url)
运行:

复制这个链接用浏览器打开:

能打开,并且标题与一级网页的标题一致,ok,解码成功,激动!!!!
python爬虫破解带有CryptoJS的aes加密的反爬机制的更多相关文章
- python爬虫破解带有RSA.js的RSA加密数据的反爬机制
		
前言 同上一篇的aes加密一样,也是偶然发现这个rsa加密的,目标网站我就不说了,保密. 当我发现这个网站是ajax加载时: 我已经习以为常,正在进行爬取时,发现返回为空,我开始用findler抓包, ...
 - Python爬虫—破解JS加密的Cookie
		
前言 在GitHub上维护了一个代理池的项目,代理来源是抓取一些免费的代理发布网站.上午有个小哥告诉我说有个代理抓取接口不能用了,返回状态521.抱着帮人解决问题的心态去跑了一遍代码.发现果真是这样. ...
 - python爬虫---详解爬虫分类,HTTP和HTTPS的区别,证书加密,反爬机制和反反爬策略,requests模块的使用,常见的问题
		
python爬虫---详解爬虫分类,HTTP和HTTPS的区别,证书加密,反爬机制和反反爬策略,requests模块的使用,常见的问题 一丶爬虫概述 通过编写程序'模拟浏览器'上网,然后通 ...
 - 第三百四十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—cookie禁用、自动限速、自定义spider的settings,对抗反爬机制
		
第三百四十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—cookie禁用.自动限速.自定义spider的settings,对抗反爬机制 cookie禁用 就是在Scrapy的配置文件set ...
 - python爬虫---CrawlSpider实现的全站数据的爬取,分布式,增量式,所有的反爬机制
		
CrawlSpider实现的全站数据的爬取 新建一个工程 cd 工程 创建爬虫文件:scrapy genspider -t crawl spiderName www.xxx.com 连接提取器Link ...
 - Python爬虫实战——反爬机制的解决策略【阿里】
		
这一次呢,让我们来试一下"CSDN热门文章的抓取". 话不多说,让我们直接进入CSND官网. (其实是因为我被阿里的反爬磨到没脾气,不想说话--) 一.URL分析 输入" ...
 - 关于使用scrapy框架编写爬虫以及Ajax动态加载问题、反爬问题解决方案
		
Python爬虫总结 总的来说,Python爬虫所做的事情分为两个部分,1:将网页的内容全部抓取下来,2:对抓取到的内容和进行解析,得到我们需要的信息. 目前公认比较好用的爬虫框架为Scrapy,而且 ...
 - 爬虫入门到放弃系列07:js混淆、eval加密、字体加密三大反爬技术
		
前言 如果再说IP请求次数检测.验证码这种最常见的反爬虫技术,可能大家听得耳朵都出茧子了.当然,也有的同学写了了几天的爬虫,觉得爬虫太简单.没有啥挑战性.所以特地找了三个有一定难度的网站,希望可以有兴 ...
 - Python 爬虫工程师必看,深入解读字体反爬虫
		
字体反爬虫开篇概述 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识.那么针对这三类人 ...
 
随机推荐
- UML图的种类
			
一.作为一种建模语言,UML的定义包括UML语义和UML表示法两个部分. UML语义:描述基于UML的精确元模型定义. UML表示法:定义UML符号的表示法,为开发者或开发工具使用这些图形符号和文本语 ...
 - HDU - 5586 Sum(区间增量最大)
			
题意:将数组A的部分区间值按照函数f(Ai)=(1890*Ai+143)mod10007修改值,区间长度可以为0,问该操作后数组A的最大值. 分析:先求出每个元素的增量,进而求出增量和.通过b[r]- ...
 - UVA - 10539 Almost Prime Numbers (几乎是素数)
			
题意:输入两个正整数L.U(L<=U<1012),统计区间[L,U]的整数中有多少个数满足:它本身不是素数,但只有一个素因子. 分析: 1.满足条件的数是素数的倍数. 2.枚举所有的素数, ...
 - js连续的日期判断,判断相差几天
			
var startTime=Date.parse(new Date('2020-02-28')); var endTime=Date.parse(new Date('2020-02-29')); $. ...
 - Spring耗时拦截器(url,restful)
			
import java.io.IOException; import java.util.Date; import javax.servlet.Filter; import javax.servlet ...
 - 吴裕雄--天生自然TensorFlow2教程:高阶操作
			
import tensorflow as tf a = tf.random.normal([3, 3]) a mask = a > 0 mask # 为True元素,即>0的元素的索引 i ...
 - 2020/1/30 PHP代码审计之CSRF漏洞
			
0x00 CSRF漏洞 CSRF(Cross-site request forgery)跨站请求伪造:也被称为"One Click Attack"或者Session Riding, ...
 - 使用NtQueryInformationFile函数获得不到完整路径
			
#include <windows.h> #include <iostream> using namespace std; typedef struct _OBJECT_NAM ...
 - APP测试关注的点 - 笔记
			
来源公开课笔记!!! 1.黑盒测试 是否正确并如设计的一样正常运行.测试自动化回归测试 2.测试主要关注参数: CPU.内存.耗电量.流量.FRS(流畅度).同时关注APP安装耗时和启动耗时 3.适配 ...
 - Ubuntu Kylin 14.04LTS  开机后卡在登陆界面,可以进入字符界面,或者登陆后鼠标不显示但是管用
			
2014年4月27日,距离中期检查还有七天,基本上什么也没做,特别着急,雨已经下了快一天了,中午用美团外卖定的黄焖排骨,MD,什么玩意,那么一点点就18块钱,一看就不值五块钱,发誓再也不吃,最重要的是 ...