爬虫逆向实战(二十)--某99网站登录

这篇具有很好参考价值的文章主要介绍了爬虫逆向实战(二十)--某99网站登录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、数据接口分析

主页地址:某99网站

1、抓包

通过抓包可以发现登录接口是AC_userlogin
爬虫逆向实战(二十)--某99网站登录,爬虫逆向实战,爬虫

2、判断是否有加密参数

  1. 请求参数是否加密?
    通过查看“载荷”可以发现txtPasswordaws是加密参数
    爬虫逆向实战(二十)--某99网站登录,爬虫逆向实战,爬虫
  2. 请求头是否加密?
  3. 响应是否加密?
  4. cookie是否加密?

二、加密位置定位

1、看启动器

查看启动器发现有一个NDUser_Login.js文件的匿名方法,点进去查看
爬虫逆向实战(二十)--某99网站登录,爬虫逆向实战,爬虫
点进去后发现,此处拼接了一个登录的地址,并且上方会赋值passwordaws,大概率是在此处进行的加密。下断点,再次登录。
爬虫逆向实战(二十)--某99网站登录,爬虫逆向实战,爬虫发现可以断住,所以此处就是加密位置

三、扣js代码

通过定位到的加密位置,扣出加密代码,缺啥补啥即可。
aws是可以写死的,每次生成的都是一样的。

通过断点进入password的加密方法,发现是加盐的md5,通过控制台测试字符串’1’,可以看出时标准的md5
爬虫逆向实战(二十)--某99网站登录,爬虫逆向实战,爬虫
但是当我使用标准的md5加密加盐后的字符串时,却发现与网站加密出的密文不同
爬虫逆向实战(二十)--某99网站登录,爬虫逆向实战,爬虫
所以此处要将网站使用的MD5算法扣出,不能使用标准的md5

四、验证码

1、分析接口

通过不断点击图片验证码可以看出,网站每次获取验证码都会发送三个请求爬虫逆向实战(二十)--某99网站登录,爬虫逆向实战,爬虫
通过观察这三个请求可以发现,第二个请求会携带第一个请求返回响应中的ticket,第二个请求返回的响应中有第三个请求的地址。
爬虫逆向实战(二十)--某99网站登录,爬虫逆向实战,爬虫
爬虫逆向实战(二十)--某99网站登录,爬虫逆向实战,爬虫
爬虫逆向实战(二十)--某99网站登录,爬虫逆向实战,爬虫

五、登录流程

首先我们需要先请求图片验证码的第一个接口,获取到ticket,再携带ticket请求第二个接口获取到图片验证码的地址,请求该地址获取到图片,破解图片验证码(我使用的是打码平台)。生成加密参数,携带加密参数以及图片验证码请求登录接口。注意:以上请求均需要携带参数callback,写死即可。
JavaScript源码:

var CryptoJS = require('crypto-js')
var hex_chr = "0123456789abcdef";
function rhex(num) {
    str = "";
    for (j = 0; j <= 3; j++)
        str += hex_chr.charAt((num >> (j * 8 + 4)) & 0x0F) + hex_chr.charAt((num >> (j * 8)) & 0x0F);
    return str;
}
function str2blks_MD5(str) {
    nblk = ((str.length + 8) >> 6) + 1;
    blks = new Array(nblk * 16);
    for (i = 0; i < nblk * 16; i++)
        blks[i] = 0;
    for (i = 0; i < str.length; i++)
        blks[i >> 2] |= str.charCodeAt(i) << ((i % 4) * 8);
    blks[i >> 2] |= 0x80 << ((i % 4) * 8);
    blks[nblk * 16 - 2] = str.length * 8;
    return blks;
}
function add(x, y) {
    var lsw = (x & 0xFFFF) + (y & 0xFFFF);
    var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
    return (msw << 16) | (lsw & 0xFFFF);
}
function rol(num, cnt) {
    return (num << cnt) | (num >>> (32 - cnt));
}
function cmn(q, a, b, x, s, t) {
    return add(rol(add(add(a, q), add(x, t)), s), b);
}
function ff(a, b, c, d, x, s, t) {
    return cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function gg(a, b, c, d, x, s, t) {
    return cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function hh(a, b, c, d, x, s, t) {
    return cmn(b ^ c ^ d, a, b, x, s, t);
}
function ii(a, b, c, d, x, s, t) {
    return cmn(c ^ (b | (~d)), a, b, x, s, t);
}

function MD5(str) {
    x = str2blks_MD5(str);
    var a = 1732584193;
    var b = -271733879;
    var c = -1732584194;
    var d = 271733878;
    for (i = 0; i < x.length; i += 16) {
        var olda = a;
        var oldb = b;
        var oldc = c;
        var oldd = d;
        a = ff(a, b, c, d, x[i + 0], 7, -680876936);
        d = ff(d, a, b, c, x[i + 1], 12, -389564586);
        c = ff(c, d, a, b, x[i + 2], 17, 606105819);
        b = ff(b, c, d, a, x[i + 3], 22, -1044525330);
        a = ff(a, b, c, d, x[i + 4], 7, -176418897);
        d = ff(d, a, b, c, x[i + 5], 12, 1200080426);
        c = ff(c, d, a, b, x[i + 6], 17, -1473231341);
        b = ff(b, c, d, a, x[i + 7], 22, -45705983);
        a = ff(a, b, c, d, x[i + 8], 7, 1770035416);
        d = ff(d, a, b, c, x[i + 9], 12, -1958414417);
        c = ff(c, d, a, b, x[i + 10], 17, -42063);
        b = ff(b, c, d, a, x[i + 11], 22, -1990404162);
        a = ff(a, b, c, d, x[i + 12], 7, 1804603682);
        d = ff(d, a, b, c, x[i + 13], 12, -40341101);
        c = ff(c, d, a, b, x[i + 14], 17, -1502002290);
        b = ff(b, c, d, a, x[i + 15], 22, 1236535329);
        a = gg(a, b, c, d, x[i + 1], 5, -165796510);
        d = gg(d, a, b, c, x[i + 6], 9, -1069501632);
        c = gg(c, d, a, b, x[i + 11], 14, 643717713);
        b = gg(b, c, d, a, x[i + 0], 20, -373897302);
        a = gg(a, b, c, d, x[i + 5], 5, -701558691);
        d = gg(d, a, b, c, x[i + 10], 9, 38016083);
        c = gg(c, d, a, b, x[i + 15], 14, -660478335);
        b = gg(b, c, d, a, x[i + 4], 20, -405537848);
        a = gg(a, b, c, d, x[i + 9], 5, 568446438);
        d = gg(d, a, b, c, x[i + 14], 9, -1019803690);
        c = gg(c, d, a, b, x[i + 3], 14, -187363961);
        b = gg(b, c, d, a, x[i + 8], 20, 1163531501);
        a = gg(a, b, c, d, x[i + 13], 5, -1444681467);
        d = gg(d, a, b, c, x[i + 2], 9, -51403784);
        c = gg(c, d, a, b, x[i + 7], 14, 1735328473);
        b = gg(b, c, d, a, x[i + 12], 20, -1926607734);
        a = hh(a, b, c, d, x[i + 5], 4, -378558);
        d = hh(d, a, b, c, x[i + 8], 11, -2022574463);
        c = hh(c, d, a, b, x[i + 11], 16, 1839030562);
        b = hh(b, c, d, a, x[i + 14], 23, -35309556);
        a = hh(a, b, c, d, x[i + 1], 4, -1530992060);
        d = hh(d, a, b, c, x[i + 4], 11, 1272893353);
        c = hh(c, d, a, b, x[i + 7], 16, -155497632);
        b = hh(b, c, d, a, x[i + 10], 23, -1094730640);
        a = hh(a, b, c, d, x[i + 13], 4, 681279174);
        d = hh(d, a, b, c, x[i + 0], 11, -358537222);
        c = hh(c, d, a, b, x[i + 3], 16, -722521979);
        b = hh(b, c, d, a, x[i + 6], 23, 76029189);
        a = hh(a, b, c, d, x[i + 9], 4, -640364487);
        d = hh(d, a, b, c, x[i + 12], 11, -421815835);
        c = hh(c, d, a, b, x[i + 15], 16, 530742520);
        b = hh(b, c, d, a, x[i + 2], 23, -995338651);
        a = ii(a, b, c, d, x[i + 0], 6, -198630844);
        d = ii(d, a, b, c, x[i + 7], 10, 1126891415);
        c = ii(c, d, a, b, x[i + 14], 15, -1416354905);
        b = ii(b, c, d, a, x[i + 5], 21, -57434055);
        a = ii(a, b, c, d, x[i + 12], 6, 1700485571);
        d = ii(d, a, b, c, x[i + 3], 10, -1894986606);
        c = ii(c, d, a, b, x[i + 10], 15, -1051523);
        b = ii(b, c, d, a, x[i + 1], 21, -2054922799);
        a = ii(a, b, c, d, x[i + 8], 6, 1873313359);
        d = ii(d, a, b, c, x[i + 15], 10, -30611744);
        c = ii(c, d, a, b, x[i + 6], 15, -1560198380);
        b = ii(b, c, d, a, x[i + 13], 21, 1309151649);
        a = ii(a, b, c, d, x[i + 4], 6, -145523070);
        d = ii(d, a, b, c, x[i + 11], 10, -1120210379);
        c = ii(c, d, a, b, x[i + 2], 15, 718787259);
        b = ii(b, c, d, a, x[i + 9], 21, -343485551);
        a = add(a, olda);
        b = add(b, oldb);
        c = add(c, oldc);
        d = add(d, oldd);
    }
    return rhex(a) + rhex(b) + rhex(c) + rhex(d);
}

function getMD5Value(data) {
    var a = data;
    var b = "\xa3\xac\xa1\xa3";
    var c = "fdjf,jkgfkl";
    var s = a + b + c;
    return MD5(s);
}

var x64Add = function(m, n) {
        m = [m[0] >>> 16, m[0] & 65535, m[1] >>> 16, m[1] & 65535];
        n = [n[0] >>> 16, n[0] & 65535, n[1] >>> 16, n[1] & 65535];
        var o = [0, 0, 0, 0];
        o[3] += m[3] + n[3];
        o[2] += o[3] >>> 16;
        o[3] &= 65535;
        o[2] += m[2] + n[2];
        o[1] += o[2] >>> 16;
        o[2] &= 65535;
        o[1] += m[1] + n[1];
        o[0] += o[1] >>> 16;
        o[1] &= 65535;
        o[0] += m[0] + n[0];
        o[0] &= 65535;
        return [(o[0] << 16) | o[1], (o[2] << 16) | o[3]]
    };
    var x64Multiply = function(m, n) {
        m = [m[0] >>> 16, m[0] & 65535, m[1] >>> 16, m[1] & 65535];
        n = [n[0] >>> 16, n[0] & 65535, n[1] >>> 16, n[1] & 65535];
        var o = [0, 0, 0, 0];
        o[3] += m[3] * n[3];
        o[2] += o[3] >>> 16;
        o[3] &= 65535;
        o[2] += m[2] * n[3];
        o[1] += o[2] >>> 16;
        o[2] &= 65535;
        o[2] += m[3] * n[2];
        o[1] += o[2] >>> 16;
        o[2] &= 65535;
        o[1] += m[1] * n[3];
        o[0] += o[1] >>> 16;
        o[1] &= 65535;
        o[1] += m[2] * n[2];
        o[0] += o[1] >>> 16;
        o[1] &= 65535;
        o[1] += m[3] * n[1];
        o[0] += o[1] >>> 16;
        o[1] &= 65535;
        o[0] += (m[0] * n[3]) + (m[1] * n[2]) + (m[2] * n[1]) + (m[3] * n[0]);
        o[0] &= 65535;
        return [(o[0] << 16) | o[1], (o[2] << 16) | o[3]]
    };
    var x64Rotl = function(m, n) {
        n %= 64;
        if (n === 32) {
            return [m[1], m[0]]
        } else {
            if (n < 32) {
                return [(m[0] << n) | (m[1] >>> (32 - n)), (m[1] << n) | (m[0] >>> (32 - n))]
            } else {
                n -= 32;
                return [(m[1] << n) | (m[0] >>> (32 - n)), (m[0] << n) | (m[1] >>> (32 - n))]
            }
        }
    };
    var x64LeftShift = function(m, n) {
        n %= 64;
        if (n === 0) {
            return m
        } else {
            if (n < 32) {
                return [(m[0] << n) | (m[1] >>> (32 - n)), m[1] << n]
            } else {
                return [m[1] << (n - 32), 0]
            }
        }
    };
    var x64Xor = function(m, n) {
        return [m[0] ^ n[0], m[1] ^ n[1]]
    };
    var x64Fmix = function(h) {
        h = x64Xor(h, [0, h[0] >>> 1]);
        h = x64Multiply(h, [4283543511, 3981806797]);
        h = x64Xor(h, [0, h[0] >>> 1]);
        h = x64Multiply(h, [3301882366, 444984403]);
        h = x64Xor(h, [0, h[0] >>> 1]);
        return h
    };

var Fingerprint2_x64hash128 = function(key, seed) {
        key = key || "";
        seed = seed || 0;
        var remainder = key.length % 16;
        var bytes = key.length - remainder;
        var h1 = [0, seed];
        var h2 = [0, seed];
        var k1 = [0, 0];
        var k2 = [0, 0];
        var c1 = [2277735313, 289559509];
        var c2 = [1291169091, 658871167];
        for (var i = 0; i < bytes; i = i + 16) {
            k1 = [((key.charCodeAt(i + 4) & 255)) | ((key.charCodeAt(i + 5) & 255) << 8) | ((key.charCodeAt(i + 6) & 255) << 16) | ((key.charCodeAt(i + 7) & 255) << 24), ((key.charCodeAt(i) & 255)) | ((key.charCodeAt(i + 1) & 255) << 8) | ((key.charCodeAt(i + 2) & 255) << 16) | ((key.charCodeAt(i + 3) & 255) << 24)];
            k2 = [((key.charCodeAt(i + 12) & 255)) | ((key.charCodeAt(i + 13) & 255) << 8) | ((key.charCodeAt(i + 14) & 255) << 16) | ((key.charCodeAt(i + 15) & 255) << 24), ((key.charCodeAt(i + 8) & 255)) | ((key.charCodeAt(i + 9) & 255) << 8) | ((key.charCodeAt(i + 10) & 255) << 16) | ((key.charCodeAt(i + 11) & 255) << 24)];
            k1 = x64Multiply(k1, c1);
            k1 = x64Rotl(k1, 31);
            k1 = x64Multiply(k1, c2);
            h1 = x64Xor(h1, k1);
            h1 = x64Rotl(h1, 27);
            h1 = x64Add(h1, h2);
            h1 = x64Add(x64Multiply(h1, [0, 5]), [0, 1390208809]);
            k2 = x64Multiply(k2, c2);
            k2 = x64Rotl(k2, 33);
            k2 = x64Multiply(k2, c1);
            h2 = x64Xor(h2, k2);
            h2 = x64Rotl(h2, 31);
            h2 = x64Add(h2, h1);
            h2 = x64Add(x64Multiply(h2, [0, 5]), [0, 944331445])
        }
        k1 = [0, 0];
        k2 = [0, 0];
        switch (remainder) {
        case 15:
            k2 = x64Xor(k2, x64LeftShift([0, key.charCodeAt(i + 14)], 48));
        case 14:
            k2 = x64Xor(k2, x64LeftShift([0, key.charCodeAt(i + 13)], 40));
        case 13:
            k2 = x64Xor(k2, x64LeftShift([0, key.charCodeAt(i + 12)], 32));
        case 12:
            k2 = x64Xor(k2, x64LeftShift([0, key.charCodeAt(i + 11)], 24));
        case 11:
            k2 = x64Xor(k2, x64LeftShift([0, key.charCodeAt(i + 10)], 16));
        case 10:
            k2 = x64Xor(k2, x64LeftShift([0, key.charCodeAt(i + 9)], 8));
        case 9:
            k2 = x64Xor(k2, [0, key.charCodeAt(i + 8)]);
            k2 = x64Multiply(k2, c2);
            k2 = x64Rotl(k2, 33);
            k2 = x64Multiply(k2, c1);
            h2 = x64Xor(h2, k2);
        case 8:
            k1 = x64Xor(k1, x64LeftShift([0, key.charCodeAt(i + 7)], 56));
        case 7:
            k1 = x64Xor(k1, x64LeftShift([0, key.charCodeAt(i + 6)], 48));
        case 6:
            k1 = x64Xor(k1, x64LeftShift([0, key.charCodeAt(i + 5)], 40));
        case 5:
            k1 = x64Xor(k1, x64LeftShift([0, key.charCodeAt(i + 4)], 32));
        case 4:
            k1 = x64Xor(k1, x64LeftShift([0, key.charCodeAt(i + 3)], 24));
        case 3:
            k1 = x64Xor(k1, x64LeftShift([0, key.charCodeAt(i + 2)], 16));
        case 2:
            k1 = x64Xor(k1, x64LeftShift([0, key.charCodeAt(i + 1)], 8));
        case 1:
            k1 = x64Xor(k1, [0, key.charCodeAt(i)]);
            k1 = x64Multiply(k1, c1);
            k1 = x64Rotl(k1, 31);
            k1 = x64Multiply(k1, c2);
            h1 = x64Xor(h1, k1)
        }
        h1 = x64Xor(h1, [0, key.length]);
        h2 = x64Xor(h2, [0, key.length]);
        h1 = x64Add(h1, h2);
        h2 = x64Add(h2, h1);
        h1 = x64Fmix(h1);
        h2 = x64Fmix(h2);
        h1 = x64Add(h1, h2);
        h2 = x64Add(h2, h1);
        return ("00000000" + (h1[0] >>> 0).toString(16)).slice(-8) + ("00000000" + (h1[1] >>> 0).toString(16)).slice(-8) + ("00000000" + (h2[0] >>> 0).toString(16)).slice(-8) + ("00000000" + (h2[1] >>> 0).toString(16)).slice(-8)
    };

function printComponents(components) {
    var values = components.map(function(component) {
        return component.value
    });
    var hash = Fingerprint2_x64hash128(values.join(''), 31);
    return hash
}

var components = [
    {
        "key": "userAgent",
        "value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36"
    },
    {
        "key": "webdriver",
        "value": false
    },
    {
        "key": "language",
        "value": "zh-CN"
    },
    {
        "key": "colorDepth",
        "value": 24
    },
    {
        "key": "deviceMemory",
        "value": 8
    },
    {
        "key": "hardwareConcurrency",
        "value": 12
    },
    {
        "key": "screenResolution",
        "value": [
            1920,
            1080
        ]
    },
    {
        "key": "availableScreenResolution",
        "value": [
            1920,
            1032
        ]
    },
    {
        "key": "timezoneOffset",
        "value": -480
    },
    {
        "key": "timezone",
        "value": "Asia/Shanghai"
    },
    {
        "key": "sessionStorage",
        "value": true
    },
    {
        "key": "localStorage",
        "value": true
    },
    {
        "key": "indexedDb",
        "value": true
    },
    {
        "key": "addBehavior",
        "value": false
    },
    {
        "key": "openDatabase",
        "value": true
    },
    {
        "key": "cpuClass",
        "value": "not available"
    },
    {
        "key": "platform",
        "value": "Win32"
    },
    {
        "key": "plugins",
        "value": [
            [
                "PDF Viewer",
                "Portable Document Format",
                [
                    [
                        "application/pdf",
                        "pdf"
                    ],
                    [
                        "text/pdf",
                        "pdf"
                    ]
                ]
            ],
            [
                "Chrome PDF Viewer",
                "Portable Document Format",
                [
                    [
                        "application/pdf",
                        "pdf"
                    ],
                    [
                        "text/pdf",
                        "pdf"
                    ]
                ]
            ],
            [
                "Chromium PDF Viewer",
                "Portable Document Format",
                [
                    [
                        "application/pdf",
                        "pdf"
                    ],
                    [
                        "text/pdf",
                        "pdf"
                    ]
                ]
            ],
            [
                "Microsoft Edge PDF Viewer",
                "Portable Document Format",
                [
                    [
                        "application/pdf",
                        "pdf"
                    ],
                    [
                        "text/pdf",
                        "pdf"
                    ]
                ]
            ],
            [
                "WebKit built-in PDF",
                "Portable Document Format",
                [
                    [
                        "application/pdf",
                        "pdf"
                    ],
                    [
                        "text/pdf",
                        "pdf"
                    ]
                ]
            ]
        ]
    },
    {
        "key": "canvas",
        "value": [
            "canvas winding:yes",
            "canvas fp:data:image/png;base64,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QGC5C5QP6PPE9Lm30o/Eis/v40Tfqzh/e2f0Tm9eEsccXTMWfafH4u7VoxFdrZV+RPOIGGpEo/W7HwIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBD4BwLLKqC3+7W9mX74x/9L7xjeESevjseZ+5uid3rLolqPrnkT/cc+xZ1L22Lm0OyvYB6NaAws6h4eRoAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQJ/FVi2Af3PT/xbUO9+3Bk9t9bG/uGuaL7dGkdnuhf0OzK26kNc2fMlVm57Frcub4+p5r2IeNiIxoMFfY5hBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQILBgAv9NQJ9P7FdUjzh4pxkXrq2Lj9ETB16uj46ZTbFrqjN+/o31v72t/i4iJuPFhq8xsvFbnH09HH3nVseT4+Px6OSkWL5g31GDCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgsCgC/3VAXxRhDyFAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBEgICeokzWZIAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEsgUE9Gxh8wkQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECghICAXuJMliRAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBbAEBPVvYfAIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAoISCglziTJQkQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIEAgW0BAzxY2nwABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgRKCAjoJc5kSQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBDIFhDQs4XNJ0CAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIESAgJ6iTNZkgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgSyBQT0bGHzCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCEgIBe4kyWJECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFsAQE9W9h8AgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECghIKCXOJMlCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQCBbQEDPFjafAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBEoICOglzmRJAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIEMgWENCzhc0nQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgRICAnqJM1mSAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBLIFBPRsYfMJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoISAgF7iTJYkQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgWwBAT1b2HwCBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQKCEgoJc4kyUJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAIFtAQM8WNp8AAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIESggI6CXOZEkCBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQyBYQ0LOFzSdAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBEgICeokzWZIAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEsgUE9Gxh8wkQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECghICAXuJMliRAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBbAEBPVvYfAIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAoISCglziTJQkQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIEAgW0BAzxY2nwABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgRKCAjoJc5kSQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBDIFhDQs4XNJ0CAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIESAgJ6iTNZkgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgSyBQT0bGHzCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCEgIBe4kyWJECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFsAQE9W9h8AgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECghIKCXOJMlCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQCBbQEDPFjafAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBEoICOglzmRJAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIEMgWENCzhc0nQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgRICAnqJM1mSAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBLIFBPRsYfMJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoISAgF7iTJYkQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgWwBAT1b2HwCBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQKCEgoJc4kyUJECBAgAABAgQIECBAgAABAgQIWgqb2wAAALBJREFUECBAgAABAgQIECBAIFtAQM8WNp8AAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIESggI6CXOZEkCBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQyBYQ0LOFzSdAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBEgICeokzWZIAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEsgW+AwUbG20F5HdnAAAAAElFTkSuQmCC"
        ]
    },
    {
        "key": "webgl",
        "value": [
            "data:image/png;base64,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",
            "extensions:ANGLE_instanced_arrays;EXT_blend_minmax;EXT_color_buffer_half_float;EXT_disjoint_timer_query;EXT_float_blend;EXT_frag_depth;EXT_shader_texture_lod;EXT_texture_compression_bptc;EXT_texture_compression_rgtc;EXT_texture_filter_anisotropic;EXT_sRGB;KHR_parallel_shader_compile;OES_element_index_uint;OES_fbo_render_mipmap;OES_standard_derivatives;OES_texture_float;OES_texture_float_linear;OES_texture_half_float;OES_texture_half_float_linear;OES_vertex_array_object;WEBGL_color_buffer_float;WEBGL_compressed_texture_s3tc;WEBGL_compressed_texture_s3tc_srgb;WEBGL_debug_renderer_info;WEBGL_debug_shaders;WEBGL_depth_texture;WEBGL_draw_buffers;WEBGL_lose_context;WEBGL_multi_draw",
            "webgl aliased line width range:[1, 1]",
            "webgl aliased point size range:[1, 1024]",
            "webgl alpha bits:8",
            "webgl antialiasing:yes",
            "webgl blue bits:8",
            "webgl depth bits:24",
            "webgl green bits:8",
            "webgl max anisotropy:16",
            "webgl max combined texture image units:32",
            "webgl max cube map texture size:16384",
            "webgl max fragment uniform vectors:1024",
            "webgl max render buffer size:16384",
            "webgl max texture image units:16",
            "webgl max texture size:16384",
            "webgl max varying vectors:30",
            "webgl max vertex attribs:16",
            "webgl max vertex texture image units:16",
            "webgl max vertex uniform vectors:4095",
            "webgl max viewport dims:[32767, 32767]",
            "webgl red bits:8",
            "webgl renderer:WebKit WebGL",
            "webgl shading language version:WebGL GLSL ES 1.0 (OpenGL ES GLSL ES 1.0 Chromium)",
            "webgl stencil bits:0",
            "webgl vendor:WebKit",
            "webgl version:WebGL 1.0 (OpenGL ES 2.0 Chromium)",
            "webgl unmasked vendor:Google Inc. (NVIDIA)",
            "webgl unmasked renderer:ANGLE (NVIDIA, NVIDIA GeForce GTX 1050 Ti Direct3D11 vs_5_0 ps_5_0, D3D11)",
            "webgl vertex shader high float precision:23",
            "webgl vertex shader high float precision rangeMin:127",
            "webgl vertex shader high float precision rangeMax:127",
            "webgl vertex shader medium float precision:23",
            "webgl vertex shader medium float precision rangeMin:127",
            "webgl vertex shader medium float precision rangeMax:127",
            "webgl vertex shader low float precision:23",
            "webgl vertex shader low float precision rangeMin:127",
            "webgl vertex shader low float precision rangeMax:127",
            "webgl fragment shader high float precision:23",
            "webgl fragment shader high float precision rangeMin:127",
            "webgl fragment shader high float precision rangeMax:127",
            "webgl fragment shader medium float precision:23",
            "webgl fragment shader medium float precision rangeMin:127",
            "webgl fragment shader medium float precision rangeMax:127",
            "webgl fragment shader low float precision:23",
            "webgl fragment shader low float precision rangeMin:127",
            "webgl fragment shader low float precision rangeMax:127",
            "webgl vertex shader high int precision:0",
            "webgl vertex shader high int precision rangeMin:31",
            "webgl vertex shader high int precision rangeMax:30",
            "webgl vertex shader medium int precision:0",
            "webgl vertex shader medium int precision rangeMin:31",
            "webgl vertex shader medium int precision rangeMax:30",
            "webgl vertex shader low int precision:0",
            "webgl vertex shader low int precision rangeMin:31",
            "webgl vertex shader low int precision rangeMax:30",
            "webgl fragment shader high int precision:0",
            "webgl fragment shader high int precision rangeMin:31",
            "webgl fragment shader high int precision rangeMax:30",
            "webgl fragment shader medium int precision:0",
            "webgl fragment shader medium int precision rangeMin:31",
            "webgl fragment shader medium int precision rangeMax:30",
            "webgl fragment shader low int precision:0",
            "webgl fragment shader low int precision rangeMin:31",
            "webgl fragment shader low int precision rangeMax:30"
        ]
    },
    {
        "key": "webglVendorAndRenderer",
        "value": "Google Inc. (NVIDIA)~ANGLE (NVIDIA, NVIDIA GeForce GTX 1050 Ti Direct3D11 vs_5_0 ps_5_0, D3D11)"
    },
    {
        "key": "adBlock",
        "value": false
    },
    {
        "key": "hasLiedLanguages",
        "value": false
    },
    {
        "key": "hasLiedResolution",
        "value": false
    },
    {
        "key": "hasLiedOs",
        "value": false
    },
    {
        "key": "hasLiedBrowser",
        "value": false
    },
    {
        "key": "touchSupport",
        "value": [
            0,
            false,
            false
        ]
    },
    {
        "key": "fonts",
        "value": [
            "Arial",
            "Arial Black",
            "Arial Narrow",
            "Book Antiqua",
            "Bookman Old Style",
            "Calibri",
            "Cambria",
            "Cambria Math",
            "Century",
            "Century Gothic",
            "Comic Sans MS",
            "Consolas",
            "Courier",
            "Courier New",
            "Georgia",
            "Helvetica",
            "Impact",
            "Lucida Console",
            "Lucida Handwriting",
            "Lucida Sans Unicode",
            "Microsoft Sans Serif",
            "Monotype Corsiva",
            "MS Gothic",
            "MS PGothic",
            "MS Reference Sans Serif",
            "MS Sans Serif",
            "MS Serif",
            "Palatino Linotype",
            "Segoe Print",
            "Segoe Script",
            "Segoe UI",
            "Segoe UI Light",
            "Segoe UI Semibold",
            "Segoe UI Symbol",
            "Tahoma",
            "Times",
            "Times New Roman",
            "Trebuchet MS",
            "Verdana",
            "Wingdings",
            "Wingdings 2",
            "Wingdings 3"
        ]
    },
    {
        "key": "audio",
        "value": "124.04347527516074"
    }
]
function get_login_url(CallBack, userName, checkCode, password) {
    password = getMD5Value(password)
    aws = printComponents(components)
    var url = 'https://aq.99.com/AjaxAction/AC_userlogin.ashx'
    return url + "?CallBack=" + CallBack + "&siteflag=995&nduseraction=login&txtUserName=" + userName + "&txtPassword=" + password + "&checkcode=" + checkCode + "&Rnd=" + Math.random() + "&aws=" + aws;
}

Python源码:文章来源地址https://www.toymoban.com/news/detail-672451.html

"""
Email:912917367@qq.com
Date: 2023/8/24 10:18
"""
import re
import time

import execjs
import requests

from utils.chaojiying import ChaojiyingClient


class Spider:
    def __init__(self, username, password):
        self.session = requests.session()
        self.session.headers = {
            "authority": "checkcode.99.com",
            "referer": "https://aq.99.com/",
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36"
        }
        self.callback = 'jQuery112401962284678331523_1692843120473'
        self.ticket = ''
        self.img_url = ''
        self.pic_str = ''
        self.username = username
        self.password = password

    def get_ticket(self):
        url = "https://checkcode.99.com/token"
        params = {
            "action": "getticket",
            "bussiness": "aq_login",
            "callback": self.callback,
            "_": str(int(time.time() * 1000))
        }
        response = self.session.get(url, params=params)
        pattern = r'"ticket":"(.*?)"'
        self.ticket = re.findall(pattern, response.text)[0]
        print('ticket:', self.ticket)

    def get_img_url(self):
        url = "https://aq.99.com/AjaxAction/AC_verifycode.ashx"
        params = {
            "CallBack": self.callback,
            "nduseraction": "getverifycodestate",
            "verifycodetype": "UserLogin",
            "bussiness": "aq_login",
            "ticket": self.ticket,
            "SiteFlag": "995",
            "RND": "0.7099289496089389",
            "_": str(int(time.time() * 1000))
        }
        response = self.session.get(url, params=params)
        pattern = r'"VerifyCodeUrl":"(.*?)"'
        self.img_url = re.findall(pattern, response.text)[0]
        print('img_url:', self.img_url)

    def get_img_code(self):
        response = self.session.get(self.img_url)
        with open('img.png', 'wb') as f:
            f.write(response.content)

        cjy = ChaojiyingClient('打码平台账号', '打码平台密码', '946014')
        im = open('img.png', 'rb').read()
        pic_data = cjy.post_pic(im, 1902)
        self.pic_str = pic_data['pic_str']
        print('pic_str:', self.pic_str)

    def login(self):
        with open('get_params.js', 'r', encoding='utf-8') as f:
            js_obj = execjs.compile(f.read())
        url = js_obj.call('get_login_url', self.callback, self.username, self.pic_str, self.password)
        response = self.session.get(url)
        print(response.text)
        print(response)


if __name__ == '__main__':
    s = Spider('账号', '密码')
    s.get_ticket()
    s.get_img_url()
    s.get_img_code()
    s.login()

到了这里,关于爬虫逆向实战(二十)--某99网站登录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 爬虫逆向实战(十三)--某课网登录

    主页地址:某课网 1、抓包 通过抓包可以发现登录接口是user/login 2、判断是否有加密参数 请求参数是否加密? 通过查看“载荷”模块可以发现有一个 password 加密参数,还有一个 browser_key 这个可以写死不需要关心 请求头是否加密? 无 响应是否加密? 无 cookie是否加密? 无

    2024年02月12日
    浏览(51)
  • 【爬虫逆向分析实战】某笔登录算法分析——本地替换分析法

    作者最近在做一个 收集粉币 的项目,可以用来干嘛这里就不展开了😁,需要进行登录换算token从而达到监控收集的作用,手机抓包发现他是通过APP进行计算之后再请求接口的,通过官网分析可能要比 APP逆向方便多 ,但是通过这几天的观察我并没有头绪,这篇文章草稿创建了

    2024年02月05日
    浏览(48)
  • 爬虫案例-使用Session登录指定网站(JS逆向AES-CBC加密+MD5加密)

    总体概览:使用Session登录该网站,其中包括对password参数进行js逆向破解                 (涉及加密:md5加密+AES-CBC加密) 难度:两颗星 目标网址:aHR0cHM6Ly93d3cuZnhiYW9nYW8uY29tLw== 下面文章将分为四个部分:         1、定位主体加密函数,进行断点         2、分

    2024年02月09日
    浏览(71)
  • 爬虫笔记(一):实战登录古诗文网站

    需求:登录古诗文网站,账号+密码+图形验证码 第一 :自己注册一个账号+密码哈 第二 :图形验证码,需要一个打码平台(充钱,超能力power!)或者tesseract开源包,这两个用于自动识别图形验证码哈~ 我用的是超级鹰,充了1块,有1000积分,一次10积分,初学者福音hhh

    2024年01月20日
    浏览(36)
  • 每日网站逆向练习:day4 某安全中心登录密码加密

    某安全中心网站登录载荷中有2个参数需要破解 首先这个aws直接就是送的,不管是多试几次或者是直接去看他的方法,都可以发现这个值是写死的 不过点进去看他的方法好像也不简单,不过既然是写死的就不管他了 我们搜索后发现竟然只有一处,而且还并不是在对它赋值 不

    2024年02月05日
    浏览(60)
  • 逆向爬虫进阶实战:突破反爬虫机制,实现数据抓取

    随着网络技术的发展,网站为了保护自己的数据和资源,纷纷采用了各种反爬虫机制。然而,逆向爬虫技术的出现,使得我们可以突破这些限制,实现对目标网站的深入分析和抓取。本文将介绍逆向爬虫进阶实战的一些技巧和代码片段,帮助读者更好地理解和掌握这一技术。

    2024年02月04日
    浏览(52)
  • 微软Bing Chat逆向爬虫实战

    最近AIGC太火了,以OpenAI为首的一批人工智能公司一次又一次的引爆科技圈的浪潮,从ChatGPT到Sora,OpenAI在一年多时间里连续发布两个重磅产品,彻底拉开了AI时代的帷幕。而作为科技巨头微软也是OpenAi的大股东,OpenAi只要出了新模型,那么微软的Bing都是第一时间集成上去,基

    2024年04月09日
    浏览(50)
  • WebSocket爬虫与JS逆向实战

    声明:本文章中所有内容仅供学习交流,不可用于任何商业用途和非法用途,否则后果自负,如有侵权,请联系作者立即删除!由于本人水平有限,如有理解或者描述不准确的地方,还望各位大佬指教!! 练习网站: Q3JhenkgUHJvTW9ua2V5IGh0dHBzOi8vd3d3LnBhbnpob3UuZ292LmNuL3p3Z2tfMTU4NjEve

    2024年02月07日
    浏览(47)
  • js逆向·找到登录时目标网站的加密算法的几种方式

    为什么要去找到目标网站的加密密码方法: 为了要把我们的payload正确的带入目标网站的服务器进行逻辑验证,那么就需要知道对方使用的什么加密或者编码规则来处理数据的,比如说我们输入的密码被base64编码了,然后发送给后端,后端会进行解码过后再带入逻辑验证中去

    2024年02月08日
    浏览(46)
  • 某网站DES加密逆向分析实战

    分析站点 : aHR0cDovL2VpcC5jaGFuZmluZS5jb20v 首先我们提交一下登陆信息: 搜索 j_password 查看加密函数: 把上图搜索到的 encryptPassword 函数拿出来分析一下:

    2024年02月11日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包