1, Foreword
Author: tiezhu
The next step is the js reverse of microblog. WebStorm needs to be used here
WebStorm Download
This article is only for study and research. If it infringes your company's rights and interests, please contact us 229456906@qq.com Delete at the first time; Dear friends, do not use it in any illegal way, otherwise you will bear the consequences yourself!
Libraries to use
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
2, Analysis process
- Go to the microblog home page Microblog home page
- F12 open the chrome developer mode and enter the account password. Here, take 138888123456 as an example
After clicking login, you can see the login interface and a pile of parameters on the right
You can see it more times
su
servertime
nonce
rsakv
sp
Only these are changing. All we need to crack is the account and password
Looking at other interfaces, you can find such an interface containing su
Let's analyze this su and press Ctrl+shift+f
Search su directly. There are many parameters. You can find them slowly and finally lock the following one
After formatting, search su:
Discovery su: d
d = sinaSSOEncoder.base64.encode(urlencode(d));
Hit the breakpoint and start debugging. Check it. This is the account encryption we need
And the su is calculated by base64
You can write it directly through pycharm
self.username is the incoming account code, as follows:
su = base64.b64encode(parse.quote(self.username).encode('utf-8')).decode('utf-8') print('Account encrypted:',su)
Operation results:
Directly, and the data returned from this interface are as follows:
Compare with the first step and find the parameters required in the post form
su
servertime
nonce
rsakv
Then there is sp left. Can this sp be a password?
Still Ctrl+shift+f to search for sp, there are many js files. After formatting, search for sp and find the following one
e.sp = b;
I found such a sentence on it
b = f.encrypt([me.servertime, me.nonce].join("\t") + "\n" + b)
Make a break and debug it
Here we see the encrypted data of sp
Now you are ready to deduct the code. Open WebStorm and copy this code
Print out the three parameters here
me.rsaPubkey
me.servertime
me.nonce
It is obtained through su that interface
Continue to look at this encrypted code
b = f.encrypt([me.servertime, me.nonce].join("\t") + "\n" + b)
In the debugging interface, place the mouse over f.encrypt and it will display as shown in the figure below
Click in f bt(a) and have a look
Copy this code into WebStorm, comment out the encrypted section and run it
Prompt ReferenceError: sinaSSOEncoder is not defined
If sinaSSOEncoder is not defined, please run it at the beginning
Then navigator is not defined
In this case, I can directly give you a navigator code, which can be written directly at the beginning
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;
There is no error during operation
Now you can rewrite the encrypted code block
If we want to print the password to check, we must first write a function declaration
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) }
If you run it directly, an error will be reported. The four parameters have not been passed in
me.rsaPubkey
me.servertime
me.nonce
b
b = f.encrypt([me.servertime, me.nonce].join("\t") + "\n" + b)
b in parentheses is the initial password passed in. Change it to p
Remove the other three from me. and finally call the pwd() function.
When calling, where is the page
me.rsaPubkey
me.servertime
me.nonce
Copy these parameter data
This is what happens when you write a function by passing parameters
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')
The operation results are as follows
Here, the account password will be analyzed
pycharm is different after writing
You need to call the js file through execjs
import execjs
Before that, you need to obtain the following parameters through pre login
servertime
nonce
rsakv
pubkey
pcid
Pre login url
'https://login.sina.com.cn/sso/prelogin.php'
Some codes are as follows:
def pre_login(self): '''Pre login to obtain data. There is anti climbing here, which needs to be added“ 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 is a bytecode and needs to be encoded, but. text is not displayed normally at all times, so it needs to be encoded manually with. Content. # How to modify the encoding method: response.content.decode("utf8") # The eval() function executes a string expression and returns the value of the expression. res = eval(response.content.decode('utf-8').replace('sinaSSOController.preloginCallBack', '')) #print(res) return res
It should be noted that there is an anti crawling mechanism, and "Referer" should be added to the headers
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'}
You can take out the following parameters
pcid = res['pcid'] pubkey = res['pubkey'] rsakv = res['rsakv'] nonce = res['nonce'] servertime = res['servertime']
Copy the previously rewritten js code into pycharm. pwd() needs to rewrite the following code as follows:
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')
You can write the call
#Get the encrypted password by calling js code with open('micro-blog.js',encoding='utf-8') as f: data = f.read() password = execjs.compile(data).call('pwd',self.password,servertime,nonce,pubkey) #Call (called function name, passed in parameters) print('Password encrypted:',password)
The js reverse analysis of this microblog is over. Here is the source code. Instead of logging in through the post submission form, you log in by scanning the code
Both methods are written in. You can explore the post form by yourself
# 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('account encrypted: ', self.su) def pre_login(self): '''Pre login to obtain data. There is anti climbing here, which needs to be added“ 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 is a bytecode and needs to be encoded, but. text is not displayed normally at all times, so it needs to be encoded manually with. Content. # How to modify the encoding method: response.content.decode("utf8") # The eval() function executes a string expression and returns the value of the expression. res = eval(response.content.decode('utf-8').replace('sinaSSOController.preloginCallBack', '')) # print(res) return res def login_data(self): '''Obtain encryption password and submit post form ''' 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) #Get the encrypted password by calling js code with open('micro-blog.js',encoding='utf-8') as f: data = f.read() password = execjs.compile(data).call('pass',self.password,nonce,pubkey) print('Password encrypted:',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): '''Obtain the QR code, scan the code, verify and log in''' 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 is an important parameter to obtain the status url of the scanned QR code self.qrid = qrid # print(res.text, '\n', api_key, '\n', qrid) #Splicing QR code image 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') #Open QR code img.show() #Display QR code # img.close() #close except Exception as e: print(u"Please go to the current directory, find the QR code and scan it") # Generally, English characters can be parsed normally under various codes, so they generally do not take u; however, Chinese characters must indicate the required code, otherwise random code will appear once the code is converted. def login(self): '''Login function''' # password = self.login_data() account password login, this method is pass # print('password encrypted: ', password) try: #Jump to the microblog pass, you can explore 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: '''Scan QR code for login, and request code scanning status every 1 second''' 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: QR code not scanned 50114002: QR code scanned unconfirmed status 20000000: QR code confirmed status 50114004: QR code is invalid ''' # print(data_js) if '50114001' in str(data_js['retcode']): print('QR code is not used, please scan the code!') elif '50114002' in str(data_js['retcode']): print('The code has been scanned, please click confirm to log in!') elif '50114004' in str(data_js['retcode']): print('The QR code is invalid, please run the program again!') elif '20000000' in str(data_js['retcode']): print('Login succeeded!') alt = data_js['data']['alt'] # print(alt) break else: print('Other situations',str(data_js['retcode'])) time.sleep(1) def get_cookies(self): '''obtain cookies,Create a txt file save''' 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('account Name: '+ Nick', 'n', 'uid:' + uid) crossDomainUrlList = data_js['crossDomainUrlList'] # print(crossDomainUrlList) #Visit the other three URLs in turn 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): '''load cookies''' self.get_cookies() cookies = cookielib.LWPCookieJar('cookie.txt') cookies.load(ignore_discard=True, ignore_expires=True) # Turn cookie s into Dictionaries cookie_dict = requests.utils.dict_from_cookiejar(cookies) # Print ('cookie Dictionary: ', cookie_dict) return cookie_dict def spider(self): '''Get a microblog comment data verification cookie Is it available? The specific rules have not been written''' 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 value is valid, no code scanning login required! ') # return session, True # else: # Print ('the cookie value has expired, please scan the code again for login! ') # return session, False # pass if __name__ == '__main__': username = '13888888888' password = '123456' weibo = Weibo(username,password) weibo.spider()
Operation results:
3, Summary
Study hard and make progress every day~
Codeword is not easy, if this article is helpful to you, please point a praise, thank you~
Author: tiezhu vx: T14589 [indicate intention]
QQ communication group: 735418202
WeChat official account can be read to learn other articles.
*Note: This article is an original article. Please attach a link to this article if you reprint the article! Otherwise, you will be held accountable. Please respect yourself! Thank you!