Skip to content

Commit 91d23f4

Browse files
committed
WebQQ模拟登录成功
1 parent 663aa8a commit 91d23f4

5 files changed

Lines changed: 152 additions & 11 deletions

File tree

tools/convert.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ def test():
4747

4848
if __name__ == "__main__":
4949
test()
50+
print system_to_decimal('000000001b2025f6', 16)
5051

5152

5253
"""

webqq/Tea.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# encoding: utf-8
2+
__author__ = 'zhanghe'
3+
4+
"""
5+
The MIT License
6+
Copyright (c) 2005 hoxide
7+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10+
QQ Crypt module.
11+
"""
12+
13+
from struct import pack as _pack
14+
from struct import unpack as _unpack
15+
from binascii import b2a_hex, a2b_hex
16+
17+
from random import seed
18+
from random import randint as _randint
19+
20+
__all__ = ['encrypt', 'decrypt']
21+
22+
seed()
23+
24+
op = 0xffffffffL
25+
26+
27+
def xor(a, b):
28+
a1, a2 = _unpack('>LL', a[0:8])
29+
b1, b2 = _unpack('>LL', b[0:8])
30+
r = _pack('>LL', (a1 ^ b1) & op, (a2 ^ b2) & op)
31+
return r
32+
33+
34+
def code(v, k):
35+
n = 16 # qq use 16
36+
delta = 0x9e3779b9L
37+
k = _unpack('>LLLL', k[0:16])
38+
y, z = _unpack('>LL', v[0:8])
39+
s = 0
40+
for i in xrange(n):
41+
s += delta
42+
y += (op & (z << 4)) + k[0] ^ z + s ^ (op & (z >> 5)) + k[1];
43+
y &= op
44+
z += (op & (y << 4)) + k[2] ^ y + s ^ (op & (y >> 5)) + k[3];
45+
z &= op
46+
r = _pack('>LL', y, z)
47+
return r
48+
49+
50+
def encrypt(v, k):
51+
END_CHAR = '\0'
52+
FILL_N_OR = 0xF8
53+
vl = len(v)
54+
filln = ((8 - (vl + 2)) % 8) + 2
55+
fills = ''
56+
for i in xrange(filln):
57+
fills += chr(_randint(0, 0xff))
58+
v = (chr((filln - 2) | FILL_N_OR)
59+
+ fills
60+
+ v
61+
+ END_CHAR * 7)
62+
tr = '\0' * 8
63+
to = '\0' * 8
64+
r = ''
65+
o = '\0' * 8
66+
for i in xrange(0, len(v), 8):
67+
o = xor(v[i:i + 8], tr)
68+
tr = xor(code(o, k), to)
69+
to = o
70+
r += tr
71+
return r
72+
73+
74+
if __name__ == "__main__":
75+
print b2a_hex(encrypt(a2b_hex(
76+
'0018001600010000044800000001000014fb02dda52300000000030900080001b73c38560002003600120002000100000000000000000000000000000114001d01020019034c4f55458f7948953c5a2256af39efaf21a0b75a7385f34100000000'),
77+
b2a_hex('b537a06cf3bcb33206237d7149c27bc3')))
78+
# print b2a_hex(decrypt(a2b_hex('16F793BD36D4F53A23DD329198E6BBBE0FC493AF02FE46148A1A63A8C2232FBD13ABB080CDC617F3D25CB3138A512042ED3D46514FDD340A04A68C3BAD8CF35BF8C8AD8CAE4AE682B4C7DAB3947B7625D077F6021971DC06DA8BA0391A247F813C5A7B310C236536'), a2b_hex('E6992970E51D5CD9DFC7D061DD52EB27')))

webqq/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# encoding: utf-8
2+
__author__ = 'zhanghe'
3+

webqq/pswEncrypt.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# encoding: utf-8
2+
__author__ = 'zhanghe'
3+
4+
import hashlib
5+
import md5
6+
import rsa
7+
import Tea
8+
import base64
9+
10+
# RSA 公钥
11+
pubkey = "F20CE00BAE5361F8FA3AE9CEFA495362FF7DA1BA628F64A347F0A8C012BF0B254A30CD92ABFFE7A6EE0DC424CB6166F8819EFA5BCCB20EDFB4AD02E412CCF579B1CA711D55B8B0B3AEB60153D5E0693A2A86F3167D7847A0CB8B00004716A9095D9BADC977CBB804DBDCBA6029A9710869A453F27DFDDF83C016D928B3CBF4C7"
12+
rsa_public_key = int(pubkey, 16)
13+
key = rsa.PublicKey(rsa_public_key, 3)
14+
15+
16+
def get_tea_pass(q, p, v):
17+
# MD5 密码
18+
p = md5.new(p).digest()
19+
20+
# TEA 的KEY
21+
m = md5.new(p + ("%0.16X" % q).decode('hex')).digest()
22+
23+
# RSA的加密结果
24+
n = rsa.encrypt(p, key)
25+
26+
# RSA 结果的长度
27+
d = ("%0.4X" % len(n)).decode('hex')
28+
29+
# RSA 加密结果
30+
d += n
31+
32+
# salt
33+
d += ("%0.16X" % q).decode('hex')
34+
35+
# 验证码长度
36+
d += ("%0.4X" % len(v)).decode('hex')
37+
38+
# 验证码
39+
d += v.upper()
40+
41+
# TEA 加密并Base64编码
42+
r = base64.b64encode(Tea.encrypt(d, m))
43+
44+
# 对特殊字符进行替换
45+
return r.replace('/', '-').replace('+', '*').replace('=', '_')

web_qq.py renamed to webqq/web_qq.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import random
88
import time
99
import os
10+
import pswEncrypt
1011

1112

1213
# 入口
@@ -25,15 +26,11 @@
2526
header = {
2627
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36'}
2728

28-
# 加密salt
29-
salt = ''
30-
3129
# 登录需要的参数
3230
payload = {
33-
'u': '234567',
34-
'p': '2rDrq7sBKdqkqzHgyntOBpaM6p8RAAcBpEio3*UCWuMNiG0LUw6WRsKTDsps2GJ6vAf1CPd-HoNl-QFekDH9Lfn54h1KOvOZeQlARGNPON0JECRoSUF1*8kOezqzRqBFMVVPM5cMJ3PFjn00*5KbpSHkHAJHF9AV3kV-JKE0iChfjaXcOBkRKv75mM2j8RQByBz0KFPssmrgKqPIGGatXw__',
35-
# 'verifycode': '!NQA',
36-
'verifycode': '!QYD',
31+
'u': '',
32+
'p': '',
33+
'verifycode': '!QYD', # !QYD
3734
# 隐藏域表单参数-------------start
3835
'webqq_type': '10', # 10: "在线",20: "离线",30: "离开",40: "隐身",50: "忙碌",60: "Q我吧",70: "请勿打扰",
3936
'remember_uin': '1',
@@ -105,8 +102,8 @@ def get_check():
105102
# 具体参数参考607行[https://ui.ptlogin2.qq.com/js/10125/mq_comm.js]
106103
response = s.get(url_check, params=check_payload, headers=header)
107104
check_dict = response.content
105+
print check_dict
108106
payload['verifycode'] = check_dict.split(',')[1].strip('\'')
109-
salt = check_dict.split(',')[2].strip('\'')
110107
payload['pt_verifysession_v1'] = check_dict.split(',')[3].strip('\'')
111108

112109

@@ -139,6 +136,11 @@ def login():
139136

140137

141138
if __name__ == "__main__":
139+
# 设置账号密码
140+
NAME = 455091702
141+
PASS = '123456'
142+
143+
payload['u'] = NAME
142144
# 获取隐藏域表单参数
143145
params_html = get_hide_params_html()
144146
params = parse_hide_params(params_html)
@@ -147,14 +149,26 @@ def login():
147149
payload = dict(payload, **payload_hide_params)
148150
# 获取验证参数
149151
get_check()
150-
152+
# 获取加密的密码
153+
payload['p'] = pswEncrypt.get_tea_pass(NAME, PASS, payload['verifycode'])
154+
# 记录登录参数
151155
print json.dumps(payload, ensure_ascii=False, indent=4)
152156
# 登录
153157
result = login()
154158
print result
155159

156160

157161
"""
158-
对于加密部分,最好的方案是引入外部js到本地作为单独的服务
159-
如果将算法集成到代码里,加密算法变更后,还要重写
162+
对于加密部分,最好的方案是引入外部js到本地作为单独的服务,但这种方案没有成功
163+
如果将算法集成到代码里,加密算法变更后,还要重写,目前是这种方式
164+
165+
登录失败提示:
166+
ptuiCB('3','0','','0','您输入的帐号或密码不正确,请重新输入。', '10000');
167+
168+
登录成功提示:
169+
ptuiCB('0','0','http://ptlogin4.web2.qq.com/check_sig?pttype=1&uin=455091702&service=login&nodirect=0&ptsigx=0cfd5d7d11011c487d8cd854cbb7cebb52ffd113651fde7f62bf959620ca6e24942484a017e32b37fc2bd677965f64b8b55a4edc5ae225eac27f0739f1a1b243&s_url=http%3A%2F%2Fw.qq.com%2Fproxy.html&f_url=&ptlang=2052&ptredirect=100&aid=501004106&daid=164&j_later=0&low_login_hour=0&regmaster=0&pt_login_type=1&pt_aid=0&pt_aaid=0&pt_light=0&pt_3rd_aid=0','0','登录成功!', '空ping子');
170+
171+
模拟登录成功实现
172+
下一步消息发送
173+
160174
"""

0 commit comments

Comments
 (0)