2021-09-29 微博扫码登录获取cookie,附带账号密码js逆向解密过程(完结)

一、前言

作者:tiezhu
接下来就是微博的js逆向了,这里需要使用到WebStorm
WebStorm下载
本文章仅供学习研究,如若侵犯到贵公司权益请联系229456906@qq.com第一时间进行删除;各位朋友切忌用于一切非法途径,否则后果自行承担!
需要使用的库

import base64
import requests
import re
import os
import http.cookiejar as cookielib
# import pickle
import execjs
import time
import json
from PIL import Image
from urllib import parse

二、分析过程

  1. 来到到微博主页微博主页
  2. F12打开chrome开发者模式,输入账号密码,这里账号密码以13888888888,123456为例
    点击登录之后 一眼就看到了login这个接口,和右边一堆的参数在这里插入图片描述
    多点几次可以看到
    su
    servertime
    nonce
    rsakv
    sp
    只有这几个在变化,我们需要破解的就只有账号和密码
    在看一下其他接口,可以发现这样一个包含su的
    在这里插入图片描述
    我们对这个su分析一下,按下Ctrl+shift+f
    直接搜索su这个参数,出现了很多个,可以慢慢去找,最终锁定了下面这个
    在这里插入图片描述
    格式化之后,搜索su:
    发现su:d
    d = sinaSSOEncoder.base64.encode(urlencode(d));
    打上断点开始调试,查看一下,这个就是咱们需要的账号加密
    在这里插入图片描述
    而且这个su是通过base64计算得来的
    可以直接通过pycharm来对其编写
    self.username是传入的账号 代码如下:
su = base64.b64encode(parse.quote(self.username).encode('utf-8')).decode('utf-8')
print('账号已加密:',su)

运行结果:
在这里插入图片描述
直接搞定,而且这个接口里面返回的数据有以下几个:
在这里插入图片描述
和第一步对比下来,发现post表单里面需要的参数
su
servertime
nonce
rsakv
那就剩下了sp了,这个sp会不会是密码呢?
依旧Ctrl+shift+f 去搜索sp,出现了很多js文件,都格式化之后搜索sp找到了下面这个
在这里插入图片描述
e.sp = b;
发现上面有这么一句
b = f.encrypt([me.servertime, me.nonce].join("\t") + “\n” + b)
打上断掉调试一下
在这里插入图片描述
这里看到是sp的加密之后数据
这下准备扣代码了,打开WebStorm,把这段代码复制上去
在这里插入图片描述
这里的三个参数,打印出来看一下
me.rsaPubkey
me.servertime
me.nonce
在这里插入图片描述
就是通过su那个接口获取的
在继续看这句加密代码

b = f.encrypt([me.servertime, me.nonce].join("\t") + "\n" + b)

在调试界面把鼠标放在f.encrypt会显示如下图这样
在这里插入图片描述
点进去 f bt(a) 看一下
在这里插入图片描述

把这段代码复制到WebStorm里面去,把加密那一段注释掉运行一下

在这里插入图片描述
提示ReferenceError: sinaSSOEncoder is not defined
sinaSSOEncoder没有定义的话,在开头定义在运行看一下

在这里插入图片描述
接着又是 navigator is not defined
这个的话,我可以直接给大家一个navigator代码,直接写在开头用就行了

navigator = {
    // WT-JS_DEBUG
    appCodeName: "Mozilla",
    appMinorVersion: "0",
    appName: "Netscape",
    appVersion: "5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3; rv:11.0) like Gecko",
    browserLanguage: "zh-CN",
    cookieEnabled: true,
    cpuClass: "x86",
    language: "zh-CN",
    maxTouchPoints: 0,
    msManipulationViewsEnabled: true,
    msMaxTouchPoints: 0,
    msPointerEnabled: true,
    onLine: true,
    platform: "Win32",
    pointerEnabled: true,
    product: "Gecko",
    systemLanguage: "zh-CN",
    userAgent: "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3; rv:11.0) like Gecko",
    userLanguage: "zh-CN",
    vendor: "",
    vendorSub: "",
    webdriver: false
}, window = global, window.navigator = navigator;

在运行一下没有报错
在这里插入图片描述
现在就可以改写加密代码块了

我们要打印密码查看,就要先写一个函数声明

function pwd() {

    var f = new sinaSSOEncoder.RSAKey;
    f.setPublic(me.rsaPubkey, "10001");
    b = f.encrypt([me.servertime, me.nonce].join("\t") + "\n" + b)
    console.log(b)
    
}

直接运行的话实会报错的,里面的四个参数还没传入
me.rsaPubkey
me.servertime
me.nonce
b

b = f.encrypt([me.servertime, me.nonce].join("\t") + "\n" + b)

括号里面的b是传入的初始密码,改成p
把另外三个去掉me.最后调用pwd()这个函数
调用的时候,在网页哪里把
me.rsaPubkey
me.servertime
me.nonce
这几个参数数据复制下来
传参的方式写入函数,就成为这个样子

function pwd(p,servertime,nonce,Pubkey) {

    var f = new sinaSSOEncoder.RSAKey;
    f.setPublic(Pubkey, "10001");
    b = f.encrypt([servertime, nonce].join("\t") + "\n" + p)
    console.log(b)

}
pwd('123456',
    '1632898111',
    '7UMHW2',
    'EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443')

运行结果如下
在这里插入图片描述
到这里账号密码就就分析完了
pycharm里面的写完又不一样了
需要通过execjs调用js文件才行

import execjs

在这之前,需要通过预登陆获取以下参数
servertime
nonce
rsakv
pubkey
pcid

预登陆url

'https://login.sina.com.cn/sso/prelogin.php'

部分代码如下:

    def pre_login(self):
        '''预登陆获取数据,这里有反爬,需要加上“Referer”'''
        self.params = {
            'entry': 'weibo',
            'callback': 'sinaSSOController.preloginCallBack',
            'su': self.su,
            'rsakt': 'mod',
            'client': 'ssologin.js(v1.4.19)',
            '_': self.time,
        }
        response = s.get(self.pre_url,params=self.params,headers = self.headers)
        # .content是字节码还要编码,但是.text不是所有时候显示都正常,这是就需要用.content进行手动编码。
        # 如何修改编码方式:response.content.decode(“utf8”)
        # eval() 函数用来执行一个字符串表达式,并返回表达式的值。
        res = eval(response.content.decode('utf-8').replace('sinaSSOController.preloginCallBack', ''))
        #print(res)
        return res

需要注意的是这里有个反爬机制,headers里面需要加上“Referer”

self.headers = {'Referer': 'https://weibo.com/',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36'}

就能取出下面这几个参数了

pcid = res['pcid']
pubkey = res['pubkey']
rsakv = res['rsakv']
nonce = res['nonce']
servertime = res['servertime']

把之前改写的js代码复制到pycharm里面,pwd()需要改写以下,代码如下:

navigator = {
    // WT-JS_DEBUG
    appCodeName: "Mozilla",
    appMinorVersion: "0",
    appName: "Netscape",
    appVersion: "5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3; rv:11.0) like Gecko",
    browserLanguage: "zh-CN",
    cookieEnabled: true,
    cpuClass: "x86",
    language: "zh-CN",
    maxTouchPoints: 0,
    msManipulationViewsEnabled: true,
    msMaxTouchPoints: 0,
    msPointerEnabled: true,
    onLine: true,
    platform: "Win32",
    pointerEnabled: true,
    product: "Gecko",
    systemLanguage: "zh-CN",
    userAgent: "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3; rv:11.0) like Gecko",
    userLanguage: "zh-CN",
    vendor: "",
    vendorSub: "",
    webdriver: false
}, window = global, window.navigator = navigator;


var sinaSSOEncoder = {};
(function() {
        function bt(a) {
            var b = bp(a, this.n.bitLength() + 7 >> 3);
            if (b == null)
                return null;
            var c = this.doPublic(b);
            if (c == null)
                return null;
            var d = c.toString(16);
            return (d.length & 1) == 0 ? d : "0" + d
        }
        function bs(a) {
            return a.modPowInt(this.e, this.n)
        }
        function br(a, b) {
            if (a != null && b != null && a.length > 0 && b.length > 0) {
                this.n = bm(a, 16);
                this.e = parseInt(b, 16)
            } else
                alert("Invalid RSA public key")
        }
  
            c[--b] = 0;
            var g = new bl
                , h = [];
            while (b > 2) {
                h[0] = 0;
                while (h[0] == 0)
                    g.nextBytes(h);
                c[--b] = h[0]
            }
            c[--b] = 2;
            c[--b] = 0;
            return new d(c)
        }
        function bo(a) {
            return a < 16 ? "0" + a.toString(16) : a.toString(16)
        }
        function bn(a, b) {
            var c = ""
                , d = 0;
            while (d + b < a.length) {
                c += a.substring(d, d + b) + "\n";
                d += b
            }
            return c + a.substring(d, a.length)
        }
        function bm(a, b) {
            return new d(a,b)
        }
        function bl() {}
        function bk(a) {
            var b;
            for (b = 0; b < a.length; ++b)
                a[b] = bj()
        }
        function bj() {
            if (bc == null) {
                bg();
                bc = ba();
                bc.init(bd);
                for (be = 0; be < bd.length; ++be)
                    bd[be] = 0;
                be = 0
            }
            return bc.next()
        }
        function bg() {
            bf((new Date).getTime())
        }
        function bf(a) {
            bd[be++] ^= a & 255;
            bd[be++] ^= a >> 8 & 255;
            bd[be++] ^= a >> 16 & 255;
            bd[be++] ^= a >> 24 & 255;
            be >= bb && (be -= bb)
        }
        function ba() {
            return new Z
        }
        function _() {
            var a;
            this.i = this.i + 1 & 255;
            this.j = this.j + this.S[this.i] & 255;
            a = this.S[this.i];
            this.S[this.i] = this.S[this.j];
            this.S[this.j] = a;
            return this.S[a + this.S[this.i] & 255]
        }
        function $(a) {
            var b, c, d;
            for (b = 0; b < 256; ++b)
                this.S[b] = b;
            c = 0;
            for (b = 0; b < 256; ++b) {
                c = c + this.S[b] + a[b % a.length] & 255;
                d = this.S[b];
                this.S[b] = this.S[c];
                
            }
            this.i = 0;
            this.j = 0
        }
        function Z() {
            this.i = 0;
            this.j = 0;
            this.S = []
        }
        function Y(a, b) {
            var c;
            a < 256 || b.isEven() ? c = new J(b) : c = new Q(b);
            return this.exp(a, c)
        }
        function X(a, b) {
            if (a > 4294967295 || a < 1)
                return d.ONE;
            var c = e()
                , f = e()
                , g = b.convert(this)
                , h = y(a) - 1;
            g.copyTo(c);
            while (--h >= 0) {
                b.sqrTo(c, f);
                if ((a & 1 << h) > 0)
                    b.mulTo(f, g, c);
                else {
                    var i = c;
                    c = f;
                    f = i
                }
            }
            return b.revert(c)
        }
        function W() {
            return (this.t > 0 ? this[0] & 1 : this.s) == 0
        }
        function V(a, b, c) {
            a.multiplyTo(b, c);
            this.reduce(c)
        }
        function U(a, b) {
            a.squareTo(b);
            this.reduce(b)
        }
        function T(a) {
            while (a.t <= this.mt2)
                a[a.t++] = 0;
            for (var b = 0; b < this.m.t; ++b) {
                var c = a[b] & 32767
                    , d = c * this.mpl + ((c * this.mph + (a[b] >> 15) * this.mpl & this.um) << 15) & a.DM;
                c = b + this.m.t;
                a[c] += this.m.am(0, d, a, b, 0, this.m.t);
                while (a[c] >= a.DV) {
                    a[c] -= a.DV;
                    a[++c]++
                }
            }
            a.clamp();
            a.drShiftTo(this.m.t, a);
            a.compareTo(this.m) >= 0 && a.subTo(this.m, a)
        }
        function S(a) {
            var b = e();
            a.copyTo(b);
            this.reduce(b);
            return b
        }
        function R(a) {
            var b = e();
            a.abs().dlShiftTo(this.m.t, b);
            b.divRemTo(this.m, null, b);
            a.s < 0 && b.compareTo(d.ZERO) > 0 && this.m.subTo(b, b);
            return b
        }
        function Q(a) {
            this.m = a;
            this.mp = a.invDigit();
            this.mpl = this.mp & 32767;
            this.mph = this.mp >> 15;
            this.um = (1 << a.DB - 15) - 1;
            this.mt2 = 2 * a.t
        }
        function P() {
            if (this.t < 1)
                return 0;
            var a = this[0];
            if ((a & 1) == 0)
                return 0;
            var b = a & 3;
            b = b * (2 - (a & 15) * b) & 15;
            b = b * (2 - (a & 255) * b) & 255;
            b = b * (2 - ((a & 65535) * b & 65535)) & 65535;
            b = b * (2 - a * b % this.DV) % this.DV;
            return b > 0 ? this.DV - b : -b
        }
        function O(a, b) {
            a.squareTo(b);
            this.reduce(b)
        }
        function N(a, b, c) {
            a.multiplyTo(b, c);
            this.reduce(c)
        }
        function M(a) {
            a.divRemTo(this.m, null, a)
        }
        function L(a) {
            return a
        }
        function K(a) {
            return a.s < 0 || a.compareTo(this.m) >= 0 ? a.mod(this.m) : a
        }
        function J(a) {
            this.m = a
        }
        function I(a) {
            var b = e();
            this.abs().divRemTo(a, null, b);
            this.s < 0 && b.compareTo(d.ZERO) > 0 && a.subTo(b, b);
            return b
        }
        function H(a, b, c) {
            var f = a.abs();
            if (!(f.t <= 0)) {
                var g = this.abs();
                if (g.t < f.t) {
                    b != null && b.fromInt(0);
                    c != null && this.copyTo(c);
                    return
                }
                c == null && (c = e());
                var h = e()
                    , i = this.s
                    , j = a.s
                    , k = this.DB - y(f[f.t - 1]);
                if (k > 0) {
                    f.lShiftTo(k, h);
                    g.lShiftTo(k, c)
                } else {
                    f.copyTo(h);
                    g.copyTo(c)
                }
                var l = h.t
                    , m = h[l - 1];
                if (m == 0)
                    return;
                var n = m * (1 << this.F1) + (l > 1 ? h[l - 2] >> this.F2 : 0)
                    , o = this.FV / n
                    , p = (1 << this.F1) / n
                    , q = 1 << this.F2
                    , r = c.t
                    , s = r - l
                    , t = b == null ? e() : b;
                h.dlShiftTo(s, t);
                if (c.compareTo(t) >= 0) {
                    c[c.t++] = 1;
                    c.subTo(t, c)
                }
                d.ONE.dlShiftTo(l, t);
                t.subTo(h, h);
                while (h.t < l)
                    h[h.t++] = 0;
                while (--s >= 0) {
                    var u = c[--r] == m ? this.DM : Math.floor(c[r] * o + (c[r - 1] + q) * p);
                    if ((c[r] += h.am(0, u, c, s, 0, l)) < u) {
                        h.dlShiftTo(s, t);
                        c.subTo(t, c);
                        while (c[r] < --u)
                            c.subTo(t, c)
                    }
                }
                if (b != null) {
                    c.drShiftTo(l, b);
                    i != j && d.ZERO.subTo(b, b)
                }
                c.t = l;
                c.clamp();
                k > 0 && c.rShiftTo(k, c);
                i < 0 && d.ZERO.subTo(c, c)
            }
        }
        function G(a) {
            var b = this.abs()
                , c = a.t = 2 * b.t;
            while (--c >= 0)
                a[c] = 0;
            for (c = 0; c < b.t - 1; ++c) {
                var d = b.am(c, b[c], a, 2 * c, 0, 1);
                if ((a[c + b.t] += b.am(c + 1, 2 * b[c], a, 2 * c + 1, d, b.t - c - 1)) >= b.DV) {
                    a[c + b.t] -= b.DV;
                    a[c + b.t + 1] = 1
                }
            }
            a.t > 0 && (a[a.t - 1] += b.am(c, b[c], a, 2 * c, 0, 1));
            a.s = 0;
            a.clamp()
        }
        function F(a, b) {
            var c = this.abs()
                , e = a.abs()
                , f = c.t;
            b.t = f + e.t;
            while (--f >= 0)
                b[f] = 0;
            for (f = 0; f < e.t; ++f)
                b[f + c.t] = c.am(0, e[f], b, f, 0, c.t);
            b.s = 0;
            b.clamp();
            this.s != a.s && d.ZERO.subTo(b, b)
        }
        function E(a, b) {
            var c = 0
                , d = 0
                , e = Math.min(a.t, this.t);
            while (c < e) {
                d += this[c] - a[c];
                b[c++] = d & this.DM;
                d >>= this.DB
            }
            if (a.t < this.t) {
                d -= a.s;
                while (c < this.t) {
                    d += this[c];
                    b[c++] = d & this.DM;
                    d >>= this.DB
                }
                d += this.s
            } else {
                d += this.s;
                while (c < a.t) {
                    d -= a[c];
                    b[c++] = d & this.DM;
                    d >>= this.DB
                }
                d -= a.s
            }
            b.s = d < 0 ? -1 : 0;
            d < -1 ? b[c++] = this.DV + d : d > 0 && (b[c++] = d);
            b.t = c;
            b.clamp()
        }
        function D(a, b) {
            b.s = this.s;
            var c = Math.floor(a / this.DB);
            if (c >= this.t)
                b.t = 0;
            else {
                var d = a % this.DB
                    , e = this.DB - d
                    , f = (1 << d) - 1;
                b[0] = this[c] >> d;
                for (var g = c + 1; g < this.t; ++g) {
                    b[g - c - 1] |= (this[g] & f) << e;
                    b[g - c] = this[g] >> d
                }
                d > 0 && (b[this.t - c - 1] |= (this.s & f) << e);
                b.t = this.t - c;
                b.clamp()
            }
        }
        function C(a, b) {
            var c = a % this.DB, d = this.DB - c, e = (1 << d) - 1, f = Math.floor(a / this.DB), g = this.s << c & this.DM, h;
            for (h = this.t - 1; h >= 0; --h) {
                b[h + f + 1] = this[h] >> d | g;
                g = (this[h] & e) << c
            }
            for (h = f - 1; h >= 0; --h)
                b[h] = 0;
            b[f] = g;
            b.t = this.t + f + 1;
            b.s = this.s;
            b.clamp()
        }
        function B(a, b) {
            for (var c = a; c < this.t; ++c)
                b[c - a] = this[c];
            b.t = Math.max(this.t - a, 0);
            b.s = this.s
        }
        function A(a, b) {
            var c;
            for (c = this.t - 1; c >= 0; --c)
                b[c + a] = this[c];
            for (c = a - 1; c >= 0; --c)
                b[c] = 0;
            b.t = this.t + a;
            b.s = this.s
        }
        function z() {
            return this.t <= 0 ? 0 : this.DB * (this.t - 1) + y(this[this.t - 1] ^ this.s & this.DM)
        }
        function y(a) {
            var b = 1, c;
            if ((c = a >>> 16) != 0) {
                a = c;
                b += 16
            }
            if ((c = a >> 8) != 0) {
                a = c;
                b += 8
            }
            if ((c = a >> 4) != 0) {
                a = c;
                b += 4
            }
            if ((c = a >> 2) != 0) {
                a = c;
                b += 2
            }
            if ((c = a >> 1) != 0) {
                a = c;
                b += 1
            }
            return b
        }
        function x(a) {
            var b = this.s - a.s;
            if (b != 0)
                return b;
            var c = this.t;
            b = c - a.t;
            if (b != 0)
                return b;
            while (--c >= 0)
                if ((b = this[c] - a[c]) != 0)
                    return b;
            return 0
        }
        function w() {
            return this.s < 0 ? this.negate() : this
        }
        function v() {
            var a = e();
            d.ZERO.subTo(this, a);
            return a
        }
        function u(a) {
            if (this.s < 0)
                return "-" + this.negate().toString(a);
            var b;
            if (a == 16)
                b = 4;
            else if (a == 8)
                b = 3;
            else if (a == 2)
                b = 1;
            else if (a == 32)
                b = 5;
            else if (a == 4)
                b = 2;
            else
                return this.toRadix(a);
            var c = (1 << b) - 1, d, e = !1, f = "", g = this.t, h = this.DB - g * this.DB % b;
            if (g-- > 0) {
                if (h < this.DB && (d = this[g] >> h) > 0) {
                    e = !0;
                    f = n(d)
                }
                while (g >= 0) {
                    if (h < b) {
                        d = (this[g] & (1 << h) - 1) << b - h;
                        d |= this[--g] >> (h += this.DB - b)
                    } else {
                        d = this[g] >> (h -= b) & c;
                        if (h <= 0) {
                            h += this.DB;
                            --g
                        }
                    }
                    d > 0 && (e = !0);
                    e && (f += n(d))
                }
            }
            return e ? f : "0"
        }
        function t() {
            var a = this.s & this.DM;
            while (this.t > 0 && this[this.t - 1] == a)
                --this.t
        }
        function s(a, b) {
            var c;
            if (b == 16)
                c = 4;
            else if (b == 8)
                c = 3;
            else if (b == 256)
                c = 8;
            else if (b == 2)
                c = 1;
            else if (b == 32)
                c = 5;
            else if (b == 4)
                c = 2;
            else {
                this.fromRadix(a, b);
                return
            }
            this.t = 0;
            this.s = 0;
            var e = a.length
                , f = !1
                , g = 0;
            while (--e >= 0) {
                var h = c == 8 ? a[e] & 255 : o(a, e);
                if (h < 0) {
                    a.charAt(e) == "-" && (f = !0);
                    continue
                }
                f = !1;
                if (g == 0)
                    this[this.t++] = h;
                else if (g + c > this.DB) {
                    this[this.t - 1] |= (h & (1 << this.DB - g) - 1) << g;
                    this[this.t++] = h >> this.DB - g
                } else
                    this[this.t - 1] |= h << g;
                g += c;
                g >= this.DB && (g -= this.DB)
            }
            if (c == 8 && (a[0] & 128) != 0) {
                this.s = -1;
                g > 0 && (this[this.t - 1] |= (1 << this.DB - g) - 1 << g)
            }
            this.clamp();
            f && d.ZERO.subTo(this, this)
        }
        function r(a) {
            var b = e();
            b.fromInt(a);
            return b
        }
        function q(a) {
            this.t = 1;
            this.s = a < 0 ? -1 : 0;
            a > 0 ? this[0] = a : a < -1 ? this[0] = a + DV : this.t = 0
        }
        function p(a) {
            for (var b = this.t - 1; b >= 0; --b)
                a[b] = this[b];
            a.t = this.t;
            a.s = this.s
        }
        function o(a, b) {
            var c = k[a.charCodeAt(b)];
            return c == null ? -1 : c
        }
        function n(a) {
            return j.charAt(a)
        }
        function h(a, b, c, d, e, f) {
            var g = b & 16383
                , h = b >> 14;
            while (--f >= 0) {
                var i = this[a] & 16383
                    , j = this[a++] >> 14
                    , k = h * i + j * g;
                i = g * i + ((k & 16383) << 14) + c[d] + e;
                e = (i >> 28) + (k >> 14) + h * j;
                c[d++] = i & 268435455
            }
            return e
        }
        function g(a, b, c, d, e, f) {
            var g = b & 32767
                , h = b >> 15;
            while (--f >= 0) {
                var i = this[a] & 32767
                    , j = this[a++] >> 15
                    , k = h * i + j * g;
                i = g * i + ((k & 32767) << 15) + c[d] + (e & 1073741823);
                e = (i >>> 30) + (k >>> 15) + h * j + (e >>> 30);
                c[d++] = i & 1073741823
            }
            return e
        }
        function f(a, b, c, d, e, f) {
            while (--f >= 0) {
                var g = b * this[a++] + c[d] + e;
                e = Math.floor(g / 67108864);
                c[d++] = g & 67108863
            }
            return e
        }
        function e() {
            return new d(null)
        }
        function d(a, b, c) {
            a != null && ("number" == typeof a ? this.fromNumber(a, b, c) : b == null && "string" != typeof a ? this.fromString(a, 256) : this.fromString(a, b))
        }
        var a, b = 0xdeadbeefcafe, c = (b & 16777215) == 15715070;
        if (c && navigator.appName == "Microsoft Internet Explorer") {
            d.prototype.am = g;
            a = 30
        } else if (c && navigator.appName != "Netscape") {
            d.prototype.am = f;
            a = 26
        } else {
            d.prototype.am = h;
            a = 28
        }
        d.prototype.DB = a;
        d.prototype.DM = (1 << a) - 1;
        d.prototype.DV = 1 << a;
        var i = 52;
        d.prototype.FV = Math.pow(2, i);
        d.prototype.F1 = i - a;
        d.prototype.F2 = 2 * a - i;
        var j = "0123456789abcdefghijklmnopqrstuvwxyz", k = [], l, m;
        l = "0".charCodeAt(0);
        for (m = 0; m <= 9; ++m)
            k[l++] = m;
        l = "a".charCodeAt(0);
        for (m = 10; m < 36; ++m)
            k[l++] = m;
        l = "A".charCodeAt(0);
        for (m = 10; m < 36; ++m)
            k[l++] = m;
        J.prototype.convert = K;
        J.prototype.revert = L;
        J.prototype.reduce = M;
        Q.prototype.sqrTo = U;
        d.prototype.copyTo = p;
        d.prototype.fromInt = q;
        d.prototype.fromString = s;
        d.prototype.clamp = t;
        d.prototype.dlShiftTo = A;
        d.prototype.drShiftTo = B;
        d.prototype.lShiftTo = C;
        d.prototype.rShiftTo = D;
        d.prototype.subTo = E;
        d.prototype.multiplyTo = F;
        d.prototype.squareTo = G;
        d.prototype.divRemTo = H;
        d.prototype.invDigit = P;
        d.prototype.isEven = W;
        d.prototype.exp = X;
        d.prototype.toString = u;
        d.prototype.negate = v;
        d.prototype.abs = w;
        d.prototype.compareTo = x;
        d.prototype.bitLength = z;
        d.prototype.mod = I;
        d.prototype.modPowInt = Y;
        d.ZERO = r(0);
        d.ONE = r(1);
        Z.prototype.init = $;
        Z.prototype.next = _;
        var bb = 256, bc, bd, be;
        if (bd == null) {
            bd = [];
            be = 0;
            var bh;
            if (navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto && typeof window.crypto.random == "function") {
                var bi = window.crypto.random(32);
                for (bh = 0; bh < bi.length; ++bh)
                    bd[be++] = bi.charCodeAt(bh) & 255
            }
            while (be < bb) {
                bh = Math.floor(65536 * Math.random());
                bd[be++] = bh >>> 8;
                bd[be++] = bh & 255
            }
            be = 0;
            bg()
        }
        bl.prototype.nextBytes = bk;
        bq.prototype.doPublic = bs;
        bq.prototype.setPublic = br;
        bq.prototype.encrypt = bt;
        this.RSAKey = bq
    }
).call(sinaSSOEncoder);
function pwd(p,servertime,nonce,Pubkey) {


    var f = new sinaSSOEncoder.RSAKey;
    f.setPublic(Pubkey, "10001");
    b = f.encrypt([servertime, nonce].join("\t") + "\n" + p)
    return b

}
//pwd('123456','1632548648','K627SW','EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443')

就可以写调用了

#通过调用js代码,获取加密后的密码
with open('微博.js',encoding='utf-8') as f:
   data = f.read()
password = execjs.compile(data).call('pwd',self.password,servertime,nonce,pubkey)
#call(调用的函数名,传入的参数)
print('密码已加密:',password)

到此微博的js逆向分析就结束了,下面是源码,没有通过post提交表单登录,是通过扫码方式登录的
两个方法都写进去了,post表单大家可以自行探索

# import base64
# import requests
# import re
# import os
# import http.cookiejar as cookielib
# # import pickle
# import execjs
# import time
# import json
# from PIL import Image
# from urllib import parse

s = requests.session()
class Weibo():
    def __init__(self,username,password):
        self.username = username
        self.password = password
        self.time = int(time.time()*1000)
        self.pre_url = 'https://login.sina.com.cn/sso/prelogin.php'
        self.url = 'https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)'
        self.image_url = 'https://login.sina.com.cn/sso/qrcode/image'
        self.qrid = ''
        # self.cookie = cookiejar()
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36'}
        self.su = base64.b64encode(parse.quote(self.username).encode('utf-8')).decode('utf-8')
        # print('账号已加密:',self.su)

    def pre_login(self):
        '''预登陆获取数据,这里有反爬,需要加上“Referer”'''
        self.params = {
            'entry': 'weibo',
            'callback': 'sin.preloginCallBack',
            'su': self.su,
            'rsakt': 'mod',
            'client': 'sslogin.js(v1.4.19)',
            '_': self.time,
        }
        response = s.get(self.pre_url,params=self.params,headers = self.headers)
        # .content是字节码还要编码,但是.text不是所有时候显示都正常,这是就需要用.content进行手动编码。
        # 如何修改编码方式:response.content.decode(“utf8”)
        # eval() 函数用来执行一个字符串表达式,并返回表达式的值。
        res = eval(response.content.decode('utf-8').replace('sinaSSOController.preloginCallBack', ''))
        # print(res)
        return res

    def login_data(self):
        '''获取加密密码,提交post表单'''
        res = self.pre_login()
        pcid = res['pcid']
        pubkey = res['puy']
        rsakv = res['rsakv']
        nonce = res['noce']
        servertime = res['servime']

        # print(nonce,pcid,pubkey,rsakv,servertime)

        #通过调用js代码,获取加密后的密码
        with open('微博.js',encoding='utf-8') as f:
            data = f.read()
        password = execjs.compile(data).call('pass',self.password,nonce,pubkey)
        print('密码已加密:',password)
        self.login_data_dict = {
            'entry': 'weibo',
            'gateway': '1',
            'from': '',
            'savestate': '0',
            'qrcode_flag': 'false',
            'useticket': '1',
            'vsnf': '1',
            'su': self.su,
            'service': 'miniblog',
            'servertime': servertime,
            'nonce': nonce,
            'pwencode': 'rsa2',
            'rsakv': rsakv,
            'sp': password,
            'sr': '1920*1080',
            'encoding': 'UTF-8',
            'prelt': '125',
            'url': 'https://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack',
            'returntype': 'META',
        }
        return password


    def image(self):
        '''获取二维码,进行扫码验证登录'''
        params = {
            'entry': 'sso',
            'size': '180',
            'seice_id': 'pc_protection',
            'callback': 'STK_'+str(time.time()*1000)
        }
        res = s.get(self.image_url,headers = self.headers,params = params)
        api_key = re.search('.*?api_ey=(.*)"', res.text).group(1)
        qrid = re.search('.*?"qr":"(.*)?",', res.text).group(1)
        # qrid 是获取扫描二维码状态url的重要参数
        self.qrid = qrid
        # print(res.text, '\n', api_key, '\n', qrid)
        #拼接二维码图片url
        img = 'https://v2.qr.weibo.cn/inf/gen?api_key='
        img_url = img + str(api_key)
        headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36'}
        cha_page = s.get(img_url,headers = headers)
        with open('img.jpg','wb') as f:
            f.write(cha_page.content)
            f.close()
        try:
            img = Image.open('img.jpg')  #打开二维码
            img.show()   #显示二维码
            # img.close()  #关闭
        except Exception as e:
            print(u"请到当前目录下,找到二维码并扫描")
            # 一般英文字符在使用各种编码下, 基本都可以正常解析, 所以一般不带u;但是中文, 必须表明所需编码, 否则一旦编码转换就会出现乱码。

    def login(self):
        '''登录函数'''
        # password = self.login_data() 账号密码登录,此方法pass
        # print('密码已加密:',password)
        try:

            #跳转微博通行证,各位可以探索
            response = s.post(self.url,headers = self.headers,data = self.login_data_dict)
            # response.encoding = 'gbk'
            # print(response.text)
        except:
            self.image()
            url = 'https://login.sina.com.cn/sso/qrcode/check?entry=sso&qrid={}&callback=STK_{}'
            while 1:
                '''扫描二维码登录,每隔1秒请求一次扫码状态'''
                response = s.get(url.format(self.qrid,str(time.time()*100000)),headers = self.headers)
                # print(response.text)
                data = re.search('.*?\((.*)\)',response.text).group(1)
                data_js = json.loads(data)
                '''
                50114001:二维码未扫描状态
                50114002:二维码已扫描未确认状态
                20000000:二维码已确认状态
                50114004:二维码已失效
                '''
                # print(data_js)
                if '50114001' in str(data_js['retcode']):
                    print('二维码未使用,请扫码!')
                elif '50114002' in str(data_js['retcode']):
                    print('已扫码,请点击确认登录!')
                elif '50114004' in str(data_js['retcode']):
                    print('该二维码已失效,请重新运行程序!')
                elif '20000000' in str(data_js['retcode']):
                    print('登录成功!')
                    alt = data_js['data']['alt']
                    # print(alt)
                    break
                else:
                    print('其他情况',str(data_js['retcode']))
                time.sleep(1)


    def get_cookies(self):
        '''获取cookies,创建一个txt文件保存'''
        alt = self.login()
        if not os.path.exists('cookies.txt'):
            with open("cookies.txt", 'w') as f:
                f.write("")
        s.cookies = cookielib.LWPCookieJar(filename='cookies.txt')
        alturl = 'https://login.sina.com.cn/sso/login.php?entry=qrcodesso&retpe=TEXT&crossdomain=1&cdult=3&domain=weibo.com&alt={}&savestate=30&callback=STK_{}'
        response = s.get(alturl.format(alt,str(time.time()*10000)),headers = self.headers)
        # print(response.text)
        data = re.search('.*\((.*)\);',response.text).group(1)
        # print(data)
        data_js = json.loads(data)
        # print(data_js)
        uid = data_js['uid']
        nick = data_js['nick']
        # print('账户名:'+nick,'\n','uid:'+uid)
        crossDomainUrlList = data_js['crossDomainUrlList']
        # print(crossDomainUrlList)
        #依次访问另外三个url
        s.get(crossDomainUrlList[0],headers = self.headers)
        s.get(crossDomainUrlList[1] + '&acton=login', headers=self.headers)
        s.get(crossDomainUrlList[2], headers=self.headers)
        s.cookies.save()

    def cookie_dict(self):
        '''加载cookies'''
        self.get_cookies()
        cookies = cookielib.LWPCookieJar('cookie.txt')
        cookies.load(ignore_discard=True, ignore_expires=True)
        # 将cookie转成字典
        cookie_dict = requests.utils.dict_from_cookiejar(cookies)
        # print('cookies字典:', cookie_dict)
        return cookie_dict

    def spider(self):
        '''获取某微博评论数据验证cookie是否可用,具体规则没有编写'''
        cookies = self.cookie_dict()

        loginurl = s.get("https://weibo.com/aj/v6/comment/small?&isMain=true&dissDataFromFeed=%5Bobject%20Object%5D&ouid=6355968578&location=page_100606_home&comment_type=0&_t=0&__rnd={}".format(int(time.time() * 1000)), headers =self.headers,cookies = cookies).json()['code']

        loginurl1 = s.get("https://weibo.com/aj/v6/comment/small?ajwvr=6&act=list&mid=4686048682050ssDataFromFeed=%5Bobject%20Object%5D&ouid=6355968578&location=page_100606_home&comment_type=0&_t=0&__rnd={}".format(int(time.time() * 1000)), headers =self.headers,cookies = cookies).json()
        print(loginurl1)
   # def islogin(session):
   #      try:
   #          session.cookies.load(ignore_discard=True)
   #      except Exception:
   #          pass
   #      loginurl = session.get("https://weibo.com/aj/v6/comment/small?ajwvr=6&act=list&mid=4686048682050569&uid=5614666660&isMain=true&dissDataFromFeed=%5Bobject%20Object%5D&ouid=6355968578&location=page_100606_home&comment_type=0&_t=0&__rnd={}".format(int(time.time() * 1000)), headers =headers).json()['code']
   #      if loginurl == '100000':
   #          print('Cookies值有效,无需扫码登录!')
   #          return session, True
   #      else:
   #          print('Cookies值已经失效,请重新扫码登录!')
   #          return session, False
   #      pass

if __name__ ==  '__main__':
    username = '13888888888'
    password = '123456'
    weibo = Weibo(username,password)
    weibo.spider()

运行结果:
在这里插入图片描述

三、总结

好好学习 天天向上 不掉头发 事业有成~

码字不易,如果本篇文章对你有帮助请点个赞,谢谢~
作者:tiezhu vx:T14589【注明来意】
QQ交流群:735418202
可以关注微信公众号查看其他文章学习
在这里插入图片描述
*注:本文为原创文章,转载文章请附上本文链接!否则将追究相关责任,请自重!谢谢!

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值