当前位置: 首页 > news >正文

网站icp备案信息是什么一号网站建设

网站icp备案信息是什么,一号网站建设,高端品牌企业管理系统,怎么查网站开发者联系方式JS渗透之咪咕登录 每篇前言#xff1a;咪咕登录参数对比 captcha参数enpassword参数搜索enpassword参数搜索J_RsaPsd参数setPublic函数encrypt加密函数运行时可能会遇到的问题此部分改写的最终形态JS代码#xff1a;运行结果python编写脚本运行此JS代码#xff1a;运行结果咪咕登录参数对比 captcha参数enpassword参数搜索enpassword参数搜索J_RsaPsd参数setPublic函数encrypt加密函数运行时可能会遇到的问题此部分改写的最终形态JS代码运行结果python编写脚本运行此JS代码运行结果 loginID 参数步骤同上面的enpassword一步步搜索会发现找到了图中的J_RsaAccout,这个就是loginID参数的加密我们继续一步步分析会发现此参数的加密方式和刚刚的enpassword的加密方式一模一样那处理方法不就简单了 运行结果 FingerPrint和FingerPrintDetail参数找到指纹加密的主函数会发现就在刚刚的函数下面分析函数功能修改FingerPrint的JS函数运行结果 编写爬虫脚本1首先编写脚本构造出post表单2然后编写脚本发送请求并通过获取响应判断是否登录成功第一步直接向其发送请求观察响应是否为登录成功的界面第二步所以下面我们要做的就是通过分析浏览器登录找到一系列的重定向的URL并找到最终返回登录成功界面的URL第三步构造登录成功之后的重定向URL并通过依此请求模拟网站登录时候的一次次重定向跳转最终达到获取咪咕登录成功的界面 3观察可知登录成功 项目源码链接 每篇前言 作者介绍【孤寒者】—CSDN全栈领域优质创作者、HDZ核心组成员、华为云享专家Python全栈领域博主、CSDN原力计划作者 本文已收录于爬虫进阶实战系列教程专栏《爬虫进阶实战系列教程》热门专栏推荐《Python全栈系列教程》、《爬虫从入门到精通系列教程》、《爬虫进阶实战系列教程》、《Scrapy框架从入门到实战》、《Flask框架从入门到实战》、《Django框架从入门到实战》、《Tornado框架从入门到实战》、《前端系列教程》。​本专栏面向广大程序猿为的是大家都做到Python全栈技术从入门到精通穿插有很多实战优化点。订阅专栏后可私聊进一千多人Python全栈交流群手把手教学问题解答 进群可领取Python全栈教程视频 多得数不过来的计算机书籍基础、Web、爬虫、数据分析、可视化、机器学习、深度学习、人工智能、算法、面试题等。加入我一起学习进步一个人可以走的很快一群人才能走的更远 咪咕登录 之前的请求中找数据: 上级页面搜索: 静态页面搜索参数内容 本级页面:Network里搜索内容 复杂登录特点: 参数多加密参数来源复杂多次请求 简单拓展 Ajax请求的底层是基于XMLHttpRequests对象实现所以在抓包时有两个特征页面不刷新 请求类型为xhr。 参数对比 captcha参数 这个值对应的是验证码的数据第一次登录时并没有这个验证码提交空值给表单就可以了验证码是账号或密码输错导致登录失败的时候会出现。这个时候会给服务器发送一条请求返回值就是验证码经过base64编码后的数据。 enpassword参数 通过观察两次请求的参数可以看出来enpassword参数是不相同的所以这个参数显然是动态变化生成的再仔细观察一下发现这个值每个字符的范围都是0-9和a-f通过我们的经验可以猜想这个参数是16进制的字符串而且很有可能是经过加密的。 搜索enpassword参数 但是搜索发现都是HTML源码里显然不可能包含此参数的值。经验可知此参数肯定是JS动态生成的所以我们就看HTML源码中此参数对应的代码既然name值参数搜索没用那么就来搜索一下class的值J_RsaPsd 搜索J_RsaPsd参数 分析JS文件,会发现三个地方都有此参数而且结构几乎一致所以为了找到目标数据我们将这三个都打上断点进行观察执行观察会停在哪一个上那我们就只分析那一个即可 执行过程分析可知是个RSA加密 分析最近的一个函数当选中var b $(this)这句时密码输入框标记选中可知此句是将密码赋值给b。 进入db函数 这里看不出有什么东西先跳过不管。 setPublic函数 这里需要传入两个参数这两个值在上一个请求的response中可以得到而且都是固定值。 这两个参数可以作为固定值写在代码里。 encrypt加密函数 传进去的参数b.val()在console中执行发现就是我们在密码框中输入的明文。 encrypt函数实际就是gb函数 这里是将gb函数赋值给db对象的原型对象下面又把db对象赋值给c.RSAKey这就是最开始定义c的语句。 gb函数执行到c.toString(16)的时候就得到了加密结果 改写JS加密基本逻辑下面的代码就写入改写的JS代码中 function getEncryptedPwd(pwd, modulus, publicExponent) {c new RSAKey;c.setPublic(modulus, publicExponent);var d c.encrypt(pwd);return d; }pwd传入明文密码modulus和publicExponent是固定值现在只要把里面有关联的函数复制出来再进行调试就可以了。 这里是RSA加密函数定义的起止位置注意我们复制两个大括号内部的所有代码 Python调用JS加密函数最终编写爬虫文件中使用 def make_encrypt_password(self, password, modulus, publicExponent):生成加密后的密码Args:password (str): 输入框内输入的原始密码modulus (str): rsa加密参数两个质数的乘积固定值前一个请求获得publicExponent (str): rsa加密参数大于1的奇数固定值前一个请求获得Returns:str: 加密后的密码return self.js_object.call(getEncryptedPwd, password, modulus, publicExponent)运行时可能会遇到的问题 遇到的错误1 报错 解决方法 把alert中的中文删去 遇到的错误2 报错 解决方法 定义navigator和window 遇到的错误3 报错 解决方法 修改如下代码 此部分改写的最终形态JS代码 var navigator {},window{};function d(a, b, c) {null ! a (number typeof a ? this.fromNumber(a, b, c) : null b string ! typeof a ? this.fromString(a, 256) : this.fromString(a, b)) } function e() {return new d(null) } function f(a, b, c, d, e, f) {for (; --f 0; ) {var g b * this[a] c[d] e;e Math.floor(g / 67108864),c[d] 67108863 g}return e } function g(a, b, c, d, e, f) {for (var g 32767 b, h b 15; --f 0; ) {var i 32767 this[a], j this[a] 15, k h * i j * g;i g * i ((32767 k) 15) c[d] (1073741823 e),e (i 30) (k 15) h * j (e 30),c[d] 1073741823 i}return e } function h(a, b, c, d, e, f) {for (var g 16383 b, h b 14; --f 0; ) {var i 16383 this[a], j this[a] 14, k h * i j * g;i g * i ((16383 k) 14) c[d] e,e (i 28) (k 14) h * j,c[d] 268435455 i}return e } function i(a) {return nb.charAt(a) } function j(a, b) {var c ob[a.charCodeAt(b)];return null c ? -1 : c } function k(a) {for (var b this.t - 1; b 0; --b)a[b] this[b];a.t this.t,a.s this.s } function l(a) {this.t 1,this.s 0 a ? -1 : 0,a 0 ? this[0] a : -1 a ? this[0] a this.DV : this.t 0 } function m(a) {var b e();return b.fromInt(a),b } function n(a, b) {var c;if (16 b)c 4;else if (8 b)c 3;else if (256 b)c 8;else if (2 b)c 1;else if (32 b)c 5;else {if (4 ! b)return void this.fromRadix(a, b);c 2}this.t 0,this.s 0;for (var e a.length, f !1, g 0; --e 0; ) {var h 8 c ? 255 a[e] : j(a, e);0 h ? - a.charAt(e) (f !0) : (f !1,0 g ? this[this.t] h : g c this.DB ? (this[this.t - 1] | (h (1 this.DB - g) - 1) g,this[this.t] h this.DB - g) : this[this.t - 1] | h g,g c,g this.DB (g - this.DB))}8 c 0 ! (128 a[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 o() {for (var a this.s this.DM; this.t 0 this[this.t - 1] a; )--this.t } function p(a) {if (this.s 0)return - this.negate().toString(a);var b;if (16 a)b 4;else if (8 a)b 3;else if (2 a)b 1;else if (32 a)b 5;else {if (4 ! a)return this.toRadix(a);b 2}var c, d (1 b) - 1, e !1, f , g this.t, h this.DB - g * this.DB % b;if (g-- 0)for (h this.DB (c this[g] h) 0 (e !0,f i(c)); g 0; )b h ? (c (this[g] (1 h) - 1) b - h,c | this[--g] (h this.DB - b)) : (c this[g] (h - b) d,0 h (h this.DB,--g)),c 0 (e !0),e (f i(c));return e ? f : 0 } function q() {var a e();return d.ZERO.subTo(this, a),a } function r() {return this.s 0 ? this.negate() : this } function s(a) {var b this.s - a.s;if (0 ! b)return b;var c this.t;if (b c - a.t,0 ! b)return this.s 0 ? -b : b;for (; --c 0; )if (0 ! (b this[c] - a[c]))return b;return 0 } function t(a) {var b, c 1;return 0 ! (b a 16) (a b,c 16),0 ! (b a 8) (a b,c 8),0 ! (b a 4) (a b,c 4),0 ! (b a 2) (a b,c 2),0 ! (b a 1) (a b,c 1),c } function u() {return this.t 0 ? 0 : this.DB * (this.t - 1) t(this[this.t - 1] ^ this.s this.DM) } function v(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 w(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 x(a, b) {var c, d a % this.DB, e this.DB - d, f (1 e) - 1, g Math.floor(a / this.DB), h this.s d this.DM;for (c this.t - 1; c 0; --c)b[c g 1] this[c] e | h,h (this[c] f) d;for (c g - 1; c 0; --c)b[c] 0;b[g] h,b.t this.t g 1,b.s this.s,b.clamp() } function y(a, b) {b.s this.s;var c Math.floor(a / this.DB);if (c this.t)return void (b.t 0);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 z(a, b) {for (var c 0, d 0, e Math.min(a.t, this.t); e c; )d this[c] - a[c],b[c] d this.DM,d this.DB;if (a.t this.t) {for (d - a.s; c this.t; )d this[c],b[c] d this.DM,d this.DB;d this.s} else {for (d this.s; c a.t; )d - a[c],b[c] d this.DM,d this.DB;d - a.s}b.s 0 d ? -1 : 0,-1 d ? b[c] this.DV d : d 0 (b[c] d),b.t c,b.clamp() } function A(a, b) {var c this.abs(), e a.abs(), f c.t;for (b.t f e.t; --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 B(a) {for (var b this.abs(), c a.t 2 * b.t; --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);(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 C(a, b, c) {var f a.abs();if (!(f.t 0)) {var g this.abs();if (g.t f.t)return null ! b b.fromInt(0),void (null ! c this.copyTo(c));null c (c e());var h e(), i this.s, j a.s, k this.DB - t(f[f.t - 1]);k 0 ? (f.lShiftTo(k, h),g.lShiftTo(k, c)) : (f.copyTo(h),g.copyTo(c));var l h.t, m h[l - 1];if (0 ! m) {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, u null b ? e() : b;for (h.dlShiftTo(s, u),c.compareTo(u) 0 (c[c.t] 1,c.subTo(u, c)),d.ONE.dlShiftTo(l, u),u.subTo(h, h); h.t l; )h[h.t] 0;for (; --s 0; ) {var v c[--r] m ? this.DM : Math.floor(c[r] * o (c[r - 1] q) * p);if ((c[r] h.am(0, v, c, s, 0, l)) v)for (h.dlShiftTo(s, u),c.subTo(u, c); c[r] --v; )c.subTo(u, c)}null ! b (c.drShiftTo(l, b),i ! j d.ZERO.subTo(b, b)),c.t l,c.clamp(),k 0 c.rShiftTo(k, c),0 i d.ZERO.subTo(c, c)}} } function D(a) {var b e();return this.abs().divRemTo(a, null, b),this.s 0 b.compareTo(d.ZERO) 0 a.subTo(b, b),b } function E(a) {this.m a } function F(a) {return a.s 0 || a.compareTo(this.m) 0 ? a.mod(this.m) : a } function G(a) {return a } function H(a) {a.divRemTo(this.m, null, a) } function I(a, b, c) {a.multiplyTo(b, c),this.reduce(c) } function J(a, b) {a.squareTo(b),this.reduce(b) } function K() {if (this.t 1)return 0;var a this[0];if (0 (1 a))return 0;var b 3 a;return b b * (2 - (15 a) * b) 15,b b * (2 - (255 a) * b) 255,b b * (2 - ((65535 a) * b 65535)) 65535,b b * (2 - a * b % this.DV) % this.DV,b 0 ? this.DV - b : -b } function L(a) {this.m a,this.mp a.invDigit(),this.mpl 32767 this.mp,this.mph this.mp 15,this.um (1 a.DB - 15) - 1,this.mt2 2 * a.t } function M(a) {var b e();return 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),b } function N(a) {var b e();return a.copyTo(b),this.reduce(b),b } function O(a) {for (; a.t this.mt2; )a[a.t] 0;for (var b 0; b this.m.t; b) {var c 32767 a[b], d c * this.mpl ((c * this.mph (a[b] 15) * this.mpl this.um) 15) a.DM;for (c b this.m.t,a[c] this.m.am(0, d, a, b, 0, this.m.t); 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 P(a, b) {a.squareTo(b),this.reduce(b) } function Q(a, b, c) {a.multiplyTo(b, c),this.reduce(c) } function R() {return 0 (this.t 0 ? 1 this[0] : this.s) } function S(a, b) {if (a 4294967295 || 1 a)return d.ONE;var c e(), f e(), g b.convert(this), h t(a) - 1;for (g.copyTo(c); --h 0; )if (b.sqrTo(c, f),(a 1 h) 0)b.mulTo(f, g, c);else {var i c;c f,f i}return b.revert(c) } function T(a, b) {var c;return c 256 a || b.isEven() ? new E(b) : new L(b),this.exp(a, c) } function U() {this.i 0,this.j 0,this.S new Array } function V(a) {var b, c, d;for (b 0; 256 b; b)this.S[b] b;for (c 0,b 0; 256 b; b)c c this.S[b] a[b % a.length] 255,d this.S[b],this.S[b] this.S[c],this.S[c] d;this.i 0,this.j 0 } function W() {var a;return 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,this.S[a this.S[this.i] 255] } function X() {return new U } function Y(a) {qb[rb] ^ 255 a,qb[rb] ^ a 8 255,qb[rb] ^ a 16 255,qb[rb] ^ a 24 255,rb sb (rb - sb) } function Z() {Y((new Date).getTime()) } function $() {if (null pb) {for (Z(),pb X(),pb.init(qb),rb 0; rb qb.length; rb)qb[rb] 0;rb 0}return pb.next() } function _(a) {var b;for (b 0; b a.length; b)a[b] $() } function ab() {} function bb(a, b) {return new d(a,b) } function cb(a, b) {if (b a.length 11)return alert(Message too long for RSA),null;for (var c new Array, e a.length - 1; e 0 b 0; ) {var f a.charCodeAt(e--);128 f ? c[--b] f : f 127 2048 f ? (c[--b] 63 f | 128,c[--b] f 6 | 192) : (c[--b] 63 f | 128,c[--b] f 6 63 | 128,c[--b] f 12 | 224)}c[--b] 0;for (var g new ab, h new Array; b 2; ) {for (h[0] 0; 0 h[0]; )g.nextBytes(h);c[--b] h[0]}return c[--b] 2,c[--b] 0,new d(c) } function db() {this.n null,this.e 0,this.d null,this.p null,this.q null,this.dmp1 null,this.dmq1 null,this.coeff null } function eb(a, b) {null ! a null ! b a.length 0 b.length 0 ? (this.n bb(a, 16),this.e parseInt(b, 16)) : alert() } function fb(a) {return a.modPowInt(this.e, this.n) } function gb(a) {var b cb(a, this.n.bitLength() 7 3);if (null b)return null;var c this.doPublic(b);if (null c)return null;var d c.toString(16);return 0 (1 d.length) ? d : 0 d } var hb, ib 0xdeadbeefcafe, jb 15715070 (16777215 ib); jb Microsoft Internet Explorer navigator.appName ? (d.prototype.am g, hb 30) : jb Netscape ! navigator.appName ? (d.prototype.am f, hb 26) : (d.prototype.am h, hb 28), d.prototype.DB hb, d.prototype.DM (1 hb) - 1, d.prototype.DV 1 hb; var kb 52; d.prototype.FV Math.pow(2, kb), d.prototype.F1 kb - hb, d.prototype.F2 2 * hb - kb; var lb, mb, nb 0123456789abcdefghijklmnopqrstuvwxyz, ob new Array; for (lb 0.charCodeAt(0), mb 0; 9 mb; mb)ob[lb] mb; for (lb a.charCodeAt(0), mb 10; 36 mb; mb)ob[lb] mb; for (lb A.charCodeAt(0), mb 10; 36 mb; mb)ob[lb] mb; E.prototype.convert F, E.prototype.revert G, E.prototype.reduce H, E.prototype.mulTo I, E.prototype.sqrTo J, L.prototype.convert M, L.prototype.revert N, L.prototype.reduce O, L.prototype.mulTo Q, L.prototype.sqrTo P, d.prototype.copyTo k, d.prototype.fromInt l, d.prototype.fromString n, d.prototype.clamp o, d.prototype.dlShiftTo v, d.prototype.drShiftTo w, d.prototype.lShiftTo x, d.prototype.rShiftTo y, d.prototype.subTo z, d.prototype.multiplyTo A, d.prototype.squareTo B, d.prototype.divRemTo C, d.prototype.invDigit K, d.prototype.isEven R, d.prototype.exp S, d.prototype.toString p, d.prototype.negate q, d.prototype.abs r, d.prototype.compareTo s, d.prototype.bitLength u, d.prototype.mod D, d.prototype.modPowInt T, d.ZERO m(0), d.ONE m(1), U.prototype.init V, U.prototype.next W; var pb, qb, rb, sb 256; if (null qb) {qb new Array,rb 0;var tb;if (window.crypto window.crypto.getRandomValues) {var ub new Uint8Array(32);for (window.crypto.getRandomValues(ub),tb 0; 32 tb; tb)qb[rb] ub[tb]}if (Netscape navigator.appName navigator.appVersion 5 window.crypto) {var vb window.crypto.random(32);for (tb 0; tb vb.length; tb)qb[rb] 255 vb.charCodeAt(tb)}for (; sb rb; )tb Math.floor(65536 * Math.random()),qb[rb] tb 8,qb[rb] 255 tb;rb 0,Z() } ab.prototype.nextBytes _, db.prototype.doPublic fb, db.prototype.setPublic eb, db.prototype.encrypt gb, RSAKey dbfunction getEncryptedPwd(pwd, modulus, publicExponent) {c new RSAKey;c.setPublic(modulus, publicExponent);var d c.encrypt(pwd);return d; } 运行结果 python编写脚本运行此JS代码 import execjspassword 123 # 模拟的密码随便写的 modulus 00833c4af965ff7a8409f8b5d5a83d87f2f19d7c1eb40dc59a98d2346cbb145046b2c6facc25b5cc363443f0f7ebd9524b7c1e1917bf7d849212339f6c1d3711b115ecb20f0c89fc2182a985ea28cbb4adf6a321ff7e715ba9b8d7261d1c140485df3b705247a70c28c9068caabbedbf9510dada6d13d99e57642b853a73406817 publicExponent 010001def make_execjs_object():with open(en_pwd.js, r) as f:js f.read()return execjs.compile(js)js_object make_execjs_object()a js_object.call(getEncryptedPwd, password, modulus, publicExponent) print(a) 运行结果 loginID 参数 步骤同上面的enpassword一步步搜索会发现找到了图中的J_RsaAccout,这个就是loginID参数的加密我们继续一步步分析会发现此参数的加密方式和刚刚的enpassword的加密方式一模一样那处理方法不就简单了 JS加密账号函数直接将下面的JS函数加入刚刚自己改写的JS代码文件中即可 function getEncryptedAccount(account, modulus, publicExponent) {c new RSAKey;c.setPublic(modulus, publicExponent);var d c.encrypt(account);return d; }Python调用JS加密函数编写爬虫脚本文件时用以下函数调用JS文件生成所需参数形同enpassword的写法 def make_encrypt_account(self, account, modulus, publicExponent):生成加密后的账号Args:account (str): 输入框内输入的账号modulus (str): 同上publicExponent (str): 同上Returns:str: 加密后的账号return self.js_object.call(getEncryptedAccount, account, modulus, publicExponent)运行结果 FingerPrint和FingerPrintDetail参数 找到指纹加密的主函数会发现就在刚刚的函数下面 分析函数功能 这里比较不好理解的是$.fingerprint.details和$.fingerprint.result这两个变量的定义位置是下面图片这里 这两个值也都是固定值据观察其中c的值就是使用者计算机的一些属性只要计算机不换这些值就是固定的所以我们直接传固定值即可它也不知道你电脑信息是啥样的呀而且d的值是根据c的值得出的所以也可以写死后面编写爬虫代码时直接复制此处的值即可 修改FingerPrint的JS函数 function rsaFingerprint(a, b, details, result) { //details和result是固定值直接作为参数传进来赋值 此处的a和b的值通过观察可知就是a.result.modulus和a.result.publicExponent这俩值前面获取过var c details, d result, e c.length, f , g new RSAKey;g.setPublic(a, b);for (var h g.encrypt(d), i 0; e i; i 117)f g.encrypt(c.substr(i, 117));// return {// details: f,// result: h// }return {fingerPrintDetail: f, //这里代码会返回字典类型的数据直接可以合并到表单里所以直接修改为表单里可以用的key值。当然不改也可fingerPrint: h} }Python调用JS加密函数 def make_rsa_fingerprint(self, modulus, publicExponent, details, result):生成rsa指纹参数Args:details (str): 请求headers信息result (str): headers的加密信息如果headers不改变这个值也是固定的Returns (dict):details: 加密后的fingerprint_details信息fingerPrintDetail表单参数result: 加密后的fingerprint_result信息fingerPrint表单参数return self.js_object.call(rsaFingerprint, modulus, publicExponent, details, result)运行结果 编写爬虫脚本 1首先编写脚本构造出post表单 import requests import jsonimport execjsclass Migu_login(object):def __init__(self, account, password):modules 00833c4af965ff7a8409f8b5d5a83d87f2f19d7c1eb40dc59a98d2346cbb145046b2c6facc25b5cc363443f0f7ebd9524b7c1e1917bf7d849212339f6c1d3711b115ecb20f0c89fc2182a985ea28cbb4adf6a321ff7e715ba9b8d7261d1c140485df3b705247a70c28c9068caabbedbf9510dada6d13d99e57642b853a73406817publicExponent 010001# 获取FingerPrint和FingerPrintDetail参数中JS函数所需的参数c和ddetails_params {user_agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89,language:zh-CN,color_depth:24,pixel_ratio:1.25,hardware_concurrency:8,resolution:1536,864,available_resolution:1536,834,timezone_offset:-480,session_storage:1,local_storage:1,indexed_db:1,open_database:1,cpu_class:unknown,navigator_platform:Win32,do_not_track:unknown,regular_plugins:Chrome PDF Plugin::Portable Document Format::application/x-google-chrome-pdf~pdf,Chrome PDF Viewer::,webgl_vendor:Google Inc.~ANGLE (Intel(R) UHD Graphics 620 Direct3D11 vs_5_0 ps_5_0),adblock:false,has_lied_languages:false,has_lied_resolution:false,has_lied_os:false,has_lied_browser:false,touch_support:0,false,false,js_fonts:Arial,Arial Black,Arial Narrow,Arial Unicode MS,Book Antiqua,Bookman Old Style,Calibri,Cambria,Cambr}result_params 984eb0bda24963a23008f493d58a84e0headers {Accept: application/json, text/javascript, */*; q0.01,Accept-Encoding: gzip, deflate, br,Accept-Language: zh-CN,zh;q0.9,en;q0.8,Cache-Control: no-cache,Connection: keep-alive,Host: passport.migu.cn,Origin: https://passport.migu.cn,Referer: https://passport.migu.cn/login?sourceid208003apptype0forceAuthnfalseisPassivefalseauthTypeMiguPassportpasswordControl0displaywebrefererhttps://www.migu.cn/logintype1qqnullweibonullalipaynullweixinnullandPassnullphoneNumbercallbackURLhttps%3A%2F%2Fwww.migu.cn%2FrelayState,Sec-Fetch-Dest: empty,Sec-Fetch-Mode: cors,Sec-Fetch-Site: same-origin,User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36,X-Requested-With: XMLHttpRequest,}self.form {# 需要传递的构造出来的参数先写空后面再使用update即可sourceID: 208003,appType: 0,relayState: ,loginID:, # 加密后的账号enpassword: , # 加密后的密码captcha: ,rememberMeBox: 1,fingerPrint: , # 指纹fingerPrintDetail:, # 指纹detailisAsync: True,}# 开启会话保持连接self.session requests.Session()self.session.headers headersself.get_cookie()# Python执行JS代码生成所需参数并更新进表单self.js_object self.compile_js()update_form self.make_rsa_fingerprint(modules, publicExponent, details_params, result_params)update_form[loginID] self.make_encrypt_account(account, modules, publicExponent)update_form[enpassword] self.make_encrypt_password(password, modules, publicExponent)self.form.update(update_form)def compile_js(self):python直接执行本地编写的JS代码:return:with open(en_pwd.js, r) as f:js f.read()return execjs.compile(js)def get_cookie(self):为了让会话携带cookie所以进行如下操作。因为使用的session会话技术所以即使不return也携带了cookie等一系列参数。:return:url https://passport.migu.cn/self.session.get(url)return self.session.cookiesdef make_encrypt_password(self, password, modulus, publicExponent):生成加密后的密码Args:password (str): 输入框内输入的原始密码modulus (str): rsa加密参数两个质数的乘积固定值前一个请求获得publicExponent (str): rsa加密参数大于1的奇数固定值前一个请求获得Returns:str: 加密后的密码return self.js_object.call(getEncryptedPwd, password, modulus, publicExponent)def make_encrypt_account(self, account, modulus, publicExponent):生成加密后的账号Args:account (str): 输入框内输入的账号modulus (str): 同上publicExponent (str): 同上Returns:str: 加密后的账号return self.js_object.call(getEncryptedAccount, account, modulus, publicExponent)def make_rsa_fingerprint(self, modulus, publicExponent, details, result):生成rsa指纹参数Args:details (str): 请求headers信息result (str): headers的加密信息如果headers不改变这个值也是固定的Returns (dict):details: 加密后的fingerprint_details信息fingerPrintDetail表单参数result: 加密后的fingerprint_result信息fingerPrint表单参数return self.js_object.call(rsaFingerprint, modulus, publicExponent, details, result) 2然后编写脚本发送请求并通过获取响应判断是否登录成功 分析可知我们应该向如上图中的url携带表单发送post请求 第一步直接向其发送请求观察响应是否为登录成功的界面 def login(self):登录函数:return: url https://passport.migu.cn/authnresponse self.session.post(url, dataself.form)print(response.text)if __name__ __main__:# 注意账号密码放在了info.txt中with open(info.txt, r) as f:info json.loads(f.read())act info[account]pwd info[password]mg Migu_login(act,pwd)mresponse mg.login()观察响应分析可知当我们登录成功之后页面进行了重定向而不是直接返回给我们登录成功的界面 第二步所以下面我们要做的就是通过分析浏览器登录找到一系列的重定向的URL并找到最终返回登录成功界面的URL 第一个登录成功之后出现的URL很容易知道这就是登录后的重定向其URL的构造只需要拼接token参数即可token参数在刚刚的响应中又存在直接提取即可 第二个登录成功之后出现的URL多次测试可知其URL是固定值 第三个登录成功之后出现的URL图一中多次测试也可知其URL是固定值图二中可知此URL刚好是由上一个URL跳转来的图三可知此URL的响应刚好是登录成功的界面 第三步构造登录成功之后的重定向URL并通过依此请求模拟网站登录时候的一次次重定向跳转最终达到获取咪咕登录成功的界面 def login(self):登录函数:return:url https://passport.migu.cn/authnresponse self.session.post(url, dataself.form)response_dict json.loads(response.text)token response_dict.get(result,{}).get(token, )if not token:returnrest_url [https://passport.migu.cn/portal/sso/authn?callbackURLrelayStatetoken{}.format(token),https://passport.migu.cn/portal/sso/authn_success?relateToMiguPassport1callbackURLrelayState,https://passport.migu.cn/portal/home/profile?sourceid100001,https://passport.migu.cn/portal/home/profile?sourceid100001,]for ru in rest_url:response self.session.get(ru)return responseif __name__ __main__:with open(info.txt, r) as f:info json.loads(f.read())act info[account]pwd info[password]mg Migu_login(act,pwd)mresponse mg.login()print(mresponse.text)3观察可知登录成功 项目源码链接 代码 链接https://pan.baidu.com/s/1zM19dGyvEpX4BuXsr_8s7Q 提取码xkxh 复制这段内容后打开百度网盘手机App操作更方便哦
http://www.pierceye.com/news/791178/

相关文章:

  • 怎么样做网站徐州市中宇建设工程有限公司网站
  • 网站建站公司官网免费企业网站建设介绍
  • 知名网站建设托管河北建筑工程学院招生信息网
  • 服务器网站建设流程图十堰网站制作公司电话
  • 营销型网站seo开发一个app需要什么技能
  • 网站的欢迎页怎么做织梦网站名称修改
  • 树莓派做博客网站济南抖音推广公司
  • 网站短链接生成济宁网络
  • 组建 网站开发团队交互设计作品集网站
  • 宜春个人网站建设网站建设惠州
  • 医院网站开发兼职wordpress 域名跳转
  • 安监局网站建设wordpress 修改路径
  • 快速搭建网站wordpress成品网站货源入口
  • 信宜手机网站建设公司广州网站建设服务商
  • 网站备案注册3g免费网站制作
  • 做网站需要vps吗建设银行etc的网站是哪个好
  • 网站服务器 2核如何做网站联盟
  • 做空间的网站吗wordpress 视频管理 主题
  • 做外链选择那些网站建网站怎样往网站传视频
  • 网站主机多大车陂手机网站建设报价
  • 网站策划书内容wordpress 一键恢复
  • wordpress+外观+权限seo排名工具
  • 江苏企业网站制作哪家好潍坊网站开发招生信息
  • 建设一个地方门户网站网站名称搜索不到
  • 南江县住房和城乡建设局网站上海seo关键词优化
  • 门窗厂家东莞网站建设湖南健康码
  • 企业网站建设的背景和目的互联网政务服务平台
  • 化州市住房和城乡建设局网站开发网站心得
  • 网站设计制作公司需要什么资质python h5网站开发
  • 广东深圳广东深圳网站建设惠州网站开发公司电话