• 二维码扫码登陆过程分析


    以pay.qq.com查询QQ账号Q币信息为例,了解一下网站的二维码登陆大致是如何实现的

    首先打开腾讯pay.qq.com主页上的登陆就可以获取到二维码了,使用浏览器的F12分析请求过程

    clip_image002

    发现通过打开的https://xui.ptlogin2.qq.com/cgi-bin/xlogin?appid=11000101&target=self&style=40&s_url=https://pay.qq.com/ipay/login-proxy.html可以获取到cookies,这个url就先记下来

    clip_image004

    继续往下,打开下面的url,响应回来的就是二维码了

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

    那这些请求的参数是如何得到的呢,多次请求分析发现只有t是随机变化的,那就给个随机数吧

    参数t的python生成方式(python生成的随机数多一位)

    import random
    a=str(random.random())
    print(a)
    print(a[:-1])
    

    当用手机扫了二维码之后,会发现一直请求一个地址,而返回的内容就是判定二维码是否过期的结果。但是请求的url随二维码的更新而变化的

    clip_image006

    获取是否过期(通过请求的url发现如下规律)

    https://ssl.ptlogin2.qq.com/ptqrlogin?u1=https://pay.qq.com/ipay/login-proxy.html&ptqrtoken=1300613866&ptredirect=0&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=0-0-1514654333018&js_ver=10233&js_type=1&login_sig=pGo5iOnV6O*DY3BgsPM22zAvlWCnVl48PPjrmWIJtQKMHpvYCoWpavmP1JcdWn6g&pt_uistyle=40&aid=11000101&

    https://ssl.ptlogin2.qq.com/ptqrlogin?u1=https://pay.qq.com/ipay/login-proxy.html&ptqrtoken=1641999182&ptredirect=0&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=0-0-1514655242011&js_ver=10233&js_type=1&login_sig=pGo5iOnV6O*DY3BgsPM22zAvlWCnVl48PPjrmWIJtQKMHpvYCoWpavmP1JcdWn6g&pt_uistyle=40&aid=11000101&

    https://ssl.ptlogin2.qq.com/ptqrlogin?u1=https://pay.qq.com/ipay/login-proxy.html&ptqrtoken=1460309603&ptredirect=0&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=0-0-1514656150867&js_ver=10233&js_type=1&login_sig=pGo5iOnV6O*DY3BgsPM22zAvlWCnVl48PPjrmWIJtQKMHpvYCoWpavmP1JcdWn6g&pt_uistyle=40&aid=11000101&

    这些url返回结果如下这样的形式

    ptuiCB('66','0','','0','二维码未失效。(2079330212)', '')

    那么,这次的url所附带的参数更多了,究竟是如何生成的,由于没有学习过JavaScript,但是猜想这种交互式的网页一定有js控制的。

    打开请求主页中所有的js链接,文件中都没有相关信息,于是重头分析请求过程,发现请求了一个url里面返回大量函数,里面有且仅有一个ptqrtoken变量

    https://imgcache.qq.com/ptlogin/ver/10233/js/c_login_2.js?max_age=604800&ptui_identifier=000E010D989AA31CE07BA6E98F56BC76012729B221D540BFF0DE375CAC8A

    clip_image008

    这个url返回的代码里面找到getSubmitUrl函数如下:

    clip_image010

    三个参数ptqrtoken、action、login_sig。两个参数都在函数中说明了,login_sig同样在这段返回的代码里面,事实上就是cookies里面的pt_login_sig

    clip_image012

    于是乎可以试着构造一个这样的url,判断二维码是否有效。响应的代码里面跟三个参数有关的代码如下

    函数的具体实现—ptqrtoken生成

    hash33:function(t){
    for(var e=0,i=0,n=t.length;i<n;++i)
    e+=(e<<5)+t.charCodeAt(i);
    return 2147483647&e
    }
    

    函数的具体实现—action生成

    ,pt.plogin={account:"",at_account:"",uin:"",salt:"",checkState:!1,lastCheckAccount:"",needVc:!1,vcFlag:!1,ckNum:{},action:[0,0],passwordErrorNum:1,isIpad:!1,seller_id:703010802
    action.join(“-”)+”-”+(new Date-0)
    

    函数的具体实现—login_sig生成(这个是http响应时返回的)

    login_sig=pt.ptui.login.sig

    用javascript测试下实现函数功能的代码(不懂js所以先试下运行出来是什么结果)

    1ptqrtoken

    <script type="text/javascript">
    document.write(isNaN(123)+ "<br />")
    function test(t){
    for(var e=0,i=0,n=t.length;i<n;++i)
    e+=(e<<5)+t.charCodeAt(i);
    return 2147483647&e;
    }
    document.write(test("l5ReOk*DhvMzPYYjfqWzkYjwSs52j6lzw1Oy6SaMsUNywLorCwuRuP8TbGfzSf*a"))
    </script>
    

    2action

    document.write(new Date-0);
    document.write("<br/>")
    var t=new Date()
    action=[0,0]
    document.write(action.join("-")+"-"+t.getTime())
    

    知道了逻辑,用python重写javascript的函数来实现同样功能

    ptqrtoken的生成

    t1="l5ReOk*DhvMzPYYjfqWzkYjwSs52j6lzw1Oy6SaMsUNywLorCwuRuP8TbGfzSf*a"
    def test(t):
    i=0
    e=0
    n=len(t)
    fori in range(n):
    e=e+(e<<5)
    e=e+ord(t[i])
    print(e)
    print(2147483647&e)
    test(t1)
    

    action的生成就只是一个时间函数

    import time
    print(int(time.time()*1000))
    

    继续往下分析连续请求该Url响应用户的扫码登陆状态,发现扫码成功后,也会返回cookies

    带着cookies请求个人账户主页https://my.pay.qq.com/account/index.shtml?aid=pay.index.header.acct&ADTAG=pay.index.header.acc

    发现返回的内容还是没有Q币的信息,说明内容还是由javascript动态生成

    image

    返回的js里面是没有Q币信息的

    clip_image015

    继续分析下面请求的url

    clip_image017

    发现了这个 https://my.pay.qq.com/cgi-bin/personal/balance_query_sortflow.cgi?items=qd,qb&_=0.9267836264725212

    clip_image019

    于是返回的json,qb_balance就是个人账户的Q币

    import requests
    import time
    import random
    def ptqrtoken_str(qrsig):  #三个函数就是url的三个参数生成
        i=0
        e=0
        n=len(qrsig)
        for i in range(n):
            e=e+(e<<5)
            e=e+ord(qrsig[i])
            e=2147483647&e
        return e
    
    def action_str():
        a=int(time.time()*1000)
        b='0-0-'+str(a)
        return b
    
    def pt_loginsig_str(ckiesget):
        st=ckiesget.headers['Set-Cookie']
        return st[st.find('pt_login_sig=')+13:st.find('pt_login_sig=')+77]
        
    url_getcookies="https://xui.ptlogin2.qq.com/cgi-bin/xlogin?appid=11000101&target=self&style=40&s_url=https://pay.qq.com/ipay/login-proxy.html"
    s=requests.session()     #requests的session可以自动管理cookies
    ckget=s.get(url_getcookies)
    
    t=str(random.random())
    url_getqr="https://ssl.ptlogin2.qq.com/ptqrshow?appid=11000101&e=2&l=M&s=3&d=72&v=4&t="+t[:-1]+"&pt_3rd_aid=0"
    qrget=s.get(url_getqr)
    
    
    f=open('tmp.png','wb') #将二维码保存为图片手动打开来扫码^_^
    f.write(qrget.content)
    f.close()
    
    
    for i in range(1,7): #简单的循环返回二维码是否失效,循环结束前扫码就获得了cookies
        time.sleep(3)
        qrsig=qrget.headers['Set-Cookie'].split(';')[0][6:]
        url_check_timeout="https://ssl.ptlogin2.qq.com/ptqrlogin?u1=https://pay.qq.com/ipay/login-proxy.html&ptqrtoken="+str(ptqrtoken_str(qrsig))+"&ptredirect=0&h=1&t=1&g=1&from_ui=1&ptlang=2052&action="+action_str()+"&js_ver=10233&js_type=1&login_sig="+pt_loginsig_str(ckget)+"&pt_uistyle=40&aid=11000101&"
        timeoutget=s.get(url_check_timeout)
        print(timeoutget.status_code)
        print('----------------text---------------')
        print(timeoutget.text)
    print(timeoutget.headers)
    
    happy3=s.get("https://my.pay.qq.com/cgi-bin/personal/balance_query_sortflow.cgi?items=qd,qb&_="+str(random.random()))
    print(happy3.text)
    
        
    
    
  • 相关阅读:
    TP3.2框架,实现空模块、空控制器、空操作的页面404替换||同步实现apache报错404页面替换
    调用支付宝PHP接口API实现在线即时支付功能(UTF-8编码)
    JQuery实现的 checkbox 全选;<select>下拉框功能
    使用PHP做移动端 api接口开发方法(适用于TP框架)
    Eclipse jvm启动参数在哪设置
    对 META标签 的一点点了解
    Java反射在整个程序运行中的位置
    Java 为什么要使用反射(通俗易懂的举例)
    粗略介绍Java AQS的实现原理
    Java并发包中线程池的种类和特点介绍
  • 原文地址:https://www.cnblogs.com/otherside/p/8331778.html
Copyright © 2020-2023  润新知