记一次QQ空间抓包(网页版 & 扫码登录)

2020/04/02 - 粉红的小小白 - 转载转发请标注来源
以下内容仅做学习交流使用,严禁非法用途

最近闲的无聊,于是随手对QQzone进行一次抓包分析

QQ空间

工作开始前我们需要准备的工具有:

工具名称 备注内容 下载链接
Chrome 谷歌浏览器,这里我们用于抓包 •点击下载
postman 一款接口调试工具 •点击下载
Python3 需要用到requests 和 PIL 库 •点击下载
VsCode 也可以使用PyCharm •点击下载

首先我们打开QQ空间网页版

QQ空间 qzone.qq.com

截图

然后我们打开F12调试,点击Network,找到二维码的来源

截图

获取二维码的接口 (ptqrshow) 地址 为:

https://ssl.ptlogin2.qq.com/ptqrshow?appid=549000912&e=2&l=M&s=3&d=72&v=4&t=0.17442452440865464&daid=5&pt_3rd_aid=0

经过多次获取该地址并对其进行分析,对比后发现:

  • 其中的get参数 &t 是随机变动的
  • 在python3中,我们可以使用random库构建一个类似的随机数,我们将他封装为一个函数t(),方便我们后面调用

写代码之前,我们先将必须用到的一些库放在首部导入,代码如下

#若没安装该库则使用pip安装
from PIL import Image # 图片处理
import requests # 发送网络请求
import time # 时间库
import random # 随机数
import json # json库,用来格式化

获取参数 &t 的代码如下

def t(): 
    return str(random.random())

接下来我们将获取二维码的过程封装成一个函数

def getQRC():  # 获取二维码
    url = 'https://ssl.ptlogin2.qq.com/ptqrshow?appid=549000912&e=2&l=M&s=3&d=72&v=4&t=' + t() + '&daid=5&pt_3rd_aid=0'
    res = requests.get(url)
    with open('QRC.png', 'wb') as f:
        f.write(res.content)
    Image.open('QRC.png').show() # 打开二维码图片
    return res.headers # 将请求结果返回,后面会用到

我们把二维码接口地址得到后,接下来我们来看它是怎么通过扫描验证码进行登录的

通过Network我们很容易发现,它会每隔一段时间向同一个接口发送请求,分析后得知,该接口用于判断用户是否已经扫码,然后登录

截图

接口 (ptqrlogin) 地址如下:

https://ssl.ptlogin2.qq.com/ptqrlogin?u1=https%3A%2F%2Fqzs.qq.com%2Fqzone%2Fv5%2Floginsucc.html%3Fpara%3Dizone&ptqrtoken=1889434358&ptredirect=0&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=0-0-1585807008960&js_ver=20032614&js_type=1&login_sig=jhMZlTwCdTy5do0qJy2b2cRJocoxd-rzRYpb9-LszY8DCDM0WJtbcYicUjiNKGI3&pt_uistyle=40&aid=549000912&daid=5&

多次对比分析后发现,我们需要用到的参数有

  • &login_sig
  • &ptqrtoken
  • &action
&login_sig

该参数内容需要从以下接口的 header 里的 Set-Cookie 里获取,并且其参数内容由64位数字,字母和符号"-"构成

接口 (xlogin) 地址如下:

https://xui.ptlogin2.qq.com/cgi-bin/xlogin?proxy_url=https://qzs.qq.com/qzone/v6/portal/proxy.html&daid=5&&hide_title_bar=1&low_login=0&qlogin_auto_login=1&no_verifyimg=1&link_target=blank&appid=549000912&style=22&target=self&s_url=https://qzs.qzone.qq.com/qzone/v5/loginsucc.html?para=izone&pt_qr_app=手机QQ空间&pt_qr_link=http://z.qzone.com/download.html&self_regurl=https://qzs.qq.com/qzone/v6/reg/index.html&pt_qr_help_link=http://z.qzone.com/download.html&pt_no_auth=1

接下来我们调用接口 (xlogin) 后,在header内的Set-Cookie内发现了参数 &login_sig

截图

根据以上需求,我们可以将获取参数 &login_sig 的操作过程封装成函数 (如下),方便我们后面调用

def getLoginSig():
    url = 'https://xui.ptlogin2.qq.com/cgi-bin/xlogin?proxy_url=https://qzs.qq.com/qzone/v6/portal/proxy.html&daid=5&&hide_title_bar=1&low_login=0&qlogin_auto_login=1&no_verifyimg=1&link_target=blank&appid=549000912&style=22&target=self&s_url=https://qzs.qzone.qq.com/qzone/v5/loginsucc.html?para=izone&pt_qr_app=手机QQ空间&pt_qr_link=http://z.qzone.com/download.html&self_regurl=https://qzs.qq.com/qzone/v6/reg/index.html&pt_qr_help_link=http://z.qzone.com/download.html&pt_no_auth=1'
    headers = requests.get(url).headers
    start_index = headers['Set-Cookie'].find('pt_login_sig=') + 13
    return headers['Set-Cookie'][start_index:start_index + 64]
&ptqrtoken

该参数内容需要从获取二维码的接口 (ptqrshow) 中的header内获取,因为不同的二维码,该参数值都是不一样的,因此我们在第一步获取二维码并保存的时候,就需要将header返回,用于参数 &ptqrtoken 的获取
我们从获取二维码的接口 (ptqrshow) 的抓包信息来看,一个名为 &qrsig 的参数符合我们的要求

截图

于是我们将获取参数 &ptqrtoken 的过程封装成一个函数

def getQRCSig(headers):  # 将获取二维码接口的headers传进来
    return ptqrtoken(headers['Set-Cookie'].split(';')[0][6:])
    
def ptqrtoken(value):  # 构造ptqrttoken的加密方式
    i = 0
    e = 0
    n = len(value)
    for i in range(n):
        e = e + (e << 5)
        e = e + ord(value[i])
    return str(2147483647 & e)
&action

通过分析后得到,该参数内容为当前的时间戳乘以1000,并在首部加上字符串"0-0-",于是我们将获取参数 &action 的过程封装成一个函数

def getAction():  # 构造action参数
    import time
    return '0-0-' + str(int(time.time() * 1000))

然后我们现在回到接口 (ptqrlogin), 我们到现在已经获取了三个必须用到的参数,我们现在来构建函数 ifLogin() ,这个函数可以设置while循环,循环一次睡眠5秒,用来检测用户是否扫描成功以及是否登录成功

def ifLogin(ptqrtoken, loginSig):
    url = "https://ssl.ptlogin2.qq.com/ptqrlogin?u1=https://qzs.qzone.qq.com/qzone/v5/loginsucc.html?para=izone&ptqrtoken=" + ptqrtoken + "&ptredirect=0&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=" + action() + "&js_ver=19112817&js_type=1&login_sig=" + loginSig + "&pt_uistyle=40&aid=549000912&daid=5&"
    return requests.get(url).text[7:-1].replace("'", "").split(',')

下面是该接口 (ptqrlogin) 在不同场景下返回的数据

  • 未扫描二维码时返回的数据
截图
  • 扫描二维码后返回的数据
截图
  • 二维码失效后返回的数据
截图
  • 扫描成功后返回的数据
截图

然后分析后得到,我们通过去除返回文本的前七个字符和倒数第一个字符,然后将剩下的文本分割成数组

数组第一个项可以作为我们判断的依据

  • 65 已失效
  • 66 未失效
  • 67 已扫描,但还未点击确认
  • 0   已经点击确认,并登录成功

注: 登录成功后返回的数据中,数组的第三项为跳转链接,最后一项为QQ网名

待更新

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • width: 65%;border: 1px solid #ddd;outline: 1300px solid #...
    邵胜奥阅读 4,762评论 0 1
  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,362评论 0 5
  • 下午喝酒有点多,睡了一觉,又吃了不少饭,撑到吐,熬到现在睡不着了。 刷刷携程,想去旅游。翻翻极客时间,没心思看。想...
    rekyll阅读 164评论 0 0
  • 1.CSS和JS在网页中的放置顺序是怎样的? CSS应该放在顶部,即 标签里,放在其他位置可能出现白屏或者-FO...
    饥人谷_bigJiao阅读 247评论 0 1
  • 我会熬过这个漫长的冬季而后前程似锦吗?
    醉媪阅读 171评论 0 0