1+ # encoding: utf-8
2+ __author__ = 'zhanghe'
3+
4+
5+ from password import tc_58
6+ from js_58 import get_p
7+ import requests
8+ import random
9+ import time
10+ import os
11+ import re
12+ import json
13+ import logging
14+
15+ # logging.basicConfig(level=logging.DEBUG, filename='58.log', filemode='w')
16+ logging .basicConfig (level = logging .DEBUG )
17+
18+ s = requests .session ()
19+ # 伪装成浏览器
20+ header = {
21+ 'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36' }
22+
23+
24+ def get_login_hidden_form ():
25+ """
26+ 获取登录隐藏域表单
27+ """
28+ url = 'http://passport.58.com/login'
29+ login_form = {}
30+ response = s .get (url )
31+ html = response .text
32+ form_path = re .compile (ur'<input type="hidden" name="path" value="(.*?)"/>' )
33+ form_ptk = re .compile (ur'<input type="hidden" id="ptk" name="ptk" id="ptk" value="(.*?)"/>' )
34+ form_cd = re .compile (ur'<input type="hidden" id="cd" name="cd" id="cd" value="(.*?)"/>' )
35+ login_form ['path' ] = form_path .findall (html )[0 ].encode ('utf-8' ) # unicode
36+ login_form ['ptk' ] = form_ptk .findall (html )[0 ].encode ('utf-8' ) # unicode
37+ login_form ['cd' ] = form_cd .findall (html )[0 ].encode ('utf-8' ) # unicode
38+ print login_form
39+ return login_form
40+
41+
42+ def get_login_encrypt_form ():
43+ """
44+ 获取登录加密表单
45+ """
46+ # 模拟22-38秒内登录
47+ timespan = 1411093327735
48+ timesign = '%13s' % (timespan + random .randint (22000 , 36000 ))
49+ data = get_p (tc_58 ['password' ], timesign )
50+ print data
51+ return data
52+
53+
54+ def login ():
55+ """
56+ 登录
57+ """
58+ hidden_form = get_login_hidden_form ()
59+ url = 'http://passport.58.com/dounionlogin'
60+ p = get_login_encrypt_form ()
61+
62+ # 登录需要提交的表单
63+ form_data = {
64+ 'isweak' : 0 ,
65+ 'path' : hidden_form ['path' ],
66+ 'p1' : p ['p1' ],
67+ 'p2' : p ['p2' ],
68+ 'p3' : p ['p3' ],
69+ 'timesign' : '%13s' % '' ,
70+ 'ptk' : hidden_form ['ptk' ],
71+ 'cd' : hidden_form ['cd' ],
72+ 'username' : tc_58 ['username' ],
73+ 'password' : '' ,
74+ 'source' : 'pc-login' ,
75+ 'mrisktype' : '1' ,
76+ 'pptmobilecodeloginmobile' : '请输入手机号' ,
77+ 'pptmobilecodeloginmobilecode' : '' ,
78+ 'mcresult' : None ,
79+ }
80+ print form_data
81+ login_response = s .post (url , data = form_data , headers = header )
82+ print login_response .text
83+ login_status = check_login_status (login_response .text )
84+ print login_status
85+ return login_status
86+
87+
88+ def check_login_status (login_response_text ):
89+ """
90+ 登录状态检查
91+ """
92+ if u'window.parent.location="http://' in login_response_text :
93+ return 'login_ok'
94+ if u'您输入的密码与账户名不符' in login_response_text :
95+ return 'name_or_pass_error'
96+ return 'login_error'
97+
98+
99+ if __name__ == '__main__' :
100+ # get_login_hidden_form()
101+ # get_login_encrypt_form()
102+ login ()
103+
104+
105+ """
106+ 登录成功页面:
107+ <script type="text/javascript">
108+ document.domain='58.com';
109+ parent.clearPassportTimeout();
110+ window.parent.location="http://my.58.com/?pts=1449556514157";
111+ parent.clearPassportTimeout();
112+ parent.$.formValidator.subfalse('submitForm', 'btnSubmit', '登录');
113+ </script>
114+
115+ 登录失败页面:
116+ <script type="text/javascript">
117+ document.domain='58.com';
118+ //验证码存在,则刷新
119+ parent.refreshvalidcode();
120+ parent.$.c.Error.setErrorTip('您输入的密码与账户名不符','tipDiv');
121+ parent.clearform();
122+ parent.clearPassportTimeout();
123+ parent.$.formValidator.subfalse('submitForm', 'btnSubmit', '登录');
124+ </script>
125+ """
126+
127+
128+ """
129+ $("#p1").val(getm32str($("#password").val(), timesign + ""));
130+ $("#p2").val(getm16str($("#password").val(), timesign + ""));
131+ $("#p3").val(encryptString(timesign + encodeURIComponent($("#password").val()), "010001", "008baf14121377fc76eaf7794b8a8af17085628c3590df47e6534574efcfd81ef8635fcdc67d141c15f51649a89533df0db839331e30b8f8e4440ebf7ccbcc494f4ba18e9f492534b8aafc1b1057429ac851d3d9eb66e86fce1b04527c7b95a2431b07ea277cde2365876e2733325df04389a9d891c5d36b7bc752140db74cb69f"));
132+ """
133+
134+
135+ """
136+ <form name="submitForm" method="post" action="/dounionlogin" id="submitForm" target="formSubmitFrame">
137+ <input type="hidden" name="isweak" id="isweak" value="0"/>
138+ <input type="hidden" name="path" value="http://my.58.com/?pts=1449541205022"/>
139+ <input type="hidden" name="p1" id="p1" />
140+ <input type="hidden" name="p2" id="p2" />
141+ <input type="hidden" name="p3" id="p3" />
142+ <input type="hidden" name="timesign" id="timesign" />
143+ <input type="hidden" id="ptk" name="ptk" id="ptk" value="ff846067b4604273aa77aeb956fd4629"/>
144+ <input type="hidden" id="cd" name="cd" id="cd" value="1025"/>
145+ """
146+
147+
148+
149+ """
150+ fun : function() {
151+ var wrongTimes = 0;
152+ if (GetCookieValue('wrongtimes') != null) {
153+ wrongTimes = parseInt(GetCookieValue('wrongtimes'));
154+ }
155+ if (wrongTimes > 4) {
156+ alert("您密码输入错误次数太多,请过一段时间再试");
157+ return false;
158+ }
159+ var timesign = new Date().getTime() + timespan;
160+ if (timesign - 1411093327735 > 1800000) {
161+ alert("页面已过期,请刷新后再提交");
162+ window.location.href = window.location.href;
163+ return false;
164+ }
165+ if (passwordIsWeak($("#username").val(), $("#password").val()))
166+ $("#isweak").val("1");
167+ else
168+ $("#isweak").val("0");
169+ $("#timesign").val(timesign);
170+ $("#p1").val(getm32str($("#password").val(), timesign + ""));
171+ $("#p2").val(getm16str($("#password").val(), timesign + ""));
172+ $("#p3").val(encryptString(timesign + encodeURIComponent($("#password").val()), "010001", "008baf14121377fc76eaf7794b8a8af17085628c3590df47e6534574efcfd81ef8635fcdc67d141c15f51649a89533df0db839331e30b8f8e4440ebf7ccbcc494f4ba18e9f492534b8aafc1b1057429ac851d3d9eb66e86fce1b04527c7b95a2431b07ea277cde2365876e2733325df04389a9d891c5d36b7bc752140db74cb69f"));
173+ $("#username").addClass("c_ccc").attr("readonly", "readonly");
174+ $("#password").val("").addClass("c_ccc").attr("readonly", "readonly");
175+ passporttimeout = setTimeout(function() {
176+ // alert("服务器繁忙,请稍后再试");
177+ $("#password").val(upwd);
178+ $.formValidator.subfalse('submitForm', 'btnSubmit', '登录');
179+ }, 10000);
180+ return true;
181+ },
182+ """
183+
184+ """
185+ 58加密js
186+ http://j2.58cdn.com.cn/js/v6/source/f01f02dc906c8e6734ed04749e5db7cb_102.js
187+
188+ // 1411093327.735 >> 2014/9/19 10:22:7
189+ var timespan = 1411093327735 - new Date().getTime();
190+ var timesign = new Date().getTime() + timespan;
191+ // 30分钟后过期 (1800000/1000/60=30)
192+ // 页面加载到登录过程必须在30分钟内完成
193+ if (timesign - 1411093327735 > 1800000) {
194+ alert("页面已过期,请刷新后再提交");
195+ window.location.href = window.location.href;
196+ return false;
197+ }
198+
199+ var hexcase=0;
200+ var b64pad="";
201+ var chrsz = 8;
202+
203+ function safe_add(a, e) {
204+ var d = (a & 65535) + (e & 65535);
205+ var c = (a >> 16) + (e >> 16) + (d >> 16);
206+ return (c << 16) | (d & 65535);
207+ }
208+ function bit_rol(a, c) {
209+ return (a << c) | (a >>> (32 - c));
210+ }
211+ function md5_cmn(h, e, d, c, g, f) {
212+ return safe_add(bit_rol(safe_add(safe_add(e, h), safe_add(c, f)), g), d);
213+ }
214+ function md5_ff(g, f, l, k, e, j, h) {
215+ return md5_cmn((f & l) | ((~f) & k), g, f, e, j, h);
216+ }
217+ function md5_gg(g, f, l, k, e, j, h) {
218+ return md5_cmn((f & k) | (l & (~k)), g, f, e, j, h);
219+ }
220+ function md5_hh(g, f, l, k, e, j, h) {
221+ return md5_cmn(f ^ l ^ k, g, f, e, j, h);
222+ }
223+ function md5_ii(g, f, l, k, e, j, h) {
224+ return md5_cmn(l ^ (f | (~k)), g, f, e, j, h);
225+ }
226+ function core_md5(r, k) {
227+ r[k >> 5] |= 128 << ((k) % 32);
228+ r[(((k + 64) >>> 9) << 4) + 14] = k;
229+ var q = 1732584193;
230+ var p = -271733879;
231+ var m = -1732584194;
232+ var l = 271733878;
233+ for (var g = 0; g < r.length; g += 16) {
234+ var j = q;
235+ var h = p;
236+ var f = m;
237+ var e = l;
238+ q = md5_ff(q, p, m, l, r[g + 0], 7, -680876936);
239+ l = md5_ff(l, q, p, m, r[g + 1], 12, -389564586);
240+ m = md5_ff(m, l, q, p, r[g + 2], 17, 606105819);
241+ p = md5_ff(p, m, l, q, r[g + 3], 22, -1044525330);
242+ q = md5_ff(q, p, m, l, r[g + 4], 7, -176418897);
243+ l = md5_ff(l, q, p, m, r[g + 5], 12, 1200080426);
244+ m = md5_ff(m, l, q, p, r[g + 6], 17, -1473231341);
245+ p = md5_ff(p, m, l, q, r[g + 7], 22, -45705983);
246+ q = md5_ff(q, p, m, l, r[g + 8], 7, 1770035416);
247+ l = md5_ff(l, q, p, m, r[g + 9], 12, -1958414417);
248+ m = md5_ff(m, l, q, p, r[g + 10], 17, -42063);
249+ p = md5_ff(p, m, l, q, r[g + 11], 22, -1990404162);
250+ q = md5_ff(q, p, m, l, r[g + 12], 7, 1804603682);
251+ l = md5_ff(l, q, p, m, r[g + 13], 12, -40341101);
252+ m = md5_ff(m, l, q, p, r[g + 14], 17, -1502002290);
253+ p = md5_ff(p, m, l, q, r[g + 15], 22, 1236535329);
254+ q = md5_gg(q, p, m, l, r[g + 1], 5, -165796510);
255+ l = md5_gg(l, q, p, m, r[g + 6], 9, -1069501632);
256+ m = md5_gg(m, l, q, p, r[g + 11], 14, 643717713);
257+ p = md5_gg(p, m, l, q, r[g + 0], 20, -373897302);
258+ q = md5_gg(q, p, m, l, r[g + 5], 5, -701558691);
259+ l = md5_gg(l, q, p, m, r[g + 10], 9, 38016083);
260+ m = md5_gg(m, l, q, p, r[g + 15], 14, -660478335);
261+ p = md5_gg(p, m, l, q, r[g + 4], 20, -405537848);
262+ q = md5_gg(q, p, m, l, r[g + 9], 5, 568446438);
263+ l = md5_gg(l, q, p, m, r[g + 14], 9, -1019803690);
264+ m = md5_gg(m, l, q, p, r[g + 3], 14, -187363961);
265+ p = md5_gg(p, m, l, q, r[g + 8], 20, 1163531501);
266+ q = md5_gg(q, p, m, l, r[g + 13], 5, -1444681467);
267+ l = md5_gg(l, q, p, m, r[g + 2], 9, -51403784);
268+ m = md5_gg(m, l, q, p, r[g + 7], 14, 1735328473);
269+ p = md5_gg(p, m, l, q, r[g + 12], 20, -1926607734);
270+ q = md5_hh(q, p, m, l, r[g + 5], 4, -378558);
271+ l = md5_hh(l, q, p, m, r[g + 8], 11, -2022574463);
272+ m = md5_hh(m, l, q, p, r[g + 11], 16, 1839030562);
273+ p = md5_hh(p, m, l, q, r[g + 14], 23, -35309556);
274+ q = md5_hh(q, p, m, l, r[g + 1], 4, -1530992060);
275+ l = md5_hh(l, q, p, m, r[g + 4], 11, 1272893353);
276+ m = md5_hh(m, l, q, p, r[g + 7], 16, -155497632);
277+ p = md5_hh(p, m, l, q, r[g + 10], 23, -1094730640);
278+ q = md5_hh(q, p, m, l, r[g + 13], 4, 681279174);
279+ l = md5_hh(l, q, p, m, r[g + 0], 11, -358537222);
280+ m = md5_hh(m, l, q, p, r[g + 3], 16, -722521979);
281+ p = md5_hh(p, m, l, q, r[g + 6], 23, 76029189);
282+ q = md5_hh(q, p, m, l, r[g + 9], 4, -640364487);
283+ l = md5_hh(l, q, p, m, r[g + 12], 11, -421815835);
284+ m = md5_hh(m, l, q, p, r[g + 15], 16, 530742520);
285+ p = md5_hh(p, m, l, q, r[g + 2], 23, -995338651);
286+ q = md5_ii(q, p, m, l, r[g + 0], 6, -198630844);
287+ l = md5_ii(l, q, p, m, r[g + 7], 10, 1126891415);
288+ m = md5_ii(m, l, q, p, r[g + 14], 15, -1416354905);
289+ p = md5_ii(p, m, l, q, r[g + 5], 21, -57434055);
290+ q = md5_ii(q, p, m, l, r[g + 12], 6, 1700485571);
291+ l = md5_ii(l, q, p, m, r[g + 3], 10, -1894986606);
292+ m = md5_ii(m, l, q, p, r[g + 10], 15, -1051523);
293+ p = md5_ii(p, m, l, q, r[g + 1], 21, -2054922799);
294+ q = md5_ii(q, p, m, l, r[g + 8], 6, 1873313359);
295+ l = md5_ii(l, q, p, m, r[g + 15], 10, -30611744);
296+ m = md5_ii(m, l, q, p, r[g + 6], 15, -1560198380);
297+ p = md5_ii(p, m, l, q, r[g + 13], 21, 1309151649);
298+ q = md5_ii(q, p, m, l, r[g + 4], 6, -145523070);
299+ l = md5_ii(l, q, p, m, r[g + 11], 10, -1120210379);
300+ m = md5_ii(m, l, q, p, r[g + 2], 15, 718787259);
301+ p = md5_ii(p, m, l, q, r[g + 9], 21, -343485551);
302+ q = safe_add(q, j);
303+ p = safe_add(p, h);
304+ m = safe_add(m, f);
305+ l = safe_add(l, e);
306+ }
307+ return Array(q, p, m, l);
308+ }
309+ function hex_md5(a) {
310+ return binl2hex(core_md5(str2binl(a), a.length * chrsz));
311+ }
312+ function reverse(d) {
313+ var a = "";
314+ for (var c = d.length - 1; c >= 0; c--) {
315+ a += d.charAt(c);
316+ }
317+ return a;
318+ }
319+ function hex_md5_16(c) {
320+ var a = hex_md5(c);
321+ a = a.substring(8, 24);
322+ return reverse(a);
323+ }
324+ function str2binl(e) {
325+ var d = Array();
326+ var a = (1 << chrsz) - 1;
327+ for (var c = 0; c < e.length * chrsz; c += chrsz) {
328+ d[c >> 5] |= (e.charCodeAt(c / chrsz) & a) << (c % 32);
329+ }
330+ return d;
331+ }
332+ function binl2hex(d) {
333+ var c = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
334+ var e = "";
335+ for (var a = 0; a < d.length * 4; a++) {
336+ e += c.charAt((d[a >> 2] >> ((a % 4) * 8 + 4)) & 15) + c.charAt((d[a >> 2] >> ((a % 4) * 8)) & 15);
337+ }
338+ return e;
339+ }
340+ function getm32str(c, a) {
341+ if (a.length != 13) {
342+ alert("timesign error !!!");
343+ return "";
344+ }
345+ return hex_md5(hex_md5(c) + a.substring(5, 11));
346+ }
347+ function getm16str(c, a) {
348+ if (a.length != 13) {
349+ alert("timesign error !!!");
350+ return "";
351+ }
352+ return hex_md5(hex_md5_16(c) + a.substring(5, 11));
353+ }
354+ 注释:
355+ js语法
356+ charCodeAt() 方法可返回指定位置的字符的 Unicode 编码。这个返回值是 0 - 65535 之间的整数。
357+ charAt() 方法可返回指定位置的字符。
358+ encodeURIComponent() 函数可把字符串作为 URI 组件进行编码。
359+
360+
361+ 关键的方法encryptString全站都无法搜索到,关于加密的线索只有下面这个链接:
362+ http://passport.58.com/rsa/ppt_security.js
363+ 需要工具解密:
364+ 工具链接:http://www.jb51.net/tools/eval/
365+ 需要了解:eval解密 eval加密
366+
367+
368+ Request URL:http://passport.58.com/dounionlogin
369+ Request Method:POST
370+
371+ Host:passport.58.com
372+ Origin:http://passport.58.com
373+ Referer:http://passport.58.com/login?path=http%3A//sh.58.com/&PGTID=0d100000-0000-28f4-530d-7d16a8b52935&ClickID=1
374+ Upgrade-Insecure-Requests:1
375+ User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36
376+
377+
378+ isweak:1
379+ path:http://sh.58.com/?pts=1449473332235
380+ p1:78106e820110e70c090f21490ae606df
381+ p2:94ab635ef656ec13c96676b1bd437ffc
382+ p3:0d99893d3f9805827f42cf7d93450d1e1de5038a1e0666c5e83e9585e94f2d29bbb7b033ed7b7297513184e75c86cca0e5bbf64d6c8f0c0587a412b761f04e4d8e3b29c0e8be00e256b3e25ceada4697de248969099d81c47616ace91adc0c2fa97d7e726e835ee73a2b36ce8ef7c69e03b6d0fb25af91c2c6ea6912dc96e5ab
383+ timesign:1411093354064
384+ ptk:a9b701b52e70403e80239c5c57026b76
385+ cd:9864
386+ username:abcdefg
387+ password:
388+ source:pc-login
389+ mrisktype:1
390+ pptmobilecodeloginmobile:请输入手机号
391+ pptmobilecodeloginmobilecode:
392+ mcresult:undefined
393+
394+ """
0 commit comments